Ouvrir une boîte

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

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.

Un domaine que vous pointez ici répond sur ces mêmes points d'accès, sans clé non plus. Pointez le MX vers nous et le premier message le connecte ; voir connexion d'un domaine. Les boîtes qu'il contient sont lisibles par quiconque connaît l'adresse, exactement comme les domaines publics.

Un seul cas garde un en-tête : un domaine que nous avons fermé sur demande se lit avec Authorization: Bearer <key>, et une clé manquante ou incorrecte répond 401 avec unauthorized. Les clés sont comparées en temps constant : rejeter une mauvaise en prend autant que d'accepter une bonne.

Domaines premium

La seule exception à la règle ci-dessus. Les domaines publics figurent sur les listes publiques de messagerie jetable, et c'est pourquoi un formulaire d'inscription refuse parfois une adresse qui s'y trouve. Un plan payant ouvre un pool de 92 domaines .com privés, hors de ces listes.

L'API ne change en rien. Mêmes chemins, mêmes paramètres, mêmes formes de réponse. La seule différence tient dans un en-tête : une adresse premium se lit avec Authorization: Bearer gm_live_…, avec une clé issue de vos clés d'API. Sans clé valable, la même requête répond 402 ou 403 — jamais une boîte.

# A public domain: no header at all.
curl -sG https://grabmail.io/api/v1/mailbox \
  --data-urlencode "address=a7f3k2@grabmail.io"

# A premium domain: the same call, plus a key.
curl -sG https://grabmail.io/api/v1/mailbox \
  -H "Authorization: Bearer gm_live_…" \
  --data-urlencode "address=a7f3k2@one-of-the-pool.com"

Les domaines publics et vos propres domaines restent gratuits, sans clé et sans limite sur tous les plans, y compris le gratuit. Les quotas ne comptent que les messages arrivant sur le pool premium. Les plans et les prix sont sur la page des plans.

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, pas d'inscription, pas de clé.

Connecter un domaine →

Bon retour

Vos boîtes et vos domaines, au même endroit.