back
voidash docs

API reference.

disposable inboxes with built-in OTP & magic-link extraction - one REST call, no inbox scraping. plus a long-poll wait, SSE, webhooks, and a hosted MCP server.

BASEhttps://api.voidash.com

introduction

voidash is a disposable-email API with built-in OTP and magic-link extraction. create an inbox, point a signup at it, and pull the verification code straight from the API - no parsing, no IMAP, no inbox scraping.

everything an agent or a CI job needs is one REST call away, plus a long-poll wait endpoint, server-sent events, outbound webhooks, and a hosted MCP server for AI agents.

base URL & versioning

all endpoints live under https://api.voidash.com. the REST API is versioned under /api/v1. the MCP server is at /mcp. responses are JSON unless noted (raw .eml and attachments return their original content type).

authentication

most endpoints require a Bearer token in the Authorization header. creating your first inbox without a token mints a new anonymous session and returns its session_key once - store it. you can also mint scoped API keys (vd_sk_...) from the account panel or the keys API; all token formats authenticate identically.

bash
curl https://api.voidash.com/api/v1/me \
  -H "Authorization: Bearer $VOIDASH_KEY"

plans & limits

two plans, free and pulsar, scale the same limits: inbox count, visible messages per inbox, retention, request rate, the long-poll wait budget, webhook count, and MCP concurrency. your live entitlements are always readable from GET /api/v1/me - don't hard-code them. rate-limit headers (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset) are returned on every call; a 429 includes Retry-After.

errors

errors use standard HTTP status codes with a JSON body { "error": "message" }. common codes: 400 bad request, 401 missing or invalid token, 403 not available on your plan, 404 not found, 429 rate limited, 5xx server error.

json
{
  "error": "webhooks are not available on your plan"
}
Inboxes
Inboxes· optional auth

create an inbox

POST /api/v1/inboxes

allocate a fresh disposable address. with a Bearer token the inbox joins that account; without one, a new anonymous session is created and its session_key is returned once. optionally request a specific issuing domain (must be one of GET /domains).

body parameters

domainstring

optional. issuing domain; defaults to the service default.

note

session_key is present only when a brand-new session was created.

request

bash
curl -X POST https://api.voidash.com/api/v1/inboxes \
  -H "Authorization: Bearer $VOIDASH_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

response

json
{
  "id": "9db42d9d-3a25-4c52-a92d-7f634282a527",
  "address": "nova.packet-orbit7qk@voidash.cyou",
  "domain": "voidash.cyou",
  "created_at": "2026-06-26T12:00:00Z",
  "expires_at": "2026-07-26T12:00:00Z",
  "last_activity": "2026-06-26T12:00:00Z",
  "session_key": "vd_sess_…"
}
Inboxes· required auth

list inboxes

GET /api/v1/inboxes

return the live inboxes owned by the current account.

request

bash
curl https://api.voidash.com/api/v1/inboxes \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{
  "inboxes": [
    {
      "id": "9db42d9d-…",
      "address": "nova.packet-orbit7qk@voidash.cyou",
      "domain": "voidash.cyou",
      "created_at": "2026-06-26T12:00:00Z"
    }
  ]
}
Inboxes· required auth

retrieve an inbox

GET /api/v1/inboxes/{id}

fetch one inbox owned by the account.

path parameters

idstring

the inbox id.

request

bash
curl https://api.voidash.com/api/v1/inboxes/{id} \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{
  "id": "9db42d9d-…",
  "address": "nova.packet-orbit7qk@voidash.cyou",
  "domain": "voidash.cyou",
  "created_at": "2026-06-26T12:00:00Z"
}
Inboxes· required auth

delete an inbox

DELETE /api/v1/inboxes/{id}

delete an inbox. an empty, never-used address goes to quarantine and may be reissued later; an address that received mail is burned and never reissued. returns 204.

path parameters

idstring

the inbox id.

request

bash
curl -X DELETE https://api.voidash.com/api/v1/inboxes/{id} \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
204 No Content
Messages
Messages· required auth

list messages in an inbox

GET /api/v1/inboxes/{id}/messages

list received messages for one inbox, newest first. each message carries any extracted OTP code and/or magic link with a confidence score.

path parameters

idstring

the inbox id.

query parameters

limitinteger

page size (default 50, max 200).

offsetinteger

offset for paging.

unreadboolean

only unread when true.

has_signalboolean

only messages with an extracted code/link.

request

