API Reference

Integrate CryptoTopCard into your applications. Issue, fund, freeze, and manage virtual cards programmatically with our REST API.

Base URL https://api.cryptotopcard.com/v1
RESTful JSON
Bearer Authentication
Sandbox Environment
Webhooks
Authentication

API Keys & Authentication

All API requests require a Bearer token. Generate your API key from Dashboard → Settings → API Keys.

API Key Security

Never expose your key in client-side code. Use environment variables. Keys prefixed with sk_live_ are production, sk_test_ are sandbox.

request-headers
Authorization: Bearer sk_live_your_api_key_here
Content-Type: application/json
X-Idempotency-Key: optional-unique-key-for-safe-retries
Rate Limits
1,000
Requests / Minute
50
Card Creates / Minute
10,000
Requests / Hour
Error Codes
error-response.json
{
  "error": "insufficient_funds",
  "message": "Your wallet balance is too low to fund this card.",
  "code": 400,
  "request_id": "req_7f8a9b2c3d4e"
}
200
Request succeeded
201
Resource created
400
Invalid request parameters
401
Missing or invalid API key
404
Resource not found
429
Rate limit exceeded
Cards

Card Management

Create, manage, and control virtual Visa & Mastercard cards. Each card is isolated with its own balance, limits, and lifecycle.

POST /cards Issue a new virtual card
Request Body
ParameterTypeDescription
bin_idstringrequiredBIN identifier (e.g. 491653). Use GET /bins to list available BINs.
amountnumberrequiredInitial funding amount in USD. Min: $1.00, Max: $5,000.00
labelstringoptionalCustom label for the card (max 64 chars)
spending_limitnumberoptionalMonthly spending limit in USD. Defaults to BIN maximum.
allowed_categoriesstring[]optionalMCC categories to whitelist (e.g. ["advertising", "software"])
auto_freeze_atnumberoptionalAuto-freeze when balance drops below this amount
metadataobjectoptionalKey-value pairs for your internal tracking (max 20 keys)
Example Request
curl
curl -X POST https://api.cryptotopcard.com/v1/cards \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "bin_id": "491653",
    "amount": 500,
    "label": "Meta Ads Campaign #12",
    "spending_limit": 2000,
    "allowed_categories": ["advertising"],
    "metadata": {"campaign": "spring_2026"}
  }'
