Construa comCryptocardium.
Emita cartões, financie contas, dispare transações e acompanhe o ciclo de vida — via cURL, de qualquer SDK, do seu agente de IA. Toda a plataforma é uma API REST estável e um servidor MCP nativo.
Bem-vindo
Cryptocardium é um programa de cartões sem KYC financiado com crypto. Toda ação que você pode executar no painel — abrir uma conta, recarregar, emitir um cartão, carregá-lo, realizar gastos, acompanhar transações — está disponível através da mesma API REST e servidor MCP.
Esta documentação cobre tudo: convenções (como a API se comunica), recursos (o que você pode solicitar), eventos (como você se mantém sincronizado) e integrações (Claude, ChatGPT, Cursor, qualquer agente).
Cadastre-se em /account, abra Configurações de API, clique em "Nova chave". O texto completo é exibido uma única vez — copie-o para um gerenciador de segredos.
Guia rápido
Do zero a um cartão virtual ativo em três chamadas. O shell abaixo usa cURL; substitua por qualquer cliente HTTP.
1. Autenticar
Coloque sua chave de API no cabeçalho Authorization. Todo endpoint exige isso.
export CCM_KEY="ccm_live_a1b2c3d4..."
2. Recarregar o tesouro
Crie um endereço de depósito USDT. Envie os fundos; creditamos após a confirmação.
curl https://api.cryptocardium.com/v1/topups \
-H "Authorization: Bearer $CCM_KEY" \
-H "Idempotency-Key: top_$(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "amount_usd": 500, "asset": "USDT", "chain": "tron" }'
3. Emitir um cartão & utilizar
Escolha um BIN (Visa Platinum para carteiras, Visa Business para anúncios), carregue-o e você está pronto para usar.
curl https://api.cryptocardium.com/v1/cards \
-H "Authorization: Bearer $CCM_KEY" \
-d '{
"type": "virtual",
"bin": "489517",
"load_usd": 300,
"wallet_provision": ["apple_pay", "google_pay"]
}'
# → 201 Created · card is live, balance loaded, wallet-ready
Quarenta e sete segundos de mediana, do cadastro à primeira autenticação. As seções restantes cobrem todo o mais — tratamento de erros, idempotência, webhooks, configuração de agentes — que você precisará em produção.
Autenticação
Três tipos de credenciais, escolhidos pelo formato da integração:
| Tipo | Formato | Utilizar para |
|---|---|---|
| Bearer de sessão | sess_… | Scripts interativos, testes, o próprio painel. |
| Chave de API | ccm_live_… | Servidores de produção, CI, jobs agendados, uso de longa duração. |
| OAuth 2.1 + DCR | eyJh… (JWT) | Agentes que se registram em tempo de execução, concessões com escopo. |
Cabeçalho Bearer
Os três são transmitidos pelo mesmo cabeçalho:
Authorization: Bearer ccm_live_a1b2c3d4...
Gerar uma chave de API
As chaves são geradas somente no painel. Nunca aceitamos uma solicitação de criação de chave via API sem uma sessão autenticada vinculada à sessão do painel.
- Faça login na sua conta.
- Abra Configurações de API.
- Clique em Nova chave, dê um nome reconhecível, salve o texto completo (exibido uma única vez).
- Armazene em um gerenciador de segredos. Adicione ao seu ambiente como
CCM_KEY.
Uma chave ccm_live_ vazada carrega permissão em nível de conta. Faça a rotação via /api-settings se suspeitar de exposição — a revogação é imediata.
Testes & sandbox
Atualmente, recargas abaixo de $200 são aceitas como reais, mas roteadas para um processador de cartão sandbox, para que você possa integrar sem consumir liquidação real. Contas de produção têm alternâncias de modo sandbox por chave.
- Recarga $200+ → trilhos de produção, liquidação real.
- Recarga <$200 → trilhos sandbox, autorizações simuladas.
- Cartões emitidos de recargas sandbox carregam
"mode": "sandbox".
URL base & versionamento
URL base de produção:
https://api.cryptocardium.com/v1
O prefixo v1 faz parte do caminho. v1 é LTS permanente — nenhuma mudança incompatível jamais será lançada sob ele. Mudanças aditivas (novos campos opcionais, novos endpoints) são lançadas de forma transparente.
Mudanças incompatíveis vão para um novo prefixo (v2) com pelo menos seis meses de sobreposição. Depreciações são anunciadas via webhook (system.deprecation) e o histórico de alterações.
Requisições
Todas as requisições são exclusivamente HTTPS (TLS 1.3). Os corpos das requisições são JSON; objetos aninhados são de primeira classe. Corpos codificados como form não são suportados.
- Content-Type:
application/jsonpara endpoints de escrita. - <strong>Charset</strong>: UTF-8 sempre.
- Métodos HTTP:
GET(leitura),POST(criação / ação),PATCH(atualização parcial),DELETE(remoção). - Limites de cabeçalho: 8 KB no total, 4 KB por valor.
- Limite de corpo: 25 MB (100 MB para uploads de evidências de contestação).
- Timeouts: 30 s de conexão, 60 s de leitura. Operações de longa duração são assíncronas.
Respostas
Toda resposta é JSON. Respostas de sucesso retornam 200/201/204 com o corpo do recurso. Erros retornam um objeto de erro estruturado — veja Erros.
Envelope padrão
{
"id": "card_8f3a91b7c4d2",
"object": "card",
"created_at": "2026-05-19T07:30:00Z",
"updated_at": "2026-05-19T07:30:00Z",
...
}
Timestamps
Todos os timestamps seguem o padrão ISO 8601 em UTC, formatados como YYYY-MM-DDTHH:MM:SSZ. Não há outros fusos horários na API.
Valores monetários
Todos os valores são decimais equivalentes em USD nos campos amount_usd. Precisão de duas casas decimais. Internamente lastreado em USDT.
Paginação
Endpoints de lista (/topups, /cards, /transactions, …) utilizam paginação por cursor. Sem offset, sem LIMIT SQL.
GET /v1/transactions?limit=50&cursor=tx_8f3a91b7c4d2
limit— tamanho da página, padrão 25, máximo 100.cursor— repasse onext_cursorda resposta anterior.- A paginação segue a ordenação natural de cada recurso (tipicamente <code>created_at</code> desc).
{
"object": "list",
"data": [ /* 50 items */ ],
"has_more": true,
"next_cursor": "tx_2bea88..."
}
Filtragem & ordenação
Todo endpoint de lista suporta filtragem nos seus campos primários via parâmetros de consulta:
GET /v1/transactions
?card_id=card_8f3a91b7c4d2
&status=captured
&created_after=2026-05-01T00:00:00Z
&sort=-amount_usd
O parâmetro sort aceita um único campo; prefixe com - para ordem decrescente. Consulte a referência de endpoint de cada recurso para as chaves de filtro suportadas.
Idempotência
Toda requisição de escrita (POST, PATCH, DELETE) aceita um cabeçalho Idempotency-Key. Passe um valor único por operação lógica. Retentativas com a mesma chave retornam a resposta original.
POST /v1/cards
Idempotency-Key: card_create_b9f1a4...
Authorization: Bearer ccm_live_...
- As chaves são armazenadas por 24 horas. Após esse período, a mesma chave pode ser reutilizada para uma nova operação.
- Formato recomendado:
<operation>_<uuid-v4>. - Mesma chave + corpo diferente →
409 Conflictcomconflict_idempotency_key. - Requisições
GETsão sempre idempotentes e não precisam (nem aceitam) o cabeçalho.
Limites de requisições
Por chave de API:
| Janela | Limite | Observações |
|---|---|---|
| Burst de 1 s | 60 req | Picos curtos tolerados. |
| 1 min | 1 000 req | Teto sustentado. |
| 1 dia | 50 000 req | Agregado por chave. |
Toda resposta carrega:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 943
X-RateLimit-Reset: 1718999999
Quando você exceder o limite, receberá 429 Too Many Requests com um cabeçalho Retry-After em segundos. Respeite-o; aplicamos backoff exponencial a infratores reincidentes.
Erros
Toda resposta de erro utiliza o mesmo formato:
{
"object": "error",
"type": "invalid_request_error",
"code": "missing_required_field",
"message": "Field 'bin' is required.",
"param": "bin",
"request_id": "req_a9f4b1..."
}
Mapeamento de status HTTP
| Status | Tipo | Significado |
|---|---|---|
| 400 | invalid_request_error | Payload malformado, campos ausentes. |
| 401 | authentication_error | Bearer ausente ou inválido. |
| 403 | permission_error | Bearer válido, ação não permitida (ex.: restrição de saldo). |
| 404 | not_found_error | Recurso inexistente (ou não pertence a você). |
| 409 | conflict_error | Conflito de estado (ex.: chave de idempotência reutilizada). |
| 419 | session_expired | Sessão do painel expirada. Autentique novamente. |
| 422 | validation_error | JSON do payload válido, regra de negócio não atendida. |
| 429 | rate_limit_error | Reduza o ritmo. Retry-After em segundos. |
| 500 | api_error | Falha nossa. Já fomos alertados. |
| 503 | service_unavailable | Emissor upstream indisponível. Retentativa automática recomendada. |
Sempre registre o request_id. Tickets de suporte o referenciam diretamente.
Contas
A conta é seu recurso raiz. Todo o restante (recargas, cartões, transações) pertence a uma conta.
Criar
POST /v1/accounts
{
"email": "[email protected]",
"password": "long-random-string"
}
Retorna um bearer de sessão imediatamente. Sem KYC, sem upload de documentos, sem etapa de verificação de e-mail para começar a usar a API.
Recuperar atual
GET /v1/accounts/me
{
"id": "acc_8f3a91b7c4d2",
"email": "[email protected]",
"balance_usd": 487.20,
"twofa_enabled": true,
"created_at": "2026-05-18T20:14:00Z"
}
Saldo & tesouro
O saldo da conta é o pool USDT disponível para gastos. Recargas o creditam; cargas de cartão e saques o debitam.
GET /v1/balance
{
"object": "balance",
"available_usd": 487.20,
"pending_usd": 200.00,
"updated_at": "2026-05-19T07:30:00Z"
}
pending_usd cobre recargas em andamento (ainda não confirmadas) e cargas de cartão em andamento.
Recargas
Uma recarga é a etapa assimétrica em que você compromete crypto on-chain e creditamos USDT após a finalidade.
Criar
POST /v1/topups
{
"amount_usd": 500,
"asset": "USDT",
"chain": "tron"
}
Retorna um endereço de depósito, URI de dados QR e uma expiração (padrão 60 min). Envie o valor exato para o endereço; creditamos após a confirmação.
{
"id": "top_4e21a99c7b",
"status": "pending",
"amount_usd": 500,
"deposit_address": "T9zFR...kQp",
"qr_data_uri": "data:image/png;base64,...",
"expires_at": "2026-05-19T08:30:00Z"
}
Ciclo de vida do status
| Status | Significado |
|---|---|
| pending | Aguardando depósito on-chain. |
| completed | Fundos creditados ao saldo. |
| expired | Janela do endereço encerrada. Depósitos tardios ainda são creditados automaticamente. |
| cancelled | Você chamou POST /v1/topups/:id/cancel. |
| error | Liquidação falhou (raro). Reembolso automático. |
Prefira o webhook topup.confirmed ao polling — ele dispara uma única vez e economiza mais de 30 polls.
Cartões
Os cartões vêm em dois tipos — virtual (ativo em segundos) e físico (entregue em 5–9 dias, vinculado ao BIN Visa Gold).
Emitir
POST /v1/cards
{
"type": "virtual",
"bin": "489517",
"load_usd": 300,
"wallet_provision": ["apple_pay", "google_pay"]
}
Catálogo de BIN
| BIN | Nome | Melhor para | Tipo |
|---|---|---|---|
| 416842 | Visa Business | Gastos com anúncios (3-D Secure) | Virtual |
| 557213 | Mastercard World | Multi-moeda, premium | Virtual |
| 489517 | Visa Platinum | Apple & Google Pay | Virtual |
| 472305 | Visa Corporate | Assinaturas SaaS | Virtual |
| 448585 | Visa Gold | Somente físico (3-D Secure) | Físico |
Revelar PAN completo + CVV
O número completo do cartão, CVV e validade são retornados apenas em uma chamada dedicada e auditada:
GET /v1/cards/:id/pan
{
"pan": "4895 1712 ●●●● 4218",
"cvv": "347",
"expires_at": "2029-08",
"audit_id": "audit_8c2e3f..."
}
Toda revelação é registrada na trilha de auditoria. Agentes devem revelar uma vez por compra, nunca armazenar, e descartar da memória após o uso.
Operações
POST /v1/cards/:id/freeze— interromper autorizações.POST /v1/cards/:id/unfreeze— retomar.POST /v1/cards/:id/load— adicionar USDT ao cartão.POST /v1/cards/:id/unload— mover saldo não utilizado de volta ao tesouro.POST /v1/cards/:id/cancel— encerramento permanente.PATCH /v1/cards/:id/limits— limites de transação / mensais por cartão.PATCH /v1/cards/:id/mcc— listas de permissão/bloqueio de MCC.PATCH /v1/cards/:id/geo— listas de permissão por país.
Cargas de cartão & saldos
O saldo do cartão é denominado em USDT equivalente em USD. Uma carga deduz do tesouro, aplica a taxa de trilho de 2% e credita o cartão.
POST /v1/cards/:id/load
{ "amount_usd": 200 }
{
"card_id": "card_8f3a91b7c4d2",
"loaded_usd": 200.00,
"rail_fee_usd": 4.00,
"new_card_balance_usd": 200.00,
"new_treasury_balance_usd": 283.20
}
As cargas são atômicas — a chamada retorna somente após a movimentação dos fundos.
Transações
Toda autorização, captura, reembolso e recusa é um objeto de transação. São apenas de adição e imutáveis.
GET /v1/cards/:id/transactions?status=captured&limit=50
{
"object": "list",
"data": [
{
"id": "tx_b1c2d3",
"object": "transaction",
"card_id": "card_8f3a91b7c4d2",
"status": "captured",
"amount_usd": 42.95,
"merchant": { "name": "OpenAI", "mcc": "7372" },
"auth_response_code": "00",
"created_at": "2026-05-19T03:14:00Z"
}
],
"has_more": false
}
Filtre por status, card_id, mcc, merchant_name, created_after, created_before, amount_min, amount_max.
Saques
Envie USDT do tesouro para qualquer carteira externa que você controle.
POST /v1/withdrawals
{
"amount_usd": 100,
"chain": "tron",
"address": "T9zFR...kQp"
}
Mínimo $10, máximo seu saldo total. Redes suportadas: tron (mais barata), ethereum, bsc. Envios entre redes são irrecuperáveis — sempre verifique o endereço.
Contestações
Registre um chargeback em qualquer transação:
POST /v1/disputes
{
"transaction_id": "tx_b1c2d3",
"reason": "duplicate",
"description": "Merchant charged twice on 2026-05-19, same order #4921."
}
Códigos de motivo: duplicate, not_received, fraud, not_as_described, cancelled_subscription, other.
Anexe evidências (recibos, capturas de tela, correspondências) via POST /v1/disputes/:id/evidence. Protocolamos junto ao emissor em seu nome — sem taxa adicional.
Webhooks · assinaturas
Webhooks enviam eventos para o seu endpoint HTTPS conforme acontecem. Evite polling; use webhooks.
POST /v1/webhooks
{
"url": "https://yourapp.example.com/webhooks/cryptocardium",
"events": [
"topup.confirmed",
"card.issued",
"transaction.captured",
"transaction.declined"
],
"description": "Production sync"
}
A resposta contém um signing_secret — armazene-o; você precisará dele para verificar os payloads. Assine "*" para receber todos os eventos.
Webhooks · verificação de assinatura
Todo webhook carrega uma assinatura HMAC-SHA256 no cabeçalho Cryptocardium-Signature:
Cryptocardium-Signature: t=1718999999,v1=4a8b2f0e6c9d...
Cryptocardium-Event-Id: evt_a1b2c3d4
Cryptocardium-Delivery: dlv_8f3a91...
Calcule a assinatura esperada sobre "{t}.{rawBody}" com seu signing_secret. Compare usando uma função de tempo constante.
Node.js
import crypto from 'crypto';
export function verify(rawBody, sigHeader, secret) {
const [t, v1] = sigHeader.split(',')
.map(s => s.split('=')[1]);
const expected = crypto
.createHmac('sha256', secret)
.update(`${t}.${rawBody}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(v1), Buffer.from(expected)
);
}
Python
import hmac, hashlib
def verify(raw_body: bytes, sig_header: str, secret: str) -> bool:
parts = dict(p.split('=') for p in sig_header.split(','))
t, v1 = parts['t'], parts['v1']
expected = hmac.new(
secret.encode(),
f"{t}.{raw_body.decode()}".encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(v1, expected)
PHP
function verify($rawBody, $sigHeader, $secret): bool {
$parts = [];
foreach (explode(',', $sigHeader) as $p) {
[$k, $v] = explode('=', $p, 2);
$parts[$k] = $v;
}
$expected = hash_hmac('sha256',
"{$parts['t']}.{$rawBody}", $secret);
return hash_equals($expected, $parts['v1']);
}
Webhooks · tentativas & reenvios
Entrega com garantia mínima de uma vez. Retentativos em qualquer resposta não-2xx ou timeout (10 s).
| Tentativa | Atraso |
|---|---|
| 1 | imediato |
| 2 | 30 s |
| 3 | 5 min |
| 4 | 30 min |
| 5 | 2 h |
| 6 | 12 h |
| 7 | 24 h (final) |
Reenvie qualquer evento pelo painel ou via POST /v1/webhooks/:id/replay/:event_id. Use o cabeçalho Cryptocardium-Event-Id para deduplicação no seu lado.
Catálogo de eventos
account.created
account.signed_in
account.signed_out
account.password_changed
account.totp_enabled
account.totp_disabled
topup.created
topup.confirmed
topup.expired
topup.cancelled
topup.error
card.issued
card.loaded
card.unloaded
card.frozen
card.unfrozen
card.cancelled
card.replaced
transaction.authorized
transaction.captured
transaction.refunded
transaction.declined
transaction.reversed
dispute.opened
dispute.responded
dispute.won
dispute.lost
withdrawal.created
withdrawal.broadcasted
withdrawal.confirmed
withdrawal.failed
system.maintenance
system.deprecation
Servidor MCP
Hospedamos um servidor Model Context Protocol em https://mcp.cryptocardium.com/v1. Ele expõe mais de 40 ferramentas mapeando 1:1 para endpoints REST, com nomes amigáveis para agentes (create_topup, issue_card, reveal_pan, etc.).
Transporte: Streamable HTTP. Auth: OAuth 2.1 com Dynamic Client Registration — agentes se registram automaticamente na primeira conexão, sem necessidade de colar uma chave de API na configuração do agente.
MCP · configuração do cliente
Claude Desktop / Claude Code
// ~/.config/claude/claude_desktop_config.json
{
"mcpServers": {
"cryptocardium": {
"url": "https://mcp.cryptocardium.com/v1",
"transport": "http"
}
}
}
Cursor / Continue / mcp-cli
# Adds the server, kicks off OAuth DCR on first connect
mcp-cli add cryptocardium \
--url https://mcp.cryptocardium.com/v1 \
--auth oauth
Após autorizar no seu navegador, o agente tem acesso a todas as ferramentas do catálogo (ou apenas às que você concedeu, caso tenha restringido o escopo).
MCP · catálogo de ferramentas
As ferramentas espelham os endpoints REST. Uma pequena amostra (a lista completa está em /api):
create_account
sign_in
get_account
enable_2fa
get_balance
create_topup
withdraw
issue_card
load_card
reveal_pan
freeze_card
set_card_limits
list_transactions
get_activity
file_dispute
MCP · OAuth 2.1 + DCR
Agentes se registram dinamicamente via RFC 7591. Fluxo:
- Agente faz
POST /oauth/register— recebeclient_id&client_secret. - O usuário é solicitado no navegador a autorizar (única vez).
- Agente recebe
access_token(com escopo, com prazo). - Requisições subsequentes carregam o bearer JWT.
Escopos por ferramenta
Restrinja um agente ao modo somente leitura, a um cartão específico ou a um subconjunto de ferramentas passando scope= no momento do registro. Exemplos:
scope=read # list & get only, no writes
scope=cards:write # manage cards but not withdraw
scope=card:card_8f3a91b7c4d2 # single card
SDKs & exemplos
SDKs oficiais em breve. Até lá, a API é uma superfície REST plana — qualquer cliente HTTP moderno dá conta do recado.
Node.js (fetch)
const res = await fetch('https://api.cryptocardium.com/v1/cards', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CCM_KEY}`,
'Idempotency-Key': `card_${crypto.randomUUID()}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'virtual', bin: '489517', load_usd: 300
})
});
const card = await res.json();
Python (requests)
import requests, os, uuid
r = requests.post(
'https://api.cryptocardium.com/v1/cards',
headers={
'Authorization': f"Bearer {os.environ['CCM_KEY']}",
'Idempotency-Key': f"card_{uuid.uuid4()}",
},
json={'type': 'virtual', 'bin': '489517', 'load_usd': 300}
)
card = r.json()
PHP (curl)
$ch = curl_init('https://api.cryptocardium.com/v1/cards');
curl_setopt_array($ch, [
CURLOPT_POST => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $_ENV['CCM_KEY'],
'Idempotency-Key: card_' . bin2hex(random_bytes(16)),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'virtual',
'bin' => '489517',
'load_usd' => 300,
]),
]);
$card = json_decode(curl_exec($ch), true);
Changelog
Alterações aditivas são publicadas de forma transparente. Alterações incompatíveis ficam sob um novo prefixo de versão.
-
2026-05-19 · v1.4
Adicionado
POST /v1/cards/:id/load&/unloadagora são atômicos. Evento de webhookcard.loadedadicionado. -
2026-05-18 · v1.3
Adicionado
Servidor MCP disponível em
mcp.cryptocardium.com. OAuth 2.1 DCR. Mais de 40 ferramentas mapeadas a partir do REST. -
2026-05-17 · v1.2
Adicionado
Programa do cartão físico Gold (BIN 448585), 3-D Secure no Visa Business e Visa Gold.
-
2026-05-15 · v1.1
Alterado
Recarga mínima reduzida para $20 no roteamento sandbox e $200 nos trilhos de produção.
-
2026-05-12 · v1.0
Lançado
v1 LTS. Mais de 50 endpoints. Autenticação Bearer + chaves de idempotência + webhooks HMAC.
Suporte
Com dificuldades? Dois caminhos:
- Consulte a central de ajuda FAQ — mais de 30 perguntas respondidas, com busca.
- Abra um ticket de suporte — exclusivo para titulares de cartão ativos, resposta em até 24h.
Inclua o request_id da resposta com falha — isso acelera a resolução em 10×.