NoteBugsDocs

Referência da API

Comentários, anexos, histórico e vínculos

O que pendura no card, e o histórico, que só se lê.

Comentário e histórico ficam fora do payload do quadro: só o diálogo do card precisa deles. Anexo tem duas rotas de criação (a do card e a do compositor de comentário), porque a imagem colada precisa existir antes do comentário.

GET/api/cards/[id]/comments
Papel: LeitorEspaço de trabalho

Os comentários de um card, em ordem cronológica.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Requisição

curl -s http://localhost:3000/api/cards/cmttg1vv00017lf01ol5bnlx2/comments \
  -H "Authorization: Bearer $TOKEN"

Resposta200

[
  {
    "id": "cmttg1w7i001hlf01wiw5pjwa",
    "cardId": "cmttg1vv00017lf01ol5bnlx2",
    "content": "Primeira versão publicada em `/api`.",
    "createdAt": "2026-09-09T01:52:59.214Z",
    "updatedAt": "2026-09-09T01:52:59.214Z",
    "attachments": []
  }
]

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403A conta não alcança o espaço de trabalho do recurso. É 403 e não 404 de propósito: assim a resposta não revela quais espaços existem.
404O recurso não existe, ou já foi apagado.

Fica fora do payload de /api/board: só o diálogo do card precisa do corpo da conversa.

POST/api/cards/[id]/comments
Papel: MembroEspaço de trabalho

Comenta num card.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Corpo da requisição

CampoTipoDescrição
contentobrigatóriostring (Markdown)Markdown. É sanitizado na renderização, e o que volta aqui é o texto como foi enviado.
attachmentIdscuid[]As imagens que o compositor já subiu por /comments/uploads e que o corpo referencia.

Requisição

curl -s -X POST http://localhost:3000/api/cards/cmttg1vv00017lf01ol5bnlx2/comments \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Primeira versão publicada em `/api`." }'

Resposta201

{
  "id": "cmttg1w7i001hlf01wiw5pjwa",
  "cardId": "cmttg1vv00017lf01ol5bnlx2",
  "content": "Primeira versão publicada em `/api`.",
  "createdAt": "2026-09-09T01:52:59.214Z",
  "updatedAt": "2026-09-09T01:52:59.214Z",
  "attachments": []
}

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403A conta não alcança o espaço de trabalho do recurso. É 403 e não 404 de propósito: assim a resposta não revela quais espaços existem.
404O recurso não existe, ou já foi apagado.
422O corpo não passou pelo schema. O campo details traz fieldErrors e formErrors do zod, campo a campo.
PATCH/api/comments/[id]
Papel: MembroEspaço de trabalho

Edita um comentário.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Corpo da requisição

CampoTipoDescrição
contentobrigatóriostring (Markdown)
attachmentIdscuid[]

Requisição

curl -s -X PATCH http://localhost:3000/api/comments/cmttg1w7i001hlf01wiw5pjwa \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Primeira versão publicada. Revisado." }'

Resposta200

{
  "id": "cmttg1w7i001hlf01wiw5pjwa",
  "cardId": "cmttg1vv00017lf01ol5bnlx2",
  "content": "Primeira versão publicada em `/api`.",
  "createdAt": "2026-09-09T01:52:59.214Z",
  "updatedAt": "2026-09-09T01:52:59.214Z",
  "attachments": []
}

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403A conta não alcança o espaço de trabalho do recurso. É 403 e não 404 de propósito: assim a resposta não revela quais espaços existem.
404O recurso não existe, ou já foi apagado.
422O corpo não passou pelo schema. O campo details traz fieldErrors e formErrors do zod, campo a campo.
DELETE/api/comments/[id]
Papel: MembroEspaço de trabalho

Apaga um comentário, levando as imagens dele junto.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Requisição

curl -s -X DELETE http://localhost:3000/api/comments/cmttg1w7i001hlf01wiw5pjwa \
  -H "Authorization: Bearer $TOKEN"

Resposta200

{ "deleted": true }

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403A conta não alcança o espaço de trabalho do recurso. É 403 e não 404 de propósito: assim a resposta não revela quais espaços existem.
404O recurso não existe, ou já foi apagado.
POST/api/cards/[id]/comments/uploads
Papel: MembroEspaço de trabalhomultipart/form-data

Sobe as imagens de um comentário antes de publicá-lo.

Existe separada da criação porque o compositor precisa da URL da imagem para escrevê-la no Markdown, antes de o comentário existir. Os anexos nascem com scope: COMMENT e soltos, e o attachmentIds da criação os prende.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Corpo da requisição

CampoTipoDescrição
filesobrigatórioarquivo[]

Requisição

curl -s -X POST http://localhost:3000/api/cards/cmttg1vv00017lf01ol5bnlx2/comments/uploads \
  -H "Authorization: Bearer $TOKEN" \
  -F "[email protected]"

Resposta201

[
  {
    "id": "cmttg2rz8001llf010yq4sk1m",
    "storedName": "18ab694d-48ed-4b56-bd2b-3a324fec55de.png",
    "originalName": "print.png",
    "mimeType": "image/png",
    "size": 25381,
    "url": "/api/files/18ab694d-48ed-4b56-bd2b-3a324fec55de.png"
  }
]

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403O envio de anexos está desativado nesta instalação.
404O recurso não existe, ou já foi apagado.
413O arquivo passa do tamanho máximo por anexo.
415O formato não é aceito. Ele é identificado pelos magic bytes, e não pela extensão do nome.
POST/api/cards/[id]/attachments
Papel: MembroEspaço de trabalhomultipart/form-data

Anexa um ou mais arquivos ao card.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Corpo da requisição

