Quickstart
The Mailbox.bot API sends postal mail programmatically. Upload a document (PDF, DOCX, and other supported formats), specify a carrier, and receive tracking numbers, proof-of-fulfillment photos, and delivery confirmations via webhook. Mail is printed and dispatched from licensed facilities.
sk_agent_test_) work on production endpoints — real document validation, real cost previews, signed webhooks. Zero code changes when you go live.Postcards and mailers — marketing campaigns, appointment reminders, thank-you cards. Design your document, we print and mail it.
Batch mail — upload a CSV of recipients and a template document. Send hundreds or thousands of identical pieces in one job with volume-discounted pricing (5% off at 500+, 10% at 1,000+, 15% at 5,000+).
Overnight and express — FedEx Overnight, FedEx 2Day, UPS Next Day, UPS Ground. Same API, same workflow — just change the
mail_class field.mail.submitted2 Printed and prepared — the facility prints your document, photographs the printed pages and sealed envelope as proof of fulfillment, and marks it ready for dispatch. Webhook:
mail.ready with fulfillment_photos3 Mailed — dispatched via your chosen carrier. You receive a carrier-format tracking number, dispatch method (post office drop-off, carrier pickup), and an optional postage receipt photo. Webhook:
mail.mailed with tracking_number + carrier4 Delivered — final confirmation. Webhook:
mail.deliveredEvery webhook is HMAC-SHA256 signed. Your dashboard shows a visual progress tracker with all fulfillment photos, tracking info, and timestamps at each stage.
Actual carrier postage — calculated from page count, weight, destination ZIP, and mail class. You pay what USPS/FedEx/UPS charges.
Immediate Stripe charge — charged at submission via PaymentIntent. No surprise invoices. Every response includes
cost_cents, cost_display, and a full cost_breakdown so you know exactly what was charged and why.Dry-run cost preview — send
dry_run=true with your real document to get an exact cost breakdown without creating a record or charging. Use this to confirm pricing before committing.Sandbox cost preview — test keys return
estimated_live_cost_cents + cost_breakdown with no actual charge, so you can verify pricing before going live.sk_agent_test_) works on the same endpoints with the same request format — the only differences are no Stripe charge and no postal mail. Everything else is real:Document validation — your document is parsed, page-counted, and checked for dimensions just like production.
Accurate cost calculation — real per-page printing + real carrier postage rates returned as
estimated_live_cost_cents with a full breakdown.HMAC-signed webhooks — your webhook endpoint receives signed payloads at every lifecycle step so you can validate your signature verification.
Always-present test_mode field — every response includes
test_mode: true or test_mode: false — never omitted. Plus an X-Test-Mode response header for middleware detection without parsing the body.Simulated facility fulfillment — advance your test record through the lifecycle and receive fulfillment photos, carrier-format tracking numbers (USPS, FedEx, UPS), dispatch confirmations, and delivery status — exactly matching what production webhooks deliver.
Dashboard verification — test records appear in your dashboard Webhooks tab with delivery status, payload inspection, and attempt-by-attempt debugging. The Mail tab shows the full progress tracker with photos, tracking, and timestamps.
Go live — swap
sk_agent_test_ for sk_agent_. Zero code changes.Standing instructions — set rules so your agent handles mail automatically (scan all envelopes, forward packages over 2 lbs, shred junk).
Multi-protocol support — REST, MCP (Model Context Protocol), A2A (Google Agent-to-Agent), OpenClaw. Same capabilities across all protocols.
Approval workflows — require human approval in the dashboard before mail is printed, if your use case needs a human in the loop.
Authentication
All requests require a Bearer token. Get your API key from the dashboard after onboarding.
Authorization: Bearer sk_agent_xxxxxxxxxxxxx
sk_live_) — full account access, all scopes, queries span all agentsAgent keys (
sk_agent_) — scoped to a single agent. This is the key type you give to your AI agent.Test keys (
sk_agent_test_) — same as agent keys but activates sandbox mode. No charges, full validation. Swap to a live key when ready.Facility keys (
sk_facility_) — scoped to a facility for external scanner appsErrors & Rate Limits
{
"error": {
"type": "invalid_request",
"message": "Agent name already in use",
"code": "agent_name_taken"
}
}Rate limits: 100 req/min per API key (standard), custom limits for enterprise.
Webhook Security
Every webhook includes an X-Mailbox-Signature header containing an HMAC-SHA256 signature. Create signing keys via the API and rotate them without downtime.
Agents
member → agentEndpoints
member → agent → endpointOutbound Mail
POST /v1/mail charges the member's card on file immediately. Four safeguards:X-Max-Cost-Cents: 1500 header. If the computed cost exceeds it, the request is rejected (422) before any charge — no record created, no money moved.2. Dry run — send
dry_run=true to validate your document and get an exact cost breakdown without creating a record or charging.3. Approval flow — send
requires_approval=true to defer charging until the member approves in their dashboard.4. Test keys — use an
sk_agent_test_ key during development. Identical flow, zero charges. Swap to a live key when ready.5. Platform limits — per-transaction and daily spend limits are enforced server-side. If a charge exceeds either limit, the request is rejected (422) before any charge. Contact support if you need higher limits.
Packages — inbound private beta
member → agent → endpoint → package{
"event": "package.received",
"package_id": "pkg-uuid",
"mailbox_id": "MB-7F3A2K9P",
"suite": "7F3A",
"agent": "procurement-bot",
"carrier": "fedex",
"tracking": "794644790132",
"weight_oz": 12.4,
"photos": [
"https://cdn.mailbox.bot/pkg/7F3A2K9P_001.jpg"
],
"received_at": "2026-02-09T14:32:00Z"
}Forwarding — inbound private beta
Actions — inbound private beta
Scanning — inbound private beta
Agent Memory — inbound private beta
Standing Instructions — inbound private beta
Webhook Auth Settings


