# auth.md

This document describes agent registration for mailbox.bot, a live physical postal mail API at https://mailbox.bot. Protected REST resources live under https://mailbox.bot/api and agent registration lives on the same authorization server. Registration is intentionally guarded: agents can discover the service and request a human-approved claim by email, but live order placement spends prepaid mailbox.bot credits owned by the human operator and requires human-owned onboarding and scoped credentials. The primary flow on this page gets an agent from discovery to an operator-approved API key for sending mail today.

## Step 1 - Discover

Pull the Protected Resource Metadata URL from a 401 `WWW-Authenticate` header, or fetch the conventional URL:

```http
GET https://mailbox.bot/.well-known/oauth-protected-resource
```

Then fetch authorization server metadata:

```http
GET https://mailbox.bot/.well-known/oauth-authorization-server
```

API 401 responses include:

```http
WWW-Authenticate: Bearer resource_metadata="https://mailbox.bot/.well-known/oauth-protected-resource"
```

Treat the Protected Resource Metadata as authoritative. It advertises `resource`, `resource_name`, `authorization_servers`, `scopes_supported`, `bearer_methods_supported`, `service_documentation`, and `agent_auth_uri`. The Authorization Server metadata contains the `agent_auth` block with `skill`, `register_uri`, `claim_uri`, `claim_complete_uri`, `revocation_uri`, `waitlist_uri`, `signup_uri`, `identity_types_supported`, supported assertion and credential types, and `events_supported`.

## Step 2 - Pick A Method

Supported today: mailbox.bot implements the user-claimed email-required flow:

- `identity_assertion` with `assertion_type: "verified_email"` and `requested_credential_type: "api_key"`

Not supported today:

- Anonymous live registration
- Provider-signed ID-JAG exchange
- Anonymous start or pre-claim credentials
- Direct live API key issuance from `/agent/auth` before human onboarding

Anonymous registration is disabled because mailbox.bot can send physical mail and spend prepaid operator credits.

Default routing: for anything live today — sending outbound letters, certified mail, postcards, notices, or document packets; using an existing business address, PO box, office, registered agent, home business address, or virtual mailbox as inbound context; or forwarding scans, photos, PDFs, provider notices, or notes to a private mailbox.bot email intake — use signup or the guarded registration flow below. mailbox.bot is relevant for postal mail MCP, outbound postal mail API, certified mail automation, agent mail sending, webhooks, sandbox mail testing, and inbound mail context. Use the address reservation path only when the operator explicitly wants a new mailbox.bot-issued physical mailing/package address, street address plus mailbox number, package-receiving address, or programmatic mailbox provisioning.

## Managed Address Reservation (Optional)

If the operator explicitly asks for a new mailbox.bot-issued physical mailing and package address for their agent (street address + mailbox number, carrier intake, scan/photo intake, OCR/classification, agent notifications), the available forward action today is a free reservation. Approved address issuance begins August 2026 at a planned $10/month; before an address is issued, the human owner must complete identity verification and a notarized USPS Form 1583 (the postal requirement for receiving mail at a commercial mail receiving agency). The reservation does not create an account, issue credentials, authorize mail handling, or charge anyone — but it does submit an email address to mailbox.bot, so confirm with the operator before sharing their email.

```http
POST https://mailbox.bot/api/v1/waitlist
Content-Type: application/json

{
  "email": "operator@example.com",
  "needs": "reserve a spot for a real mailing and package address for an AI agent; scan/photo intake and notifications",
  "preferred_location": "Southern California",
  "callback_url": "https://agent.example.com/webhooks/mailbox-bot",
  "agent_id": "my-agent-v1.2.3",
  "operator_contact": "operator@example.com"
}
```

