tempmail / API v1
Reference

tempmail API

REST API for disposable email addresses. Use it to receive verification codes, signup emails, and one-time passwords programmatically — without setting up your own SMTP.

Push delivery via Gmail API · ~5s typical latency
Base URL
https://temp.coda.ink/v1
Auth
Bearer <token>
Format
application/json
Delivery
push

Quick start

Three calls: create an address, fetch incoming emails, clean up.

# 1. Create an address (returns address + token)
RESP=$(curl -s -X POST https://temp.coda.ink/v1/address)
ADDR=$(echo "$RESP" | jq -r '.data.address')
TOKEN=$(echo "$RESP" | jq -r '.data.token')

# 2. Use $ADDR somewhere (sign up for a service, etc.)

# 3. Poll for incoming emails
curl -s https://temp.coda.ink/v1/address/$ADDR/emails \
  -H "Authorization: Bearer $TOKEN" | jq .

# 4. Read a specific email
curl -s https://temp.coda.ink/v1/email/EMAIL_ID \
  -H "Authorization: Bearer $TOKEN" | jq '.data.body_text'
// fetch / Node 18+ / browser
const base = 'https://temp.coda.ink/v1';

const create = await fetch(base + '/address', { method: 'POST' });
const { data } = await create.json();
const { address, token } = data;

// ... use address ...

const emails = await fetch(`${base}/address/${address}/emails`, {
  headers: { Authorization: `Bearer ${token}` },
}).then(r => r.json());

console.log(emails.data);
import requests
base = 'https://temp.coda.ink/v1'

r = requests.post(base + '/address').json()
address, token = r['data']['address'], r['data']['token']

# ... use address ...

emails = requests.get(
    f"{base}/address/{address}/emails",
    headers={"Authorization": f"Bearer {token}"},
).json()

print(emails['data'])

Authentication

Pass a Bearer token in the Authorization header, or as a token query string parameter. There are two token types:

TypePrefixScopeHow to get
Address token tm_at_… Single address (returned at creation) Auto, on POST /v1/address
API key tm_… All addresses created with this key + higher rate limits Message us on Telegram
curl
# Bearer header (recommended)
curl https://temp.coda.ink/v1/address/abc123@bb.coda.ink \
  -H "Authorization: Bearer tm_at_xxxxx"

# Query param (handy for browser-only environments)
curl 'https://temp.coda.ink/v1/address/abc123@bb.coda.ink?token=tm_at_xxxxx'

Rate limits

Rate limits are tracked per IP for free usage, and per API key when authenticated.

Free (no key)With API key
Create address3 / min20 / min
Read requests20 / min120 / min
Max active addresses325

Exceeding a limit returns 429 Too Many Requests with a Retry-After header.

Providers

The provider body parameter on POST /v1/address selects the address type:

tempmail
∞ forever
@bb.coda.ink · @tt.coda.ink · @startup.coda.ink
Random local part on our domain. No expiry. Always available. Default if provider is omitted. Domain is picked at random from bb.coda.ink, tt.coda.ink, startup.coda.ink per address.
gmail
15 min
+tag@gmail.com
Plus-addressed real Gmail (coda.temp+xxxxxxxx@gmail.com). Mail is pulled via IMAP and routed by tag. Auto-expires after 15 min. Max 3 active per owner.
Heads up: some sites strip + from emails during signup (Steam, certain banks). Gmail won't work there — use tempmail instead.

Create address

POST /v1/address no auth

Create a new disposable address. Returns the address and a secret token used to read its mail.

Body parameters

provider "tempmail" | "gmail" optional
Address type. Defaults to "tempmail". Use "gmail" for a 15-min Gmail subaddress.
# Default tempmail (permanent, our domain)
curl -X POST https://temp.coda.ink/v1/address

# Gmail (15-min TTL)
curl -X POST https://temp.coda.ink/v1/address \
  -H "Content-Type: application/json" \
  -d '{"provider": "gmail"}'
await fetch('https://temp.coda.ink/v1/address', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ provider: 'gmail' }), // or 'tempmail'
}).then(r => r.json());
requests.post(
    'https://temp.coda.ink/v1/address',
    json={'provider': 'gmail'},  # or 'tempmail'
).json()

Response (200)

{
  "success": true,
  "data": {
    "address": "abc123@bb.coda.ink",
    "token": "tm_at_8a3f2c…",
    "provider": "tempmail",
    "created_at": "2025-01-01T00:00:00Z"
  }
}
{
  "success": true,
  "data": {
    "address": "coda.temp+a8f3k2qm@gmail.com",
    "token": "tm_at_8a3f2c…",
    "provider": "gmail",
    "ttl_minutes": 15,
    "expires_at": "2025-01-01T00:15:00Z",
    "created_at": "2025-01-01T00:00:00Z"
  }
}
Save the token. It's the only way to read emails for this address — it's not retrievable later.

Get address info

GET /v1/address/:address token

Returns metadata about an address (creation time, email count).

