This guide walks through the complete flow for integrating AgentCard into your product — from initial setup to issuing and managing cards programmatically on behalf of your users.
This page is designed to be self-contained. You can hand it to an AI agent or developer and they’ll have everything needed to implement the full integration.
Overview
CLI setup (one-time) API operations (repeatable)
───────────────────── ─────────────────────────────
1. Login 3. Create cardholders
2. Create org + API key --> 4. Attach payment methods
5. Issue cards
6. Get card credentials
7. Close cards
Steps 1–2 use the agent-cards-admin CLI. Steps 3–7 use the REST API with your API key.
Phase 1: Setup (CLI, one-time)
Install and log in
npm install -g agent-cards-admin
agent-cards-admin login
# Enter your email -> click the magic link -> authenticated
Create an organization
Organizations are the billing unit. All cardholders, cards, and API keys are scoped to an org.
agent-cards-admin orgs create --name "My Company" --email billing@mycompany.com
Save the org ID from the output (e.g. org_abc123).
Create an API key
agent-cards-admin keys create --org < org-i d > --name "production-key"
Save the API key — it starts with sk_test_ (sandbox) or sk_live_ (production) and won’t be shown again .
export AGENTCARD_API_KEY = "sk_test_..."
Use sk_test_ keys during development. Sandbox mode uses Stripe’s test environment — no real charges are made. Switch to sk_live_ keys for production.
Other CLI commands
agent-cards-admin orgs list # list orgs
agent-cards-admin orgs get < org-i d > # org details
agent-cards-admin keys list --org < org-i d > # list API keys
agent-cards-admin keys revoke # revoke a key
agent-cards-admin keys rotate # rotate a key
agent-cards-admin members add --org < org-i d > --email teammate@co.com # add team member
agent-cards-admin members list --org < org-i d > # list members
Phase 2: API Integration
All endpoints below use API key authentication:
Authorization: Bearer sk_test_...
Content-Type: application/json
Base URL: https://api.agentcard.sh (production) or https://sandbox.api.agentcard.sh (sandbox)
Step 1: Create a cardholder
Each user who will have cards issued on their behalf needs a cardholder record.
curl -X POST https://api.agentcard.sh/api/v1/cardholders \
-H "Authorization: Bearer $AGENTCARD_API_KEY " \
-H "Content-Type: application/json" \
-d '{
"firstName": "Jane",
"lastName": "Smith",
"dateOfBirth": "1990-03-15",
"phoneNumber": "+14155551234",
"email": "jane@example.com"
}'
Field Type Required Notes firstNamestring Yes Non-empty lastNamestring Yes Non-empty dateOfBirthstring Yes ISO date, e.g. "1990-03-15" phoneNumberstring Yes Non-empty emailstring No Must be unique within the organization
{
"id" : "ch_abc123" ,
"firstName" : "Jane" ,
"lastName" : "Smith" ,
"email" : "jane@example.com" ,
"dateOfBirth" : "1990-03-15T00:00:00.000Z" ,
"phoneNumber" : "+14155551234" ,
"stripeCardholderId" : "ich_1abc123" ,
"createdAt" : "2026-03-10T12:00:00.000Z" ,
"updatedAt" : "2026-03-10T12:00:00.000Z"
}
Error Cause 400Missing or invalid required field 409A cardholder with this email already exists in the org
See also: List cardholders , Get cardholder , Update cardholder
Step 2: Attach a payment method
Each cardholder needs a payment method before you can issue cards. This creates a Stripe Checkout session the user must complete in a browser.
curl -X POST https://api.agentcard.sh/api/v1/cardholders/ch_abc123/payment-method/setup \
-H "Authorization: Bearer $AGENTCARD_API_KEY "
No request body needed.
{
"checkoutUrl" : "https://checkout.stripe.com/c/pay/cs_test_abc123..." ,
"stripeSessionId" : "cs_test_abc123"
}
Redirect the user to checkoutUrl to complete payment method setup. After the user completes it, the payment method is automatically saved.
Step 3: Verify payment method
Poll this endpoint to confirm the user completed payment method setup before issuing cards.
curl https://api.agentcard.sh/api/v1/cardholders/ch_abc123/payment-method/status \
-H "Authorization: Bearer $AGENTCARD_API_KEY "
{
"hasPaymentMethod" : true ,
"paymentMethodId" : "pm_abc123"
}
{
"hasPaymentMethod" : false
}
Step 4: Create a card
Issue a single-use virtual Visa card. The amountCents is authorized (held) on the cardholder’s payment method immediately.
curl -X POST https://api.agentcard.sh/api/v1/cards \
-H "Authorization: Bearer $AGENTCARD_API_KEY " \
-H "Content-Type: application/json" \
-d '{"amountCents": 2500, "cardholderId": "ch_abc123"}'
Field Type Required Notes amountCentsinteger Yes Positive integer. Max 50.00 ( 5000 ) o n f r e e p l a n , 50.00 (5000) on free plan, 50.00 ( 5000 ) o n f ree pl an , 500.00 (50000) on basic plan. cardholderIdstring Yes ID from Step 1
{
"id" : "card_abc123" ,
"cardholderId" : "ch_abc123" ,
"last4" : "4242" ,
"expiry" : "12/27" ,
"spendLimitCents" : 2500 ,
"balanceCents" : 2500 ,
"status" : "OPEN" ,
"createdAt" : "2026-03-10T12:00:00.000Z"
}
Error Cause 400amountCents invalid or exceeds maximum402Payment method declined. The declined method is automatically detached. 404Cardholder not found 422No payment method. Response includes setupUrl to initiate setup.
{
"status" : "payment_method_required" ,
"message" : "Cardholder has no payment method. Set one up first." ,
"setupUrl" : "/api/v1/cardholders/ch_abc123/payment-method/setup"
}
Step 5: Get card credentials
Retrieve the full card number (PAN), CVV, and expiry for your agent to use.
curl https://api.agentcard.sh/api/v1/cards/card_abc123/details \
-H "Authorization: Bearer $AGENTCARD_API_KEY "
{
"id" : "card_abc123" ,
"cardholderId" : "ch_abc123" ,
"pan" : "4242424242424242" ,
"cvv" : "123" ,
"expiry" : "12/27" ,
"last4" : "4242" ,
"balanceCents" : 2500 ,
"spendLimitCents" : 2500 ,
"status" : "OPEN"
}
All card credential access is logged in the audit trail.
Step 6: Close a card
Permanently close a card and release any held funds. Idempotent — closing an already-closed card returns success.
curl -X DELETE https://api.agentcard.sh/api/v1/cards/card_abc123 \
-H "Authorization: Bearer $AGENTCARD_API_KEY "
{
"id" : "card_abc123" ,
"status" : "CLOSED"
}
List and filter cards
curl "https://api.agentcard.sh/api/v1/cards?status=OPEN&cardholderId=ch_abc123&limit=10" \
-H "Authorization: Bearer $AGENTCARD_API_KEY "
Parameter Type Default Notes limitinteger 50 1–100 offsetinteger 0 statusstring — OPEN, IN_USE, CLOSED, PAUSEDcardholderIdstring — Filter by cardholder
{
"cards" : [ { "id" : "..." , "last4" : "4242" , "status" : "OPEN" , ... } ],
"total" : 1 ,
"limit" : 10 ,
"offset" : 0
}
Card lifecycle
OPEN ──> IN_USE ──> CLOSED
| ^
+────────────────────────+
(close)
OPEN — Card is issued and ready to use. Funds are held on the cardholder’s payment method.
IN_USE — A transaction has been authorized on the card.
CLOSED — Card is permanently closed (via API, auto-close after single use, or spend limit reached).
Cards are single-use by default . After one successful transaction, the card auto-cancels.
Error responses
All errors return JSON:
{
"error" : "error_code_or_message"
}
Status Meaning 400Bad request — missing or invalid fields 401Unauthorized — invalid or missing API key 402Payment failed — card declined or authorization failed 403Forbidden — org suspended or beta capacity reached 404Resource not found 409Conflict — duplicate resource (e.g. cardholder email) 422Precondition not met (e.g. no payment method) 429Rate limit exceeded (default: 1,000 req/hour per key) 500Internal server error 502Provider error — upstream card provider failed
Webhooks
Register a webhook endpoint to receive real-time notifications about card events.
Register an endpoint
curl -X POST https://api.agentcard.sh/user-webhooks \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/agentcard",
"events": ["card.created", "charge.authorized", "card.cancelled", "balance.low"]
}'
Use "*" to subscribe to all events. The response includes a secret (shown once) for signature verification.
Event types
Event Description card.createdA new card was issued charge.authorizedA transaction was authorized on a card card.cancelledA card was closed balance.lowA card’s balance is running low
Webhook payload
{
"event" : "charge.authorized" ,
"createdAt" : "2026-03-10T12:05:00.000Z" ,
"data" : {
"cardId" : "card_abc123" ,
"last4" : "4242" ,
"amountCents" : 1500 ,
"merchant" : "ACME Corp"
}
}
Signature verification
Each delivery includes an X-AgentCard-Signature header — an HMAC-SHA256 of the request body signed with your endpoint’s secret.
const crypto = require ( 'crypto' );
function verifyWebhook ( body , signature , secret ) {
const expected = crypto
. createHmac ( 'sha256' , secret )
. update ( body )
. digest ( 'hex' );
return crypto . timingSafeEqual (
Buffer . from ( signature ),
Buffer . from ( expected )
);
}
Failed deliveries are retried up to 3 times : immediately, after 1 minute, after 5 minutes.
Manage endpoints
# List
curl https://api.agentcard.sh/user-webhooks \
-H "Authorization: Bearer <jwt>"
# Update
curl -X PATCH https://api.agentcard.sh/user-webhooks/ < i d > \
-H "Authorization: Bearer <jwt>" \
-H "Content-Type: application/json" \
-d '{"status": "disabled"}'
# Delete
curl -X DELETE https://api.agentcard.sh/user-webhooks/ < i d > \
-H "Authorization: Bearer <jwt>"
Complete example
# -- Setup (one-time, via CLI) --
npm install -g agent-cards-admin
agent-cards-admin login
agent-cards-admin orgs create --name "My Company" --email billing@mycompany.com
agent-cards-admin keys create --org < org-i d > --name "my-key"
# Save the sk_test_... key
# -- API operations --
export AGENTCARD_API_KEY = "sk_test_..."
export BASE = "https://api.agentcard.sh"
# Create cardholder
CARDHOLDER = $( curl -s -X POST " $BASE /api/v1/cardholders" \
-H "Authorization: Bearer $AGENTCARD_API_KEY " \
-H "Content-Type: application/json" \
-d '{"firstName":"Jane","lastName":"Smith","dateOfBirth":"1990-03-15","phoneNumber":"+14155551234","email":"jane@example.com"}' )
CARDHOLDER_ID = $( echo $CARDHOLDER | jq -r '.id' )
# Setup payment method -> send user to checkoutUrl
SETUP = $( curl -s -X POST " $BASE /api/v1/cardholders/ $CARDHOLDER_ID /payment-method/setup" \
-H "Authorization: Bearer $AGENTCARD_API_KEY " )
echo "User must visit: $( echo $SETUP | jq -r '.checkoutUrl')"
# Verify payment method attached
curl -s " $BASE /api/v1/cardholders/ $CARDHOLDER_ID /payment-method/status" \
-H "Authorization: Bearer $AGENTCARD_API_KEY "
# Create a $25 card
CARD = $( curl -s -X POST " $BASE /api/v1/cards" \
-H "Authorization: Bearer $AGENTCARD_API_KEY " \
-H "Content-Type: application/json" \
-d "{ \" amountCents \" :2500, \" cardholderId \" : \" $CARDHOLDER_ID \" }" )
CARD_ID = $( echo $CARD | jq -r '.id' )
# Get credentials
curl -s " $BASE /api/v1/cards/ $CARD_ID /details" \
-H "Authorization: Bearer $AGENTCARD_API_KEY "
# Close card
curl -s -X DELETE " $BASE /api/v1/cards/ $CARD_ID " \
-H "Authorization: Bearer $AGENTCARD_API_KEY "
Next steps
API Reference Full reference for all REST API endpoints.
Sandbox Test your integration with sandbox API keys.