Pular para o conteúdo
couryo

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.

Ver em Markdown

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.

Erro
{
  "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.