Référence API

Trois points d'accès, JSON en entrée et en sortie. Ni clé ni compte sur les domaines publics — collez une requête dans un terminal et ça fonctionne.

Vue d'ensemble

Une boîte n'est jamais créée — elle existe dès qu'un message arrive à une adresse, et disparaît 5 jours plus tard. Il n'y a rien à enregistrer, donc sur les domaines publics l'API ne connaît ni utilisateur, ni projet, ni jeton.

  • Chaque réponse est du JSON, y compris chaque erreur.
  • Toutes les heures sont en UTC au format RFC 3339 — 2026-08-04T18:31:07Z.
  • Les identifiants de message sont des chaînes opaques. Ne les analysez pas.
  • Réception uniquement. Il n'existe volontairement aucun point d'accès pour envoyer du courrier.

URL de base

https://grabmail.io/api/v1

HTTPS uniquement ; le HTTP simple est redirigé. La version figure dans le chemin, et v1 ne changera pas de forme sous vos pieds — un changement incompatible reçoit un nouveau numéro.

Authentification

Aucune, sur les domaines publics. Quiconque connaît une adresse peut lire sa boîte, aussi bien via l'API que via le site. C'est le compromis que fait tout service jetable partagé : ne confiez jamais à une adresse publique quelque chose auquel vous tenez.

Sur un domaine que vous possédez, la boîte est privée, donc les requêtes portent une clé — c'est elle qui prouve que la boîte est la vôtre. La clé est délivrée quand vous vérifier le domaine, affichée une seule fois, et stockée ici uniquement sous forme de hachage :

Authorization: Bearer <your key>

Une clé erronée ou absente sur un domaine privé répond 401 avec unauthorized. Les clés sont comparées en temps constant, donc une mauvaise clé met aussi longtemps à être rejetée qu'une bonne à être acceptée.

Points d'accès

GET /api/v1/mailbox

Tout ce qui attend à une adresse, du plus récent au plus ancien. C'est l'appel que votre suite de tests interroge en boucle.

Paramètres

NomEntréeTypeRequisDescription
address query string oui La boîte à lire, par ex. k7fq2m@grabmail.io.
limit query integer non Nombre de messages à renvoyer pour cet appel, 1–200. Par défaut 50, du plus récent au plus ancien. Cela limite une réponse, pas la boîte — utilisez before pour lire au-delà.
before query string non L'id du message le plus ancien que vous avez déjà ; renvoie la page suivante. Repassez le champ next de la réponse précédente. Quand next vaut null, vous avez tout.

Exemple

Lister une boîte de réception
$ curl -G https://grabmail.io/api/v1/mailbox \
  --data-urlencode "address=k7fq2m@grabmail.io"

{
  "address": "k7fq2m@grabmail.io",
  "count": 1,
  "next": null,
  "messages": [
    {
      "id":          "01JR8W2K4Q",
      "from":        "no-reply@example.com",
      "subject":     "Your verification code",
      "date":        "2026-08-04T18:31:07Z",
      "seen":        false,
      "attachments": 0,
      "expires_at":  "2026-08-09T18:31:07Z"
    }
  ]
}

Codes d'état

200
La boîte a été lue. Une boîte vide donne un 200 avec count: 0, jamais un 404. next porte le curseur pour la page suivante, ou null à la fin.
400
L'adresse est mal formée, ou before n'est pas un id de message.
400
address est manquant ou n'est pas une adresse valide.
404
Ce domaine n'est pas hébergé ici — vérifiez l'enregistrement MX.
429
Limite de débit dépassée. Réessayez après le délai indiqué dans Retry-After.
GET /api/v1/message/{id}

Les en-têtes, la partie texte brut, la partie HTML et les éventuelles pièces jointes.

Paramètres

NomEntréeTypeRequisDescription
id path string oui L'id de message renvoyé par l'appel de liste.
mailbox query string oui L'adresse à laquelle le message a été livré.

Exemple

Lire un message
$ curl -G https://grabmail.io/api/v1/message/01JR8W2K4Q \
  --data-urlencode "mailbox=k7fq2m@grabmail.io"

{
  "id":      "01JR8W2K4Q",
  "from":    "no-reply@example.com",
  "to":      "k7fq2m@grabmail.io",
  "subject": "Your verification code",
  "date":    "2026-08-04T18:31:07Z",
  "text":    "Your code is 481920. It expires in 10 minutes.",
  "html":    null,
  "attachments": []
}

Codes d'état

200
Le message. html vaut null quand l'expéditeur n'a envoyé que du texte brut.
400
mailbox est manquant ou invalide.
404
Aucun message de ce type dans cette boîte — ou il a dépassé sa fenêtre de rétention.
429
Limite de débit dépassée.
DELETE /api/v1/message/{id}

Le supprime immédiatement, plutôt que d'attendre l'expiration de la fenêtre de rétention.

Paramètres

NomEntréeTypeRequisDescription
id path string oui Le message à supprimer.
mailbox query string oui L'adresse à laquelle il a été livré.

Exemple

Supprimer un message
$ curl -X DELETE -G https://grabmail.io/api/v1/message/01JR8W2K4Q \
  --data-urlencode "mailbox=k7fq2m@grabmail.io"

{
  "deleted": true,
  "id": "01JR8W2K4Q"
}

Codes d'état

200
Supprimé. L'appel est idempotent : supprimer deux fois répond quand même 200.
400
mailbox est manquant ou invalide.
404
Aucun message de ce type dans cette boîte.
429
Limite de débit dépassée.

Pièces jointes

Chaque message liste ses pièces jointes avec une URL prête à l'emploi. Récupérez-la avec la même autorisation que le message lui-même.

GET /api/v1/attachment/{id}?mailbox={address}

Elle répond toujours application/octet-stream avec Content-Disposition: attachment, quelle que soit l'étiquette donnée par l'expéditeur. C'est volontaire : renvoyer tel quel un text/html d'inconnu permettrait à une pièce jointe de s'exécuter comme une page sur cette origine. Le vrai type figure dans le JSON du message, où il est une donnée et non une instruction.

Erreurs

Chaque échec est un JSON avec les deux mêmes champs, pour qu'un client les traite en un seul endroit. Le statut porte la catégorie, error est un identifiant stable destiné aux machines, et message est destiné aux humains et peut être reformulé à tout moment.

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error":   "invalid_address",
  "message": "address must look like name@domain"
}

Ne conditionnez jamais votre logique à message. Les identifiants utilisés sont invalid_address, unknown_domain, not_found et rate_limited.

Limites de débit

Une requête par seconde, par adresse. Interroger une boîte une fois par seconde est le comportement prévu et n'est jamais limité.

Au-delà de la limite, vous obtenez 429 avec Retry-After en secondes. Il n'y a ni quota journalier ni crédit de rafale à gérer.

Rétention

Un message est supprimé 5 jours après son arrivée, lu ou non. Chaque message porte expires_at, vous n'avez donc jamais à calculer cette date vous-même.

C'est une limite fixe, pas un réglage — aucun paramètre ne l'étend. Si un message doit survivre à la fenêtre, récupérez-le et stockez-le de votre côté.

Votre propre domaine

Pointez votre MX vers smtp.grabmail.io et chaque adresse de votre domaine répond via ces mêmes points d'accès — pas de seconde API à apprendre, et les boîtes ne sont lisibles qu'avec votre clé.

Connecter un domaine →