Construye conCryptocardium.
Emite tarjetas, financia cuentas, dispara transacciones y sigue el ciclo de vida — desde cURL, desde cualquier SDK, desde tu agente de IA. Toda la plataforma es una API REST estable y un servidor MCP nativo.
Bienvenida
Cryptocardium es un programa de tarjetas sin KYC financiado con cripto. Cada acción que puedes realizar en el panel — abrir una cuenta, recargar, emitir una tarjeta, cargarla, gastar, consultar transacciones — está disponible a través de la misma API REST y el mismo servidor MCP.
Estos docs cubren todo: convenciones (cómo habla la API), recursos (qué puedes pedir), eventos (cómo te mantienes sincronizado) e integraciones (Claude, ChatGPT, Cursor, cualquier agente).
Regístrate en /account, abre Configuración API, haz clic en "Nueva clave". El texto plano completo se muestra una sola vez — cópialo en un gestor de secretos.
Inicio rápido
De cero a una tarjeta virtual activa en tres llamadas. El shell de abajo usa cURL; sustitúyelo por cualquier cliente HTTP.
1. Autenticarse
Coloca tu clave API en la cabecera Authorization. Todos los endpoints la requieren.
export CCM_KEY="ccm_live_a1b2c3d4..."
2. Recargar la tesorería
Crea una dirección de depósito USDT. Envía fondos; acreditamos en la confirmación.
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 una tarjeta & gastar
Elige un BIN (Visa Platinum para carteras, Visa Business para publicidad), cárgalo y ya estás activo.
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
Cuarenta y siete segundos de mediana, del registro a la primera autorización. Las secciones restantes cubren todo lo demás — gestión de errores, idempotencia, webhooks, configuración de agentes — que necesitarás en producción.
Autenticación
Tres tipos de credencial, elegidos según la forma de integración:
| Tipo | Formato | Usar para |
|---|---|---|
| Bearer de sesión | sess_… | Scripts interactivos, pruebas, el panel en sí. |
| Clave API | ccm_live_… | Servidores en producción, CI, tareas programadas, larga duración. |
| OAuth 2.1 + DCR | eyJh… (JWT) | Agentes que se registran solos en tiempo de ejecución, permisos con alcance. |
Cabecera bearer
Las tres pasan por la misma cabecera:
Authorization: Bearer ccm_live_a1b2c3d4...
Generar una clave API
Las claves se generan solo en el panel. No aceptamos solicitudes de creación de claves vía API sin una sesión autenticada vinculada a la sesión del panel.
- Inicia sesión en tu cuenta.
- Abre Configuración API.
- Haz clic en Nueva clave, dale un nombre reconocible, guarda el texto plano (se muestra una vez).
- Guárdalo en un gestor de secretos. Añádelo a tu entorno como
CCM_KEY.
Una clave ccm_live_ filtrada tiene permisos a nivel de cuenta. Rótala en /api-settings si sospechas exposición — la revocación es instantánea.
Pruebas & sandbox
Actualmente, las recargas por debajo de 200 $ se aceptan como reales pero se enrutan a un procesador de tarjetas sandbox, por lo que puedes integrar sin consumir liquidación real. Las cuentas de producción tienen interruptores de modo sandbox por clave.
- Recarga 200 $+ → raíles de producción, liquidación real.
- Recarga <200 $ → raíles sandbox, autorizaciones simuladas.
- Las tarjetas emitidas desde recargas sandbox llevan
"mode": "sandbox".
URL base & versionado
URL base de producción:
https://api.cryptocardium.com/v1
El prefijo v1 forma parte de la ruta. v1 es LTS para siempre — nunca se publicarán cambios que rompan la compatibilidad bajo él. Los cambios aditivos (nuevos campos opcionales, nuevos endpoints) se publican de forma transparente.
Los cambios que rompen la compatibilidad van bajo un nuevo prefijo (v2) con al menos seis meses de solapamiento. Las deprecaciones se anuncian vía webhook (system.deprecation) y el registro de cambios.
Solicitudes
Todas las solicitudes son HTTPS únicamente (TLS 1.3). Los cuerpos de solicitud son JSON; los objetos anidados son de primer nivel. Los cuerpos codificados en formulario no están soportados.
- Content-Type:
application/jsonpara endpoints de escritura. - <strong>Charset</strong>: UTF-8 siempre.
- Métodos HTTP:
GET(leer),POST(crear / acción),PATCH(actualización parcial),DELETE(eliminar). - Límites de cabecera: 8 KB total, 4 KB por valor.
- Límite de cuerpo: 25 MB (100 MB para cargas de evidencias de disputa).
- Timeouts: 30 s de conexión, 60 s de lectura. Las operaciones de larga duración son asíncronas.
Respuestas
Cada respuesta es JSON. Las respuestas exitosas devuelven 200/201/204 con el cuerpo del recurso. Los errores devuelven un objeto de error estructurado — ver Errores.
Envelope estándar
{
"id": "card_8f3a91b7c4d2",
"object": "card",
"created_at": "2026-05-19T07:30:00Z",
"updated_at": "2026-05-19T07:30:00Z",
...
}
Marcas de tiempo
Todas las marcas de tiempo son ISO 8601 en UTC, formateadas como YYYY-MM-DDTHH:MM:SSZ. No hay otras zonas horarias en la API.
Valores monetarios
Todos los importes son decimales equivalentes a USD en campos amount_usd. Precisión de dos decimales. Respaldado internamente por USDT.
Paginación
Los endpoints de lista (/topups, /cards, /transactions, …) están paginados por cursor. Sin offset, sin LIMIT SQL.
GET /v1/transactions?limit=50&cursor=tx_8f3a91b7c4d2
limit— tamaño de página, por defecto 25, máximo 100.cursor— devuelve elnext_cursorde la respuesta anterior.- La paginación sigue el orden natural de cada recurso (normalmente <code>created_at</code> desc).
{
"object": "list",
"data": [ /* 50 items */ ],
"has_more": true,
"next_cursor": "tx_2bea88..."
}
Filtrado & ordenación
Cada endpoint de lista admite filtrado en sus campos principales mediante parámetros de consulta:
GET /v1/transactions
?card_id=card_8f3a91b7c4d2
&status=captured
&created_after=2026-05-01T00:00:00Z
&sort=-amount_usd
El parámetro sort acepta un solo campo; usa el prefijo - para descendente. Consulta la referencia de endpoint de cada recurso para conocer las claves de filtro admitidas.
Idempotencia
Cada solicitud de escritura (POST, PATCH, DELETE) acepta una cabecera Idempotency-Key. Pasa un valor único por operación lógica. Los reintentos con la misma clave devuelven la respuesta original.
POST /v1/cards
Idempotency-Key: card_create_b9f1a4...
Authorization: Bearer ccm_live_...
- Las claves se almacenan durante 24 horas. Después, la misma clave puede reutilizarse para una operación nueva.
- Formato recomendado:
<operación>_<uuid-v4>. - Misma clave + cuerpo diferente →
409 Conflictconconflict_idempotency_key. - Las solicitudes
GETson siempre idempotentes y no necesitan (ni aceptan) la cabecera.
Límites de tasa
Por clave API:
| Ventana | Límite | Notas |
|---|---|---|
| Ráfaga de 1 s | 60 req | Se toleran picos cortos. |
| 1 min | 1 000 req | Techo sostenido. |
| 1 día | 50 000 req | Agregado por clave. |
Cada respuesta incluye:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 943
X-RateLimit-Reset: 1718999999
Cuando superas el límite, recibirás 429 Too Many Requests con una cabecera Retry-After en segundos. Respétala; aplicamos backoff exponencial a los infractores.
Errores
Cada respuesta de error usa la misma forma:
{
"object": "error",
"type": "invalid_request_error",
"code": "missing_required_field",
"message": "Field 'bin' is required.",
"param": "bin",
"request_id": "req_a9f4b1..."
}
Mapeo de estado HTTP
| Estado | Tipo | Significado |
|---|---|---|
| 400 | invalid_request_error | Payload malformado, campos que faltan. |
| 401 | authentication_error | Bearer ausente o inválido. |
| 403 | permission_error | Bearer válido, acción no permitida (p. ej., restricción de saldo). |
| 404 | not_found_error | El recurso no existe (o no es tuyo). |
| 409 | conflict_error | Conflicto de estado (p. ej., clave de idempotencia reutilizada). |
| 419 | session_expired | Sesión del panel expirada. Reautentícate. |
| 422 | validation_error | JSON válido, regla de negocio incumplida. |
| 429 | rate_limit_error | Reduce la velocidad. Retry-After en segundos. |
| 500 | api_error | Nuestro error. Ya hemos sido alertados. |
| 503 | service_unavailable | Emisor upstream caído. Se recomienda reintento automático. |
Registra siempre el request_id. Los tickets de soporte lo referencian directamente.
Cuentas
La cuenta es tu recurso raíz. Todo lo demás (recargas, tarjetas, transacciones) pertenece a una cuenta.
Crear
POST /v1/accounts
{
"email": "[email protected]",
"password": "long-random-string"
}
Devuelve un bearer de sesión de inmediato. Sin KYC, sin subir documentos, sin paso de verificación de email necesario para empezar a usar la API.
Recuperar la actual
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 & tesorería
El saldo de la cuenta es el fondo USDT disponible para gastar. Las recargas lo incrementan; las cargas de tarjeta y las retiradas lo decrementan.
GET /v1/balance
{
"object": "balance",
"available_usd": 487.20,
"pending_usd": 200.00,
"updated_at": "2026-05-19T07:30:00Z"
}
pending_usd cubre recargas en vuelo (aún no confirmadas) y cargas de tarjeta en vuelo.
Recargas
Una recarga es el paso asimétrico donde comprometes cripto en cadena y nosotros acreditamos USDT tras la finalidad.
Crear
POST /v1/topups
{
"amount_usd": 500,
"asset": "USDT",
"chain": "tron"
}
Devuelve una dirección de depósito, datos URI de QR y una expiración (por defecto 60 min). Envía el importe exacto a la dirección; acreditamos en la confirmación.
{
"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 del estado
| Estado | Significado |
|---|---|
| pending | Esperando depósito en cadena. |
| completed | Fondos acreditados al saldo. |
| expired | Ventana de dirección cerrada. Los depósitos tardíos se acreditan automáticamente. |
| cancelled | Llamaste a POST /v1/topups/:id/cancel. |
| error | Liquidación fallida (infrecuente). Reembolsado automáticamente. |
Usa el webhook topup.confirmed en lugar de sondear — se dispara una vez y te ahorra más de 30 sondeos.
Tarjetas
Las tarjetas son de dos tipos: virtual (activa en segundos) y física (enviada en 5–9 días, limitada al BIN de Visa Gold).
Emitir
POST /v1/cards
{
"type": "virtual",
"bin": "489517",
"load_usd": 300,
"wallet_provision": ["apple_pay", "google_pay"]
}
Catálogo de BIN
| BIN | Nombre | Ideal para | Tipo |
|---|---|---|---|
| 416842 | Visa Business | Gasto publicitario (3-D Secure) | Virtual |
| 557213 | Mastercard World | Multidivisa, premium | Virtual |
| 489517 | Visa Platinum | Apple & Google Pay | Virtual |
| 472305 | Visa Corporate | Suscripciones SaaS | Virtual |
| 448585 | Visa Gold | Solo física (3-D Secure) | Física |
Revelar PAN completo + CVV
El número completo de tarjeta, CVV y vencimiento se devuelven solo en una llamada dedicada y auditada:
GET /v1/cards/:id/pan
{
"pan": "4895 1712 ●●●● 4218",
"cvv": "347",
"expires_at": "2029-08",
"audit_id": "audit_8c2e3f..."
}
Cada revelación queda registrada en el rastro de auditoría. Los agentes deben revelar una vez por compra, nunca almacenar y descartar de la memoria tras el uso.
Operaciones
POST /v1/cards/:id/freeze— detener autorizaciones.POST /v1/cards/:id/unfreeze— reanudar.POST /v1/cards/:id/load— añadir USDT a la tarjeta.POST /v1/cards/:id/unload— mover el saldo no utilizado de vuelta a la tesorería.POST /v1/cards/:id/cancel— cancelación permanente.PATCH /v1/cards/:id/limits— límites de transacción / mensuales por tarjeta.PATCH /v1/cards/:id/mcc— listas de MCC permitidos/denegados.PATCH /v1/cards/:id/geo— listas de países permitidos.
Cargas & saldos de tarjeta
El saldo de tarjeta está denominado en USDT equivalente a USD. Una carga deduce de la tesorería, aplica la comisión de rail del 2 % y acredita la tarjeta.
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
}
Las cargas son atómicas — la llamada devuelve respuesta solo tras el movimiento de fondos.
Transacciones
Cada autorización, captura, reembolso y rechazo es un objeto de transacción. Son de solo adición e inmutables.
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
}
Filtra por status, card_id, mcc, merchant_name, created_after, created_before, amount_min, amount_max.
Retiradas
Envía USDT de la tesorería a cualquier cartera externa que controles.
POST /v1/withdrawals
{
"amount_usd": 100,
"chain": "tron",
"address": "T9zFR...kQp"
}
Mín. 10 $, máx. tu saldo completo. Cadenas soportadas: tron (la más barata), ethereum, bsc. Los envíos entre redes son irrecuperables — verifica siempre la dirección.
Disputas
Presenta un contracargo sobre cualquier transacción:
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.
Adjunta evidencias (recibos, capturas, correspondencia) vía POST /v1/disputes/:id/evidence. Tramitamos ante el emisor en tu nombre — sin coste adicional.
Webhooks · suscribirse
Los webhooks envían eventos a tu endpoint HTTPS a medida que ocurren. Evita el sondeo; usa webhooks.
POST /v1/webhooks
{
"url": "https://yourapp.example.com/webhooks/cryptocardium",
"events": [
"topup.confirmed",
"card.issued",
"transaction.captured",
"transaction.declined"
],
"description": "Production sync"
}
La respuesta contiene un signing_secret — guárdalo; lo necesitarás para verificar los payloads. Suscríbete a "*" para recibir cada evento.
Webhooks · verificación de firma
Cada webhook lleva una firma HMAC-SHA256 en la cabecera Cryptocardium-Signature:
Cryptocardium-Signature: t=1718999999,v1=4a8b2f0e6c9d...
Cryptocardium-Event-Id: evt_a1b2c3d4
Cryptocardium-Delivery: dlv_8f3a91...
Calcula la firma esperada sobre "{t}.{rawBody}" con tu signing_secret. Compara usando una función de tiempo 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 · reintentos & reproducciones
Entrega al menos una vez. Reintentamos en cualquier respuesta no-2xx o timeout (10 s).
| Intento | Retraso |
|---|---|
| 1 | inmediato |
| 2 | 30 s |
| 3 | 5 min |
| 4 | 30 min |
| 5 | 2 h |
| 6 | 12 h |
| 7 | 24 h (final) |
Reproduce cualquier evento desde el panel o vía POST /v1/webhooks/:id/replay/:event_id. Usa la cabecera Cryptocardium-Event-Id para deduplicación en tu 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
Alojamos un servidor del Protocolo de Contexto de Modelo en https://mcp.cryptocardium.com/v1. Expone más de 40 herramientas mapeadas 1:1 a endpoints REST, con nombres adaptados para agentes (create_topup, issue_card, reveal_pan, etc.).
Transporte: HTTP streamable. Auth: OAuth 2.1 con Registro Dinámico de Clientes — los agentes se registran solos en la primera conexión, sin necesidad de pegar una clave API en la configuración del agente.
MCP · configuración del 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
Tras autorizar en tu navegador, el agente tiene acceso a todas las herramientas del catálogo (o solo las que hayas concedido si ajustaste el alcance).
MCP · catálogo de herramientas
Las herramientas reflejan los endpoints REST. Una pequeña muestra (la lista completa está en /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
Los agentes se registran dinámicamente vía RFC 7591. Flujo:
- El agente hace
POST /oauth/register— recibeclient_id&client_secret. - Se solicita al usuario que autorice en el navegador (una sola vez).
- El agente recibe
access_token(con alcance, tiempo limitado). - Las solicitudes posteriores llevan el bearer JWT.
Alcances por herramienta
Restringe un agente a solo lectura, a una tarjeta específica o a un subconjunto de herramientas pasando scope= en el momento del registro. Ejemplos:
scope=read # list & get only, no writes
scope=cards:write # manage cards but not withdraw
scope=card:card_8f3a91b7c4d2 # single card
SDKs & ejemplos
Los SDKs oficiales llegan pronto. Mientras tanto, la API es una superficie REST plana — cualquier cliente HTTP moderno la maneja.
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);
Registro de cambios
Los cambios aditivos se publican de forma transparente. Los cambios que rompen la compatibilidad van bajo un nuevo prefijo de versión.
-
2026-05-19 · v1.4
Añadido
POST /v1/cards/:id/load&/unloadson ahora atómicos. Evento de webhookcard.loadedañadido. -
2026-05-18 · v1.3
Añadido
Servidor MCP activo en
mcp.cryptocardium.com. DCR OAuth 2.1. Más de 40 herramientas mapeadas desde REST. -
2026-05-17 · v1.2
Añadido
Programa de tarjeta Gold física (BIN 448585), 3-D Secure en Visa Business y Visa Gold.
-
2026-05-15 · v1.1
Modificado
Mínimo de recarga reducido a 20 $ para enrutamiento sandbox, 200 $ para raíles de producción.
-
2026-05-12 · v1.0
Publicado
v1 LTS. Más de 50 endpoints. Auth bearer + claves de idempotencia + webhooks HMAC.
Soporte
¿Atascado? Dos vías:
- Consulta las preguntas frecuentes del centro de ayuda — más de 30 preguntas y respuestas, con búsqueda.
- Abre un ticket de soporte — solo para titulares activos, respuesta en 24 h.
Incluye el request_id de la respuesta fallida — acelera la resolución 10 veces.