Guia do desenvolvedorReferência
Erros
Formato dos erros da API do Couryo, tipos, status HTTP e todos os códigos com causa e correção.
Todo erro tem o mesmo formato. O code é estável: pode usar no seu código sem medo de mudar. Cada code tem sempre o mesmo type e o mesmo status HTTP.
{
"error": {
"type": "invalid_request",
"code": "domain_not_verified",
"message": "O domínio exemplo.com.br ainda não foi verificado neste projeto.",
"param": "from",
"doc_url": "https://couryo.com/docs/errors#domain_not_verified",
"request_id": "req_6f2a9c1e7b0k3m4n"
}
}| Campo | O que é |
|---|---|
type |
a categoria do erro (tabela abaixo) |
code |
o motivo exato, estável |
message |
explicação para pessoas, em português ou inglês conforme o Accept-Language (o padrão é português) |
param |
o campo com problema, quando houver (por exemplo, to[1] ou emails[2].from) |
doc_url |
o link para a explicação nesta página |
request_id |
o ID da chamada, igual ao cabeçalho Request-Id; mande ao suporte se precisar de ajuda |
Tipos#
type |
HTTP | Quando |
|---|---|---|
invalid_request |
400 ou 422 | o pedido tem algum problema que você pode corrigir |
authentication |
401 | chave ausente ou inválida |
permission |
403 | a chave ou o plano não permite isso |
not_found |
404 | o recurso ou a rota não existe |
conflict |
409 | conflito, como uma chave de idempotência reaproveitada |
rate_limited |
429 | muitas chamadas em pouco tempo |
tier_limit |
429 | limite do seu nível, do seu plano ou do seu limite de gasto |
api_error |
500 ou 503 | problema do nosso lado; pode tentar de novo |
Códigos#
code |
type |
HTTP | Resumo |
|---|---|---|---|
missing_field |
invalid_request |
400 | falta um campo obrigatório |
invalid_field |
invalid_request |
400 | um campo tem valor inválido |
invalid_json |
invalid_request |
400 | o corpo não é JSON |
batch_too_large |
invalid_request |
400 | mais de 100 e-mails no lote |
invalid_cloudflare_token |
invalid_request |
400 | token da Cloudflare recusado |
cloudflare_zone_not_found |
invalid_request |
400 | o token não alcança a zona do domínio |
domain_not_verified |
invalid_request |
422 | o domínio do from não está verificado |
recipient_suppressed |
invalid_request |
422 | todos os destinatários estão suprimidos |
missing_api_key |
authentication |
401 | sem chave |
invalid_api_key |
authentication |
401 | chave inválida |
not_authenticated |
authentication |
401 | painel sem sessão |
insufficient_scope |
permission |
403 | escopo da chave insuficiente |
ip_not_allowed |
permission |
403 | IP fora da lista da chave |
sandbox_recipient |
permission |
403 | conta no nível 0 enviando para fora |
domain_limit_reached |
permission |
403 | a conta já tem os domínios do plano |
forbidden_origin |
permission |
403 | escrita no painel vinda de outro site |
resource_not_found |
not_found |
404 | ID inexistente |
route_not_found |
not_found |
404 | rota inexistente |
idempotency_conflict |
conflict |
409 | mesma chave de idempotência, corpo diferente |
idempotency_in_progress |
conflict |
409 | o mesmo pedido ainda está em andamento |
domain_exists |
conflict |
409 | domínio já cadastrado |
already_suppressed |
conflict |
409 | endereço já está na lista |
last_project |
conflict |
409 | tentativa de apagar o único projeto |
rate_limited |
rate_limited |
429 | chamadas demais por segundo |
daily_limit_reached |
tier_limit |
429 | limite diário atingido |
monthly_limit_reached |
tier_limit |
429 | cota do mês atingida |
spend_limit_reached |
tier_limit |
429 | o excedente chegou ao seu limite de gasto |
sending_paused |
tier_limit |
429 | envio pausado, com motivo |
internal_error |
api_error |
500 | erro do nosso lado |
billing_unavailable |
api_error |
503 | cobrança indisponível agora |
missing_field#
Falta um campo obrigatório, indicado em param. Para enviar, são obrigatórios from, to, subject e um entre html ou text (sem nenhum dos dois, o param vem como html).
invalid_field#
O campo indicado em param tem um valor que não aceitamos: um endereço mal formado, mais de 50 destinatários somando to, cc e bcc, um scheduled_at no passado ou a mais de 30 dias, uma URL de webhook sem https://. A message diz o que está errado. Em lote, o param vem com o índice: emails[2].to[0].
invalid_json#
O corpo não é um JSON válido. Confira o Content-Type: application/json e as aspas.
batch_too_large#
O lote tem mais de 100 e-mails. Divida em chamadas menores.
invalid_cloudflare_token#
O token da Cloudflare não foi aceito. Ele precisa ter a permissão Zona > DNS > Editar para o domínio. Veja Domínios e DNS.
cloudflare_zone_not_found#
O token é válido, mas não dá acesso à zona do domínio na Cloudflare. Crie o token incluindo essa zona.
domain_not_verified#
O domínio do from não está verificado no projeto da chave. Verifique em Domínios e DNS e tente de novo. Chaves ck_test_ não exigem domínio verificado.
recipient_suppressed#
Todos os destinatários estão na lista de supressão, por devolução permanente, reclamação, descadastro ou inclusão manual. O param indica o primeiro (to[n]). Se só alguns estiverem suprimidos, o e-mail sai para os outros e a linha do tempo ganha um evento suppressed para cada endereço pulado.
missing_api_key#
Faltou o cabeçalho Authorization: Bearer ck_.... Veja Autenticação.
invalid_api_key#
A chave não existe, foi apagada ou foi copiada pela metade. Crie uma nova no painel se precisar.
not_authenticated#
Chamada ao painel (/api) sem sessão. Entre de novo em app.couryo.com. Não acontece na API pública (/v1).
insufficient_scope#
A chave não tem permissão para esta operação. Por exemplo, uma chave send tentando ler e-mails, que exige read. A message diz qual escopo falta.
ip_not_allowed#
A chave tem uma lista de IPs permitidos, e a chamada veio de outro endereço. Ajuste a lista no painel.
sandbox_recipient#
A conta está no nível 0 (sandbox), ou o remetente é teste@sandbox.couryo.com, e esse caminho só envia para os e-mails da própria conta. Verifique um domínio para subir ao nível 1. Veja Limites e níveis.
domain_limit_reached#
A conta já tem o número de domínios que o plano permite: Grátis 1, Pro 10, Escala 50, Empresa sem limite (somando todos os projetos). Apague um domínio que não usa ou mude de plano. A message diz o limite atual e o do plano seguinte.
forbidden_origin#
Uma escrita no painel veio de outro site (proteção contra CSRF). Não acontece na API pública.
resource_not_found#
O ID informado não existe neste projeto, ou pertence a outro projeto. A message diz qual recurso não foi encontrado.
route_not_found#
O caminho não existe. Confira o método e o endereço, por exemplo POST /v1/emails.
idempotency_conflict#
A mesma Idempotency-Key foi usada nas últimas 24 horas com um corpo diferente. Use uma chave nova para um pedido novo. Veja Idempotência.
idempotency_in_progress#
Um pedido com a mesma Idempotency-Key ainda está sendo processado. Espere o Retry-After (1 segundo) e repita: você recebe a resposta do primeiro.
domain_exists#
Esse domínio já está cadastrado no Couryo, nesta ou em outra conta. Se ele é seu e está em outra conta, apague de lá primeiro.
already_suppressed#
O endereço já está na lista de supressão desse fluxo.
last_project#
A conta precisa de pelo menos um projeto. Crie outro antes de apagar este.
rate_limited#
Chamadas demais em pouco tempo (o padrão é 10 por segundo por chave). Espere os segundos do cabeçalho Retry-After e tente de novo com a mesma Idempotency-Key. Os cabeçalhos RateLimit-Limit, RateLimit-Remaining e RateLimit-Reset mostram sua folga.
daily_limit_reached#
Você atingiu o limite diário do seu nível de confiança, ou o do plano Grátis (100 por dia). A message diz o limite, quanto já foi enviado e o que falta para subir de nível. O contador zera à meia-noite no fuso da sua conta.
monthly_limit_reached#
Você atingiu a cota do mês: 3 mil no plano Grátis e também no nível 1 de qualquer plano. O envio volta no mês seguinte (no plano pago, no próximo período). No nível 1, a cota sobe quando a conta chega ao nível 2; no Grátis, ao assinar o Pro ou o Escala.
spend_limit_reached#
O excedente do mês chegou ao limite de gasto que você definiu em Cobrança. Todo o envio para (transacional e marketing) até você aumentar o limite ou o período virar. Nada é cobrado acima do teto.
sending_paused#
O envio está pausado. Na pausa comum, o marketing para e o transacional continua com até 30 por dia; na pausa total, tudo para. A message traz o motivo, os números e como corrigir, e o painel tem o botão Pedir revisão. Veja Limites e níveis.
internal_error#
Um problema do nosso lado. O pedido não foi processado. Tente de novo com a mesma Idempotency-Key: não há risco de duplicar.
billing_unavailable#
A cobrança está indisponível agora (checkout ou portal de pagamento). Tente de novo em alguns minutos; o envio de e-mails não é afetado.