API Documentation
Overview
OTPBox provides a simple REST API for creating disposable email inboxes and retrieving verification codes programmatically.
All API responses are JSON. Rate limits apply: 10 requests per hour per IP.
Create Inbox
POST /api/inboxCreates a new temporary inbox. Returns the inbox email address and access token.
{
"id": "abc123xyz789",
"email": "abc123xyz789@box.otpbox.app",
"expiresAt": 1704153600000,
"token": "def456uvw012..."
}curl -X POST https://otpbox.app/api/inbox
Get Inbox State
GET /api/inbox/:tokenRetrieves the inbox metadata and all messages. Messages are sorted newest first.
{
"inbox": {
"id": "abc123xyz789",
"email": "abc123xyz789@box.otpbox.app",
"token": "def456uvw012...",
"createdAt": 1704150000000,
"expiresAt": 1704153600000
},
"messages": [
{
"id": "msg001",
"inboxId": "abc123xyz789",
"from": "noreply@service.com",
"subject": "Your verification code",
"body": "Your code is: 123456",
"otp": "123456",
"magicLink": null,
"receivedAt": 1704150100000
}
]
}Get Latest Extraction
GET /api/inbox/:token/latestReturns only the extracted OTP and/or magic link from the most recent message. Useful for CI/CD automation.
{
"otp": "123456",
"link": "https://service.com/verify?token=...",
"from": "noreply@service.com",
"subject": "Your verification code",
"receivedAt": 1704150100000
}{
"error": "No messages found"
}This endpoint returns 404 when the inbox exists but has no messages yet. Use a wait/retry loop in your automation (see CI examples below).
CI / Automation
OTPBox is designed for headless automation. Create a disposable inbox, trigger your app to send a verification email, then poll for the OTP.
Shell Script Example
#!/bin/bash
set -e
# 1. Create disposable inbox
echo "Creating inbox..."
RESPONSE=$(curl -s -X POST https://otpbox.app/api/inbox)
TOKEN=$(echo "$RESPONSE" | jq -r '.token')
EMAIL=$(echo "$RESPONSE" | jq -r '.email')
echo "Inbox: $EMAIL"
echo "Token: $TOKEN"
# 2. Trigger your app to send verification email to $EMAIL
# Example: curl -X POST https://yourapp.com/signup -d "email=$EMAIL"
echo "Triggering verification email..."
# ... your app logic here ...
# 3. Poll for OTP (wait up to 30 seconds)
echo "Waiting for OTP..."
MAX_ATTEMPTS=10
SLEEP_SECONDS=3
for i in $(seq 1 $MAX_ATTEMPTS); do
RESPONSE=$(curl -s https://otpbox.app/api/inbox/$TOKEN/latest)
OTP=$(echo "$RESPONSE" | jq -r '.otp // empty')
if [ -n "$OTP" ] && [ "$OTP" != "null" ]; then
echo "✓ Got OTP: $OTP"
# 4. Use the OTP in your test
# Example: curl -X POST https://yourapp.com/verify -d "code=$OTP"
exit 0
fi
echo " Attempt $i/$MAX_ATTEMPTS - no message yet, waiting..."
sleep $SLEEP_SECONDS
done
echo "✗ Timeout: No OTP received after $MAX_ATTEMPTS attempts"
exit 1GitHub Actions Example
name: E2E Verification Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create OTPBox inbox
id: inbox
run: |
RESPONSE=$(curl -s -X POST https://otpbox.app/api/inbox)
echo "token=$(echo $RESPONSE | jq -r '.token')" >> $GITHUB_OUTPUT
echo "email=$(echo $RESPONSE | jq -r '.email')" >> $GITHUB_OUTPUT
- name: Trigger signup with OTPBox email
run: |
curl -X POST https://yourapp.com/api/signup \
-H "Content-Type: application/json" \
-d '{"email": "${{ steps.inbox.outputs.email }}"}'
- name: Wait for OTP
id: otp
run: |
for i in {1..10}; do
RESPONSE=$(curl -s https://otpbox.app/api/inbox/${{ steps.inbox.outputs.token }}/latest)
OTP=$(echo "$RESPONSE" | jq -r '.otp // empty')
if [ -n "$OTP" ] && [ "$OTP" != "null" ]; then
echo "otp=$OTP" >> $GITHUB_OUTPUT
echo "✓ Received OTP: $OTP"
exit 0
fi
echo "Waiting for OTP (attempt $i/10)..."
sleep 3
done
echo "✗ Timeout waiting for OTP"
exit 1
- name: Verify OTP
run: |
curl -X POST https://yourapp.com/api/verify \
-H "Content-Type: application/json" \
-d '{"code": "${{ steps.otp.outputs.otp }}"}'Rate Limits & Best Practices
/latest returns 404 when inbox is empty. Check response.otp for null or empty.Wait/Retry Pattern
Email delivery typically takes 1-5 seconds. The /latest endpoint returns 404 with { "error": "No messages found" } when the inbox exists but has no messages yet.
Recommended pattern: Poll every 3 seconds for up to 30 seconds (10 attempts). This handles normal email latency while staying well under rate limits.
# Minimal wait/retry in curl
for i in {1..10}; do
OTP=$(curl -s https://otpbox.app/api/inbox/$TOKEN/latest | jq -r '.otp // empty')
[ -n "$OTP" ] && [ "$OTP" != "null" ] && break
sleep 3
doneError Responses
404 Not FoundInbox does not exist
410 GoneInbox has expired
429 Too Many RequestsRate limit exceeded
Notes
- Inboxes expire automatically after 1 hour
- Tokens are opaque and random - do not parse or predict them
- Messages appear typically within seconds of being sent
- For real-time updates, poll every 3-5 seconds or use the web UI
- OTP extraction uses regex patterns for 4-8 digit codes
- Magic link detection looks for common verification URL patterns