Skip to content

Posts ​

O módulo de posts é o coração do seu blog. Ele permite que você crie, gerencie e publique artigos ricos em conteúdo, com suporte a SEO, categorias, tags e imagens de capa.

Cada post possui um ciclo de vida simples: ele nasce como rascunho (draft) e, quando estiver pronto, pode ser publicado (published) — com uma data de publicação opcional para agendamento.


Estrutura de Dados Principal ​

Um post contém as seguintes informações principais:

CampoTipoDescrição
titleStringTítulo principal do artigo (máx. 150 caracteres).
slugStringURL amigável única no blog (ex: meu-artigo-incrivel).
excerptStringResumo curto do artigo (máx. 500 caracteres).
contentStringConteúdo completo (suporta HTML).
readingTimeIntegerTempo de leitura estimado em segundos (calculado automaticamente a partir do conteúdo).
statusEnumdraft ou published.
isFeaturedBooleanIndica se o post está em destaque.
viewCountIntegerContador de visualizações (incrementado a cada acesso público por slug).
publishedAtDateData de publicação (formato YYYY-MM-DD HH:mm:ss).
seoTitleStringTítulo para SEO (máx. 200 caracteres).
seoDescriptionStringDescrição para SEO (máx. 200 caracteres).
seoKeywordsStringPalavras-chave para SEO (máx. 200 caracteres).

Endpoints Públicos ​

Estes endpoints são voltados para o frontend do blog e não exigem autenticação administrativa — apenas o header X-Blog-Id. Eles retornam apenas posts com o status published.

Listar Posts Publicados ​

Retorna uma lista paginada de todos os posts publicados.

http
GET /v1/blog/posts/public/published

Parâmetros de Query ​

NomeTipoObrigatórioDescrição
pagenumberNãoO número da página (mínimo: 1).
perPagenumberNãoItens por página.
searchstringNãoBusca por termo no título (máx. 150 caracteres).
isFeaturedbooleanNãoFiltra apenas posts em destaque.
categoriesnumber[]NãoFiltra por IDs de categorias (ex: categories[]=5).
tagsnumber[]NãoFiltra por IDs de tags (ex: tags[]=1&tags[]=2).
orderByenumNãoCampo de ordenação: id, title ou createdAt.
orderDirectionenumNãoDireção da ordenação: asc ou desc.

Exemplo de Requisição ​

bash
curl -X GET "https://api.us.basis.tavares.in/v1/blog/posts/public/published?page=1&perPage=10" \
  -H "X-Blog-Id: {blog-id}" \
  -H "Accept: application/json"

Respostas ​

200 OK

Retorna um objeto de paginação contendo a lista de posts publicados.

json
{
  "meta": {
    "currentPage": "1",
    "perPage": "25"
  },
  "data": [
    {
      "id": "16",
      "blogUserId": "6",
      "blogImageId": "7",
      "title": "Novidades da Versão 2.0",
      "slug": "novidades-versao-2-0",
      "excerpt": "Um resumo sobre as novidades...",
      "seoTitle": "Novidades da Versão 2.0",
      "seoDescription": "Conheça tudo o que chegou na versão 2.0.",
      "seoKeywords": "novidades, versão, release",
      "createdAt": "2026-03-25T16:24:24.411-03:00",
      "updatedAt": "2026-03-25T16:53:33.693-03:00",
      "readingTime": 29,
      "isFeatured": true,
      "viewCount": "11111",
      "publishedAt": "2026-03-25T17:17:00.000+00:00",
      "status": "published",
      "blogImage": {
        "id": "7",
        "name": "capa.jpg",
        "uri": "https://cdn.exemplo.com/images/4efdbdfa-b867-4821-aa63-8e135eac8bb2.jpg"
      },
      "blogUser": {
        "id": "6",
        "firstName": "Maria",
        "lastName": "Silva",
        "email": "autor@exemplo.com",
        "blogImageId": "5",
        "blogImage": {
          "id": "5",
          "name": "avatar.jpg",
          "uri": "https://cdn.exemplo.com/images/1635fe4c-c41f-439b-8dd8-0ab0613d569e.jpg"
        }
      }
    }
  ]
}

Obter Post por Slug ​

Recupera os detalhes completos de um post publicado através do seu slug único. Cada acesso a este endpoint incrementa o viewCount do post.

http
GET /v1/blog/posts/public/slug/:slug

Parâmetros de Rota ​

NomeTipoObrigatórioDescrição
slugstringSimO slug único do post (ex: novidades-versao-2-0).

Exemplo de Requisição ​

javascript
fetch('https://api.us.basis.tavares.in/v1/blog/posts/public/slug/novidades-versao-2-0', {
  headers: { 'X-Blog-Id': '{blog-id}' }
})
  .then(response => response.json())
  .then(data => console.log(data));

Respostas ​

200 OK

Retorna o post completo, incluindo content, autor e imagem de capa.

