Skip to main content
A card is issued to a cardholder against a funding account. Cards can be virtual or physical, and move through a simple lifecycle.

Lifecycle

Issue a card

Prerequisites (in order):
  1. Applicant status: APPROVED and issuerKycReady: true
  2. Funding account created (POST /v1/accounts)
  3. Cardholder created (POST /v1/cardholders)
  4. Issue card with body fields below
Supports virtual and physical cards, debit (budget) and prepaid programs (product_type on the program).
cURL
curl -s -X POST 'https://sandbox.apocor.ai/v1/cards' \
  -H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' \
  -d '{
    "program_id": "prog_abc123",
    "account_id": "acct_abc123",
    "cardholder_id": "ch_abc123",
    "form_factor": "VIRTUAL",
    "spend_limit_cents": 50000
  }'
Physical cards are created INACTIVE until shipped and activated.

Batch issue and delete

Batch issuance is asynchronous — the issuer returns a task_id you can poll. Up to 100 cards per request.
cURL
curl -s -X POST 'https://sandbox.apocor.ai/v1/cards/batch' \
  -H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' \
  -d '{
    "program_id": "prog_abc123",
    "account_id": "acct_abc123",
    "cardholder_id": "ch_abc123",
    "form_factor": "VIRTUAL",
    "cards": [
      { "label": "Ops card 1" },
      { "label": "Ops card 2" }
    ]
  }'
Poll batch progress:
cURL
curl -s 'https://sandbox.apocor.ai/v1/cards/batch/{task_id}?applicant_id=app_abc123' \
  -H 'Authorization: Bearer YOUR_TOKEN'
Delete up to 100 cards at once:
cURL
curl -s -X POST 'https://sandbox.apocor.ai/v1/cards/batch-delete' \
  -H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' \
  -d '{ "card_ids": ["card_1", "card_2"] }'

Spend controls (MCC / consumption scenarios)

Configure issuer-level whitelist/blacklist rules for MCC codes, transaction scenarios, or currencies.
ActionEndpoint
List controlsGET /v1/cards/spend-controls?applicant_id=...&usage=MCC&list_type=BLACKLIST
Create / updatePOST /v1/cards/spend-controls
DeleteDELETE /v1/cards/spend-controls?id=...&applicant_id=...
Batch upsertPOST /v1/cards/spend-controls/batch
usage is one of MCC, SCENARIO, or TRANSACTION_CURRENCY. For MCC rules, keywords must be a 4-digit MCC string (e.g. "7995"). Optionally scope rules to specific Apocor card_ids or issuer card_bin_ids.
cURL
curl -s -X POST 'https://sandbox.apocor.ai/v1/cards/spend-controls' \
  -H 'Authorization: Bearer YOUR_TOKEN' -H 'Content-Type: application/json' \
  -d '{
    "applicant_id": "app_abc123",
    "usage": "MCC",
    "keywords": "7995",
    "list_type": "BLACKLIST",
    "card_ids": ["card_abc123"]
  }'

Fund cards and accounts

ActionEndpoint
Fund prepaid cardPOST /v1/cards/{id}/fund — body { "amount": "25.00" }
Withdraw from prepaidPOST /v1/cards/{id}/defund
Fund/deplete budget accountPOST /v1/accounts/{id}/transfers{ "applicant_id", "direction": "in|out", "amount" }
List issuer budgetsGET /v1/accounts/{id}/budgets?applicant_id=...

Manage a card

ActionEndpoint
FreezePOST /v1/cards/{id}/freeze
UnfreezePOST /v1/cards/{id}/unfreeze
ActivatePOST /v1/cards/{id}/activate (physical: calls issuer activate)
ClosePOST /v1/cards/{id}/close
Update label / spend limitPATCH /v1/cards/{id}
Card transactionsGET /v1/cards/{id}/transactions or GET /v1/transactions?card_id=...
Reveal detailsGET /v1/cards/{id}/secure-details

Physical cards

ActionEndpoint
ShipPOST /v1/cards/{id}/physical/ship
Shipping statusGET /v1/cards/{id}/physical/shipping
Set PINPUT /v1/cards/{id}/pin

Cardholders

ActionEndpoint
CreatePOST /v1/cardholders
ListGET /v1/cardholders
GetGET /v1/cardholders/{id}
UpdatePATCH /v1/cardholders/{id}

Sandbox testing

POST /v1/sandbox/simulate with { "type": "authorization\|refund\|reversal\|kyc_review", "card_id": "..." } (sandbox issuer only).

Revealing PAN & CVV securely

Full card numbers never pass through your servers. Request a short-lived reveal token and render the sensitive fields inside a PCI-compliant iframe.
cURL
curl -s 'https://sandbox.apocor.ai/v1/cards/card_abc123/secure-details' \
  -H 'Authorization: Bearer YOUR_TOKEN'
{ "data": { "revealToken": "rvl_9f8e...", "expiresIn": 300 } }
A revealToken is single-purpose and expires in ~5 minutes. Never log it, and never attempt to fetch or store the raw PAN server-side.