Integration
API reference
Every endpoint. REST over HTTPS, JSON in and out. All POSTs accept an optional Idempotency-Key header. Base URL: https://agentpay-mvp.vercel.app/v1
| POST | /v1/cards |
| GET | /v1/cards |
| GET | /v1/cards/:id |
| POST | /v1/cards/:id/close |
| GET | /v1/balance |
| GET | /v1/policies/default |
| PUT | /v1/policies/default |
| GET | /v1/approvals |
| POST | /v1/approvals/:id/approve |
| POST | /v1/approvals/:id/reject |
/v1/cardsCreate a virtual card
Resolves the effective policy (default + optional override). If approval_required is true, returns 202 PENDING_APPROVAL. Otherwise places an off-session auth-hold on the user's saved payment method and mints a Stripe Issuing virtual card.
Request body
{
amount_cents: number // required, 1..50000
agent_id?: string // optional identifier for your agent
purpose?: string // optional human description (<=500 chars)
policy_override?: {
approval_required?: boolean
max_amount_cents?: number
}
}Example
curl -X POST https://agentpay-mvp.vercel.app/v1/cards \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"amount_cents": 2000,
"agent_id": "claude-desktop",
"purpose": "Cloudflare domain"
}'Responses
{
"id": "card_01HX...",
"status": "OPEN",
"last_four": "4242",
"expiration": "12/29",
"spending_limit_cents": 2000,
"remaining_cents": 2000,
"agent_id": "claude-desktop",
"created_at": "2026-04-22T15:32:11Z"
}{
"status": "PENDING_APPROVAL",
"approval_id": "appr_01HX...",
"expires_at": "2026-04-22T16:32:11Z"
}{
"error": {
"code": "setup_required",
"message": "AgentPay setup must be completed before cards can be issued. Open: <setup_url>",
"details": {
"missing": ["kyb", "payment_method"],
"setup_url": "https://app.agentpay.dev/setup?return=mcp"
},
"request_id": "req_..."
}
}{
"error": {
"code": "policy_violation",
"message": "Amount 60000 exceeds policy max_amount_cents 50000",
"details": { "max_amount_cents": 50000, "requested": 60000 },
"request_id": "req_..."
}
}/v1/cardsList cards
Returns the user's cards in reverse-chronological order.
Query
?status=OPEN|USED|CLOSED|PENDING_APPROVAL # optional filter ?agent_id=claude-desktop # optional filter ?limit=50 # max 100
Example
curl "https://agentpay-mvp.vercel.app/v1/cards?status=OPEN&limit=20" \
-H "Authorization: Bearer sk_test_..."Responses
{
"data": [
{
"id": "card_01HX...",
"status": "OPEN",
"last_four": "4242",
"expiration": "12/29",
"amount_cents": 2000,
"agent_id": "claude-desktop",
"purpose": "Cloudflare domain",
"created_at": "2026-04-22T15:32:11Z"
}
]
}/v1/cards/:idGet a card (with PAN/CVV reveal)
Returns the card plus a Stripe ephemeral_key_secret you can use client-side with Stripe.js to reveal the PAN and CVV securely. We never return raw PAN or CVV ourselves.
Example
curl "https://agentpay-mvp.vercel.app/v1/cards/card_01HX..." \
-H "Authorization: Bearer sk_test_..."Responses
{
"id": "card_01HX...",
"status": "OPEN",
"last_four": "4242",
"expiration": "12/29",
"amount_cents": 2000,
"agent_id": "claude-desktop",
"purpose": "Cloudflare domain",
"created_at": "2026-04-22T15:32:11Z",
"closed_at": null,
"stripe_card_id": "ic_1...",
"ephemeral_key_secret": "ek_test_..." // use with Stripe.js to reveal PAN/CVV
}/v1/cards/:id/closeClose a card
Revokes the card in Stripe and cancels the auth-hold on your PM (if still open). Idempotent — closing a closed card returns OK.
Example
curl -X POST "https://agentpay-mvp.vercel.app/v1/cards/card_01HX.../close" \
-H "Authorization: Bearer sk_test_..."Responses
{ "ok": true, "status": "CLOSED" }/v1/balanceGet spend summary
Aggregate of your active holds and open cards. Useful for a status tool or CLI dashboard.
Example
curl "https://agentpay-mvp.vercel.app/v1/balance" -H "Authorization: Bearer sk_test_..."Responses
{
"held_cents": 1500,
"open_cards": 2,
"pending_approvals": 0,
"max_per_card_cents": 50000,
"approval_required": false,
"setup_complete": true
}/v1/policies/defaultGet default policy
Example
curl "https://agentpay-mvp.vercel.app/v1/policies/default" -H "Authorization: Bearer sk_test_..."Responses
{ "approval_required": false, "max_amount_cents": 50000 }/v1/policies/defaultUpdate default policy
Request body
{
approval_required?: boolean
max_amount_cents?: number // 1..50000
}Example
curl -X PUT "https://agentpay-mvp.vercel.app/v1/policies/default" \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{"approval_required": true}'Responses
{ "approval_required": true, "max_amount_cents": 10000 }/v1/approvalsList pending approvals
Query
?status=PENDING|APPROVED|REJECTED|EXPIRED # default PENDING
Example
curl "https://agentpay-mvp.vercel.app/v1/approvals" -H "Authorization: Bearer sk_test_..."Responses
{
"data": [
{
"id": "appr_01HX...",
"amount_cents": 1000,
"agent_id": "claude-desktop",
"purpose": "API credits",
"status": "PENDING",
"expires_at": "2026-04-22T16:32:11Z",
"created_at": "2026-04-22T15:32:11Z"
}
]
}/v1/approvals/:id/approveApprove a pending request
Runs the auth-hold + mint flow synchronously. Returns the newly-issued card.
Example
curl -X POST "https://agentpay-mvp.vercel.app/v1/approvals/appr_01HX.../approve" \
-H "Authorization: Bearer sk_test_..."Responses
{
"id": "card_01HX...",
"status": "OPEN",
"last_four": "4242",
...
}/v1/approvals/:id/rejectReject a pending request
Request body
{ reason?: string }Example
curl -X POST "https://agentpay-mvp.vercel.app/v1/approvals/appr_01HX.../reject" \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{"reason":"out of budget"}'Responses
{ "ok": true, "status": "REJECTED" }