json
{
  "id": "16",
  "title": "Novidades da Versão 2.0",
  "slug": "novidades-versao-2-0",
  "excerpt": "Um resumo sobre as novidades...",
  "content": "<p>Conteúdo completo do artigo...</p>",
  "seoTitle": "Novidades da Versão 2.0",
  "seoDescription": "Conheça tudo o que chegou na versão 2.0.",
  "seoKeywords": "novidades, versão, release",
  "createdAt": "2026-03-25T16:24:24.411-03:00",
  "updatedAt": "2026-03-25T16:51:11.991-03:00",
  "blogUserId": "6",
  "blogImageId": "7",
  "readingTime": 29,
  "isFeatured": true,
  "viewCount": "1111",
  "status": "published",
  "blogImage": {
    "id": "7",
    "name": "capa.jpg",
    "uri": "https://cdn.exemplo.com/images/4efdbdfa-b867-4821-aa63-8e135eac8bb2.jpg"
  },
  "blogUser": {
    "id": "6",
    "firstName": "Maria",
    "lastName": "Silva",
    "email": "autor@exemplo.com",
    "blogImageId": "5",
    "bio": null,
    "blogImage": {
      "id": "5",
      "name": "avatar.jpg",
      "uri": "https://cdn.exemplo.com/images/1635fe4c-c41f-439b-8dd8-0ab0613d569e.jpg"
    }
  }
}

404 Not Found

Ocorre quando o post não existe ou não está publicado.


Obter Post por ID ​

Recupera os detalhes completos de um post publicado através do seu ID.

http
GET /v1/blog/posts/public/:id

Parâmetros de Rota ​

NomeTipoObrigatórioDescrição
idnumberSimO ID do post publicado.

Respostas ​

200 OK

Retorna o post completo, na mesma estrutura do endpoint por slug.


Endpoints Administrativos ​

Endpoints protegidos para gerenciamento de conteúdo. Requerem autenticação de usuário do blog (Authorization: Bearer {token} e X-Blog-Id).

Listar Todos os Posts ​

Lista todos os posts do blog, incluindo rascunhos.

http
GET /v1/blog/posts

Parâmetros de Query ​

Além dos filtros de paginação e busca (page, perPage, search, orderBy, orderDirection), permite filtrar por status, destaque, categorias e tags:

NomeTipoObrigatórioDescrição
statusenumNãoFiltra por published ou draft.
isFeaturedbooleanNãoFiltra apenas posts em destaque.
categoriesnumber[]NãoFiltra por IDs de categorias.
tagsnumber[]NãoFiltra por IDs de tags.

Exemplo de Requisição ​

bash
curl -X GET "https://api.us.basis.tavares.in/v1/blog/posts?page=1&perPage=15&status=draft&tags[]=2" \
  -H "Authorization: Bearer {token}" \
  -H "X-Blog-Id: {blog-id}"

Respostas ​

200 OK

Retorna a lista paginada de posts, incluindo tags e categorias vinculadas.

json
{
  "meta": {
    "currentPage": "1",
    "perPage": "25"
  },
  "data": [
    {
      "id": "17",
      "blogUserId": "6",
      "blogImageId": "5",
      "title": "Novidades da Versão 2.0",
      "slug": "novidades-versao-2-0",
      "excerpt": "Um resumo sobre as novidades...",
      "seoTitle": "Novidades da Versão 2.0",
      "seoDescription": "Conheça tudo o que chegou na versão 2.0.",
      "seoKeywords": "novidades, versão, release",
      "createdAt": "2026-03-30T00:45:48.940+00:00",
      "updatedAt": "2026-03-30T00:45:48.940+00:00",
      "readingTime": 29,
      "isFeatured": true,
      "viewCount": "0",
      "publishedAt": null,
      "status": "draft",
      "blogTags": [
        { "id": "1", "name": "Release" },
        { "id": "2", "name": "Produto" }
      ],
      "blogImage": {
        "id": "5",
        "name": "capa.jpg",
        "uri": "https://cdn.exemplo.com/images/1635fe4c-c41f-439b-8dd8-0ab0613d569e.jpg"
      },
      "blogCategories": [
        { "id": "5", "name": "Tecnologia" },
        { "id": "6", "name": "Desenvolvimento" }
      ],
      "blogUser": {
        "id": "6",
        "firstName": "Maria",
        "lastName": "Silva",
        "email": "autor@exemplo.com",
        "blogImageId": "5",
        "blogImage": {
          "id": "5",
          "name": "avatar.jpg",
          "uri": "https://cdn.exemplo.com/images/1635fe4c-c41f-439b-8dd8-0ab0613d569e.jpg"
        }
      }
    }
  ]
}

Criar Novo Post ​

Cria um novo post e vincula categorias e tags. O autor (blogUserId) é definido automaticamente como o usuário autenticado, e o readingTime é calculado a partir do conteúdo.

http
POST /v1/blog/posts

Payload (Body) ​

