Autenticación

API keys, su entorno (Sandbox o Live) y sus permisos, Sandbox y Live en los requests, el header Idempotency-Key, el formato de error, la paginación y los límites de requests.

Última actualización 27 oct 2026

La API vive en https://api.aliquot.cc. Todos los endpoints de vendedor están bajo /api/v1/crypto y se autentican con una API key. También la administración de webhooks, bajo /api/v1/organizations/{organizationId}/webhooks (ver Webhooks). Los endpoints para el comprador bajo /api/v1/public (checkout, páginas de payment links, reclamos de reembolso) no llevan autenticación: el ID de la factura, el slug del link o el token de reclamo en el path es la credencial.

Los requests y las respuestas son JSON, con nombres de campo en snake_case.

API keys

Creá las keys en el dashboard, en Desarrolladores → API keys. Dale un nombre a la key, elegí su entorno (Sandbox o Live, ver más abajo) y sus permisos y, si querés, una fecha de vencimiento. El secreto se muestra una sola vez, cuando se crea la key; Aliquot guarda solo un hash, así que un secreto perdido no se puede recuperar. En ese caso, creá una key nueva y revocá la anterior.

Una key pertenece a tu organización y actúa solo sobre sus datos. No podés darle a una key un permiso que tu propio rol en la organización no tiene.

Revocá una key desde la misma página. Una key revocada o vencida se rechaza de inmediato.

Keys y entornos

Cada key queda atada a un entorno, que elegís al crearla. Su prefijo dice cuál:

PrefijoEntornoAcepta
aq_sandbox_SandboxSolo mode: "test" y redes de prueba
aq_live_LiveSolo mode: "live" y mainnets

En el dashboard, el formulario de la key te pide el entorno (Sandbox por defecto). Por la API, mandá "environment": "sandbox" o "environment": "live" a POST /api/v1/organizations/{organizationId}/api-keys; por defecto es sandbox, o el entorno de la key que hace el request si es una key de Sandbox o de Live. Una key no puede crear una key del otro entorno: eso responde 403 API_KEY_ENVIRONMENT_MISMATCH.

Todo request bajo /api/v1/crypto hecho con la key se queda en su entorno:

  • Si omitís el parámetro de query mode, toma el entorno de la key: una key de Sandbox lista las facturas de Sandbox sin ?mode=test.
  • Una factura creada sin network ni mode se crea en el entorno de la key.
  • Un mode, un network o una red de los accepted_pairs de un payment link del otro entorno responde 403 API_KEY_ENVIRONMENT_MISMATCH, y no se crea nada.
  • Una factura, un payment link o un payout del otro entorno, leído, anulado o editado por ID, responde 404 NOT_FOUND, como si no existiera.

Los datos nunca cruzan de entorno: una factura de Sandbox nunca aparece en Live, y los saldos de Sandbox no se pueden pagar a una mainnet.

Keys legacy. Las keys creadas antes de que existieran los entornos empiezan con fk_live_ y no están atadas a ninguno: funcionan en los dos, y cada request elige su entorno como se explica en Sandbox y Live en los requests (los listados usan live por defecto). El dashboard las muestra como "Legacy · ambos entornos". Reemplazalas por una key de Sandbox o de Live.

Cómo mandar la key

Mandá el secreto como bearer token en el header Authorization:

curl "https://api.aliquot.cc/api/v1/crypto/invoices?mode=test" \
  -H "Authorization: Bearer $ALIQUOT_API_KEY"

Sin key, la respuesta es 401 UNAUTHORIZED. Una key inválida, revocada o vencida responde 401 UNAUTHORIZED con el mensaje Invalid or revoked API key. Una key válida sin el permiso que necesita un endpoint responde 403 FORBIDDEN con Missing permission: <permission>.

Los requests hechos con API keys quedan en el registro de requests: Desarrolladores → Registros en el dashboard, o GET /api/v1/crypto/requests. Cada entrada tiene el método, el path, el status, la duración, el Idempotency-Key si lo hubo, y si la respuesta fue un replay.

Permisos

