API reference
Wait for the verification email from your test suite
Create an inbox, sign up with its address, call wait, read the code. Available on Pro ($12/month) and TEAM — see pricing. Keys are created in Settings → API in your workspace.
Authentication
Send your key as a bearer token on every request to https://api.inflovy.com/v1. Keys are workspace-scoped and shown once at creation.
Authorization: Bearer ik_live_…Playwright
const api = 'https://api.inflovy.com/v1';
const headers = { Authorization: `Bearer ${process.env.INFLOVY_API_KEY}` };
const inbox = await (await fetch(`${api}/inboxes`, { method: 'POST', headers })).json();
await page.goto('https://yourapp.test/signup');
await page.fill('#email', inbox.emailAddress);
await page.click('text=Sign up');
const res = await (await fetch(`${api}/inboxes/${inbox.id}/messages/wait?timeout=30`, { headers })).json();
expect(res.status).toBe('received');
await page.fill('#code', res.message.verificationCode);
await page.click('text=Verify');
await fetch(`${api}/inboxes/${inbox.id}`, { method: 'DELETE', headers });Cypress
const api = 'https://api.inflovy.com/v1';
const auth = { Authorization: `Bearer ${Cypress.env('INFLOVY_API_KEY')}` };
cy.request({ method: 'POST', url: `${api}/inboxes`, headers: auth }).then(({ body: inbox }) => {
cy.visit('/signup');
cy.get('#email').type(inbox.emailAddress);
cy.contains('Sign up').click();
cy.request({ url: `${api}/inboxes/${inbox.id}/messages/wait?timeout=30`, headers: auth, timeout: 40000 })
.its('body').then((res) => {
expect(res.status).to.eq('received');
cy.get('#code').type(res.message.verificationCode);
cy.contains('Verify').click();
});
});Endpoints
| Method | Path | What it does |
|---|---|---|
| POST | /v1/inboxes | Create an inbox. Body: { label?, projectId? }. 201 → InboxView. |
| GET | /v1/inboxes?page&limit | List inboxes (newest first). |
| DELETE | /v1/inboxes/:id | Delete an inbox and its messages. 204. |
| GET | /v1/inboxes/:id/messages?page&limit | List messages (no bodies). |
| GET | /v1/messages/:id | One message with bodyHtml. |
| GET | /v1/inboxes/:id/messages/wait?timeout=30&since=… | Long-poll: returns the first message that arrived at Inflovy after `since` (default: call start), or { status: "timeout" } after `timeout` seconds (1–60). |
Message shape
{
"id": "…", "inboxId": "…",
"subject": "Your verification code is 482913",
"from": "[email protected]", "to": "mail+…@inbound.inflovy.com",
"snippet": "…", "bodyHtml": "…", // bodyHtml only on GET /v1/messages/:id and wait
"receivedAt": "2026-09-16T10:05:00.000Z", "expiresAt": "2026-10-16T10:05:00.000Z",
"verificationCode": "482913", // best guess, or null
"candidates": ["482913"], // every plausible 4–8 digit code
"links": ["https://yourapp.test/verify?t=…"]
}wait responds { "status": "received", "message": … } or { "status": "timeout", "waitedMs": 30000, "since": "…" } — a timeout is a normal result, so loop if you need longer than 60 s. Pass a message id as since to skip everything up to and including it.
Webhooks (TEAM)
Register up to 5 https endpoints in Settings → Webhooks. Every new message in the workspace is POSTed within seconds; respond 2xx within 10 s. Failures retry 5 times (1 s, 5 s, 25 s, 125 s, 625 s); an endpoint is paused after 20 consecutive failures. Private and internal addresses are refused.
POST <your url>
Content-Type: application/json
X-Inflovy-Event: message.received
X-Inflovy-Delivery: <deliveryId>
X-Inflovy-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>
{ "id": "…", "type": "message.received", "createdAt": "…",
"data": { "workspaceId": "…", "inbox": InboxView, "message": MessageView } }Errors and limits
| 401 | API_KEY_INVALID | Header missing/malformed, or the key is unknown or revoked. |
| 403 | API_NOT_ON_PLAN | Workspace is on FREE. Response names nextPlan. |
| 403 | WORKSPACE_INACTIVE | Billing is paused for the workspace. |
| 403 | WEBHOOKS_NOT_ON_PLAN | Webhooks need TEAM; response names nextPlan. |
| 403 | limitType: aliases | Inbox limit reached; response carries nextPlan and nextPlanLimit. |
| 404 | — | The id does not exist in your workspace (never 403). |
| 429 | — | Rate limit for this key; see Retry-After. |
Per key: 30 inbox creations/min, 120 wait calls/min, 300 other requests/min. Errors use the shared envelope { statusCode, message: { code, … } }.