AtributoTipoObrigatórioDescrição
post.titlestringSimTítulo (máx. 150 caracteres).
post.slugstringSimSlug único no blog (máx. 150 caracteres).
post.contentstringSimConteúdo principal em HTML (máx. 1.000.000 caracteres).
post.blogImageIdnumberSimID da imagem de capa (deve pertencer ao blog).
post.statusenumSimdraft ou published.
post.isFeaturedbooleanSimDefine se o post fica em destaque.
post.excerptstringNãoResumo do artigo (máx. 500 caracteres). Aceita null.
post.seoTitlestringNãoTítulo SEO (máx. 200 caracteres). Aceita null.
post.seoDescriptionstringNãoDescrição SEO (máx. 200 caracteres). Aceita null.
post.seoKeywordsstringNãoPalavras-chave SEO (máx. 200 caracteres). Aceita null.
post.publishedAtdateNãoData de publicação no formato YYYY-MM-DD HH:mm:ss. Aceita null.
tagsnumber[]NãoIDs das tags (ex: [1, 2]). Aceita null.
categoriesnumber[]NãoIDs das categorias (ex: [5]). Aceita null.

Exemplo de Requisição ​

bash
curl -X POST "https://api.us.basis.tavares.in/v1/blog/posts" \
  -H "Authorization: Bearer {token}" \
  -H "X-Blog-Id: {blog-id}" \
  -H "Content-Type: application/json" \
  -d '{
    "post": {
      "blogImageId": 5,
      "title": "Novo Artigo",
      "slug": "novo-artigo",
      "excerpt": "Um breve resumo do artigo.",
      "content": "<p>Conteúdo aqui...</p>",
      "seoTitle": "Novo Artigo",
      "seoDescription": "Descrição do novo artigo.",
      "seoKeywords": "artigo, blog",
      "isFeatured": true,
      "status": "published",
      "publishedAt": null
    },
    "tags": [1, 2],
    "categories": [5]
  }'

Respostas ​

201 Created

Retorna o ID do post criado.

json
{
  "id": "18"
}

422 Unprocessable Entity

Erro de validação nos campos enviados.

json
{
  "errors": [
    {
      "message": "Slug já cadastrado",
      "rule": "database.unique",
      "field": "post.slug"
    }
  ]
}

Obter Post por ID (Gerenciamento) ​

Recupera todos os dados de um post, independente do status, para edição no dashboard.

http
GET /v1/blog/posts/:id

Parâmetros de Rota ​

NomeTipoObrigatórioDescrição
idnumberSimO ID do post.

Respostas ​

200 OK

Retorna o post completo, incluindo content, blogTags e blogCategories.

404 Not Found

Ocorre quando o post não existe no blog.


Atualizar Post ​

Atualiza um post existente. Os campos title, slug, status, content e isFeatured são obrigatórios (envie o objeto completo). O tempo de leitura é recalculado automaticamente e os vínculos de tags e categorias são substituídos pelos arrays enviados.

http
PUT /v1/blog/posts/:id

Exemplo de Requisição ​

bash
curl -X PUT "https://api.us.basis.tavares.in/v1/blog/posts/18" \
  -H "Authorization: Bearer {token}" \
  -H "X-Blog-Id: {blog-id}" \
  -H "Content-Type: application/json" \
  -d '{
    "post": {
      "blogImageId": 7,
      "title": "Título Atualizado",
      "slug": "titulo-atualizado",
      "excerpt": "Resumo atualizado.",
      "content": "<p>Conteúdo atualizado...</p>",
      "seoTitle": "Título Atualizado",
      "seoDescription": "Descrição atualizada.",
      "seoKeywords": "artigo, atualizado",
      "isFeatured": true,
      "status": "published",
      "publishedAt": "2026-03-25 17:17:00"
    },
    "tags": [1, 2],
    "categories": [5, 6]
  }'

Respostas ​

204 No Content

Post atualizado com sucesso. A resposta não contém corpo.


Alterar Status do Post ​

Atalho para publicar ou despublicar um post sem reenviar todos os dados.

http
PATCH /v1/blog/posts/change-status/:id

Parâmetros do Body ​

AtributoTipoObrigatórioDescrição
statusenumSimNovo status: draft ou published.

Exemplo de Requisição ​

bash
curl -X PATCH "https://api.us.basis.tavares.in/v1/blog/posts/change-status/18" \
  -H "Authorization: Bearer {token}" \
  -H "X-Blog-Id: {blog-id}" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "published"
  }'

Respostas ​

204 No Content

Status alterado com sucesso. A resposta não contém corpo.


Remover Post ​

Exclui um post permanentemente (Soft Delete).

http
DELETE /v1/blog/posts/:id

Exemplo de Requisição ​

bash
curl -X DELETE "https://api.us.basis.tavares.in/v1/blog/posts/18" \
  -H "Authorization: Bearer {token}" \
  -H "X-Blog-Id: {blog-id}"

Respostas ​

204 No Content

Remoção concluída com sucesso. A resposta não contém corpo.