Справочник по API

Три эндпоинта, JSON на входе и на выходе. Без ключа и без аккаунта на публичных доменах — вставьте запрос в терминал, и он сработает.

Обзор

Почтовый ящик никогда не создаётся — он появляется в момент, когда на адрес приходит письмо, и исчезает через 5 дней. Регистрировать нечего, поэтому на публичных доменах у API нет понятия пользователя, проекта или токена.

  • Каждый ответ — это JSON, включая любую ошибку.
  • Всё время указано в UTC в формате RFC 3339 — 2026-08-04T18:31:07Z.
  • ID сообщений — непрозрачные строки. Не разбирайте их.
  • Только приём. Эндпоинта для отправки почты нет — так и задумано.

Базовый URL

https://grabmail.io/api/v1

Только HTTPS; обычный HTTP перенаправляется. Версия указана в пути, и v1 не изменит свою форму у вас под ногами — для несовместимого изменения будет использован новый номер.

Аутентификация: не требуется

Никакой — на публичных доменах. Любой, кто знает адрес, может прочитать его почтовый ящик — через API точно так же, как через сайт. Таковы условия общего одноразового сервиса, поэтому никогда не направляйте на публичный адрес то, что вам дорого.

Домен, который вы направите сюда, отвечает на те же эндпоинты, тоже без ключа. Направьте MX на нас, и первое же письмо подключит домен; см. подключение домена. Ящики на нём читает любой, кто знает адрес, — точно так же, как на публичных доменах.

Один случай всё же требует заголовка: домен, который мы закрыли по запросу, читается с Authorization: Bearer <key>, а неверный или отсутствующий ключ отвечает 401 с unauthorized. Ключи сравниваются за постоянное время, поэтому неверный отклоняется так же долго, как верный принимается.

Премиум-домены

Единственное исключение из правила выше. Публичные домены входят в публичные списки одноразовой почты — именно поэтому форма регистрации иногда отклоняет адрес на них. Платный тариф открывает пул из 92 частных домена .com, вне этих списков.

В API не меняется ничего. Те же пути, те же параметры, те же формы ответа. Единственное отличие — один заголовок: премиум-адрес читается с Authorization: Bearer gm_live_…, ключом из ваши API-ключи. Без действующего ключа тот же запрос отвечает 402 или 403 — но не ящиком.

# 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"

Публичные домены и ваши собственные остаются бесплатными, без ключа и без ограничений на всех тарифах, включая бесплатный. Квоты считают только письма, приходящие в премиум-пул. Тарифы и цены — на страница тарифов.

Эндпоинты

GET /api/v1/mailbox

Всё, что ждёт на адресе, сначала новые. Это тот самый вызов, который опрашивает ваш набор тестов.

Параметры

ИмяВходТипОбязательноОписание
address query string да Ящик для чтения, например k7fq2m@grabmail.io.
limit query integer нет Сколько сообщений вернуть в этом вызове, 1–200. По умолчанию 50, сначала новые. Это ограничивает один ответ, а не ящик — используйте before, чтобы читать дальше.
before query string нет id самого старого сообщения, которое у вас уже есть; возвращает страницу после него. Передайте обратно поле next из предыдущего ответа. Когда next равно null, у вас есть всё.

Пример

Список ящика
$ 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"
    }
  ]
}

Коды состояния

200
Ящик прочитан. Пустой ящик — это 200 с count: 0, никогда не 404. next несёт курсор для следующей страницы или null в конце.
400
Адрес некорректен, либо before не является id сообщения.
400
address отсутствует или не является допустимым адресом.
404
Этот домен не размещён здесь — проверьте запись MX.
429
Превышен лимит запросов. Повторите попытку после задержки, указанной в Retry-After.
GET /api/v1/message/{id}

Заголовки, текстовую часть, HTML-часть и любые вложения.

Параметры

ИмяВходТипОбязательноОписание
id path string да Id сообщения, возвращённый вызовом списка.
mailbox query string да Адрес, на который было доставлено сообщение.

Пример

Прочитать сообщение
$ 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": []
}

Коды состояния

200
Сообщение. html равно null, если отправитель прислал только текст.
400
mailbox отсутствует или недействителен.
404
Такого сообщения в этом ящике нет — либо истёк срок хранения.
429
Превышен лимит запросов.
DELETE /api/v1/message/{id}

Удаляет сразу, не дожидаясь истечения срока хранения.

Параметры

ИмяВходТипОбязательноОписание
id path string да Сообщение для удаления.
mailbox query string да Адрес, на который оно было доставлено.

Пример

Удалить сообщение
$ curl -X DELETE -G https://grabmail.io/api/v1/message/01JR8W2K4Q \
  --data-urlencode "mailbox=k7fq2m@grabmail.io"

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

Коды состояния

200
Удалено. Вызов идемпотентен: повторное удаление всё равно вернёт 200.
400
mailbox отсутствует или недействителен.
404
Такого сообщения в этом ящике нет.
429
Превышен лимит запросов.

Вложения

У каждого письма есть список вложений с готовыми URL. Загружайте вложение с той же авторизацией, что и само письмо.

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

Ответ всегда приходит как application/octet-stream с заголовком Content-Disposition: attachment, независимо от того, что указал отправитель. Это сделано намеренно: вернуть чужой text/html как есть означало бы позволить вложению исполниться как странице на этом источнике. Настоящий тип указан в JSON письма — там это данные, а не команда.

Ошибки

Любая ошибка возвращается в JSON с одними и теми же двумя полями, поэтому клиент обрабатывает их в одном месте. Категория — в статусе, error — это стабильный машиночитаемый код, а message предназначен для людей и может быть переформулирован в любой момент.

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

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

Никогда не принимайте решения по message. Используемые коды — invalid_address, unknown_domain, not_found и rate_limited.

Лимиты запросов

Один запрос в секунду на адрес. Опрашивать ящик раз в секунду — предусмотренный режим, и он никогда не ограничивается.

При превышении лимита вы получаете 429 с заголовком Retry-After в секундах. Дневной квоты и запаса на всплеск нет — управлять нечем.

Срок хранения

Письмо удаляется через 5 дней после получения — прочитано оно или нет. У каждого письма есть поле expires_at, так что вычислять эту дату самостоятельно не нужно.

Это жёсткий предел, а не настройка — никакой параметр его не продлевает. Если письмо должно пережить это окно, заберите его и сохраните на своей стороне.

Собственный домен

Направьте свою MX-запись на smtp.grabmail.io, и каждый адрес на вашем домене начнёт отвечать через эти же эндпоинты — учить второй API не нужно, регистрироваться не нужно, и ключ не нужен.

Подключить домен →

С возвращением

Ваши ящики и ваши домены в одном месте.