Response 201 Created
response.json
{
  "id": "card_8xK2m9Lp4q",
  "bin_id": "491653",
  "network": "visa",
  "last4": "2039",
  "status": "active",
  "balance": 500.00,
  "spending_limit": 2000.00,
  "label": "Meta Ads Campaign #12",
  "allowed_categories": ["advertising"],
  "auto_freeze_at": null,
  "metadata": { "campaign": "spring_2026" },
  "created_at": "2026-04-15T12:00:00Z",
  "expires_at": "2029-04-15T23:59:59Z"
}
GET /cards List all cards with filters & pagination
Query Parameters
ParameterTypeDescription
statusstringoptionalactive, frozen, terminated
bin_idstringoptionalFilter by BIN
labelstringoptionalSearch by label (partial match)
sortstringoptionalcreated_at, balance, last_used. Default: created_at
orderstringoptionalasc or desc. Default: desc
pageintegeroptionalPage number. Default: 1
per_pageintegeroptionalItems per page (1-100). Default: 25
Response 200 OK
response.json
{
  "data": [
    {
      "id": "card_8xK2m9Lp4q",
      "bin_id": "491653",
      "network": "visa",
      "last4": "2039",
      "status": "active",
      "balance": 487.50,
      "label": "Meta Ads Campaign #12",
      "created_at": "2026-04-15T12:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 25,
    "total": 142,
    "total_pages": 6
  }
}
GET /cards/{card_id} Get card summary (no sensitive data)

Returns card info without sensitive details. Use /cards/{card_id}/details for the full PAN & CVV.

Response 200 OK
response.json
{
  "id": "card_8xK2m9Lp4q",
  "bin_id": "491653",
  "network": "visa",
  "last4": "2039",
  "status": "active",
  "balance": 487.50,
  "spending_limit": 2000.00,
  "total_spent": 12.50,
  "transaction_count": 3,
  "label": "Meta Ads Campaign #12",
  "metadata": { "campaign": "spring_2026" },
  "created_at": "2026-04-15T12:00:00Z",
  "expires_at": "2029-04-15T23:59:59Z",
  "last_used_at": "2026-04-15T14:32:00Z"
}
GET /cards/{card_id}/details Get full PAN, CVV & expiry

Sensitive Endpoint

Returns full card PAN, CVV, and expiry. PCI-sensitive — never log or store unencrypted. Rate limited to 30 req/min.

Response 200 OK
response.json
{
  "id": "card_8xK2m9Lp4q",
  "pan": "4916531288472039",
  "cvv": "847",
  "exp_month": 4,
  "exp_year": 2029,
  "holder_name": "ANONYMOUS",
  "billing_address": {
    "line1": "123 Privacy Street",
    "city": "Wilmington",
    "state": "DE",
    "zip": "19801",
    "country": "US"
  }
}
PATCH /cards/{card_id} Update card settings
Request Body
ParameterTypeDescription
labelstringoptionalUpdate card label
spending_limitnumberoptionalUpdate monthly spending limit
allowed_categoriesstring[]optionalUpdate allowed MCC categories
auto_freeze_atnumberoptionalSet auto-freeze threshold. 0 to disable.
metadataobjectoptionalMerge with existing metadata
Response 200 OK

Returns the updated card object.

POST /cards/{card_id}/freeze Temporarily suspend a card

Suspends all transactions. Balance is preserved. Card can be unfrozen later.

Response 200 OK
response.json
{ "id": "card_8xK2m9Lp4q", "status": "frozen", "frozen_at": "2026-04-15T15:00:00Z" }
POST /cards/{card_id}/unfreeze Re-enable a frozen card

Re-enables transactions on a frozen card. Returns the card object with status: "active".

DELETE /cards/{card_id} Permanently terminate a card

Irreversible Action

Terminating a card is permanent. Remaining balance is returned to your wallet instantly.

Response 200 OK
response.json
{
  "id": "card_8xK2m9Lp4q",
  "status": "terminated",
  "refunded_amount": 487.50,
  "terminated_at": "2026-04-15T16:00:00Z"
}
Funding

Card Funding

Add or withdraw funds from individual cards. Funds come from your wallet balance.

POST /cards/{card_id}/fund Add funds to a card
Request Body
ParameterTypeDescription
amountnumberrequiredAmount in USD to add. Min: $1.00, Max: $5,000.00
Response 200 OK
response.json
{
  "id": "card_8xK2m9Lp4q",
  "previous_balance": 487.50,
  "funded_amount": 200.00,
  "new_balance": 687.50,
  "wallet_balance": 1312.50
}
POST /cards/{card_id}/withdraw Withdraw funds back to wallet
Request Body
ParameterTypeDescription
amountnumberrequiredAmount in USD to withdraw from the card back to wallet
Response 200 OK

Returns updated card and wallet balances.

Transactions

Transaction History

View all transactions across your cards. Includes authorizations, settlements, refunds, and declines.

GET /transactions List all transactions with filters
Query Parameters
ParameterTypeDescription
card_idstringoptionalFilter by card
typestringoptionalauthorization, settlement, refund, decline
fromstringoptionalStart date (ISO 8601)
tostringoptionalEnd date (ISO 8601)
merchantstringoptionalSearch by merchant name (partial match)
min_amountnumberoptionalMinimum transaction amount
max_amountnumberoptionalMaximum transaction amount
pageintegeroptionalPage number. Default: 1
per_pageintegeroptionalItems per page (1-100). Default: 50
Response 200 OK
response.json
{
  "data": [
    {
      "id": "txn_a1b2c3d4",
      "card_id": "card_8xK2m9Lp4q",
      "type": "settlement",
      "amount": -12.50,
      "currency": "USD",
      "merchant": {
        "name": "FACEBK ADS",
        "category": "advertising",
        "mcc": "7311",
        "country": "US"
      },
      "balance_after": 487.50,
      "created_at": "2026-04-15T14:32:00Z"
    }
  ],
  "pagination": { "page": 1, "per_page": 50, "total": 328 }
}
GET /transactions/{txn_id} Get full transaction details

Returns the full transaction object including merchant details, MCC code, 3DS status, and authorization timeline.

Wallet

Wallet & Deposits

Manage your account wallet. Deposit crypto, check balances, and track incoming deposits.

GET /wallet/balance Get wallet balance & stats
Response 200 OK
response.json
{
  "balance": 1312.50,
  "currency": "USD",
  "pending_deposits": 500.00,
  "total_deposited": 15000.00,
  "total_spent": 13687.50,
  "cards_active": 8,
  "cards_total_balance": 2450.00
}
GET /wallet/deposit-address Get crypto deposit addresses
Query Parameters
ParameterTypeDescription
currencystringoptionalbtc, eth, sol, usdt. Omit to get all.
Response 200 OK
response.json
{
  "addresses": {
    "btc": "bc1qxy2kgdygjrsqtzq2n0yrf...",
    "eth": "0x742d35Cc6634C0532925a3b...",
    "sol": "7xKXtg2CW87d97TXJSDpbD5j...",
    "usdt": "0x742d35Cc6634C0532925a3b..."
  },
  "networks": {
    "btc": "bitcoin",
    "eth": "ethereum",
    "sol": "solana",
    "usdt": "erc-20"
  },
  "min_deposit": {
    "btc": "0.0001",
    "eth": "0.005",
    "sol": "0.1",
    "usdt": "5.00"
  }
}
GET /wallet/deposits List deposit history
Query Parameters
ParameterTypeDescription
statusstringoptionalpending, confirmed, expired
currencystringoptionalFilter by crypto currency
Response 200 OK
response.json
{
  "data": [
    {
      "id": "dep_x9y8z7w6",
      "currency": "btc",
      "amount_crypto": "0.0075",
      "amount_usd": 500.00,
      "fee_usd": 10.00,
      "credited_usd": 490.00,
      "status": "confirmed",
      "tx_hash": "3a1b2c3d4e5f...",
      "confirmations": 6,
      "created_at": "2026-04-15T10:00:00Z",
      "confirmed_at": "2026-04-15T10:42:00Z"
    }
  ]
}
BINs

BIN Selection

List available BIN ranges with their capabilities, limits, and acceptance rates.

GET /bins List all available BINs
Response 200 OK
response.json
{
  "data": [
    {
      "id": "491653",
      "network": "visa",
      "type": "advertising",
      "issuer_country": "US",
      "3ds": true,
      "apple_pay": true,
      "google_pay": true,
      "max_transaction": 5000.00,
      "max_monthly": 50000.00,
      "acceptance_rate": 97.2,
      "best_for": ["meta_ads", "google_ads", "tiktok_ads"]
    },
    {
      "id": "531993",
      "network": "mastercard",
      "type": "everyday",
      "issuer_country": "US",
      "3ds": true,
      "apple_pay": true,
      "google_pay": true,
      "max_transaction": 1000.00,
      "max_monthly": 10000.00,
      "acceptance_rate": 95.8,
      "best_for": ["subscriptions", "saas", "shopping"]
    }
  ]
}
3D Secure

3D Secure Authentication

Retrieve 3DS challenges and OTP codes. All cards are enrolled in 3DS 2.0 automatically.

GET /3ds List pending 3DS challenges
Query Parameters
ParameterTypeDescription
card_idstringoptionalFilter by card
statusstringoptionalpending, completed, expired
Response 200 OK
response.json
{
  "data": [
    {
      "id": "3ds_m4n5o6p7",
      "card_id": "card_8xK2m9Lp4q",
      "merchant": "SPOTIFY",
      "amount": 9.99,
      "otp": "847291",
      "status": "pending",
      "expires_at": "2026-04-15T15:05:00Z",
      "created_at": "2026-04-15T15:00:00Z"
    }
  ]
}
GET /3ds/{challenge_id} Get a specific 3DS OTP

Returns the full 3DS challenge object including the OTP code. OTPs expire after 5 minutes.

Webhooks

Webhooks & Events

Receive real-time notifications when events occur. Payloads are signed with HMAC-SHA256.

Available Events
card.createdA new card was issued
card.frozenA card was frozen
card.unfrozenA card was unfrozen
card.terminatedA card was terminated
card.fundedFunds added to a card
transaction.authorizedTransaction authorized
transaction.settledTransaction settled
transaction.declinedTransaction declined
transaction.refundedRefund processed
3ds.challenge3DS verification required
deposit.pendingCrypto deposit detected
deposit.confirmedCrypto deposit confirmed
Signature Verification
verify-webhook.py
import hmac, hashlib

def verify_webhook(payload, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)
POST /webhooks Register a webhook endpoint
Request Body
ParameterTypeDescription
urlstringrequiredHTTPS endpoint URL to receive events
eventsstring[]requiredEvent types to subscribe. Use ["*"] for all.
secretstringoptionalCustom signing secret. Auto-generated if omitted.
Response 201 Created
response.json
{
  "id": "wh_r5s6t7u8",
  "url": "https://yourapp.com/webhooks/ctc",
  "events": ["transaction.authorized", "transaction.declined"],
  "secret": "whsec_a1b2c3d4e5f6...",
  "active": true,
  "created_at": "2026-04-15T12:00:00Z"
}
GET /webhooks List registered webhooks

Returns array of all registered webhook endpoints with their event subscriptions and status.

DELETE /webhooks/{webhook_id} Delete a webhook

Permanently removes the webhook. No further events will be delivered to this endpoint.

SDKs

SDKs & Libraries

Official client libraries for your stack. All SDKs support live and sandbox environments.

Python

Python

pip install cryptotopcard

Node.js

Node.js

npm i cryptotopcard

Go

Go

go get cryptotopcard

Quick Start — Python
quickstart.py
from cryptotopcard import Client

client = Client("sk_live_your_api_key")

# Create a card
card = client.cards.create(
    bin_id="491653",
    amount=500,
    label="Ad Spend"
)
print(card.id, card.last4)

# Get full card details (PAN, CVV)
details = client.cards.details(card.id)
print(details.pan, details.cvv)

# Fund the card
client.cards.fund(card.id, amount=200)

# List transactions
txns = client.transactions.list(card_id=card.id)
for t in txns.data:
    print(t.merchant.name, t.amount)
Quick Start — Node.js
quickstart.js
const { CryptoTopCard } = require('cryptotopcard');

const client = new CryptoTopCard('sk_live_your_api_key');

// Create a card
const card = await client.cards.create({
  binId: '491653',
  amount: 500,
  label: 'Ad Spend',
});

// Get 3DS OTPs
const challenges = await client.threeds.list({
  cardId: card.id,
  status: 'pending',
});

// Set up webhooks
await client.webhooks.create({
  url: 'https://yourapp.com/hooks',
  events: ['transaction.authorized', '3ds.challenge'],
});