curl
curl https://temp.coda.ink/v1/address/abc123@bb.coda.ink \
  -H "Authorization: Bearer tm_at_…"

Delete address

DELETE /v1/address/:address token

Permanently delete the address and all emails received for it.

curl
curl -X DELETE https://temp.coda.ink/v1/address/abc123@bb.coda.ink \
  -H "Authorization: Bearer tm_at_…"

List emails

GET /v1/address/:address/emails token

List emails received for an address (newest first). Returns metadata only — call GET /v1/email/:id for body.

curl
curl https://temp.coda.ink/v1/address/abc123@bb.coda.ink/emails \
  -H "Authorization: Bearer tm_at_…"

Response (200)

json
{
  "success": true,
  "data": [
    {
      "id": "9f5d09cb-7c79-431c-92ec-1c7e871c07f9",
      "from_address": "no-reply@example.com",
      "subject": "Verify your email",
      "created_at": "2025-01-01T00:01:23Z"
    }
  ]
}

Get email

GET /v1/email/:id token

Get the full body of a single email. The token must own the address this email was sent to.

curl
curl https://temp.coda.ink/v1/email/<UUID> \
  -H "Authorization: Bearer tm_at_…"

Response (200)

json
{
  "success": true,
  "data": {
    "id": "9f5d09cb-…",
    "from": "no-reply@example.com",
    "to": "abc123@bb.coda.ink",
    "subject": "Verify your email",
    "body_text": "Your code is 482931.",
    "body_html": "<p>Your code is <strong>482931</strong>.</p>",
    "created_at": "2025-01-01T00:01:23Z"
  }
}

Delete email

DELETE /v1/email/:id token

Delete a single email.

curl
curl -X DELETE https://temp.coda.ink/v1/email/<UUID> \
  -H "Authorization: Bearer tm_at_…"

Errors

Errors are returned as JSON with success: false and an error message.

json
{
  "success": false,
  "error": "Rate limit exceeded for address creation."
}

Status codes

CodeMeaning
400Malformed request body or query.
403Token missing or doesn't grant access to this resource.
404Address or email not found (or expired).
429Rate limit exceeded. Retry after the time in Retry-After.
503Provider unavailable (e.g. gmail bridge not configured).

API keys

API keys raise your rate limits and let you manage many addresses with a single secret. Keys are issued manually.

Need a key? Message us on Telegram. Tell us roughly what you're building — most legitimate use cases get approved.

Once you have a key, just pass it instead of an address token:

curl
# Create with API key
curl -X POST https://temp.coda.ink/v1/address \
  -H "Authorization: Bearer tm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"provider": "gmail"}'

# The returned address token works as before.
# Or use the API key directly to read mail for any address you own.

Examples

Wait for a verification code

Poll the inbox until a code arrives, then extract it. Ideal for automated signups.

const base = 'https://temp.coda.ink/v1';
const headers = (t) => ({ Authorization: `Bearer ${t}` });

const { data: a } = await fetch(base + '/address', { method: 'POST' }).then(r => r.json());
console.log('Use this address:', a.address);

// Poll for up to 60s
const start = Date.now();
while (Date.now() - start < 60_000) {
  const { data: list } = await fetch(`${base}/address/${a.address}/emails`, { headers: headers(a.token) }).then(r => r.json());
  if (list.length > 0) {
    const { data: full } = await fetch(`${base}/email/${list[0].id}`, { headers: headers(a.token) }).then(r => r.json());
    const code = full.body_text.match(/\b\d{4,8}\b/)?.[0];
    console.log('Code:', code);
    break;
  }
  await new Promise(r => setTimeout(r, 3000));
}
import re, time, requests
base = 'https://temp.coda.ink/v1'

a = requests.post(base + '/address').json()['data']
print('Use this address:', a['address'])

headers = {'Authorization': f"Bearer {a['token']}"}
for _ in range(20):
    emails = requests.get(f"{base}/address/{a['address']}/emails", headers=headers).json()['data']
    if emails:
        full = requests.get(f"{base}/email/{emails[0]['id']}", headers=headers).json()['data']
        m = re.search(r'\b\d{4,8}\b', full['body_text'])
        if m:
            print('Code:', m.group(0))
            break
    time.sleep(3)

Throwaway Gmail for short-lived signups

Use the Gmail provider when a service requires a real Gmail address. Address auto-expires in 15 min.

curl
RESP=$(curl -s -X POST https://temp.coda.ink/v1/address \
  -H "Content-Type: application/json" \
  -d '{"provider":"gmail"}')

ADDR=$(echo "$RESP" | jq -r '.data.address')
TOKEN=$(echo "$RESP" | jq -r '.data.token')
EXP=$(echo "$RESP" | jq -r '.data.expires_at')

echo "Use $ADDR (expires $EXP)"

# Poll for mail (will arrive within ~10s of being received)
sleep 5
curl -s https://temp.coda.ink/v1/address/$ADDR/emails -H "Authorization: Bearer $TOKEN" | jq .