EndpointPermiso
POST /api/v1/crypto/invoicescrypto-invoices:create
GET /api/v1/crypto/invoices, GET /api/v1/crypto/invoices/{id}crypto-invoices:read
POST /api/v1/crypto/invoices/{id}/voidcrypto-invoices:update
POST /api/v1/crypto/quotecrypto-invoices:read
GET /api/v1/crypto/networkscrypto-invoices:read
GET /api/v1/crypto/refundscrypto-invoices:read
GET /api/v1/crypto/overviewcrypto-invoices:read
GET /api/v1/crypto/requestscrypto-invoices:read
POST /api/v1/crypto/payment-linkscrypto-links:create
GET /api/v1/crypto/payment-links, GET /api/v1/crypto/payment-links/{id}crypto-links:read
PATCH /api/v1/crypto/payment-links/{id}crypto-links:update
POST /api/v1/crypto/accountscrypto-accounts:create
GET /api/v1/crypto/accounts, GET /api/v1/crypto/accounts/{id}crypto-accounts:read
GET /api/v1/crypto/balances, GET /api/v1/crypto/ledger/transactions, GET /api/v1/crypto/ledger/accountscrypto-ledger:read
POST /api/v1/crypto/payoutscrypto-payouts:create
GET /api/v1/crypto/payouts, GET /api/v1/crypto/payouts/{id}crypto-payouts:read
/api/v1/organizations/{organizationId}/webhooks/… (endpoints, deliveries, resend)webhooks:manage

El formulario de keys del dashboard ofrece todos los permisos de esta tabla, agrupados por recurso y cada uno con una descripción de una línea. crypto-invoices:create, crypto-invoices:read, crypto-links:create, crypto-links:read, crypto-accounts:read y crypto-ledger:read vienen preseleccionados; crypto-invoices:update, crypto-links:update, crypto-accounts:create, crypto-payouts:read, crypto-payouts:create y webhooks:manage los marcás vos.

Keys que pueden hacer payouts

Una key con crypto-payouts:create saca dinero de tus saldos sin un código por cada payout. Por eso crearla exige una verificación adicional: necesitás tener la autenticación de dos factores activada en tu usuario (Configuración → Seguridad) y un código vigente de tu app de autenticación al momento de crear la key: en el dashboard, al marcar crypto-payouts:create aparece un campo para ingresarlo; por la API, mandalo como totp_code. Sin 2FA, el request responde 422 TWO_FACTOR_NOT_ENABLED; sin un código válido, 403 STEP_UP_REQUIRED. Una key que no se creó de esta forma responde 403 STEP_UP_REQUIRED en POST /api/v1/crypto/payouts. Ver Payouts.

Solo crypto-payouts:create hace que una key pueda hacer payouts. Los permisos se comparan de forma exacta, así que crypto-payouts:manage no incluye crypto-payouts:create ni crypto-payouts:read y no da acceso a ningún endpoint de payouts.

Sandbox y Live en los requests

Sandbox (mode: "test" en la API) y Live se separan por red, no por endpoint:

  • Al crear una factura: el network que mandás decide el entorno (BASE_SEPOLIA es Sandbox, BASE_MAINNET es Live). Si dejás que el comprador elija la red, la factura toma el entorno de tu key; con una key legacy, mandá "mode": "test" o "mode": "live". Una red y un mode que no coinciden dan 422 (con una key de Sandbox o de Live, el que no coincide con la key da 403 antes).
  • Los payment links toman su entorno de sus accepted_pairs, y los payouts de su network.
  • Al leer: los endpoints de listado aceptan un parámetro de query mode, que por defecto es el entorno de tu key (live con una key legacy fk_live_). Con una key legacy, agregá mode=test para ver facturas, payouts, reembolsos, payment links, saldos y asientos del ledger de Sandbox.

Toda factura, payout y payment link trae livemode: false en Sandbox, true en Live.

Idempotencia

POST /api/v1/crypto/invoices y POST /api/v1/crypto/payouts requieren un header Idempotency-Key (1–255 caracteres). Usá un valor que identifique la operación en tu sistema, como el ID de un pedido o de un retiro, y reusalo cuando reintentes.

SituaciónRespuesta
Sin header, o con más de 255 caracteres400 IDEMPOTENCY_KEY_REQUIRED
Primer request con la keyLa respuesta normal (201)
Misma key, mismo request, el primero salió bienLa respuesta guardada, con status 200 y el header Idempotent-Replay: true
Misma key, distinto método, path o body409 IDEMPOTENCY_KEY_REUSED
Misma key mientras el primer request todavía se está procesando409 IDEMPOTENCY_IN_PROGRESS; reintentá en unos instantes