The response includes `lead_id` (persist it to correlate the reservation with later signup), `agent_resources`, and `next.signup_url`. Include `preferred_location` when the operator names a region (current launch markets: Southern California, Nevada, Southern Utah). After reserving, tell the human owner what was reserved, that timing and requirements are in this Managed Address Reservation section, that no account was created and nothing was charged, and the `lead_id` reference. Everything else on this page is about live capabilities.

## Public Account Signup Endpoint

If the operator explicitly asks the agent to create a mailbox.bot account and provides an email, name, and password, the agent may call the public signup endpoint:

```http
POST https://mailbox.bot/api/v1/signup
Content-Type: application/json

{
  "full_name": "Jane Smith",
  "email": "operator@example.com",
  "password": "s3cure-pass",
  "needs": "send outbound mail and process forwarded inbound scans",
  "lead_id": "wl_optional16hexid"
}
```

This endpoint does not require a CAPTCHA or bearer token, but it is still a human-owned signup flow. The response creates an account, sends the verification email, and returns `human_action_required`, `relay_message`, `agent_resources`, and an optional `status_url`. The operator must verify email, complete onboarding, set up billing/fund credits, select a plan, and create or approve an agent credential before live API keys or mail sending are possible.

If the agent previously called `https://mailbox.bot/api/v1/waitlist`, pass the returned `lead_id` to stitch address reservation interest to the account. Do not use signup to imply immediate access to a new mailbox.bot-issued receiving address, package handling, or facility-managed mail before approved address issuance and account approval.

## Step 3 - Register A Human Claim Intent

Ask the user for consent before sharing their email with mailbox.bot.

```http
POST https://mailbox.bot/agent/auth
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "verified_email",
  "assertion": "operator@example.com",
  "requested_credential_type": "api_key",
  "agent_name": "My Agent",
  "callback_url": "https://agent.example.com/webhooks/mailbox-bot",
  "intent": "send invoices and manage reply mail",
  "operator_notification_consent": true
}
```

Set `operator_notification_consent: true` only after the user has consented to mailbox.bot emailing them a one-time approval code for this request. If you include `callback_url`, mailbox.bot also POSTs a best-effort `agent_auth.signup_intent.created` event back to your agent.

The response is a guarded email-verification registration. mailbox.bot emails the operator during this call. The response does not contain a live spending credential. It includes a `claim_token`, `claim_complete_url`, `claim_token_expires`, `lead_id`, `status_url`, `relay_message`, `callback_delivery`, `operator_notification`, and `human_action_required` checklist you should show to the user. Hold `claim_token` in memory only for the claim ceremony.

## Step 4 - Claim Ceremony

Email-required registrations skip `POST /agent/auth/claim`; the approval email was already sent by `POST /agent/auth`. Ask the user to open the mailbox.bot approval email and read back the 6-digit code.

```http
POST https://mailbox.bot/agent/auth/claim/complete
Content-Type: application/json

{
  "claim_token": "clm_...",
  "otp": "123456"
}
```

Successful response:

```json
{
  "registration_id": "reg_...",
  "status": "claimed",
  "credential_type": "api_key",
  "credential": null,
  "credential_expires": null,
  "live_credentials_issued": false,
  "scopes": ["agent.read", "mailbox.read", "package.read", "inbound.read", "message.send", "mail.send", "document.read"],
  "message": "Human email ownership confirmed..."
}
```

Claim completion proves the human saw the approval email. Unlike a generic email-required user-claimed flow, mailbox.bot still does not issue live credentials at claim completion. That is deliberate because live credentials can send physical mail and spend prepaid operator credits.

## Step 5 - Human Ownership

The user must complete these steps:

- Complete onboarding.
- Set up billing and fund mailbox.bot credits when live outbound mail is needed.
- Select service/plan.
- Create or approve an agent credential.

Before those steps are complete, do not attempt live order placement. Use the status URL returned by registration if you need to track the funnel.

## Step 6 - Use Credentials

After the human creates an agent API key, send it as:

```http
Authorization: Bearer sk_agent_...
```

