Skip to main content
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-id> --name "production-key"
Save the API key — it starts with sk_test_ (test mode) or sk_live_ (production) and won’t be shown again.
export AGENTCARD_API_KEY="sk_test_..."
Use sk_test_ keys during development. Test mode never moves real money — no 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-id>                                    # org details
agent-cards-admin keys list --org <org-id>                             # 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-id> --email teammate@co.com   # add team member
agent-cards-admin members list --org <org-id>                          # 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 for both test and live mode. Your API key prefix decides the mode — sk_test_ keys issue test cards (no real charges), sk_live_ keys issue real Visa cards.

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"
  }'
FieldTypeRequiredNotes
firstNamestringYesNon-empty
lastNamestringYesNon-empty
dateOfBirthstringYesISO date, e.g. "1990-03-15"
phoneNumberstringYesNon-empty
emailstringNoMust be unique within the organization
Response
{
  "id": "ch_abc123",
  "firstName": "Jane",
  "lastName": "Smith",
  "email": "jane@example.com",
  "dateOfBirth": "1990-03-15T00:00:00.000Z",
  "phoneNumber": "+14155551234",
  "createdAt": "2026-03-10T12:00:00.000Z",
  "updatedAt": "2026-03-10T12:00:00.000Z"
}
ErrorCause
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 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.
Response
{
  "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"
Response (ready)
{
  "hasPaymentMethod": true,
  "paymentMethodId": "pm_abc123"
}
Response (not yet)
{
  "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"}'
FieldTypeRequiredNotes
amountCentsintegerYesAmount in cents (2500 = 25.00;25wouldbe25.00; `25` would be 0.25). Min 100 (1.00),max5000(1.00), max `5000` (50.00) by default for API organizations — contact support to raise it.
cardholderIdstringYesID from Step 1
Response
{
  "id": "card_abc123",
  "cardholderId": "ch_abc123",
  "last4": "4242",
  "expiry": "12/27",
  "spendLimitCents": 2500,
  "balanceCents": 2500,
  "status": "OPEN",
  "createdAt": "2026-03-10T12:00:00.000Z"
}
ErrorCause
400amountCents invalid or exceeds maximum
402Payment 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"
Response
{
  "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"
Response
{
  "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"
ParameterTypeDefaultNotes
limitinteger501–100
offsetinteger0
statusstringOPEN, IN_USE, CLOSED, PAUSED
cardholderIdstringFilter by cardholder
Response
{
  "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"
}
StatusMeaning
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

Subscribe a URL to events on your organization and receive signed JSON pushes when cards, cardholders, or transactions change.
curl -X POST https://api.agentcard.sh/api/v1/webhook_endpoints \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourapp.com/webhooks/agentcard",
    "enabled_events": ["card.*", "transaction.authorized", "transaction.declined"]
  }'
The response returns a signing secret (whsec_…) — shown once. Verify every delivery with the timestamped AgentCard-Signature header. Available event types include card.created, card.updated, card.closed, cardholder.created, cardholder.updated, transaction.authorized, transaction.declined, transaction.cleared, transaction.voided, and balance.low. Use prefix wildcards like card.* to forward-subscribe to new event types as we add them. See the Webhooks section for the full event catalog, signature verification snippets (Node, Python, Go), local testing with ngrok, and production best practices.

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-id> --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.

Test mode

Test your integration with test API keys.