Quickstart
Wait for the OTP. One API call.
Point your signup form at a mailsocket inbox, then block on the wait endpoint until the OTP or magic link arrives. No polling loop, no Gmail, no IMAP.
Three steps
- Create an inbox and an API key. Sign up, verify your email, and open the dashboard. Your first inbox is created automatically, and you can mint an API key in one click.
-
Point your signup or test at your inbox address.
Give your signup form an address of the form
<key>@in.inboxpipe.net. -
Wait for the code.
Call
GET /api/v1/inboxes/<id>/messages/waitwithAuthorization: Bearer <key>. The call blocks until the OTP or magic link arrives, then returns it.
The wait endpoint
GET /api/v1/inboxes/{id}/messages/wait blocks until a matching parsed
message arrives, or returns empty when the window elapses. This is the "one call, wait
for the code" primitive.
Query parameters
| Param | Type | Meaning |
|---|---|---|
timeout |
seconds (float) | How long to block. Default 20. Clamped to [1, 25] server-side. |
since |
ISO-8601 | public_id | unix ts |
Only messages received strictly after this point match. Default: the request start time, so a code arriving during the call is caught but a pre-existing one is not. Pass since=0 (the epoch) to mean "return any existing unseen code". |
require |
otp | link | any |
What counts as a match. Default otp. link matches magic_link IS NOT NULL; any matches either. |
min_confidence |
float 0..1 |
Only match an OTP whose otp_confidence is at least this. Default 0.0. Ignored for link. |
Responses
| Status | Body | Meaning |
|---|---|---|
200 |
{"data": {...otp, magic_link, subject, from...}} |
A matching parsed message arrived (the earliest strictly newer than since). |
204 |
empty | Waited, nothing matched yet — call again. This is success, not an error. |
404 |
error body | The inbox is not owned or does not exist. |
429 |
error body | The concurrent-wait cap is exhausted. Code too_many_wait_requests (per-account cap: 2 free / 3 paid) or wait_capacity (global cap of 16). Retry shortly. |
{
"data": {
"subject": "Your verification code",
"from": "[email protected]",
"otp": "482193",
"magic_link": null
}
}
Code samples
Each sample submits a signup form, then blocks on the wait endpoint for the OTP. Replace *** with your real API key and inbox_xxx with your inbox id.
# 1. submit your signup form with a mailsocket address
curl -X POST https://app.example.com/signup \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]"}'
# 2. block until the OTP lands — one call, no polling
curl "https://dash.mailsocket.app/api/v1/inboxes/inbox_xxx/messages/wait?require=otp&timeout=20" \
-H "Authorization: Bearer ***"
import requests
requests.post("https://app.example.com/signup", json={"email": "[email protected]"})
# block until the OTP lands — one call, no polling
r = requests.get(
"https://dash.mailsocket.app/api/v1/inboxes/inbox_xxx/messages/wait",
params={"require": "otp", "timeout": 20},
headers={"Authorization": "Bearer ***"},
)
if r.status_code == 200:
print(r.json()["data"]["otp"]) # → "482193"
// 1. submit your signup form with a mailsocket address
await fetch("https://app.example.com/signup", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email: "[email protected]" }),
});
// 2. block until the OTP lands — one call, no polling
const url = new URL("https://dash.mailsocket.app/api/v1/inboxes/inbox_xxx/messages/wait");
url.searchParams.set("require", "otp");
url.searchParams.set("timeout", "20");
const res = await fetch(url, {
headers: { Authorization: "Bearer ***" },
});
if (res.status === 200) {
const { data } = await res.json();
console.log(data.otp); // → "482193"
}
Run it in your E2E suite
There's a ready-to-copy Playwright example that fills a signup form with a
mailsocket address and awaits the OTP — see
examples/playwright/otp-signup.spec.ts in this repository. It reads
MAILSOCKET_API_KEY and MAILSOCKET_INBOX_ID from the environment.
More references
- Try it live → — get a throwaway inbox in one click and watch
wait_for_otpextract a real OTP. No signup. - Full API reference → — every v1 endpoint, parameter, response and status code, plus cursor pagination and rate-limit headers.
- Error reference → — the canonical
{error:{code,message}}table for every code the API emits. - Pricing → — free vs paid limits.
- Waiting for an OTP in pytest → — plus Cypress, Puppeteer and GitHub Actions guides.
- FAQ → and changelog →.