# AGNT Mail — standalone email for agents No existing AGNT account or app subscription is required. Human signup: open https://mail.agnt.gg/app.html, request a code with your email and verify it; a new account is created automatically. Add credit through Stripe ($10 minimum), activate $5/month hosting, then create a mailbox. Base URL: https://mail.agnt.gg/mail/v1 Auth: Authorization: Bearer (secrets start with mail_) Spec: https://mail.agnt.gg/openapi.json Docs: https://mail.agnt.gg/docs.html ## Headless signup (no email, no browser) POST /agents {"name":"my-agent"} → 201 {agentId, secret (shown once), balance:0, fund:{claimUrl, x402:"POST /mail/v1/funding/x402"}} The secret is your identity. Store it. The account is unfunded until a human opens claimUrl and pays, so you cannot create an inbox yet. GET /agents/{agentId}/claim → {funded:boolean, available} (poll this) ## Once hosting is active POST /inboxes {"name":"my-agent"} → 201 {id, address, state:"provisioning"}; poll GET /inboxes until state="active" POST /inboxes/{id}/messages header Idempotency-Key: {"to","subject","text"} → 202 {id, state:"queued"} GET /deliveries/{id} → state: queued | submitting | uncertain | accepted_remote | accepted_local | rejected GET /inboxes/{id}/messages?cursor= → {messages:[{id,subject,from,to,createdAt}], nextCursor} GET /inboxes/{id}/messages/{mid} → {text, replyTo, messageId, attachments[]} GET /inboxes/{id}/messages/{mid}/attachments/{index} → bytes POST /inboxes/{id}/messages/{mid}/reply Idempotency-Key {"text"} → 202 GET /usage → {credit, reserved, available} (microUSD; 1,000 microUSD = one email unit) ## Hosting and allowances Standalone hosting is selected by plan: Starter $5, Pro $15, Business $39 per month, paid from prepaid credit. GET /plans is public and returns the policy. GET /usage returns separate cash and hosting/allowance fields. POST /hosting/purchase with Idempotency-Key: <8-100 chars> activates a month from existing credit. Never submits a card charge. Owner or mail:manage key required. PUT /hosting/preferences {"autoRenew":false,"allowOverage":false} changes explicit opt-ins. Neither option authorizes charging a card. Included units reset on day 1 UTC, do not roll over, and are consumed before prepaid overage. Overage is $1/1000 units, default off. Purchased credit never expires at reset. Existing reads remain available after hosting lapses, but new mail/inboxes pause. Daily limit: No separate daily sending quota. 1 recipient/send, 10 MiB encoded message, 5 MiB total attachments (10 files), 100 KB text or HTML body. Higher-volume approval and more storage are not automatically unlocked by funds. ## Errors 401 authentication_required · 402 insufficient_credit / hosting_required / monthly_allowance_exhausted · 403 scope_required / account_frozen · 404 *_not_found · 409 conflict · 429 rate limited · 503 checkout_disabled / service_not_enabled ## Attachments POST /inboxes/{id}/messages accepts optional html and attachments:[{filename,contentType,content}] where content is base64. Maximum 10 attachments, 5 MiB decoded total; MIME cap 10 MiB. Executables/scripts rejected. Idempotency includes file content. POST /agents/{agentId}/fund with owner JWT and Idempotency-Key transfers $5 from owner credit and activates one month of agent hosting atomically. It does not claim the identity or grant the payer mailbox access. ## Exact account limits Paid AGNT includes Mail by plan: Personal includes Starter (1 inbox, 1,000 emails sent + received/month, 250 MB); Always-On includes Pro (5 inboxes, 5,000 emails/month, 1 GB); Business and Enterprise include Business (15 inboxes, 20,000 emails/month, 3 GB). Limits are pooled per account. Purchased credit and current-month usage are preserved; higher active paid Mail allowances remain available. GET /usage returns effective limits. ## Standalone tier selection POST /hosting/purchase {"plan":"starter"|"pro"|"business"} with Idempotency-Key. Starter $5/month: 1 inbox, 1000 monthly combined units, 250 MB pooled incoming storage. Pro $15: 5 inboxes, 5000 units, 1 GB. Business $39: 15 inboxes, 20000 units, 3 GB. Per-account limits. No separate daily sending quota. Paid AGNT tiers map to the Mail tiers listed above. Upgrades deduct price difference without extending expiry; lower plans can be chosen after expiration. No automatic deletion. ## Automatic notifications Owner-authenticated POST /webhooks {"url":"https://your-public-receiver.example/events"} returns endpoint ID and one-time signing secret. GET /webhooks lists endpoints; DELETE /webhooks/{id} disables one. GET /notifications?after=SEQUENCE returns account events. GET /webhook-deliveries shows retries; POST /webhook-replay {"eventId":"...","endpointId":"..."} queues an authorized replay. Events: message.received (inboxId; fetch messages with an authorized key), delivery.accepted, delivery.failed (deliveryId/state). Acceptance is not inbox placement. Delivery is at least once. Verify HMAC-SHA256(secret, X-AGNT-Timestamp + "." + exact raw request body) equals the hex value after v1= in X-AGNT-Signature; reject stale timestamps and deduplicate event IDs. HTTPS public IPv4 destinations on port443 only; private networks and redirects are not supported. 12 attempts with backoff; exhausted deliveries remain available for manual replay. ## Payment methods Humans: Stripe Checkout with cards or supported stablecoin wallets (POST /funding/checkout). Agents: x402, headless, no browser. ## Agents pay for themselves with x402 (USDC on Base, x402 v2) — live and proven Fastest path (JavaScript, npm i @x402/fetch @x402/evm @x402/core viem): 1. POST /funding/x402 {"amountCents":1000|2500|5000} with Authorization: Bearer → 402 {orderId,state:"awaiting_payment",expiresAt,requirements}. 2. const client=new x402Client().setSpendControls({maxAmountPerPayment:'$50'}); registerExactEvmScheme(client,{signer:privateKeyToAccount(KEY),networks:['eip155:8453']}); const paidFetch=wrapFetchWithPayment(fetch,client); await paidFetch('https://mail.agnt.gg/mail/v1/funding/x402/'+orderId,{method:'POST',headers:auth,body:'{}'}) → 200 {state:"credited",transactionId,paymentIntent}. 3. POST /hosting/purchase {"plan":"starter"} (Idempotency-Key) then POST /inboxes {"name":"…"}. Done: the agent has a funded, hosted mailbox. Critical: (a) the client's default spend cap is $1 — you MUST raise it or every order is refused; (b) the wallet needs only USDC on Base, no ETH — the facilitator pays gas; (c) retry the SAME order after a timeout, never create a second one to pay again; (d) a 400 {error,reason,detail} means the wallet lacks USDC, the amount/destination is wrong, or the authorization expired — nothing was charged. Protocol (any language): requirements.accepts[0]={scheme:"exact",network:"eip155:8453",amount:,asset:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",payTo:,maxTimeoutSeconds:600,extra:{name:"USD Coin",version:"2"}}. Sign an EIP-3009 transferWithAuthorization for exactly payTo/amount/asset on chain 8453, wrap in an x402 v2 payload, base64, POST to the order URL with header PAYMENT-SIGNATURE (X-PAYMENT also accepted). Credit is added exactly once; PAYMENT-RESPONSE header carries the settlement receipt. GET /funding/x402/{orderId} → 402 while awaiting, 200 once credited or expired. GET /capabilities autonomousFunding:true means x402 is live.