bash
curl https://api.voidash.com/api/v1/inboxes/{id}/messages \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{
  "messages": [
    {
      "id": "a1b2c3d4-…",
      "inbox_id": "9db42d9d-…",
      "from_addr": "noreply@github.com",
      "subject": "Your GitHub launch code",
      "preview_text": "Continue signing in…",
      "otp_code": "778899",
      "otp_confidence": 96,
      "otp_source": "subject",
      "otp_format": "numeric",
      "magic_link": null,
      "has_attachments": false,
      "received_at": "2026-06-26T12:01:10Z",
      "is_read": false
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}
Messages· required auth

list all messages

GET /api/v1/messages

list messages across all of the account’s inboxes (same filters as above, plus inbox_id and a free-text q search).

query parameters

limitinteger

page size (default 50, max 200).

offsetinteger

offset for paging.

inbox_idstring

filter to one inbox.

unreadboolean

only unread when true.

has_signalboolean

only messages with a code/link.

qstring

free-text search over sender/subject.

request

bash
curl https://api.voidash.com/api/v1/messages?has_signal=true \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{ "messages": [], "total": 12, "limit": 50, "offset": 0 }
Messages· required auth

retrieve a message

GET /api/v1/messages/{id}

fetch one message with its sanitized text + html bodies (inline), its attachment list, and all extracted signals. fetching also marks it read.

path parameters

idstring

the message id.

request

bash
curl https://api.voidash.com/api/v1/messages/{id} \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{
  "id": "a1b2c3d4-…",
  "inbox_id": "9db42d9d-…",
  "from_addr": "noreply@github.com",
  "subject": "Your GitHub launch code",
  "text": "Your verification code is 778899.",
  "html": "<p>Your verification code is <b>778899</b>.</p>",
  "otp_code": "778899",
  "otp_confidence": 96,
  "magic_link": null,
  "received_at": "2026-06-26T12:01:10Z",
  "is_read": true,
  "attachments": []
}
Messages· required auth

download raw .eml

GET /api/v1/messages/{id}/raw

return the original RFC822 message (message/rfc822). raw retention is plan-dependent.

path parameters

idstring

the message id.

request

bash
curl https://api.voidash.com/api/v1/messages/{id}/raw \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

eml
From: noreply@github.com
To: nova.packet-orbit7qk@voidash.cyou
Subject: Your GitHub launch code
…
Messages· required auth

download an attachment

GET /api/v1/messages/{id}/attachments/{aid}

stream one attachment in its original content type. availability is plan-dependent.

path parameters

idstring

the message id.

aidstring

the attachment id.

request

bash
curl https://api.voidash.com/api/v1/messages/{id}/attachments/{aid} \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

bash
200 OK  (original content type)
Messages· required auth

mark all read

POST /api/v1/messages/read

mark every message in the account read, or scope to one inbox with an optional {"inbox_id":"…"} body. returns the number updated.

body parameters

inbox_idstring

optional. scope to one inbox; omit for all.

request

bash
curl -X POST https://api.voidash.com/api/v1/messages/read \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{ "updated": 12 }
Messages· required auth

report an extraction

POST /api/v1/messages/{id}/feedback

tell us a code/link was wrong, missed, or low-confidence. used to improve the extractor; reason-only.

path parameters

idstring

the message id.

body parameters

reasonstring

one of wrong, missed, low_confidence, other.

request

bash
curl -X POST https://api.voidash.com/api/v1/messages/{id}/feedback \
  -H "Authorization: Bearer $VOIDASH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason":"missed"}'

response

json
{
  "message_id": "a1b2c3d4-…",
  "reason": "missed",
  "created_at": "2026-06-26T12:02:00Z",
  "updated_at": "2026-06-26T12:02:00Z"
}
Messages· required auth

set read state

PATCH /api/v1/messages/{id}

explicitly mark one message read or unread with {"seen": true|false}. (fetching a message via GET /messages/{id} auto-marks it read; this is the manual control.) returns the updated message metadata.

path parameters

idstring

the message id.

body parameters

seenboolean

required. true = read, false = unread.

request

bash
curl -X PATCH https://api.voidash.com/api/v1/messages/{id} \
  -H "Authorization: Bearer $VOIDASH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"seen":false}'

response

json
{ "id": "a1b2c3d4-…", "is_read": false, "received_at": "2026-06-26T12:01:10Z",}
Messages· required auth

delete a message

DELETE /api/v1/messages/{id}

permanently delete a message and its stored blobs (raw .eml, bodies, attachments). returns 204.

