Introdução

Documentação de Implantação — API Pública do Blog

Este documento descreve como usuários do SaaS devem integrar e implantar chamadas ao conjunto de rotas públicas do blog (posts, categorias, tags). Essas rotas exigem uma chave de API (X-API-Key).

Quickstart

Passos essenciais

  1. Obtenha a API Key do seu blog (Configurações → API Key).
  2. Faça uma chamada GET para /public/posts com o header X-API-Key: {SUA_API_KEY}.
  3. Use os endpoints de posts, categories e tags conforme necessário.

Exemplo de requisição básica

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getPosts() {
  const url = 'https://api.draftin.io/public/posts?limit=10&offset=0';
  const response = await axios.get(url, config);
  console.log(response.data);
}

getPosts();
      

Autenticação

Uso do header X-API-Key

Todas as rotas públicas exigem o header HTTP X-API-Key com a chave associada ao blog.

Header necessário: X-API-Key: {API_KEY_DO_BLOG}

Como obter a chave: a chave é gerada/visualizada no painel do blog (Configurações → Blogs)

Nota de segurança: a API key identifica o blog para leituras públicas. Não a exponha em logs públicos ou em repositórios.

Endpoints

Observação: todas as rotas usam o prefixo /public

1) Lista de posts

Método: GET — Rota: /public/posts

Query params: status (opcional), limit (opcional), offset (opcional).

Listar posts

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function listPosts() {
  const url = 'https://api.draftin.io/public/posts?limit=5&offset=0';
  const response = await axios.get(url, config);
  console.log(response.data);
}

listPosts();
      

2) Buscar post por ID

GET /public/posts/{id}

Buscar post por ID

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getPostById(postId) {
  const url = 'https://api.draftin.io/public/posts/' + postId;
  const response = await axios.get(url, config);
  console.log(response.data);
}

getPostById(123);
      

3) Buscar post por slug

GET /public/posts/slug/{slug}

Buscar post por slug

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getPostBySlug(slug) {
  const url = 'https://api.draftin.io/public/posts/slug/' + slug;
  const response = await axios.get(url, config);
  console.log(response.data);
}

getPostBySlug('meu-post-exemplo');
      

4) Lista de categorias

GET /public/categories

Listar categorias

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getCategories() {
  const response = await axios.get('https://api.draftin.io/public/categories', config);
  console.log(response.data);
}

getCategories();
      

5) Buscar categoria por ID

GET /public/categories/{id}

Buscar categoria por ID

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getCategoryById(categoryId) {
  const url = 'https://api.draftin.io/public/categories/' + categoryId;
  const response = await axios.get(url, config);
  console.log(response.data);
}

getCategoryById(123);
      

6) Lista de posts por categoria

GET /public/categories/{id}/posts

Posts por categoria

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getPostsByCategoryId(categoryId) {
  const url = 'https://api.draftin.io/public/categories/' + categoryId + '/posts';
  const response = await axios.get(url, config);
  console.log(response.data);
}

getPostsByCategoryId(123);
      

7) Lista de tags

GET /public/tags

Listar tags

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getTags() {
  const response = await axios.get('https://api.draftin.io/public/tags', config);
  console.log(response.data);
}

getTags();
      

8) Buscar tag por ID

GET /public/tags/{id}

Buscar tag por ID

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getTagById(tagId) {
  const url = 'https://api.draftin.io/public/tags/' + tagId;
  const response = await axios.get(url, config);
  console.log(response.data);
}

getTagById(123);
      

9) Lista de posts por tag

GET /public/tags/{id}/posts

Posts por tag

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'abcd1234-exemplo' } // Substitua pela sua API Key
};

async function getPostsByTagId(tagId) {
  const url = 'https://api.draftin.io/public/tags/' + tagId + '/posts';
  const response = await axios.get(url, config);
  console.log(response.data);
}

getPostsByTagId(123);
      

Formato dos objetos (resumo rápido)

Post: campos relevantes — id, title, subtitle, slug, content, coverUrl, status, publishedAt, scheduledAt, authorId, blogId, tenantId, createdAt, updatedAt.

Category: id, name, slug, description, blogId, tenantId, createdAt, updatedAt.

Tag: id, name, slug, blogId, tenantId, createdAt, updatedAt.

Tratamento de erros e códigos HTTP

Respostas de erro seguem o esquema ErrorResponse com objeto error contendo message, code, type, statusCode, timestamp e details.

  • 401 Unauthorized: chave X-API-Key ausente ou inválida.
  • 404 Not Found: recurso não encontrado.
  • 429 Too Many Requests: limite de requisições alcançado.
  • 500 Internal Server Error: erro do servidor.

Exemplo de resposta de erro

        {
  "success": false,
  "error": {
    "message": "API key inválida ou ausente",
    "code": "AUTH_INVALID_API_KEY",
    "type": "authentication",
    "statusCode": 401,
    "timestamp": "2025-08-21T10:00:00.000Z",
    "retryable": false
  }
}
      

Boas práticas

  • Cacheie as respostas públicas (posts, categorias, tags) no CDN/edge por alguns minutos.
  • Use limit + offset para paginação.
  • Valide os slugs localmente antes de fazer requests.
  • Trate 429 com backoff exponencial.
  • Não exponha a X-API-Key em repositórios públicos.

Exemplo de integração rápida (Javascript / fetch)

Exemplo de integração com JavaScript

        import axios from 'axios';

const config = {
  headers: { 'X-API-Key': 'SUA_API_KEY_AQUI' } // Lembre-se de substituir pela sua chave
};

async function fetchPosts(limit = 10, offset = 0) {
  const response = await axios.get('https://api.draftin.io/public/posts', {
    ...config,
    params: { limit, offset }
  });
  return response.data;
}

async function main() {
  const posts = await fetchPosts(5);
  console.log('Posts recebidos:', posts);
}

main();
      

Perguntas frequentes (FAQ)

Q: Preciso de autenticação por usuário para acessar essas rotas?
A: Não. As rotas públicas usam X-API-Key para identificar o blog.

Q: A API pública retorna conteúdo filtrado por permissões?
A: A chave do blog identifica o blog e o conteúdo visível (posts com PUBLISHED).

Suporte

Se encontrar comportamento inconsistente entre a spec e os endpoints, reporte ao time de suporte com: exemplo de request (URL + headers), payload de resposta (body) e timestamp UTC da requisição para [email protected].