Las keys tienen alcance de organización. Dos requests cuentan como el mismo cuando coinciden el método, el path y el body JSON; el orden de las claves dentro del body no importa. Solo se guardan las respuestas exitosas (2xx): si el primer request falla, la key se libera y podés corregir el request y mandarlo otra vez con la misma key.

Errores

Todos los errores tienen la misma forma:

{
  "code": "VALIDATION_FAILED",
  "message": "mode (test | live) is required when no network is given",
  "issues": [{ "path": "mode", "message": "mode (test | live) is required when no network is given" }]
}

code es estable y está pensado para tu código; message es para personas. issues aparece en los errores de validación y apunta al campo (path usa puntos para el anidamiento, como splits.0.percent).

StatuscodeCuándo
400BAD_REQUESTEl body no es JSON válido.
400IDEMPOTENCY_KEY_REQUIREDFalta Idempotency-Key en un endpoint que lo necesita.
401UNAUTHORIZEDSin key, o con una key inválida, revocada o vencida.
403FORBIDDENA la key le falta el permiso, o la acción no está permitida.
403STEP_UP_REQUIREDLa key no se autorizó para payouts cuando se creó.
403API_KEY_ENVIRONMENT_MISMATCHUna key de Sandbox usada para Live (un mode, una red o una key nueva de Live), o una key de Live usada para el Sandbox. Ver Keys y entornos.
404NOT_FOUNDEl objeto no existe en tu organización (o, con una key de Sandbox o de Live, es del otro entorno).
409CONFLICTEl objeto está en un estado que no permite la acción (por ejemplo, anular una factura detectada), o una reference ya está tomada.
409IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_IN_PROGRESSVer Idempotencia.
409INSUFFICIENT_BALANCEUn payout supera el saldo disponible. No se creó nada.
413PAYLOAD_TOO_LARGEEl body pesa más de 1 MB.
422VALIDATION_FAILEDFalta un campo o es inválido; ver issues.
422TWO_FACTOR_NOT_ENABLEDCrear una key que puede hacer payouts sin 2FA.
429RATE_LIMITEDDemasiados requests; ver más abajo.
429STEP_UP_LOCKEDDemasiados códigos de dos factores fallidos; esperá 15 minutos.
500INTERNAL_ERRORUn error inesperado del lado de Aliquot.
503CRYPTO_NOT_CONFIGUREDLos pagos no están disponibles en el servidor.

Manejá los códigos que no reconozcas según su status HTTP.

Límites de requests

Los requests se cuentan por minuto, por separado para lecturas (GET) y escrituras (POST, PATCH, DELETE). Los valores por defecto son 300 lecturas y 60 escrituras por minuto. Los requests hechos con una API key cuentan para el usuario que creó la key; los endpoints públicos del checkout cuentan por dirección IP.

Las respuestas traen los headers estándar RateLimit y RateLimit-Policy con el límite, lo que queda y cuándo se reinicia la ventana. Por encima del límite, la API responde 429 con:

{ "code": "RATE_LIMITED", "message": "Too many requests. Try again later." }

Paginación

GET sobre facturas, payouts, reembolsos, transacciones del ledger y el registro de requests devuelve una página:

{ "items": [], "next_cursor": "inv_01JB7Q8M3X4K9TPZ2R6WVN5HDC" }

Mandá next_cursor de vuelta como cursor para obtener la página siguiente; vale null en la última página. limit va de 1 a 100 (25 por defecto; 50 para el registro de requests). Los items vienen del más nuevo al más viejo. Los demás endpoints de listado (redes, cuentas, payment links, saldos, cuentas del ledger) devuelven { "items": [...] } en una sola respuesta.

Montos e IDs

  • Los montos son strings decimales, nunca números. Los precios en USD tienen como máximo dos decimales ("100", "100.5", "100.00"); los montos en tokens son exactos, con al menos dos decimales ("102.50", "76.875").
  • Los porcentajes (markup_percent, splits[].percent) son números JSON con como máximo dos decimales (2.5 es 2.5 %).
  • Los IDs de objeto llevan un prefijo: inv_ facturas, acct_ cuentas, po_ payouts, rfd_ reembolsos, plink_ payment links, ltx_ transacciones del ledger. Se ordenan por fecha de creación.
  • Los timestamps son ISO 8601 en UTC.