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.
Le seul identifiant de cette API est la clé de votre compte, décrite ci-dessous — une avec un compte gratuit, davantage avec les plans payants. Une clé n'a pas de niveau propre : chaque appel est jugé sur le plan qu'a son compte à cet instant, si bien que la même clé perd les plafonds gratuits et ouvre le pool premium dès que vous vous abonnez, puis revient au quota gratuit quand le plan prend fin. Les domaines publics n'en demandent aucune ; envoyée avec eux, elle compte vos appels pour votre compte plutôt que pour votre adresse IP. Une clé envoyée qui est inconnue ou révoquée répond 401 avec unauthorized sur tous les points d'accès, quel que soit le domaine — pour qu'une faute de frappe se voie tout de suite plutôt que de ressembler à une boîte vide.
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
97 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é provenant d'un plan payant, la même requête répond 404 — mot pour mot la réponse pour un domaine que nous n'hébergeons pas, volontairement, afin que le pool ne puisse pas être énuméré en devinant des noms. Jamais une boîte.
Où sont les domaines du pool
GET /api/v1/domains avec votre clé renvoie les domaines publics et les noms de domaine du pool. Le même appel sans clé — ou avec une clé provenant d'un compte gratuit ou expiré — renvoie les domaines publics, le nombre de domaines que compte le pool et son prix, mais jamais un nom : les garder hors des listes noires de courriel jetable, c'est ce que le plan achète. Un abonné connecté voit aussi le pool dans le sélecteur de domaine sur la page d'accueil.
GET /api/v1/me est le seul appel qui juge une clé isolément : 200 avec le plan, la période en cours, le quota consommé et restant, les adresses tenues et votre limite de débit — ou 401unauthorized si la clé est inconnue ou révoquée. Appelez-le en premier quand quelque chose sur le pool répond 404 : cette réponse masque volontairement un problème de clé, celui-ci le révèle.
Chaque cas, et sa raison. Les deux premiers semblent surprenants tant qu'on n'a pas lu la raison.
404
unknown_domain — pas de clé, ou une clé provenant d'un compte gratuit ou expiré. Identique, volontairement, à la réponse pour un domaine que nous n'hébergeons pas : distinguer les deux permettrait d'énumérer le pool en devinant des noms. Vérifiez la clé avec /api/v1/me.
401
unauthorized — la clé envoyée est inconnue ou révoquée. Cette réponse est donnée sur tous les points d'accès, quel que soit le domaine : elle dit quelque chose sur la clé, jamais sur un domaine.
402
quota_reached — le quota de cette période est épuisé et le dépassement est désactivé. overage_cap / overage_funds — le dépassement est activé, mais le plafond que vous avez fixé est atteint, ou le solde est insuffisant. Les adresses déjà tenues continuent de fonctionner dans les trois cas.
403
address_taken — un autre abonné tient cette adresse. Choisissez un autre nom.
409
address_limit — réservé à un plan qui plafonne les adresses. Aucun plan ne le fait aujourd'hui.
429
rate_limited — sur le plan gratuit (sans clé, ou avec une clé gratuite), plus de 60 requêtes par minute, ou plus d'une lecture par seconde sur une même adresse ; avec une clé payante, plus de 2, 3 ou 5 lectures par seconde sur une même adresse, selon le plan. daily_limit_reached — les 1 000 requêtes gratuites de la journée sont épuisées. Les plans payants n'ont ni le plafond par minute ni le plafond quotidien. Les deux s'accompagnent de Retry-After.
Adresses tenues et quota
Une adresse premium est tenue par le premier compte qui la lit avec une clé valable — n'importe quelle lecture, sur n'importe quel point d'accès ou via MCP, rien à réserver à l'avance. Tant qu'elle est tenue, seul ce compte peut la lire ; tout autre compte obtient 403. Elle reste tenue jusqu'à ce que vous la rendiez depuis le tableau de bord, ou que le plan prenne fin — à sa date d'échéance, sans délai de grâce.
Le quota compte des unités : un message reçu sur une adresse premium ou une nouvelle adresse premium ouverte, selon ce qui arrive en premier — donc une adresse que vous ouvrez sans jamais la lire en utilise quand même une. Relire une adresse déjà tenue est gratuit. Aucun plan ne plafonne le nombre d'adresses qu'un compte tient ; c'est le quota qui le borne, et /api/v1/me indique ce qu'il en reste.
L'alias, même sur les adresses premium
Chaque boîte listée porte un alias : une seconde adresse qui délivre dans la même boîte et n'en révèle rien. Donnez l'alias à un formulaire et interrogez l'adresse ; quiconque connaît l'alias voit toujours une boîte vide. Il est stable pour une adresse donnée, gratuit, et renvoyé pour les adresses premium exactement comme pour les publiques. Son domaine est l'un des nôtres et n'est volontairement listé nulle part.
Le tout, en quatre appels
KEY="gm_live_…" # depuis votre page de clés d'API, avec un plan payant
# 1. Vérifier la clé : plan, quota restant, limite de débit. 401 si elle est mauvaise.
curl -s https://grabmail.io/api/v1/me -H "Authorization: Bearer $KEY"
# 2. Lister le pool. Les noms ne figurent dans la réponse qu'avec une clé payante.
curl -s https://grabmail.io/api/v1/domains -H "Authorization: Bearer $KEY"
# 3. Lire une boîte sur l'une d'elles. Cette première lecture tient désormais l'adresse et compte pour une unité.
curl -sG https://grabmail.io/api/v1/mailbox -H "Authorization: Bearer $KEY" \
--data-urlencode "address=a7f3k2@one-of-the-pool.com"
# 4. Lire un message, même en-tête.
curl -sG https://grabmail.io/api/v1/message/MESSAGE_ID -H "Authorization: Bearer $KEY" \
--data-urlencode "mailbox=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. Le quota ne compte que le pool premium, rien d'autre. 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
Nom
Entrée
Type
Requis
Description
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.
La boîte a été lue. Une boîte vide est un 200 avec count: 0, jamais un 404. next porte le curseur pour la page suivante, ou null à la fin. alias est une seconde adresse qui délivre ici et ne révèle rien de celle-ci — donnez-la à un formulaire à la place d'address ; quiconque la connaît voit toujours une boîte vide. Elle est stable, gratuite, et renvoyée aussi pour les adresses premium.
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.
401
Une clé API a été envoyée et elle est inconnue ou révoquée. Une mauvaise clé est refusée sur tous les domaines ; les domaines publics n'en ont besoin d'aucune.
402
Pool premium uniquement : le quota du plan est épuisé — quota_reached, ou overage_cap / overage_funds quand le dépassement est activé. Les adresses déjà tenues continuent de fonctionner.
403
Pool premium uniquement : un autre abonné tient cette adresse (address_taken).
404
Ce domaine n'est pas hébergé ici — vérifiez l'enregistrement MX. Un domaine du pool premium lu sans clé provenant d'un plan payant répond exactement cela, volontairement.
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.
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, bad_cursor, unknown_domain, not_found, rate_limited, daily_limit_reached, unauthorized et, sur le pool premium uniquement, quota_reached, overage_cap, overage_funds, address_taken et address_limit.
Certaines erreurs portent plus que ces deux champs : un hint indiquant quoi faire, un lien docs, sur 404 et 429 un bloc premium_pool avec le prix du pool et comment l'ouvrir, et sur un 429 dû à une limite gratuite un bloc upgrade qui indique ce qu'un plan payant supprime — pensé pour un assistant qui lit le corps de la réponse pour le compte de quelqu'un, afin qu'il puisse transmettre l'option plutôt que d'abandonner.
Limites de débit
Gratuit, sans clé : 60 requêtes par minute et 1 000 par jour, par adresse IP. Chaque appel sur une boîte compte — la lister, lire un message, son corps HTML ou une pièce jointe, en supprimer un — tout comme chaque appel d'outil MCP. Le décompte quotidien repart de zéro à 00:00 UTC.
Avec une clé d'API gratuite, le même quota suit votre compte et non votre adresse IP — pratique quand vos appels partent d'adresses changeantes, comme un exécuteur de CI. Un compte gratuit a une clé, et les boîtes qu'elle lit sont listées dans vos boîtes. Créer une clé gratuite
Dans ce cadre, une lecture par seconde et par adresse : interroger une boîte une fois par seconde est le rythme prévu.
Les plans payants n'ont ni plafond par minute ni plafond quotidien. Envoyez la clé d'un plan payant en Authorization: Bearer et il ne reste que le débit par adresse de votre plan — 2, 3 ou 5 requêtes par seconde, sur tous les domaines, décomptées par compte. Le plan Premium commence à $12,99 par mois. Voir les plans
La boîte de réception de ce site ne puise pas dans le quota gratuit de l'API : une page laissée ouverte continue de guetter le courrier tant que vous en avez besoin.
Au-delà d'une limite, vous recevez 429 avec un en-tête Retry-After exprimé en secondes entières : rate_limited pour la limite par minute ou par adresse, daily_limit_reached pour la limite quotidienne, avec le temps restant jusqu'à minuit UTC. En accès gratuit, chaque réponse vous indique où vous en êtes : X-RateLimit-Remaining pour la minute, X-RateLimit-Daily-Remaining pour la journée.
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é.