API guide
chobitmail’s HTTP API lets you automate tests that involve email addresses.
An OpenAPI definition is also available — use it to generate clients when you need to.
- Full API reference: https://chobitmail.com/api/docs
- OpenAPI JSON: https://chobitmail.com/api/openapi.json
Basics
| Item | Value |
|---|---|
| Base URL | https://chobitmail.com |
| Auth | Authorization: Bearer <API key> |
| Format | JSON for both request and response |
Create API keys in the dashboard. You can issue up to 2 keys per team, and disable, re-enable, or delete them from the dashboard as well.
Common flow
- Create a one-time address with
POST /api/inboxes - In your test, send email to that one-time address
- Wait for delivery with
GET /api/inboxes/{id}/messages/wait - Use OTP codes or URLs from the response JSON
- When the test finishes, delete the address with
DELETE /api/inboxes/{id}
KEY=$CHOBITMAIL_API_KEY
BASE=https://chobitmail.com
curl -s -X POST $BASE/api/inboxes -H "Authorization: Bearer $KEY"
# => {"id":"...","address":"...@chobitmail.com",...}
curl -s "$BASE/api/inboxes/{inboxId}/messages/wait?timeout=25" \
-H "Authorization: Bearer $KEY"
# => {"message":{"codes":["123456"],"links":["https://..."],...}}
Endpoint overview
Detailed request/response schemas live in OpenAPI. This section only describes purpose.
| Method | Path | Purpose |
|---|---|---|
GET |
/api/inboxes |
List the team’s active inboxes (newest first) |
POST |
/api/inboxes |
Create an inbox. Optional ttl (seconds) |
GET |
/api/inboxes/{id}/messages |
List received messages (does not wait) |
GET |
/api/inboxes/{id}/messages/wait |
Wait for mail (core of the API) |
DELETE |
/api/inboxes/{id} |
Delete an inbox immediately |
DELETE |
/api/inboxes |
Delete all active inboxes for the team |
GET |
/api/usage |
Quota usage |
Waiting (messages/wait)
Waits until a matching message arrives, then returns it. If one is already present, it returns immediately.
Common query parameters (all optional):
| Parameter | Description |
|---|---|
timeout |
Wait seconds (1–30, default 25) |
from |
Exact match on sender |
subject |
Partial match on subject |
timestamp_from / timestamp_to |
Receive-time range (Unix milliseconds) |
Response:
| Status | Meaning |
|---|---|
| 200 | {"message": {...}} — first message that matched the filters |
| 408 | {"error":"timeout"} — nothing yet → safe to reconnect |
| 429 | {"error":"tooManyWaiters"} — concurrent wait limit per inbox (10) |
408 is not a hard failure; it means “not yet.” Reconnect until your overall test timeout. Multiple filters are AND. Messages that don’t match are stored only and do not resolve the wait.
ttl on create
Seconds. Range 60–600 (default 600 = 10 minutes). Values outside the range are clamped. Check the effective max via ttl on GET /api/usage. Ignored on the persistent plan, where expiresAt is null.
Message object
Main fields on the message JSON returned by list and wait.
| Field | Description |
|---|---|
id |
Message ID |
from |
Sender (envelope) |
subject |
Subject (MIME-decoded) |
text / html |
Body |
links |
Extracted URLs (max 20) |
codes |
OTP-like 6-digit numbers (max 10; digits inside URLs excluded) |
attachments |
Metadata only (bodies are not stored) |
receivedAt |
Received time (ISO 8601) |
links and codes are extracted server-side. Use links for confirmation URLs and codes for OTPs as-is.
Reading errors
| Status | Body (example) | Meaning |
|---|---|---|
| 401 | unauthorized |
Missing, invalid, or disabled key |
| 403 | forbidden |
Account suspended |
| 404 | notFound |
Inbox missing, expired, or another tenant (not distinguished) |
| 408 | timeout |
Wait timed out (reconnect OK) |
| 429 | quotaExceeded |
Concurrent slot or daily limit on create |
| 429 | tooManyWaiters |
Too many waiters on the same inbox |
404 does not distinguish the three cases so other tenants’ IDs cannot be probed. In tests, the usual cause of 404 is TTL expiry.
Free-tier reference
Values may change. For current limits, use GET /api/usage and Sender domain verification.
| Item | Unverified Free | Verified Free |
|---|---|---|
| Concurrent active inboxes | 1 | 2 |
| Creates / day (UTC) | 5 | 50 |
| Receives / day (UTC) | 5 | 100 |
| TTL | Max 10 minutes | Same |
Other limits: up to 50 messages stored per inbox, max email size 1MB, attachment bodies not stored.
Node.js wait helper example
const BASE = "https://chobitmail.com";
const KEY = process.env.CHOBITMAIL_API_KEY;
const AUTH = { Authorization: `Bearer ${KEY}` };
async function createInbox(ttl = 600) {
const res = await fetch(`${BASE}/api/inboxes`, {
method: "POST",
headers: { ...AUTH, "Content-Type": "application/json" },
body: JSON.stringify({ ttl }),
});
return res.json();
}
async function waitForMessage(inboxId, params = {}, maxWaitMs = 120_000) {
const query = new URLSearchParams({ timeout: "25", ...params });
const deadline = Date.now() + maxWaitMs;
while (Date.now() < deadline) {
const res = await fetch(
`${BASE}/api/inboxes/${inboxId}/messages/wait?${query}`,
{ headers: AUTH },
);
if (res.status === 200) return (await res.json()).message;
if (res.status !== 408) throw new Error(`unexpected: ${res.status}`);
}
throw new Error("message did not arrive");
}
If you use Playwright, prefer @chobitmail/playwright instead of writing the above yourself (guide currently Japanese).