API reference
One REST API, bearer-key authentication, JSON in and out. 51 operations across7 groups. Every action the panel performs is one of these calls.
Authenticate
Create a key in the panel, then send it as a bearer token. Keys carry their own IP scope, budget, and quota, so one key cannot borrow another's limits.
curl -s https://milbox.dev/api/v1/account \
-H "authorization: Bearer $MILBOX_KEY"Endpoints
Grouped by what they act on. Paths are relative to /api/v1.
Account
What this key is allowed to do. Call it once on boot to fail fast on a bad or moved IP.
/api/v1/accountDescribe the key itself: label, premium scope, allowlist, budget, and usage counters.
/api/v1/account/quotaAddress quota, message totals, retention, and the key profile in one call.
/api/v1/account/usageEverything a client needs to self-throttle: scopes, request counters for 24h and 7d, the twenty busiest endpoints with their error counts, address quota, message counters, and the effective retention window.
/api/v1/metaMachine-readable capabilities document: api version, operation count per group, the full error-code list, request and response headers, pagination style, and the webhook event catalogue. Useful for client bootstrapping without fetching openapi.json.
/api/v1/keysIntrospect the presented key: scopes, premium flag, budgets, quotas, effective retention, status, and the lifetime request counter. Read-only by design, keys are provisioned from the panel.
/api/v1/keys/rotateRoll the presented key: a fresh secret is generated, the old one stops working on the next request. Shown once, in full, in this response only.
/api/v1/plansThe plan the key resolves to, the hard limits that plan enforces, and the whole assignable catalog so a client can render an upgrade path without guessing.
/api/v1/account/requestsPer-request audit trail for this key: method, path, status, outcome, IP, and the request id you also receive in the x-request-id header. Filter it to isolate every denied or throttled call.
curl https://milbox.dev/api/v1/account \
-H "x-api-key: ${API_KEY_ENV}"Addresses
Temporary addresses on an active domain. Each key owns the addresses it creates; quota is per key.
/api/v1/addressesList every address this key owns, newest first, with the quota snapshot in meta.
/api/v1/addressesCreate an address. Omit local_part for a random one, or choose its shape with local_part_type. Domain must be active with mail enabled.
/api/v1/addresses/{id}One address, its alias group, and its newest messages. Accepts the public id or the full email address.
/api/v1/addresses/{id}/messagesThe mailbox subresource: every message on one address, with the full /inbox filter grammar still available. Use it when the address is the scope and you do not want to repeat the address on every call.
/api/v1/addresses/{id}Soft-delete the address and hide its messages from the inbox. purge_after is stamped so the row survives the five minute grace window before the hard delete.
/api/v1/addresses/{id}Relabel, disable, re-enable, extend the lifetime, or rotate the password of an address without changing the address string. Extending ttl_minutes also moves purge_after.
curl "https://milbox.dev/api/v1/addresses" \
-H "x-api-key: ${API_KEY_ENV}"Inbox
The mailbox router: list, count, mark, star, delete, restore, and index attachments across every address this key owns. Single-message reads and binary downloads live in the Messages group under /messages.
/api/v1/inboxNewest messages first. Filter by address, sender, subject, To recipient, sender display name, exact Message-ID, header Date window, size range, priority, attachments, spam state, unread, or poll with since_id.
/api/v1/inbox/readBulk mark messages as read. Every inbox filter is honoured, plus an optional ids array to target specific messages. Send no body to act on the whole filtered scope. Returns the affected row count and the refreshed counters.
/api/v1/inbox/unreadBulk mark messages as unread. Identical contract to /inbox/read: same filters, same optional ids array, same response shape.
/api/v1/inbox/countsCounter snapshot for the whole filtered scope: total, unread, read, deleted, attachments, starred. Accepts every inbox filter, so you can scope it per address.
/api/v1/inbox/starMark messages as starred. Same body and filter contract as /inbox/read: optional ids array, otherwise the whole filtered scope.
/api/v1/inbox/unstarRemove the star flag from messages. Identical contract to /inbox/star.
/api/v1/inbox/deleteBulk soft delete every message matching the filters or the supplied ids, up to 5000 rows in one call. message_count is recalculated for each touched address.
/api/v1/inbox/restoreUndo a soft delete. Restores the messages into the inbox and refreshes the per-address message_count.
/api/v1/inbox/attachmentsFlat attachment index across every message this key can read, newest first. One page of messages in, every attachment on those messages out, each with checksum_sha256 and a ready-to-call download_path pointing at /messages/{id}/attachment/{attachmentId}.
curl "https://milbox.dev/api/v1/[email protected]&unread=true" \
-H "x-api-key: ${API_KEY_ENV}"Messages
The single-message router: read one message with full RFC 5322 fidelity, patch its flags, soft-delete it, download the raw .eml, or download one attachment. The attachment index that produces these ids lives at GET /inbox/attachments in the Inbox group.
/api/v1/messages/{id}The full message: envelope-level sender and recipient, header Date with a validity flag, In-Reply-To, References, priority, Received chain, DKIM signatures, Authentication-Results (joined into one string), attachment checksums, raw_available, and the decoded text and html bodies. Marks it read. Password-protected addresses require the password query param.
/api/v1/messages/{id}Update the read flag or restore a soft-deleted message. Send seen and/or is_deleted; send neither and the call is rejected with 422.
/api/v1/messages/{id}/downloadDownload the stored message as raw RFC 822 bytes (message/rfc822, attachment disposition).
/api/v1/messages/{id}/attachment/{attachmentId}Fetch one attachment by its SHA-256 checksum (full or prefix), its zero-based index, or its att_N label. Content-type and filename come from the MIME part.
/api/v1/messages/{id}Soft-delete one message.
/api/v1/messages/bulkOne call for the whole sweep: delete, read, unread, star or unstar every message that matches an address, a filter, or an explicit id list. Caps at 500 rows per call on purpose so a runaway sweep cannot take the mailbox with it.
/api/v1/messages/searchFull-text search across subject and body for the mail this key owns. Same filter grammar as /inbox, prefix q with +term to require a word and -term to exclude it, quote a phrase to match it literally.
curl "https://milbox.dev/api/v1/messages/8f2c1d9a4b6e" \
-H "x-api-key: ${API_KEY_ENV}"Domains
The domain inventory for the account behind the key. Premium rows are hidden unless the key carries premium_access.
/api/v1/domainsTwo views in one route: with no key ownership rows this lists the public catalog; domains this key registered always appear here too. Filters cover status, type, and mail routing state.
/api/v1/domains/{id}Fetch one domain by public id or by name. One call, no list scan.
/api/v1/domains/checkAsk whether a domain is registerable before the user commits to it.
/api/v1/domainsRegister a custom domain for temp mail. Returns the TXT challenge to publish before verifying.
/api/v1/domains/{id}Update notes, toggle mail routing, or set mail_cap_hours. mail_enabled only flips while the domain is active.
/api/v1/domains/{id}Soft-delete your domain and pull it from the MX routing table instantly.
/api/v1/domains/{id}/verifyRun the TXT + MX check and flip pending_verification to verified on success.
/api/v1/domains/{id}/rotateIssue a fresh 72h TXT challenge token; resets verification state.
/api/v1/domains/{id}/checkLive DNS probe without state changes; writes last_check_result for the detail view.
/api/v1/domains/{id}/transitionLifecycle moves plus moderation: activate, resume, block for spam, fraud, abuse, or phishing, and lift the block.
/api/v1/domains/poolPer-domain counters for this key only: how many addresses live on each routable domain and how many live messages it holds. Answers "which of my domains is actually carrying traffic" without paging the inbox.
curl "https://milbox.dev/api/v1/domains?type=platform_pool&per_page=100" \
-H "x-api-key: ${API_KEY_ENV}"Webhooks
Push instead of poll. Register an HTTPS endpoint, pick events, and every delivery carries an HMAC-SHA256 signature over `${timestamp}.${body}` in the x-milbox-signature header. Failed deliveries retry twice with a 5s then 10s backoff and the per-hook failure counter resets on the next success.
/api/v1/webhooksList the webhooks registered for this key, newest first. The signing secret is returned once at creation and afterwards only as a stored value on this endpoint.
/api/v1/webhooksRegister a webhook. Ten active hooks per key. Honours the idempotency-key header so a retried POST does not double-register.
/api/v1/webhooks/{id}One webhook plus its recent delivery log: event, HTTP status, duration, attempts, error. Use it to debug a receiver that started refusing payloads.
/api/v1/webhooks/{id}Change the target URL, description, event list, or flip active on and off. Pausing keeps the delivery log.
/api/v1/webhooks/{id}Delete the webhook and its delivery log. Irreversible; pause with PATCH active=false when the receiver is only temporarily broken.
/api/v1/webhooks/{id}/testSend a signed webhook.test delivery right now and get the receiver status back synchronously. The fastest way to prove the signature check on your end before a real mail arrives.
curl "https://milbox.dev/api/v1/webhooks" \
-H "x-api-key: ${API_KEY_ENV}"Sender rules
Inbound allow and block rules evaluated during ingest, before a message is written. A blocked sender is rejected with the SMTP code sender_blocked and never appears in the inbox.
/api/v1/sender-rulesThe inbound allow and block list for this key, with counts per kind. Rules are evaluated before a message is stored, so a blocked sender never lands in the mailbox at all.
/api/v1/sender-rulesAdd a rule, or flip the kind on an existing pattern. Once a key carries at least one allow rule the list becomes a real allowlist: any sender that matches nothing is treated as blocked.
/api/v1/sender-rules/{id}One rule by numeric id.
/api/v1/sender-rules/{id}Remove a rule. Mail from that sender flows normally on the next ingest.
curl "https://milbox.dev/api/v1/sender-rules" \
-H "x-api-key: ${API_KEY_ENV}"Error codes
Every failure returns the same envelope with a stable code, so a client can branch on it without parsing prose. A meta.request_id is included for support.
0[object Object]1[object Object]2[object Object]3[object Object]4[object Object]5[object Object]6[object Object]7[object Object]8[object Object]9[object Object]10[object Object]11[object Object]12[object Object]13[object Object]Full contract, pagination rules, and the OpenAPI document are in themachine-readable spec. Written guides live in Docs.