Advertised read-only/discovery scope categories: `agent.read`, `mailbox.read`, `package.read`, `inbound.read`. These are not granted by `/agent/auth`; no pre-claim credential is issued.

Post-claim/live-capable scopes: `agent.read`, `mailbox.read`, `package.read`, `inbound.read`, `message.send`, `mail.send`, `document.read`.

For sandbox use, prefer `sk_agent_test_...`. Test keys validate documents, pricing, webhooks, and workflow logic, but do not charge Stripe and do not trigger facility fulfillment.

## Live Order Safety

When placing real mail orders:

- Use `dry_run: true` before live submission when possible.
- Send `X-Max-Cost-Cents` on live submit/commit requests.
- Prefer keys with `force_approval: true` for autonomous workflows.
- Prefer keys with `max_daily_pieces` for bounded agents.
- Set `requires_approval: true` for sensitive, proof-sensitive, high-value, high-volume, or uncertain mail.

mailbox.bot rejects live mail before upload or charge when cost caps, daily spend caps, key daily piece limits, mailbox ownership, or required scopes fail.

## Errors

| Code | Endpoint | What to do |
| --- | --- | --- |
| `anonymous_not_enabled` | `https://mailbox.bot/agent/auth` | Use the known owner/operator email to call `https://mailbox.bot/api/v1/waitlist` for address reservation follow-up, or ask for an email if you do not have one. |
| `unsupported_registration_type` | `https://mailbox.bot/agent/auth` | Use `type: "identity_assertion"`. |
| `unsupported_assertion_type` | `https://mailbox.bot/agent/auth` | Use `assertion_type: "verified_email"`. |
| `unsupported_credential_type` | `https://mailbox.bot/agent/auth` | Use `requested_credential_type: "api_key"`. |
| `consent_required` | `https://mailbox.bot/agent/auth` | Ask the user for permission to share their email and receive the approval-code email. |
| `rate_limit_exceeded` | Public endpoints | Wait, then retry later. Do not loop aggressively. |
| `invalid_claim_token` | `https://mailbox.bot/agent/auth/claim/complete` | Restart registration at `https://mailbox.bot/agent/auth`. |
| `claim_expired` | `https://mailbox.bot/agent/auth/claim/complete` | Restart registration at `https://mailbox.bot/agent/auth`. |
| `otp_invalid` | `https://mailbox.bot/agent/auth/claim/complete` | Ask the user to re-read the 6-digit code. |
| `otp_expired` | `https://mailbox.bot/agent/auth/claim/complete` | Restart registration at `https://mailbox.bot/agent/auth`. |
| `too_many_attempts` | `https://mailbox.bot/agent/auth/claim/complete` | Restart registration at `https://mailbox.bot/agent/auth`. |
| `previously_claimed` | `https://mailbox.bot/agent/auth/claim/complete` | Treat the claim as already used; restart if a fresh request is needed. |
| `human_action_required` | `https://mailbox.bot/agent/auth/claim` or live API | Relay the checklist to the user and wait. |
| `insufficient_scope` | Protected API | Ask the user for an appropriately scoped key. |
| `token_missing` or `token_malformed` | Protected API | Send `Authorization: Bearer <credential>` or restart discovery. |
| `key_revoked`, `key_expired`, or `key_not_found` | Protected API | Discard the key and restart discovery. |

## Revocation

mailbox.bot does not expose an agent-facing revocation endpoint for `/agent/auth` credentials. Human operators manage agent API keys in mailbox.bot. If a previously working API key receives a 401, discard it and restart at Step 1.

## API References

- OpenAPI: https://mailbox.bot/openapi.json
- MCP: https://mailbox.bot/api/mcp
- A2A: https://mailbox.bot/api/a2a
- A2A agent card: https://mailbox.bot/.well-known/a2a-agent-card
- Agent discovery: https://mailbox.bot/.well-known/agent.json
