Saltar para a documentação
API

Erros

Um formato, dois níveis, e um id de pedido em tudo.

O envelope

type é um conjunto fechado pelo qual pode ramificar e que nunca vai crescer. code é específico e aditivo, por isso trate um que não reconheça como o seu type. requestId está em todas as respostas, sucessos incluídos, e é o que liga um relato a uma linha de registo.

422 Unprocessable Entity
{  "error": {    "type": "validation_error",    "code": "invalid_email_address",    "message": "Not a valid email address: ada@",    "param": "to.0",    "docUrl": "https://openemail.uk/docs/api/errors#invalid_email_address",    "requestId": "req_e103790543af4…"  }}

param é indicado com pontos e índices, pelo que aponta para o elemento exato (to.0, attachments.2.filename) e não para o campo que o contém.

Códigos de estado

EstadotypeCódigos comuns
400invalid_request_errormalformed_json, invalid_idempotency_key
401authentication_errormissing_api_key, invalid_api_key, revoked_api_key, invalid_credential_type
403permission_errorinsufficient_scope, from_address_forbidden
404not_found_errorresource_not_found
409conflict_erroremail_not_cancellable, translation_not_configured
422validation_errorinvalid_email_address, reserved_header, too_many_recipients, unknown_parameter, idempotency_key_reuse, label_not_directly_settable, unknown_language, translation_too_long
429rate_limit_errorsend_quota_exceeded, too_many_inboxes
500api_errorinternal_error
503api_errortranslation_failed

Um 404 nunca distingue «não existe» de «pertence a outro workspace». Isso é deliberado: a diferença é, em si, informação.

Um 429 nunca traz Retry-After, por isso escolha a sua própria espera. send_quota_exceeded é a franquia mensal de envio e reinicia no primeiro dia do mês, por isso mostre-o a uma pessoa em vez de recuar. too_many_inboxes é o teto de criação de caixas descartáveis, e prolongar uma caixa que já tem não conta nada para esse teto.

500 e 503 partilham um type e significam coisas diferentes para quem chama. Um 503 é uma dependência que não respondeu (hoje, o tradutor), e vale a pena repetir o pedido tal como está; um 500 é nosso e vale a pena reportá-lo com o respetivo requestId.

Como lidar com eles

Ramifique por type para o comportamento e leia code para a mensagem que mostra a uma pessoa. Um code não reconhecido não é um erro no seu cliente. Significa que nomeámos uma falha com mais precisão do que antes.

TypeScript
const res = await fetch(`${BASE}/emails`, { method: 'POST', headers, body }); if (!res.ok) {  const { error } = await res.json();   switch (error.type) {    case 'rate_limit_error':      throw new RateLimited(error.code);    case 'validation_error':      // error.param points at the offending field      throw new BadRequest(`${error.param}: ${error.message}`);    case 'authentication_error':      // revoked_api_key and expired_api_key are worth telling an operator apart      throw new AuthFailed(error.code);    default:      // quote requestId when you report it      throw new Unexpected(error.message, error.requestId);  }}