sk_agent_test_ key or POST /v1/test/webhook) shows up here immediately. Click any row to see the full JSON payload and every delivery attempt with HTTP status code, response time, and error details.Live events — production webhooks from real mailings appear in the same view. Filter by status to find failures, then inspect the delivery attempt to see exactly what your server returned.
Sandbox
POST /v1/agents/:id/credentials with "environment": "test". You get an sk_agent_test_ key.2. Use the same endpoints — sandbox keys work on every production endpoint (mail, packages, actions, agents, webhooks). Same routes, same headers, same body shape. The four
/v1/test/* helpers below exist only to synthesize state you can't produce locally (a fake inbound package, a manual webhook fire, a no-PDF mail submission, a lifecycle step).3. No charge — the response includes
cost_cents: 0 (no Stripe charge) plus estimated_live_cost_cents showing exactly what production would cost, with a full cost_breakdown (printing per page, postage by class, color surcharge).4. Webhooks fire normally — your webhook endpoint receives HMAC-signed payloads with the same structure as production.
5. Advance through fulfillment — call
POST /v1/test/mail/:id/advance to step the record through submitted → ready → mailed → delivered. Each step simulates real facility work: fulfillment photos, tracking numbers, dispatch method. Open your dashboard Webhooks tab to watch each event arrive, and the Mail tab to see the progress tracker with photos.6. Go live — swap
sk_agent_test_ for sk_agent_. No code changes.POST /v1/agents/:id/credentials
Authorization: Bearer sk_live_...
{ "scopes": ["mail.send", "package.read", "webhook.manage"], "environment": "test" }Returns an sk_agent_test_ key. Use it on any production endpoint — same code, no charge, HMAC-signed webhooks fire normally.
| sk_agent_test_ | sk_agent_ | |
|---|---|---|
| Endpoint | POST /v1/mail | POST /v1/mail |
| Body | Multipart (real document) | Multipart (real document) |
| Document validation | Full validation | Full validation |
| Header | X-Mailbox-MD-Version | X-Mailbox-MD-Version |
| Charge | cost_cents: 0 | Real Stripe charge |
| Cost breakdown | cost_breakdown: {...} | cost_breakdown: {...} |
| Cost estimate | estimated_live_cost_cents | dry_run=true for preview |
| test_mode field | true (always present) | false (always present) |
| X-Test-Mode header | true | false |
| Webhooks | HMAC-signed | HMAC-signed |
| Facility | Not queued | Real fulfillment |
| Webhook logs | Dashboard → Webhooks | Dashboard → Webhooks |
| Go live | Swap the key | — |
These guards apply identically to both sandbox and live keys — test the integration once and the same protections run in production:
POST /v1/mail to validate the document and return the full cost_breakdown + warnings array without creating a record or charging. Works with any key.X-Max-Cost-Cents — set this header to a cap (e.g.
5000) and the request rejects with 422 before any charge if the computed cost exceeds it.force_approval — set on the credential at mint time. Every submission with this key routes to
pending_approval regardless of requires_approval in the body.max_daily_pieces — set on the credential to cap outbound mail per 24h window per key. Surfaces as a
warnings entry in dry_run; rejects with 422 once exceeded.Dashboard segmentation — sandbox traffic appears under the orange Sandbox tab on
/dashboard/mail and /dashboard/webhooks. Live and test data never co-mingle in the default views.These endpoints skip document upload entirely — useful for quick webhook testing and lifecycle exploration.
Discovery & Protocols
/.well-known/agent.json, and REST API.v1.0 — live