path parameters

idstring

the message id.

request

bash
curl -X DELETE https://api.voidash.com/api/v1/messages/{id} \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
204 No Content
Auth signals
Auth signals· required auth

wait for an OTP (legacy)

GET /api/v1/inboxes/{id}/otp

legacy long-poll kept stable for older integrations. /auth is the canonical endpoint.

path parameters

idstring

the inbox id.

query parameters

waitinteger

seconds to long-poll (plan-capped).

afterstring

RFC3339 lower bound.

request

bash
curl https://api.voidash.com/api/v1/inboxes/{id}/otp?wait=60 \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{ "code": "778899", "confidence": 96, "magic_link": null, "message_id": "a1b2c3d4-…" }
Streaming (SSE)
Streaming (SSE)· required auth

stream all events

GET /api/v1/events

server-sent events for every inbox in the account. each message.new event carries the same payload as a message list item.

request

bash
curl https://api.voidash.com/api/v1/events \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
event: message.new
data: { "id": "a1b2c3d4-…", "inbox_id": "9db42d9d-…", "otp_code": "778899",}
Streaming (SSE)· required auth

stream one inbox

GET /api/v1/inboxes/{id}/events

server-sent events scoped to a single inbox.

path parameters

idstring

the inbox id.

request

bash
curl https://api.voidash.com/api/v1/inboxes/{id}/events \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
event: message.new
data: {}
Account & keys
Account & keys· required auth

get account & entitlements

GET /api/v1/me

return the account summary: current plan, live entitlements (limits + feature flags), inbox count, linked logins, and API-key count.

request

bash
curl https://api.voidash.com/api/v1/me \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{
  "account_id": "9db42d9d-…",
  "plan": {
    "id": "dev",
    "name": "Pulsar",
    "price": "$9.99 -> $4.99",
    "price_monthly_cents": 999,
    "intro_price_monthly_cents": 499
  },
  "inbox_count": 3,
  "max_inboxes": 10000,
  "is_supporter": false,
  "keys_count": 1,
  "logins": [],
  "limits": {
    "msg_cap_per_inbox": 100,
    "size_cap_per_inbox_bytes": 2147483648,
    "message_ttl_seconds": 1209600,
    "raw_ttl_seconds": 1209600
  },
  "entitlements": {
    "plan_id": "dev",
    "rate_limit_per_minute": 6000,
    "wait_max_seconds": 90,
    "webhook_limit": 1,
    "mcp_enabled": true,
    "allow_raw_eml": true,
    "allow_attachments": true
  }
}
Account & keys· required auth

list API keys

GET /api/v1/keys

list the account’s API keys (metadata only; secrets are never returned). scopes: [] means full access; expires_at: null means the key never expires.

request

bash
curl https://api.voidash.com/api/v1/keys \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{
  "keys": [
    {
      "id": "k_…",
      "name": "ci-reader",
      "last4": "9f2a",
      "kind": "api",
      "scopes": ["mail:read"],
      "expires_at": "2026-07-26T12:00:00Z",
      "last_used_at": "2026-06-26T12:30:00Z",
      "created_at": "2026-06-26T12:00:00Z"
    }
  ]
}
Account & keys· required auth

create an API key

POST /api/v1/keys

mint a new API key (vd_sk_...). the secret is returned exactly once. optionally scope the key to least privilege and give it an expiry - omit both for a full-access, non-expiring key.

body parameters

namestring

optional label (max 64 chars).

scopesstring[]

optional least-privilege grants. any of mail:read (read inboxes & messages), mail:write (create/delete inboxes, mark read, edit messages), account (manage keys, billing, webhooks, logins). omit or send [] for full access; account implies the mail scopes.

expires_in_daysnumber

optional. key expires this many days after creation; omit or 0 to never expire.

request

bash
curl -X POST https://api.voidash.com/api/v1/keys \
  -H "Authorization: Bearer $VOIDASH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"ci-reader","scopes":["mail:read"],"expires_in_days":30}'

response

json
{
  "id": "k_…",
  "name": "ci-reader",
  "last4": "9f2a",
  "kind": "api",
  "scopes": ["mail:read"],
  "expires_at": "2026-07-26T12:00:00Z",
  "created_at": "2026-06-26T12:00:00Z",
  "secret": "vd_sk_…"
}
Account & keys· required auth

rotate an API key

POST /api/v1/keys/{id}/rotate

issue a new secret for a key and invalidate the old one. the new secret is returned once.

