Get started
Concepts
A precise mental model for how AgentPay issues cards, funds them, and decides when an agent can or cannot spend. Read this once; the API will make sense forever.
The platform shape
AgentPay is one Stripe Connect account that we control. End-users don't have Stripe accounts; they fill our KYB form (name, date of birth, address, phone) and we create a Stripe Issuing cardholder representing them on our one Connect account. All your cards live under that cardholder.
AgentPay platform Stripe account
└── AgentPay Issuer (ONE Stripe Connect account, we control it)
├── Cardholder for user A (real KYB: name, DOB, address, phone)
│ └── Card 1, Card 2, … (each with metadata.agent_id, spend limit)
├── Cardholder for user B
│ └── Card 1, …
└── … (one cardholder per end-user)The funding model — honestly
When your agent asks for a $20 card, here's what actually happens on our side:
- We place a $20 off-session auth-hold on your saved payment method — an uncaptured
PaymentIntentwithcapture_method: 'manual'. You don't see a prompt; the card is not charged yet. - We mint a Stripe Issuing virtual card with
spending_controls.spending_limitset to $20. - When the agent uses the card, Stripe authorizes the charge against our Issuing balance (pre-funded float). The card is single-use, so it self-destructs after.
- Our webhook handler catches
issuing_authorization.createdand captures your auth-hold — you pay us, we replenish the float.
Cards
- Single-use (v0). Designed for one authorization. Multi-use cards for recurring subscriptions are planned for v1.
- $500 max per card in v0 (Stripe Issuing soft default). Adjustable via policy up to that ceiling.
- metadata.agent_id on every card — set it at creation so you can group cards by agent in your own reporting.
- PAN/CVV reveal is via Stripe's ephemeral-key flow.
GET /v1/cards/:idreturns anephemeral_key_secretyour client exchanges for the full number using Stripe.js. We never return the raw PAN over our API.
Agents — what they are, honestly
An agent in AgentPay is a logical actor under your account — it has a name, a status (active, paused, revoked), and optional per-agent policy overrides. When you pass agent_id on POST /v1/cards, we attribute the card to that agent and apply agent-level rules on top of your user-level policy.
Agents DO
- • Kill-switch — pause/revoke to instantly stop new cards for that agent.
- • Per-agent lifetime + live card caps (
max_cards_per_agent,max_active_cards_per_agent). - • Per-agent per-card amount override below the policy default.
- • Per-agent MCC allowlist (stored; v1 enforces at authorization).
- • Fleet caps (
max_agents,max_active_agents). - • Group reporting — see spend per agent in the dashboard.
Agents DO NOT
- • Authenticate. All agents under one user share one API key.
- • Bind cryptographically.
agent_idis a claim from the caller. - • Rate-limit separately. The 1000 req/hr cap is per-key, not per-agent.
- • Enforce anything if
agent_idis omitted oncreate_card— only the user-level policy applies.
v1 direction: per-agent API keys (sk_*_agt_) so one compromised agent can be revoked without killing the others. Today agents are an organizational + policy primitive, not a security boundary.
Policies
A policy is the record that decides whether a card can be created, how big it can be, andwhen it needs human approval. Every user has exactly one default policy. Each card request can override selected fields.
{
"approval_required": false,
"approval_threshold_cents": 2000,
"approval_channels": ["dashboard"],
"max_card_amount_cents": 5000,
"max_total_held_cents": 50000,
"max_agents": 10,
"max_active_agents": 5,
"max_cards_per_agent": 25,
"max_active_cards_per_agent": 5,
"velocity_day_cents": 10000,
"velocity_week_cents": 50000
}- Approval:
approval_requiredforces every card to queue;approval_threshold_centsqueues only cards at or above that amount. - Per-card + aggregate caps:
max_card_amount_cents+max_total_held_cents. - Fleet caps:
max_agents,max_active_agents,max_cards_per_agent,max_active_cards_per_agent. - Velocity: rolling-window spend caps per 24h and 7d.
See the policy cookbook for common patterns (allowed ceiling by agent tier, auto-approve under $X, etc.).
Approvals
When a request is queued, POST /v1/cards returns 202 PENDING_APPROVAL with an approval_id. The request lives in approval_requests for up to 1 hour. Either approve (mints the card) or reject (records a decline) from /approvals or via POST /v1/approvals/:id/approve|reject.
The setup-required flow
If the authenticated user hasn't completed KYB or connected a payment method, we return a structured 403 setup_required error with a setup_url. The MCP server surfaces this verbatim so your agent can tell the user exactly what to do:
{
"error": {
"code": "setup_required",
"message": "AgentPay setup must be completed before cards can be issued. Open: https://app.agentpay.dev/setup?return=mcp",
"details": {
"missing": ["kyb", "payment_method"],
"setup_url": "https://app.agentpay.dev/setup?return=mcp"
},
"request_id": "req_…"
}
}On the first blocked request we also email the user a one-click setup link — historically a 10x conversion lift over the welcome email alone.