CampoTipoDescrição
filesobrigatórioarquivo[]Pode repetir o campo para mandar vários. file também é aceito, no singular.

Requisição

curl -s -X POST http://localhost:3000/api/cards/cmttg1vv00017lf01ol5bnlx2/attachments \
  -H "Authorization: Bearer $TOKEN" \
  -F "[email protected]" \
  -F "[email protected]"

Resposta201

[
  {
    "id": "cmttg2rz8001llf010yq4sk1m",
    "storedName": "18ab694d-48ed-4b56-bd2b-3a324fec55de.png",
    "originalName": "print.png",
    "mimeType": "image/png",
    "size": 25381,
    "url": "/api/files/18ab694d-48ed-4b56-bd2b-3a324fec55de.png"
  }
]

Respostas de erro

CódigoQuando acontece
400Nenhum arquivo veio no multipart, ou o arquivo está vazio.
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403O envio de anexos está desativado nesta instalação.
404O recurso não existe, ou já foi apagado.
413O arquivo passa do tamanho máximo por anexo.
415O formato não é aceito. Ele é identificado pelos magic bytes, e não pela extensão do nome.

O nome do arquivo é gerado pelo SERVIDOR, e o tipo é detectado pelos magic bytes: a extensão do nome enviado não decide nada.

DELETE/api/attachments/[id]
Papel: MembroEspaço de trabalho

Remove o anexo e o arquivo por trás dele.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Requisição

curl -s -X DELETE http://localhost:3000/api/attachments/cmttg2rz8001llf010yq4sk1m \
  -H "Authorization: Bearer $TOKEN"

Resposta200

{ "deleted": true }

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403A conta não alcança o espaço de trabalho do recurso. É 403 e não 404 de propósito: assim a resposta não revela quais espaços existem.
404O recurso não existe, ou já foi apagado.
GET/api/cards/[id]/history
Papel: LeitorEspaço de trabalho

O histórico de trocas de coluna do card, da mais antiga para a mais nova.

A coluna viaja pelo NOME que ela tinha no momento da troca: renomear ou apagar a coluna depois não reescreve o passado.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Requisição

curl -s http://localhost:3000/api/cards/cmttg1vv00017lf01ol5bnlx2/history \
  -H "Authorization: Bearer $TOKEN"

Resposta200

[
  {
    "id": "cmttg1vw50019lf01b7knmm8g",
    "fromName": null,
    "toName": "A fazer",
    "movedAt": "2026-09-09T01:52:58.805Z"
  },
  {
    "id": "cmttg1w3r001flf01xfiggnhl",
    "fromName": "A fazer",
    "toName": "Fazendo",
    "movedAt": "2026-09-09T01:52:59.080Z"
  }
]

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403A conta não alcança o espaço de trabalho do recurso. É 403 e não 404 de propósito: assim a resposta não revela quais espaços existem.
404O recurso não existe, ou já foi apagado.

Não existe rota de escrita de histórico. O registro é gravado pelo servidor, na mesma transação que muda a coluna, nos três caminhos que a mudam.

POST/api/cards/[id]/relations
Papel: MembroEspaço de trabalho

Cria um vínculo tendo o card da rota como ORIGEM.

A rota não conhece “direção escolhida na tela”: para os rótulos inversos (“é filho de”, “é bloqueado por”), o cliente troca os ids e chama esta mesma rota no outro card.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Corpo da requisição

CampoTipoDescrição
targetIdobrigatóriocuidO card de destino, do mesmo espaço de trabalho.
kindobrigatórioenumO tipo do vínculo, na direção origem → destino.PARENT · BLOCKS · GENERATED · RELATED

Requisição

curl -s -X POST http://localhost:3000/api/cards/cmttg1vv00017lf01ol5bnlx2/relations \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "targetId": "cmttg1vyj001blf01888i4wn8",
    "kind": "BLOCKS"
  }'

Resposta201

{
  "id": "cmttg2rve001jlf018csp3gc0",
  "sourceId": "cmttg1vv00017lf01ol5bnlx2",
  "targetId": "cmttg1vyj001blf01888i4wn8",
  "kind": "BLOCKS",
  "createdAt": "2026-09-09T01:53:40.251Z"
}

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403A conta não alcança o espaço de trabalho do recurso. É 403 e não 404 de propósito: assim a resposta não revela quais espaços existem.
404O recurso não existe, ou já foi apagado.
409Já existe um vínculo entre esses dois cards. Há no máximo um, em qualquer sentido.
422Um card não se vincula a ele mesmo.
422Os dois cards precisam estar no mesmo espaço de trabalho. Essa fronteira não tem configuração que a libere.
422Vínculos entre projetos diferentes estão desligados. Ligue allowCrossProjectLinks nas Configurações: dois cards sem projeto contam como o mesmo agrupamento.

Há no máximo UM vínculo entre dois cards, em qualquer sentido.

DELETE/api/relations/[id]
Papel: MembroEspaço de trabalho

Remove o vínculo: ele some dos dois cards.

Parâmetros de rota

CampoTipoDescrição
idobrigatóriocuid

Requisição

curl -s -X DELETE http://localhost:3000/api/relations/cmttg2rve001jlf018csp3gc0 \
  -H "Authorization: Bearer $TOKEN"

Resposta200

{ "deleted": true }

Respostas de erro

CódigoQuando acontece
401Sem credencial, ou com uma que não vale mais. Mande o cookie de sessão ou o cabeçalho Authorization: Bearer.
403A conta não alcança o espaço de trabalho do recurso. É 403 e não 404 de propósito: assim a resposta não revela quais espaços existem.
404O recurso não existe, ou já foi apagado.