path parameters

idstring

the key id.

request

bash
curl -X POST https://api.voidash.com/api/v1/keys/{id}/rotate \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{ "id": "k_…", "key": "vd_sk_…", "last4": "1c7d" }
Account & keys· required auth

revoke an API key

DELETE /api/v1/keys/{id}

permanently revoke an API key.

path parameters

idstring

the key id.

request

bash
curl -X DELETE https://api.voidash.com/api/v1/keys/{id} \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{ "status": "revoked" }
Account & keys· required auth

redeem a promo code

POST /api/v1/promo/redeem

redeem a promo code to grant a plan trial. codes are single-use per account.

body parameters

codestring

the promo code.

request

bash
curl -X POST https://api.voidash.com/api/v1/promo/redeem \
  -H "Authorization: Bearer $VOIDASH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code":"VOID-EXAMPLE1"}'

response

json
{ "status": "redeemed", "plan": { "plan_id": "dev" }, "grant_expires_at": "2026-07-03T12:00:00Z" }
Webhooks
Webhooks· required auth

list webhooks

GET /api/v1/webhooks

list the account’s webhooks and your plan’s webhook limit. webhooks are a paid feature - free returns 403; pulsar allows 1.

request

bash
curl https://api.voidash.com/api/v1/webhooks \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{ "webhooks": [ { "id": "wh_…", "url": "https://example.com/hook", "events": ["message.new"], "active": true } ], "limit": 1 }
Webhooks· required auth

create a webhook

POST /api/v1/webhooks

register an HTTPS endpoint that receives delivered mail events, signed with HMAC. the signing secret is returned once. optionally scope to one inbox_id.

body parameters

urlstring

HTTPS endpoint to deliver to.

eventsstring[]

defaults to ["message.new"].

inbox_idstring

optional. scope to one inbox; omit for all.

note

each delivery is signed: X-Voidash-Signature: sha256=HMAC_SHA256(secret, body). return any 2xx to acknowledge; failures retry with backoff.

request

bash
curl -X POST https://api.voidash.com/api/v1/webhooks \
  -H "Authorization: Bearer $VOIDASH_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/hook","events":["message.new"]}'

response

json
{
  "id": "wh_…",
  "url": "https://example.com/hook",
  "events": ["message.new"],
  "secret": "whsec_…"
}
Webhooks· required auth

delete a webhook

DELETE /api/v1/webhooks/{id}

delete a webhook and its pending deliveries.

path parameters

idstring

the webhook id.

request

bash
curl -X DELETE https://api.voidash.com/api/v1/webhooks/{id} \
  -H "Authorization: Bearer $VOIDASH_KEY"

response

json
{ "status": "deleted" }
MCP (for AI agents)
MCP (for AI agents)· required auth

hosted MCP server

POST /mcp

a Model Context Protocol server (JSON-RPC 2.0 over Streamable HTTP) so agents like Claude or Cursor can create inboxes and wait for codes natively. auth is the same Bearer token. tools: create_inbox, list_inboxes, wait_for_otp, list_messages, get_message. MCP is available on every plan, but the wait_for_otp budget scales: free is capped at a 15s wait and 1 concurrent call; pulsar unlocks 90s waits and 20 concurrent.

request

json
// client config
{
  "mcpServers": {
    "voidash": {
      "url": "https://api.voidash.com/mcp",
      "headers": { "Authorization": "Bearer vd_sk_…" }
    }
  }
}

response

json
// tools/call → wait_for_otp
{
  "content": [
    { "type": "text", "text": "{\"code\":\"778899\",\"confidence\":96}" }
  ]
}
Reference
Reference· no auth

list domains

GET /api/v1/domains

list the domains addresses can be issued on. tier runs 1 (premium .com) to 3 (free pool); the first entry is the default. premium domains need a paid plan (plan_required: "paid") - pass one as domain to POST /inboxes.

request

bash
curl https://api.voidash.com/api/v1/domains

response

json
{
  "domains": [
    { "domain": "voidash.cyou", "tier": 2, "default": true },
    { "domain": "voidash.com", "tier": 1, "premium": true, "plan_required": "paid" }
  ]
}
Reference· no auth

OpenAPI spec

GET /api/v1/openapi.yaml

the machine-readable OpenAPI description of the REST API.

request

bash
curl https://api.voidash.com/api/v1/openapi.yaml

response

bash
openapi: 3.0.0
info:
  title: Voidash API
…
voidash disposable mail, read by machines.