Developers
OTP inbox API
Read verification codes and magic links sent to any OTP address, for automated sign-up tests and scripts. Plain HTTPS GET requests, JSON responses.
Addresses
Any name works at @otp.886.wiki. There is nothing to create: mail to anything@otp.886.wiki is accepted. Names use letters, numbers, dots, hyphens, underscores and +; upper and lower case are the same inbox. Every full address is its own inbox, so name+shop@otp.886.wiki and name@otp.886.wiki are read separately. To get a hard-to-guess name, call:
GET https://886.wiki/api/otp/new
→ { "address": "k3m9x2…@otp.886.wiki", "inbox": "https://886.wiki/otp/inbox/…", "retentionMinutes": 60 }
Latest message
GET https://886.wiki/api/otp/{address}/latest
Returns the newest message, or "message": null when the inbox is empty. Poll every 2–5 seconds until it arrives.
{
"address": "k3m9x2…@otp.886.wiki",
"message": {
"id": 1042,
"from": "no-reply@acme.com",
"fromName": "Acme",
"subject": "Your Acme verification code",
"code": "482915",
"link": null,
"snippet": "Your verification code is 482915. It expires in 10 minutes.",
"text": "…full plain text…",
"spam": false,
"receivedAt": "2026-11-14T06:12:09.000Z",
"expiresAt": "2026-11-14T07:12:09.000Z"
}
}
All messages
GET https://886.wiki/api/otp/{address}/messages?after={id}&limit=50
GET https://886.wiki/api/otp/{address}/messages/{id}?html=1
The list is newest first and has no full bodies. after returns only messages newer than that id. The single-message call adds text, and html (sanitized) when you pass html=1.
Example
ADDR=$(curl -s https://886.wiki/api/otp/new | jq -r .address) # … submit $ADDR on the sign-up form under test … for i in $(seq 30); do CODE=$(curl -s "https://886.wiki/api/otp/$ADDR/latest" | jq -r '.message.code // empty') [ -n "$CODE" ] && echo "$CODE" && break; sleep 2 done
API keys
The API works without a key and has no request cap. You can still send an API key from the site administrator as shown below. Send it as Authorization: Bearer otp_… or X-API-Key: otp_….
Fields and errors
- code: the one-time code we found (4–10 digits, or letters and digits), or null.
- link: the most likely sign-in, confirm or verify link, or null.
- spam: true when the spam filter flagged the message. Mail that scores very high is refused before it gets here.
- Errors return JSON like { "error": "…", "code": "not_found" } with status 400, 401, 404, 429 or 503.
Inbound only: these addresses cannot send mail.