Mídia
Assets de mídia — imagens e outros uploads — ficam no site dono da chave de API. Envie um, obtenha o id dele e referencie esse id em um bloco de imagem do corpo de um post. O site é sempre derivado da chave, então uma chave só consegue ver e mexer nos próprios assets.
- URL base:
https://api.canverly.com - Autenticação: chave de API Bearer —
Authorization: Bearer ck_… - Limite de requisição: 60 req/min por chave
| Método | Caminho | Escopo |
|---|---|---|
GET |
/v1/media |
media:read |
POST |
/v1/media |
media:write |
GET |
/v1/media/{id} |
media:read |
DELETE |
/v1/media/{id} |
media:write |
GET /v1/media
Seção intitulada “GET /v1/media”Lista os assets do site, do mais recente para o mais antigo. A listagem não é paginada por cursor: você pede um tamanho de página com limit.
| Parâmetro | Tipo | Obrigatório | Observações |
|---|---|---|---|
limit |
integer | não | 1..500, padrão 100. Fora da faixa (ou não inteiro) devolve 400 — o valor nunca é ajustado em silêncio. |
folder_id |
string | não | Restringe a uma pasta. |
tag_id |
string | não | Restringe a uma tag. |
curl "https://api.canverly.com/v1/media?limit=20" \ -H "Authorization: Bearer ck_live_xxx"{ "items": [ { "id": "019eedd0-1111-7000-8000-000000000001", "key": "sites/01KVPWYKT6AJDGG2EJN7DW4VT5/2026/08/hero.png", "mime": "image/png", "bytes": 184320, "width": 1600, "height": 900, "alt_text": "Dashboard screenshot", "hash": "9f2b1c7d5e4a3b8c6d0f1e2a3b4c5d6e7f8091a2b3c4d5e6f7081920a3b4c5d6", "status": "ready", "original_url": "https://cdn.example.com/sites/01KVPWYKT6AJDGG2EJN7DW4VT5/2026/08/hero.png" } ]}A resposta é sempre { "items": [...] } — o array vem vazio quando o site não tem assets (ou nenhum corresponde aos filtros).
POST /v1/media
Seção intitulada “POST /v1/media”Envia um asset como multipart/form-data. A parte do arquivo precisa se chamar literalmente file — nenhum outro nome de parte é lido.
- Content-Type:
multipart/form-data(qualquer outro devolve400) - Corpo máximo: 8 MiB (acima disso devolve
413) - Escopo:
media:write
curl -X POST https://api.canverly.com/v1/media \ -H "Authorization: Bearer ck_live_xxx" \ -F "file=@./hero.png"202 Accepted
Seção intitulada “202 Accepted”O asset é armazenado imediatamente, mas suas variantes derivadas são geradas de forma assíncrona. Por isso a chamada responde 202 e o asset volta com status: "processing":
{ "id": "019eedd0-1111-7000-8000-000000000001", "key": "sites/01KVPWYKT6AJDGG2EJN7DW4VT5/2026/08/hero.png", "mime": "image/png", "bytes": 184320, "width": null, "height": null, "alt_text": null, "hash": "9f2b1c7d5e4a3b8c6d0f1e2a3b4c5d6e7f8091a2b3c4d5e6f7081920a3b4c5d6", "status": "processing", "original_url": null}Consulte GET /v1/media/{id} até status mudar para "ready". O id pode ser usado assim que você o tiver — não é preciso esperar "ready" para registrá-lo.
Falhas específicas do upload
Seção intitulada “Falhas específicas do upload”-
Não é multipart — enviar JSON (ou nenhum
Content-Type) devolve400:{ "error": { "code": "bad_request", "message": "expected multipart/form-data body with a `file` field" } } -
Corpo acima de 8 MiB —
413. É o mesmo teto de 8 MiB que o resto da borda pública aplica. -
Tipo de arquivo não suportado —
415, repassado pelo serviço de mídia. -
Chave sem contexto de autoria — uma chave emitida antes de o contexto de autor/organização existir não consegue fazer upload. Ela devolve
422:{ "error": { "code": "unprocessable", "message": "this api key has no org context; re-create it in Configurações → Integrações API" } }A correção fica do lado do dono: exclua a chave e gere uma nova em Configurações → Integrações API (veja Autenticação).
GET /v1/media/{id}
Seção intitulada “GET /v1/media/{id}”Lê um asset. Use para consultar um upload até ele ficar "ready".
curl https://api.canverly.com/v1/media/019eedd0-1111-7000-8000-000000000001 \ -H "Authorization: Bearer ck_live_xxx"{ "id": "019eedd0-1111-7000-8000-000000000001", "key": "sites/01KVPWYKT6AJDGG2EJN7DW4VT5/2026/08/hero.png", "mime": "image/png", "bytes": 184320, "width": 1600, "height": 900, "alt_text": "Dashboard screenshot", "hash": "9f2b1c7d5e4a3b8c6d0f1e2a3b4c5d6e7f8091a2b3c4d5e6f7081920a3b4c5d6", "status": "ready", "original_url": "https://cdn.example.com/sites/01KVPWYKT6AJDGG2EJN7DW4VT5/2026/08/hero.png"}Um id que pertence a outro site devolve 404, exatamente como um id que não existe — a existência nunca é revelada:
{ "error": { "code": "not_found", "message": "media asset not found" } }DELETE /v1/media/{id}
Seção intitulada “DELETE /v1/media/{id}”Faz soft delete de um asset.
curl -X DELETE https://api.canverly.com/v1/media/019eedd0-1111-7000-8000-000000000001 \ -H "Authorization: Bearer ck_live_xxx" \ -i204 No Content
Seção intitulada “204 No Content”Sem corpo de resposta. Assim como no GET, um id de outro site devolve 404, e não 403.
O objeto asset
Seção intitulada “O objeto asset”| Campo | Tipo | Observações |
|---|---|---|
id |
string | Identificador do asset — é isto que você coloca no bloco de imagem de um post. |
key |
string | Caminho do objeto no storage. |
mime |
string | Tipo MIME detectado, ex.: image/png. |
bytes |
integer | Tamanho armazenado, em bytes. |
width |
integer | null | Largura em pixels; null quando desconhecida (normalmente enquanto status é processing, ou para tipos que não são imagem). |
height |
integer | null | Altura em pixels; mesma ressalva de width. |
alt_text |
string | null | Texto alternativo, quando definido. |
hash |
string | Hash do conteúdo do objeto armazenado. |
status |
string | "processing" enquanto as variantes estão sendo geradas, "ready" depois. |
original_url |
string (URI) | null | URL do objeto original, quando disponível. |
Como usar um asset em um post
Seção intitulada “Como usar um asset em um post”Um bloco de imagem no corpo de um post pode carregar o id do asset como attrs.media_id em vez de uma URL. Quando o post é servido, uma imagem registrada como media id volta com a URL já resolvida em content_html; se o asset foi excluído ou está indisponível, o bloco é omitido em vez de renderizado como um <img> quebrado.
{ "v": 1, "blocks": [ { "id": "img1", "type": "image", "attrs": { "media_id": "019eedd0-1111-7000-8000-000000000001", "alt": "Dashboard screenshot" } } ]}Veja Blocos de conteúdo para o formato do documento de blocos e POST /v1/posts para criar o post em si.
Envelope: { "error": { "code", "message" } }. Tabela completa em Erros e limites de requisição.
| Status | error.code |
Quando |
|---|---|---|
400 |
bad_request |
limit não inteiro ou fora de 1..500 (lista); corpo que não é multipart/form-data, ou sem a parte file (upload). |
401 |
unauthorized |
Chave ausente, malformada, desconhecida ou revogada — inclusive uma chave pública de leitura pk_…. |
403 |
forbidden |
A chave não tem media:read (lista/leitura) ou media:write (upload/exclusão). |
404 |
not_found |
Nenhum asset com esse id neste site — a mesma resposta para o id de outro site. |
413 |
— | Corpo do upload acima de 8 MiB. |
415 |
— | Tipo de mídia não suportado, repassado pelo serviço de mídia. |
422 |
unprocessable |
Upload com uma chave sem contexto de organização — recrie a chave. |
429 |
rate_limited |
Acima de 60 req/min — respeite o Retry-After. |
5xx |
upstream |
Transitório; tente de novo com backoff. Detalhes internos são removidos da mensagem. |