Aller à la documentation
API

Erreurs

Une seule forme, deux niveaux, et un identifiant de requête sur tout.

L'enveloppe

type est un ensemble figé sur lequel vous pouvez brancher et qui ne s'agrandira jamais. code est précis et additif : traitez donc un code que vous ne reconnaissez pas comme son type. requestId figure sur chaque réponse, succès compris, et c'est ce qui relie un signalement à une ligne de journal.

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 est pointé et indexé, si bien qu'il désigne l'élément exact (to.0, attachments.2.filename) plutôt que le champ qui le contient.

Codes de statut

StatuttypeCodes courants
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

Un 404 ne distingue jamais « n'existe pas » de « appartient à un autre espace de travail ». C'est délibéré : la différence est elle-même une information.

Un 429 ne porte jamais de Retry-After : choisissez donc vous-même votre délai d'attente. send_quota_exceeded correspond au quota d'envoi mensuel, qui se réinitialise le premier du mois ; montrez-le à une personne plutôt que de temporiser. too_many_inboxes est le plafond de création de boîtes de réception jetables, et prolonger une boîte que vous détenez déjà ne coûte rien sur ce plafond.

500 et 503 partagent un même type et signifient des choses différentes pour un appelant. Un 503 est une dépendance qui n'a pas répondu (aujourd'hui, le traducteur), et la requête mérite d'être réessayée telle quelle ; un 500 est de notre côté et mérite d'être signalé avec son requestId.

Les gérer

Branchez sur type pour le comportement et lisez code pour le message que vous montrez à un humain. Un code non reconnu n'est pas une erreur de votre client. Cela signifie que nous avons nommé une défaillance plus précisément qu'auparavant.

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);  }}