{"openapi":"3.0.0","paths":{"/v1/health":{"get":{"description":"Comprobación de vida, **sin credencial**. Responde `200` mientras el proceso atienda peticiones.\n\nNo comprueba dependencias: que responda no garantiza que un cobro vaya a liquidar. Si necesitas saber si TU credencial funciona, usa `/v1/ping`, que además te dice sus alcances.\n\n**Alcance requerido:** ninguno. Basta una credencial válida — es una comprobación, y exigir un alcance para ella empujaría a emitir claves más permisivas de lo necesario.","operationId":"health","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"timestamp":{"type":"string","example":"2026-09-06T14:32:07.482Z"}}},"example":{"status":"ok","timestamp":"2026-09-06T14:32:07.482Z"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[],"summary":"¿Está la API en pie?","tags":["Cuenta"],"x-binkio-scopes":[]}},"/v1/ping":{"get":{"description":"La primera llamada que conviene hacer al integrar: confirma de punta a punta que tu credencial funciona, **contra qué entorno** estás pegando y qué alcances tiene — sin mover un peso.\n\nSi `environment` no es el que esperabas, tienes la credencial del otro entorno configurada.\n\n**Alcance requerido:** ninguno. Basta una credencial válida — es una comprobación, y exigir un alcance para ella empujaría a emitir claves más permisivas de lo necesario.","operationId":"ping","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"environment":{"type":"string","example":"live"},"api_key":{"type":"object","properties":{"id":{"type":"string","example":"7c1f0a4e-3d2b-4f9a-8b11-2e6c9d4a5f30"},"name":{"type":"string","example":"TPV sucursal Centro"},"last_four":{"type":"string","example":"x9f2"},"scopes":{"type":"array","items":{"type":"string","example":"balances:read"}}}},"account":{"type":"object","properties":{"id":{"type":"string","example":"b3d9c1a2-5e4f-4c8b-9a70-1f2e3d4c5b6a"}}},"server_time":{"type":"string","example":"2026-08-04T15:04:05.000Z"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}},"example":{"ok":true,"environment":"live","api_key":{"id":"7c1f0a4e-3d2b-4f9a-8b11-2e6c9d4a5f30","name":"TPV sucursal Centro","last_four":"x9f2","scopes":["balances:read","links:write"]},"account":{"id":"b3d9c1a2-5e4f-4c8b-9a70-1f2e3d4c5b6a"},"server_time":"2026-08-04T15:04:05.000Z","request_id":"req_9f2a4c8b7e1d3a5f"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Comprueba la credencial y devuelve la identidad autenticada","tags":["Cuenta"],"x-binkio-scopes":[]},"post":{"description":"Llama dos veces con la MISMA `Idempotency-Key` y el mismo cuerpo. Si el `execution_id` es idéntico y la segunda respuesta trae `Idempotent-Replay: true`, acabas de comprobar que tu reintento no duplicó nada. Si cambia, tu cliente ejecutó dos veces — y más vale descubrirlo aquí que con un cobro.\n\nPruébalo también con un cuerpo distinto y la misma clave: debe darte `422 idempotency_key_reused`.\n\n**Alcance requerido:** ninguno. Basta una credencial válida — es una comprobación, y exigir un alcance para ella empujaría a emitir claves más permisivas de lo necesario.\n\nExige la cabecera `Idempotency-Key`.","operationId":"ping_write","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":false,"description":"Cualquier objeto JSON. Se devuelve tal cual en `echo`, para que puedas comprobar que la MISMA clave con un cuerpo distinto da `422 idempotency_key_reused`.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Ejecución real (o repetición guardada).","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"execution_id":{"type":"string","example":"0f8c2b1a-7d6e-4c3b-9a58-1e2f3d4c5b6a"},"executed_at":{"type":"string","example":"2026-08-04T15:04:05.000Z"},"idempotency_key":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"},"echo":{"type":"object","properties":{"hola":{"type":"string","example":"mundo"}}},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}},"example":{"ok":true,"execution_id":"0f8c2b1a-7d6e-4c3b-9a58-1e2f3d4c5b6a","executed_at":"2026-08-04T15:04:05.000Z","idempotency_key":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c","echo":{"hola":"mundo"},"request_id":"req_9f2a4c8b7e1d3a5f"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Comprueba la idempotencia de extremo a extremo (no mueve dinero)","tags":["Cuenta"],"x-binkio-scopes":[]}},"/v1/balances":{"get":{"description":"Devuelve el saldo de cada activo con fondos. `available` es lo que se puede operar, `pending` lo retenido y `total` la suma — publicada ya calculada para que nadie la sume mal.\n\nLos importes son cadenas decimales de 8 decimales, la escala del libro. `as_of` dice cuándo se leyó: un saldo sin marca temporal es un dato del que no se puede decir si está viejo.\n\n**Alcance requerido:** `balances:read`.","operationId":"list_balances","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"balance_list"},"account_id":{"type":"string","example":"b3d9c1a2-5e4f-4c8b-9a70-1f2e3d4c5b6a"},"as_of":{"type":"string","example":"2026-08-04T15:04:05.000Z"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"balance"},"asset":{"type":"string","example":"MXNB"},"available":{"type":"string","example":"18450.00000000"},"pending":{"type":"string","example":"0.00000000"},"total":{"type":"string","example":"18450.00000000"}}}}}},"example":{"object":"balance_list","account_id":"b3d9c1a2-5e4f-4c8b-9a70-1f2e3d4c5b6a","as_of":"2026-08-04T15:04:05.000Z","data":[{"object":"balance","asset":"MXNB","available":"18450.00000000","pending":"0.00000000","total":"18450.00000000"}]}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Saldos de la cuenta, por activo","tags":["Cuenta"],"x-binkio-scopes":["balances:read"]}},"/v1/payment_links":{"post":{"description":"Reintentar con la misma `Idempotency-Key` devuelve el MISMO enlace, sin crear un segundo. Si no se envían `accepted_methods`, el sistema determina los métodos viables a partir de la divisa y el importe.\n\nEl `amount` es lo que **recibirá tu cuenta**. Cuando el pagador use un método en otra divisa, el importe que él debe enviar viene en `methods[].amount_due`, con su caducidad en `amount_due_expires_at`: está bloqueado contra el proveedor y un envío por otra cantidad no acredita.\n\n**Alcance requerido:** `links:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"create_payment_link","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicPaymentLinkDto"}}}},"responses":{"201":{"description":"Enlace creado.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}},"Location":{"description":"URL del recurso recién creado. Se puede seguir tal cual para consultarlo.","schema":{"type":"string","example":"/v1/payment_links/{code}"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"payment_link"},"code":{"type":"string","example":"PL-4F2A-9C8B-7E1D"},"status":{"type":"string","enum":["active","processing","paid","cancelled","expired"],"example":"active"},"amount":{"type":"string","example":"1500.00000000"},"currency":{"type":"string","example":"MXNB"},"description":{"type":"string","example":"Pedido #10432"},"metadata":{"type":"object","properties":{"order_id":{"type":"string","example":"4821"},"sucursal":{"type":"string","example":"centro"}}},"fee_bearer":{"type":"string","enum":["merchant","payer"],"example":"merchant"},"accepted_methods":{"type":"array","items":{"type":"string","example":"SPEI"}},"url":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"checkout_url":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"return_url":{"type":"string","example":"https://tutienda.com/pedido/4821/gracias","nullable":true},"qr":{"type":"object","properties":{"object":{"type":"string","example":"checkout_qr"},"format":{"type":"string","example":"svg"},"encodes":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"svg":{"type":"string","example":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"}}},"created_at":{"type":"string","example":"2026-08-04T14:30:00.000Z"},"expires_at":{"type":"string","example":"2026-08-05T14:30:00.000Z"},"paid_at":{"type":"string","nullable":true},"paid_with_method":{"type":"string","nullable":true},"methods":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"payment_link_method"},"method":{"type":"string","example":"SPEI"},"asset":{"type":"string","example":"MXN"},"requires_conversion":{"type":"boolean","example":true},"amount_due":{"type":"string","example":"1522.50"},"fee":{"type":"string","example":"0.00"},"exchange_rate":{"type":"string","example":"1.00000000"},"amount_due_expires_at":{"type":"string","example":"2026-08-04T14:45:00.000Z"},"quote_status":{"type":"string","enum":["locked","expired","native","calculating"],"example":"locked"},"instructions":{"type":"object","properties":{"clabe":{"type":"string","example":"710969000000123456"},"address":{"type":"string","example":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b"},"network":{"type":"string","example":"ARBITRUM"},"reference":{"type":"string","example":"BNK4F2A9C"},"bank":{"type":"object","properties":{"name":{"type":"string","example":"Banco Ejemplo"},"account_number":{"type":"string","example":"0000123456"},"routing_number":{"type":"string","example":"021000021"},"account_name":{"type":"string","example":"Binkio SA de CV"},"address":{"type":"string","example":"Ciudad de México, MX"}}}}}}}}}},"example":{"object":"payment_link","code":"PL-4F2A-9C8B-7E1D","status":"active","amount":"1500.00000000","currency":"MXNB","description":"Pedido #10432","metadata":{"order_id":"4821","sucursal":"centro"},"fee_bearer":"merchant","accepted_methods":["SPEI","MXNB"],"url":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","checkout_url":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","return_url":"https://tutienda.com/pedido/4821/gracias","qr":{"object":"checkout_qr","format":"svg","encodes":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"},"created_at":"2026-08-04T14:30:00.000Z","expires_at":"2026-08-05T14:30:00.000Z","paid_at":null,"paid_with_method":null,"methods":[{"object":"payment_link_method","method":"SPEI","asset":"MXN","requires_conversion":true,"amount_due":"1522.50","fee":"0.00","exchange_rate":"1.00000000","amount_due_expires_at":"2026-08-04T14:45:00.000Z","quote_status":"locked","instructions":{"clabe":"710969000000123456","address":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b","network":"ARBITRUM","reference":"BNK4F2A9C","bank":{"name":"Banco Ejemplo","account_number":"0000123456","routing_number":"021000021","account_name":"Binkio SA de CV","address":"Ciudad de México, MX"}}}]}}}},"400":{"description":"`invalid_request` — El cuerpo no valida: importe fuera de los límites de la divisa, método no admitido para ese par, o un campo con formato incorrecto. `param` dice cuál.\n\n`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_request":{"summary":"invalid_request","value":{"error":{"type":"invalid_request","code":"invalid_request","message":"El cuerpo no valida: importe fuera de los límites de la divisa, método no admitido para ese par, o un campo con formato incorrecto. `param` dice cuál.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`account_suspended` — La cuenta está suspendida. Escríbenos: no se resuelve desde la API.\n\n`account_blocked` — La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.\n\n`email_not_verified` — El correo de la cuenta no está verificado. Se hace desde el panel.\n\n`phone_not_verified` — El teléfono de la cuenta no está verificado. Se hace desde el panel.\n\n`kyb_not_started` — La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.\n\n`kyb_incomplete` — La verificación de la empresa está a medias. El panel dice qué paso falta.\n\n`kyb_pending_review` — La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.\n\n`kyc_not_started` — La persona titular no ha empezado su verificación.\n\n`kyc_incomplete` — La verificación de la persona titular está a medias.\n\n`user_not_found` — La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.\n\n`forbidden` — La cuenta no tiene la verificación de empresa aprobada, o el método pedido no está habilitado para ella.\n\n`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"account_suspended":{"summary":"account_suspended","value":{"error":{"type":"permission_error","code":"account_suspended","message":"La cuenta está suspendida. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"account_blocked":{"summary":"account_blocked","value":{"error":{"type":"permission_error","code":"account_blocked","message":"La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"email_not_verified":{"summary":"email_not_verified","value":{"error":{"type":"permission_error","code":"email_not_verified","message":"El correo de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"phone_not_verified":{"summary":"phone_not_verified","value":{"error":{"type":"permission_error","code":"phone_not_verified","message":"El teléfono de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_not_started":{"summary":"kyb_not_started","value":{"error":{"type":"permission_error","code":"kyb_not_started","message":"La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_incomplete":{"summary":"kyb_incomplete","value":{"error":{"type":"permission_error","code":"kyb_incomplete","message":"La verificación de la empresa está a medias. El panel dice qué paso falta.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_pending_review":{"summary":"kyb_pending_review","value":{"error":{"type":"permission_error","code":"kyb_pending_review","message":"La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_not_started":{"summary":"kyc_not_started","value":{"error":{"type":"permission_error","code":"kyc_not_started","message":"La persona titular no ha empezado su verificación.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_incomplete":{"summary":"kyc_incomplete","value":{"error":{"type":"permission_error","code":"kyc_incomplete","message":"La verificación de la persona titular está a medias.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"user_not_found":{"summary":"user_not_found","value":{"error":{"type":"permission_error","code":"user_not_found","message":"La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"forbidden":{"summary":"forbidden","value":{"error":{"type":"permission_error","code":"forbidden","message":"La cuenta no tiene la verificación de empresa aprobada, o el método pedido no está habilitado para ella.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Crea un enlace de pago","tags":["Enlaces de pago"],"x-binkio-scopes":["links:write"]},"get":{"description":"Devuelve los enlaces del más reciente al más antiguo. Para recorrer el histórico completo, repite la llamada pasando `next_cursor` en `cursor` mientras `has_more` sea `true`.\n\nEl listado NO trae `methods`: los importes por método salen del detalle, que es una llamada por enlace.\n\n**Alcance requerido:** `links:read`.","operationId":"list_payment_links","parameters":[{"name":"limit","required":false,"in":"query","description":"Cuántos enlaces por página.","schema":{"minimum":1,"maximum":100,"format":"int32","default":25,"example":25,"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"El `next_cursor` de la respuesta anterior, tal cual. Es opaco: no lo interpretes ni lo construyas.","schema":{"maxLength":512,"example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wOFQxNzo1ODo0Mi40MzgyMzRaIn0","type":"string"}},{"name":"status","required":false,"in":"query","description":"Devuelve sólo los enlaces en este estado.","schema":{"example":"paid","type":"string","enum":["active","processing","paid","cancelled","expired"]}},{"name":"currency","required":false,"in":"query","description":"Devuelve sólo los enlaces emitidos en esta divisa.","schema":{"example":"MXNB","type":"string","enum":["MXNB","USDC","COP"]}},{"name":"created_after","required":false,"in":"query","description":"Sólo enlaces creados en o después de esta fecha.","schema":{"format":"date-time","example":"2026-09-01T00:00:00Z","type":"string"}},{"name":"created_before","required":false,"in":"query","description":"Sólo enlaces creados en o antes de esta fecha.","schema":{"format":"date-time","example":"2026-09-01T00:00:00Z","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"payment_link"},"code":{"type":"string","example":"PL-4F2A-9C8B-7E1D"},"status":{"type":"string","enum":["active","processing","paid","cancelled","expired"],"example":"paid"},"amount":{"type":"string","example":"1500.00000000"},"currency":{"type":"string","example":"MXNB"},"description":{"type":"string","example":"Pedido #10432"},"metadata":{"type":"object","properties":{"order_id":{"type":"string","example":"4821"},"sucursal":{"type":"string","example":"centro"}}},"fee_bearer":{"type":"string","enum":["merchant","payer"],"example":"merchant"},"accepted_methods":{"type":"array","items":{"type":"string","example":"SPEI"}},"url":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"checkout_url":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"created_at":{"type":"string","example":"2026-08-04T14:30:00.000Z"},"expires_at":{"type":"string","example":"2026-08-05T14:30:00.000Z"},"paid_at":{"type":"string","example":"2026-08-04T14:41:22.000Z","nullable":true},"paid_with_method":{"type":"string","example":"SPEI","nullable":true}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"payment_link","code":"PL-4F2A-9C8B-7E1D","status":"paid","amount":"1500.00000000","currency":"MXNB","description":"Pedido #10432","metadata":{"order_id":"4821","sucursal":"centro"},"fee_bearer":"merchant","accepted_methods":["SPEI","MXNB"],"url":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","checkout_url":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","created_at":"2026-08-04T14:30:00.000Z","expires_at":"2026-08-05T14:30:00.000Z","paid_at":"2026-08-04T14:41:22.000Z","paid_with_method":"SPEI"}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`invalid_cursor` — El `cursor` no es uno nuestro. Usa el `next_cursor` de la respuesta anterior, tal cual.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_cursor":{"summary":"invalid_cursor","value":{"error":{"type":"invalid_request","code":"invalid_cursor","message":"El `cursor` no es uno nuestro. Usa el `next_cursor` de la respuesta anterior, tal cual.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Enlaces de pago de la cuenta, paginados por cursor","tags":["Enlaces de pago"],"x-binkio-scopes":["links:read"]}},"/v1/payment_links/stats":{"get":{"description":"El resumen que pinta un panel de comercio. Existe para no tener que recorrer el histórico entero: con páginas de 100, una cuenta con diez mil enlaces son cien llamadas para cuatro números.\n\nLos estados son los del contrato público, así que `processing` agrupa los enlaces cobrados que todavía se están asentando.\n\n**Alcance requerido:** `links:read`.","operationId":"get_payment_link_stats","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"payment_link_stats"},"active":{"type":"integer","example":12},"processing":{"type":"integer","example":2},"paid":{"type":"integer","example":340},"cancelled":{"type":"integer","example":7},"expired":{"type":"integer","example":23},"total":{"type":"integer","example":384}}},"example":{"object":"payment_link_stats","active":12,"processing":2,"paid":340,"cancelled":7,"expired":23,"total":384}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Cuántos enlaces hay en cada estado","tags":["Enlaces de pago"],"x-binkio-scopes":["links:read"]}},"/v1/payment_links/payment_methods":{"get":{"description":"Crear un enlace con un `accepted_methods` que el importe no soporta devuelve `400`. Los métodos de la OTRA familia de divisa exigen convertir, y la conversión tiene mínimos: un enlace de 500 MXNB no puede cobrarse en USDC.\n\nHasta ahora la única forma de saberlo por API era intentarlo y leer el error. Esto se pregunta ANTES, con el importe del carrito en la mano, y no crea ni consulta ningún enlace.\n\n**Alcance requerido:** `links:read`.","operationId":"list_payment_method_options","parameters":[{"name":"currency","required":true,"in":"query","description":"Divisa en la que recibiría la cuenta.","schema":{"example":"MXNB","type":"string","enum":["MXNB","USDC","COP"]}},{"name":"amount","required":true,"in":"query","description":"Importe que recibiría la cuenta, en esa divisa.","schema":{"pattern":"^\\d{1,12}(\\.\\d{1,8})?$","example":"50000.00","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"payment_method_options"},"currency":{"type":"string","example":"MXNB"},"amount":{"type":"string","example":"80.00"},"available_methods":{"type":"array","items":{"type":"string","example":"MXNB"}},"conversion_enabled":{"type":"boolean","example":false},"methods":{"type":"array","items":{"type":"object","properties":{"method":{"type":"string","example":"SPEI"},"available":{"type":"boolean","example":false},"requires_conversion":{"type":"boolean","example":false},"unavailable_reason":{"type":"string","example":"BELOW_FIAT_MINIMUM"},"minimum_required":{"type":"string","example":"100"}}}},"amount_limits":{"type":"object","properties":{"min_amount":{"type":"string","example":"10.00"},"max_amount":{"type":"string","example":"999999.00"}}}}},"example":{"object":"payment_method_options","currency":"MXNB","amount":"80.00","available_methods":["MXNB"],"conversion_enabled":false,"methods":[{"method":"SPEI","available":false,"requires_conversion":false,"unavailable_reason":"BELOW_FIAT_MINIMUM","minimum_required":"100"},{"method":"WIRE","available":false,"requires_conversion":true,"unavailable_reason":"BELOW_CONVERSION_THRESHOLD","minimum_required":"1800"},{"method":"MXNB","available":true,"requires_conversion":false},{"method":"USDC","available":false,"requires_conversion":true,"unavailable_reason":"BELOW_CONVERSION_THRESHOLD","minimum_required":"100"},{"method":"USDT","available":false,"requires_conversion":true,"unavailable_reason":"BELOW_CONVERSION_THRESHOLD","minimum_required":"100"}],"amount_limits":{"min_amount":"10.00","max_amount":"999999.00"}}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Con qué se puede pagar un importe, antes de crear el enlace","tags":["Enlaces de pago"],"x-binkio-scopes":["links:read"]}},"/v1/payment_links/{code}":{"get":{"description":"Devuelve lo PERSISTIDO, no una cotización nueva: el importe bloqueado tal como se guardó y su caducidad. Si venció, se dice (`quote_status: \"expired\"`) en lugar de refrescarlo por la espalda — una lectura que cambiara la CLABE que el pagador tiene delante significaría un pago llegando a una cuenta que ya nadie mira.\n\n**Alcance requerido:** `links:read`.","operationId":"get_payment_link","parameters":[{"name":"code","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"payment_link"},"code":{"type":"string","example":"PL-4F2A-9C8B-7E1D"},"status":{"type":"string","enum":["active","processing","paid","cancelled","expired"],"example":"active"},"amount":{"type":"string","example":"1500.00000000"},"currency":{"type":"string","example":"MXNB"},"description":{"type":"string","example":"Pedido #10432"},"metadata":{"type":"object","properties":{"order_id":{"type":"string","example":"4821"},"sucursal":{"type":"string","example":"centro"}}},"fee_bearer":{"type":"string","enum":["merchant","payer"],"example":"merchant"},"accepted_methods":{"type":"array","items":{"type":"string","example":"SPEI"}},"url":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"checkout_url":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"return_url":{"type":"string","example":"https://tutienda.com/pedido/4821/gracias","nullable":true},"qr":{"type":"object","properties":{"object":{"type":"string","example":"checkout_qr"},"format":{"type":"string","example":"svg"},"encodes":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"svg":{"type":"string","example":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"}}},"created_at":{"type":"string","example":"2026-08-04T14:30:00.000Z"},"expires_at":{"type":"string","example":"2026-08-05T14:30:00.000Z"},"paid_at":{"type":"string","nullable":true},"paid_with_method":{"type":"string","nullable":true},"methods":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"payment_link_method"},"method":{"type":"string","example":"SPEI"},"asset":{"type":"string","example":"MXN"},"requires_conversion":{"type":"boolean","example":true},"amount_due":{"type":"string","example":"1522.50"},"fee":{"type":"string","example":"0.00"},"exchange_rate":{"type":"string","example":"1.00000000"},"amount_due_expires_at":{"type":"string","example":"2026-08-04T14:45:00.000Z"},"quote_status":{"type":"string","enum":["locked","expired","native","calculating"],"example":"locked"},"instructions":{"type":"object","properties":{"clabe":{"type":"string","example":"710969000000123456"},"address":{"type":"string","example":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b"},"network":{"type":"string","example":"ARBITRUM"},"reference":{"type":"string","example":"BNK4F2A9C"},"bank":{"type":"object","properties":{"name":{"type":"string","example":"Banco Ejemplo"},"account_number":{"type":"string","example":"0000123456"},"routing_number":{"type":"string","example":"021000021"},"account_name":{"type":"string","example":"Binkio SA de CV"},"address":{"type":"string","example":"Ciudad de México, MX"}}}}}}}}}},"example":{"object":"payment_link","code":"PL-4F2A-9C8B-7E1D","status":"active","amount":"1500.00000000","currency":"MXNB","description":"Pedido #10432","metadata":{"order_id":"4821","sucursal":"centro"},"fee_bearer":"merchant","accepted_methods":["SPEI","MXNB"],"url":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","checkout_url":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","return_url":"https://tutienda.com/pedido/4821/gracias","qr":{"object":"checkout_qr","format":"svg","encodes":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"},"created_at":"2026-08-04T14:30:00.000Z","expires_at":"2026-08-05T14:30:00.000Z","paid_at":null,"paid_with_method":null,"methods":[{"object":"payment_link_method","method":"SPEI","asset":"MXN","requires_conversion":true,"amount_due":"1522.50","fee":"0.00","exchange_rate":"1.00000000","amount_due_expires_at":"2026-08-04T14:45:00.000Z","quote_status":"locked","instructions":{"clabe":"710969000000123456","address":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b","network":"ARBITRUM","reference":"BNK4F2A9C","bank":{"name":"Banco Ejemplo","account_number":"0000123456","routing_number":"021000021","account_name":"Binkio SA de CV","address":"Ciudad de México, MX"}}}]}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`payment_link_not_found` — No hay ningún enlace con ese código en esta cuenta. Mismo error si no existe que si es de otra cuenta: los códigos son cortos y distinguirlos convertiría el endpoint en un oráculo.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"payment_link_not_found":{"summary":"payment_link_not_found","value":{"error":{"type":"not_found","code":"payment_link_not_found","message":"No hay ningún enlace con ese código en esta cuenta. Mismo error si no existe que si es de otra cuenta: los códigos son cortos y distinguirlos convertiría el endpoint en un oráculo.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Detalle de un enlace, con el importe exacto de cada método","tags":["Enlaces de pago"],"x-binkio-scopes":["links:read"]},"delete":{"description":"Sólo se borra lo que ya no puede cobrar: un enlace `cancelled` o `expired`. Un enlace `active` hay que cancelarlo primero, y uno `paid` **no se borra nunca** — es el respaldo de un cobro que ocurrió, y en tus movimientos seguirá estando.\n\nNo se deshace.\n\n**Alcance requerido:** `links:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"delete_payment_link","parameters":[{"name":"code","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"responses":{"204":{"description":"Borrado. Sin cuerpo.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`payment_link_not_found` — No hay ningún enlace con ese código en esta cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"payment_link_not_found":{"summary":"payment_link_not_found","value":{"error":{"type":"not_found","code":"payment_link_not_found","message":"No hay ningún enlace con ese código en esta cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`payment_link_not_deletable` — El enlace todavía puede cobrar (`active`) o ya cobró (`paid`). Cancélalo primero; si ya cobró, no se borra.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"payment_link_not_deletable":{"summary":"payment_link_not_deletable","value":{"error":{"type":"conflict","code":"payment_link_not_deletable","message":"El enlace todavía puede cobrar (`active`) o ya cobró (`paid`). Cancélalo primero; si ya cobró, no se borra.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Borra un enlace cancelado o caducado","tags":["Enlaces de pago"],"x-binkio-scopes":["links:write"]}},"/v1/payment_links/{code}/qr":{"get":{"description":"Devuelve `image/svg+xml`. Codifica exactamente la misma `checkout_url` que el detalle del enlace. Sin medidas fijas: el tamaño lo decide quien lo pinta.\n\n**Alcance requerido:** `links:read`.","operationId":"get_payment_link_qr","parameters":[{"name":"code","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"El SVG del QR, sin medidas fijas.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"image/svg+xml":{"schema":{"type":"string"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"image/svg+xml":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"image/svg+xml":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"image/svg+xml":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`payment_link_not_found` — No existe ese código en tu cuenta. Es el mismo error si no existe que si es de otra cuenta.","content":{"image/svg+xml":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"payment_link_not_found":{"summary":"payment_link_not_found","value":{"error":{"type":"not_found","code":"payment_link_not_found","message":"No existe ese código en tu cuenta. Es el mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"image/svg+xml":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"image/svg+xml":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"QR de la página de cobro, como imagen SVG","tags":["Enlaces de pago"],"x-binkio-scopes":["links:read"]}},"/v1/payment_links/{code}/cancel":{"post":{"description":"Sólo se puede cancelar un enlace `active`. Cancelar uno ya cobrado, ya cancelado o caducado devuelve `409` — nunca un éxito silencioso: un 200 sobre un enlace ya pagado le diría a tu sistema que el cobro quedó anulado cuando el dinero ya está en tu saldo.\n\n**Alcance requerido:** `links:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"cancel_payment_link","parameters":[{"name":"code","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"responses":{"200":{"description":"Enlace cancelado. Devuelve su estado final.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"payment_link"},"code":{"type":"string","example":"PL-4F2A-9C8B-7E1D"},"status":{"type":"string","enum":["active","processing","paid","cancelled","expired"],"example":"active"},"amount":{"type":"string","example":"1500.00000000"},"currency":{"type":"string","example":"MXNB"},"description":{"type":"string","example":"Pedido #10432"},"metadata":{"type":"object","properties":{"order_id":{"type":"string","example":"4821"},"sucursal":{"type":"string","example":"centro"}}},"fee_bearer":{"type":"string","enum":["merchant","payer"],"example":"merchant"},"accepted_methods":{"type":"array","items":{"type":"string","example":"SPEI"}},"url":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"checkout_url":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"return_url":{"type":"string","example":"https://tutienda.com/pedido/4821/gracias","nullable":true},"qr":{"type":"object","properties":{"object":{"type":"string","example":"checkout_qr"},"format":{"type":"string","example":"svg"},"encodes":{"type":"string","example":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D"},"svg":{"type":"string","example":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"}}},"created_at":{"type":"string","example":"2026-08-04T14:30:00.000Z"},"expires_at":{"type":"string","example":"2026-08-05T14:30:00.000Z"},"paid_at":{"type":"string","nullable":true},"paid_with_method":{"type":"string","nullable":true},"methods":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"payment_link_method"},"method":{"type":"string","example":"SPEI"},"asset":{"type":"string","example":"MXN"},"requires_conversion":{"type":"boolean","example":true},"amount_due":{"type":"string","example":"1522.50"},"fee":{"type":"string","example":"0.00"},"exchange_rate":{"type":"string","example":"1.00000000"},"amount_due_expires_at":{"type":"string","example":"2026-08-04T14:45:00.000Z"},"quote_status":{"type":"string","enum":["locked","expired","native","calculating"],"example":"locked"},"instructions":{"type":"object","properties":{"clabe":{"type":"string","example":"710969000000123456"},"address":{"type":"string","example":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b"},"network":{"type":"string","example":"ARBITRUM"},"reference":{"type":"string","example":"BNK4F2A9C"},"bank":{"type":"object","properties":{"name":{"type":"string","example":"Banco Ejemplo"},"account_number":{"type":"string","example":"0000123456"},"routing_number":{"type":"string","example":"021000021"},"account_name":{"type":"string","example":"Binkio SA de CV"},"address":{"type":"string","example":"Ciudad de México, MX"}}}}}}}}}},"example":{"object":"payment_link","code":"PL-4F2A-9C8B-7E1D","status":"active","amount":"1500.00000000","currency":"MXNB","description":"Pedido #10432","metadata":{"order_id":"4821","sucursal":"centro"},"fee_bearer":"merchant","accepted_methods":["SPEI","MXNB"],"url":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","checkout_url":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","return_url":"https://tutienda.com/pedido/4821/gracias","qr":{"object":"checkout_qr","format":"svg","encodes":"https://app.binkio.com/pay/PL-4F2A-9C8B-7E1D","svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"},"created_at":"2026-08-04T14:30:00.000Z","expires_at":"2026-08-05T14:30:00.000Z","paid_at":null,"paid_with_method":null,"methods":[{"object":"payment_link_method","method":"SPEI","asset":"MXN","requires_conversion":true,"amount_due":"1522.50","fee":"0.00","exchange_rate":"1.00000000","amount_due_expires_at":"2026-08-04T14:45:00.000Z","quote_status":"locked","instructions":{"clabe":"710969000000123456","address":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b","network":"ARBITRUM","reference":"BNK4F2A9C","bank":{"name":"Banco Ejemplo","account_number":"0000123456","routing_number":"021000021","account_name":"Binkio SA de CV","address":"Ciudad de México, MX"}}}]}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`payment_link_not_found` — No hay ningún enlace con ese código en esta cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"payment_link_not_found":{"summary":"payment_link_not_found","value":{"error":{"type":"not_found","code":"payment_link_not_found","message":"No hay ningún enlace con ese código en esta cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`payment_link_not_cancellable` — El enlace ya no está activo (cobrado, cancelado o caducado). Vuelve a consultarlo para ver su estado real.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"payment_link_not_cancellable":{"summary":"payment_link_not_cancellable","value":{"error":{"type":"conflict","code":"payment_link_not_cancellable","message":"El enlace ya no está activo (cobrado, cancelado o caducado). Vuelve a consultarlo para ver su estado real.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Cancela un enlace de pago","tags":["Enlaces de pago"],"x-binkio-scopes":["links:write"]}},"/v1/qr":{"post":{"description":"Una cuenta tiene **un** QR maestro. Esta llamada lo crea; si ya hay uno, responde `409` — el que existe se consulta con `GET /v1/qr`.\n\nLos dos campos son opcionales: sin cuerpo, la divisa se deduce de los activos que la cuenta tenga aprobados.\n\nEl `id` que devuelve es lo que se va a IMPRIMIR en el cartel, y no cambia. Por eso el alta es una llamada explícita y no un efecto secundario de la primera lectura.\n\n**Alcance requerido:** `qr:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"create_qr","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicQrDto"}}}},"responses":{"201":{"description":"QR dado de alta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}},"Location":{"description":"URL del recurso recién creado. Se puede seguir tal cual para consultarlo.","schema":{"type":"string","example":"/v1/qr"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"qr"},"id":{"type":"string","example":"AShgI3mMYzIadVWN3maozr"},"status":{"type":"string","example":"active"},"currency":{"type":"string","example":"MXNB"},"display_name":{"type":"string","example":"Caja 1"},"url":{"type":"string","example":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr"},"verification_code":{"type":"string","example":"4F9C"},"max_amount_per_charge":{"type":"string","example":"5000.00000000"},"max_amount_per_day":{"type":"string","example":"50000.00000000"},"amount_paid_today":{"type":"string","example":"1250.00000000"},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"qr","id":"AShgI3mMYzIadVWN3maozr","status":"active","currency":"MXNB","display_name":"Caja 1","url":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr","verification_code":"4F9C","max_amount_per_charge":"5000.00000000","max_amount_per_day":"50000.00000000","amount_paid_today":"1250.00000000","created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`qr_already_exists` — La cuenta ya tiene su QR maestro. Consúltalo con `GET /v1/qr`.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_already_exists":{"summary":"qr_already_exists","value":{"error":{"type":"conflict","code":"qr_already_exists","message":"La cuenta ya tiene su QR maestro. Consúltalo con `GET /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Da de alta el QR maestro de la cuenta","tags":["Cobro con QR"],"x-binkio-scopes":["qr:write"]},"get":{"description":"Devuelve la URL que codifica el QR, su divisa, sus topes y cuánto se lleva cobrado hoy. No crea nada: si la cuenta todavía no tiene QR, responde 404.\n\n`verification_code` es para el mostrador: se enseña para que el pagador compruebe que el QR que escaneó es el del comercio y no una pegatina que alguien encimó.\n\n**Alcance requerido:** `qr:read`.","operationId":"get_qr","parameters":[{"name":"qr_id","required":false,"in":"query","description":"El QR sobre el que operar. Hoy la cuenta tiene uno solo y se puede omitir; mandarlo desde el principio deja la terminal preparada para cuando haya varios.","schema":{"maxLength":32,"example":"qr_7Kd93Lm2Pq8Rt5Vw1Xy4Zb","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"qr"},"id":{"type":"string","example":"AShgI3mMYzIadVWN3maozr"},"status":{"type":"string","example":"active"},"currency":{"type":"string","example":"MXNB"},"display_name":{"type":"string","example":"Caja 1"},"url":{"type":"string","example":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr"},"verification_code":{"type":"string","example":"4F9C"},"max_amount_per_charge":{"type":"string","example":"5000.00000000"},"max_amount_per_day":{"type":"string","example":"50000.00000000"},"amount_paid_today":{"type":"string","example":"1250.00000000"},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"qr","id":"AShgI3mMYzIadVWN3maozr","status":"active","currency":"MXNB","display_name":"Caja 1","url":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr","verification_code":"4F9C","max_amount_per_charge":"5000.00000000","max_amount_per_day":"50000.00000000","amount_paid_today":"1250.00000000","created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`qr_not_found` — La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_not_found":{"summary":"qr_not_found","value":{"error":{"type":"not_found","code":"qr_not_found","message":"La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Configuración del QR maestro de la cuenta","tags":["Cobro con QR"],"x-binkio-scopes":["qr:read"]},"patch":{"description":"Parcial: lo que no se envía se queda como está. Enviar `null` en un campo opcional quita el tope.\n\nLos topes son tu red de seguridad: un QR de mostrador está expuesto, y acotar el máximo por cargo acota lo que puede salir mal.\n\n**Alcance requerido:** `qr:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"update_qr","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePublicQrDto"}}}},"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"qr"},"id":{"type":"string","example":"AShgI3mMYzIadVWN3maozr"},"status":{"type":"string","example":"active"},"currency":{"type":"string","example":"MXNB"},"display_name":{"type":"string","example":"Caja 1"},"url":{"type":"string","example":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr"},"verification_code":{"type":"string","example":"4F9C"},"max_amount_per_charge":{"type":"string","example":"5000.00000000"},"max_amount_per_day":{"type":"string","example":"50000.00000000"},"amount_paid_today":{"type":"string","example":"1250.00000000"},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"qr","id":"AShgI3mMYzIadVWN3maozr","status":"active","currency":"MXNB","display_name":"Caja 1","url":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr","verification_code":"4F9C","max_amount_per_charge":"5000.00000000","max_amount_per_day":"50000.00000000","amount_paid_today":"1250.00000000","created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`qr_not_found` — La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_not_found":{"summary":"qr_not_found","value":{"error":{"type":"not_found","code":"qr_not_found","message":"La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`qr_revoked` — El QR fue revocado. No admite cambios ni cobros: hay que dar de alta otro.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_revoked":{"summary":"qr_revoked","value":{"error":{"type":"conflict","code":"qr_revoked","message":"El QR fue revocado. No admite cambios ni cobros: hay que dar de alta otro.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Actualiza la configuración del QR maestro","tags":["Cobro con QR"],"x-binkio-scopes":["qr:write"]}},"/v1/qr/pause":{"post":{"description":"Los cobros ya generados siguen su curso y se pueden pagar. Pausar uno ya pausado devuelve el mismo estado, sin error.\n\n**Alcance requerido:** `qr:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"pause_qr","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicQrRefDto"}}}},"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"qr"},"id":{"type":"string","example":"AShgI3mMYzIadVWN3maozr"},"status":{"type":"string","example":"active"},"currency":{"type":"string","example":"MXNB"},"display_name":{"type":"string","example":"Caja 1"},"url":{"type":"string","example":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr"},"verification_code":{"type":"string","example":"4F9C"},"max_amount_per_charge":{"type":"string","example":"5000.00000000"},"max_amount_per_day":{"type":"string","example":"50000.00000000"},"amount_paid_today":{"type":"string","example":"1250.00000000"},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"qr","id":"AShgI3mMYzIadVWN3maozr","status":"active","currency":"MXNB","display_name":"Caja 1","url":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr","verification_code":"4F9C","max_amount_per_charge":"5000.00000000","max_amount_per_day":"50000.00000000","amount_paid_today":"1250.00000000","created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`qr_not_found` — La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_not_found":{"summary":"qr_not_found","value":{"error":{"type":"not_found","code":"qr_not_found","message":"La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`qr_revoked` — El QR fue revocado. No admite cambios ni cobros: hay que dar de alta otro.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_revoked":{"summary":"qr_revoked","value":{"error":{"type":"conflict","code":"qr_revoked","message":"El QR fue revocado. No admite cambios ni cobros: hay que dar de alta otro.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Pausa el QR: deja de generar cobros","tags":["Cobro con QR"],"x-binkio-scopes":["qr:write"]}},"/v1/qr/resume":{"post":{"description":"Reanudar uno que ya estaba activo devuelve el mismo estado, sin error.\n\n**Alcance requerido:** `qr:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"resume_qr","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicQrRefDto"}}}},"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"qr"},"id":{"type":"string","example":"AShgI3mMYzIadVWN3maozr"},"status":{"type":"string","example":"active"},"currency":{"type":"string","example":"MXNB"},"display_name":{"type":"string","example":"Caja 1"},"url":{"type":"string","example":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr"},"verification_code":{"type":"string","example":"4F9C"},"max_amount_per_charge":{"type":"string","example":"5000.00000000"},"max_amount_per_day":{"type":"string","example":"50000.00000000"},"amount_paid_today":{"type":"string","example":"1250.00000000"},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"qr","id":"AShgI3mMYzIadVWN3maozr","status":"active","currency":"MXNB","display_name":"Caja 1","url":"https://app.binkio.com/pay/master/AShgI3mMYzIadVWN3maozr","verification_code":"4F9C","max_amount_per_charge":"5000.00000000","max_amount_per_day":"50000.00000000","amount_paid_today":"1250.00000000","created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`qr_not_found` — La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_not_found":{"summary":"qr_not_found","value":{"error":{"type":"not_found","code":"qr_not_found","message":"La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`qr_revoked` — El QR fue revocado. No admite cambios ni cobros: hay que dar de alta otro.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_revoked":{"summary":"qr_revoked","value":{"error":{"type":"conflict","code":"qr_revoked","message":"El QR fue revocado. No admite cambios ni cobros: hay que dar de alta otro.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Reanuda un QR pausado","tags":["Cobro con QR"],"x-binkio-scopes":["qr:write"]}},"/v1/qr/charges":{"post":{"description":"Crea un enlace de pago por el importe indicado, en la divisa del QR. Devuelve el enlace con su `url`: eso es lo que la terminal convierte en el QR que ve el pagador.\n\nUsa el número de ticket como `Idempotency-Key`. Si la terminal pierde la red justo al enviar y el cajero vuelve a pulsar, la misma clave devuelve el cobro original en vez de generar un segundo cargo — en un mostrador con prisa eso pasa más de lo que parece.\n\n**Alcance requerido:** `qr:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"create_qr_charge","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicQrChargeDto"}}}},"responses":{"201":{"description":"Cobro generado.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}},"Location":{"description":"URL del recurso recién creado. Se puede seguir tal cual para consultarlo.","schema":{"type":"string","example":"/v1/payment_links/{code}"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"payment_link"},"qr_id":{"type":"string","example":"AShgI3mMYzIadVWN3maozr"},"code":{"type":"string","example":"PL-7C3D-1A2B-9E4F"},"status":{"type":"string","example":"active"},"amount":{"type":"string","example":"350.50000000"},"currency":{"type":"string","example":"MXNB"},"description":{"type":"string","example":"ticket-77"},"metadata":{"type":"object","properties":{"order_id":{"type":"string","example":"4821"},"sucursal":{"type":"string","example":"centro"}}},"fee_bearer":{"type":"string","example":"merchant"},"accepted_methods":{"type":"array","items":{"type":"string","example":"SPEI"}},"url":{"type":"string","example":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F"},"checkout_url":{"type":"string","example":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F"},"created_at":{"type":"string","example":"2026-09-07T18:22:41.000Z"},"expires_at":{"type":"string","example":"2026-09-07T19:22:41.000Z"},"paid_at":{"type":"string","nullable":true},"paid_with_method":{"type":"string","nullable":true},"qr":{"type":"object","properties":{"object":{"type":"string","example":"checkout_qr"},"format":{"type":"string","example":"svg"},"encodes":{"type":"string","example":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F"},"svg":{"type":"string","example":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"}}}}},"example":{"object":"payment_link","qr_id":"AShgI3mMYzIadVWN3maozr","code":"PL-7C3D-1A2B-9E4F","status":"active","amount":"350.50000000","currency":"MXNB","description":"ticket-77","metadata":{"order_id":"4821","sucursal":"centro"},"fee_bearer":"merchant","accepted_methods":["SPEI","MXNB"],"url":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F","checkout_url":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F","created_at":"2026-09-07T18:22:41.000Z","expires_at":"2026-09-07T19:22:41.000Z","paid_at":null,"paid_with_method":null,"qr":{"object":"checkout_qr","format":"svg","encodes":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F","svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"}}}}},"400":{"description":"`qr_amount_not_positive` — El importe es cero o negativo.\n\n`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_amount_not_positive":{"summary":"qr_amount_not_positive","value":{"error":{"type":"invalid_request","code":"qr_amount_not_positive","message":"El importe es cero o negativo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`account_suspended` — La cuenta está suspendida. Escríbenos: no se resuelve desde la API.\n\n`account_blocked` — La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.\n\n`email_not_verified` — El correo de la cuenta no está verificado. Se hace desde el panel.\n\n`phone_not_verified` — El teléfono de la cuenta no está verificado. Se hace desde el panel.\n\n`kyb_not_started` — La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.\n\n`kyb_incomplete` — La verificación de la empresa está a medias. El panel dice qué paso falta.\n\n`kyb_pending_review` — La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.\n\n`kyc_not_started` — La persona titular no ha empezado su verificación.\n\n`kyc_incomplete` — La verificación de la persona titular está a medias.\n\n`user_not_found` — La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.\n\n`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"account_suspended":{"summary":"account_suspended","value":{"error":{"type":"permission_error","code":"account_suspended","message":"La cuenta está suspendida. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"account_blocked":{"summary":"account_blocked","value":{"error":{"type":"permission_error","code":"account_blocked","message":"La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"email_not_verified":{"summary":"email_not_verified","value":{"error":{"type":"permission_error","code":"email_not_verified","message":"El correo de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"phone_not_verified":{"summary":"phone_not_verified","value":{"error":{"type":"permission_error","code":"phone_not_verified","message":"El teléfono de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_not_started":{"summary":"kyb_not_started","value":{"error":{"type":"permission_error","code":"kyb_not_started","message":"La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_incomplete":{"summary":"kyb_incomplete","value":{"error":{"type":"permission_error","code":"kyb_incomplete","message":"La verificación de la empresa está a medias. El panel dice qué paso falta.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_pending_review":{"summary":"kyb_pending_review","value":{"error":{"type":"permission_error","code":"kyb_pending_review","message":"La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_not_started":{"summary":"kyc_not_started","value":{"error":{"type":"permission_error","code":"kyc_not_started","message":"La persona titular no ha empezado su verificación.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_incomplete":{"summary":"kyc_incomplete","value":{"error":{"type":"permission_error","code":"kyc_incomplete","message":"La verificación de la persona titular está a medias.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"user_not_found":{"summary":"user_not_found","value":{"error":{"type":"permission_error","code":"user_not_found","message":"La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`qr_not_found` — La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_not_found":{"summary":"qr_not_found","value":{"error":{"type":"not_found","code":"qr_not_found","message":"La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`qr_revoked` — El QR fue revocado. No admite cambios ni cobros: hay que dar de alta otro.\n\n`qr_paused` — El QR está pausado. Reanúdalo con `POST /v1/qr/resume`.\n\n`qr_amount_above_max_per_charge` — Supera el `max_amount_per_charge` que configuraste. Es TU tope, no el nuestro: se cambia con `PATCH /v1/qr`.\n\n`qr_daily_limit_reached` — Se agotó el `max_amount_per_day` que configuraste. Compara con `amount_paid_today`.\n\n`qr_too_many_pending_charges` — Demasiados cobros generados sin pagar acumulados. Deja que caduquen o cancélalos.\n\n`qr_charge_unavailable` — No se pudo generar el cobro por otro motivo. Reintenta con la misma clave; si persiste, escríbenos con el `request_id`.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_revoked":{"summary":"qr_revoked","value":{"error":{"type":"conflict","code":"qr_revoked","message":"El QR fue revocado. No admite cambios ni cobros: hay que dar de alta otro.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"qr_paused":{"summary":"qr_paused","value":{"error":{"type":"conflict","code":"qr_paused","message":"El QR está pausado. Reanúdalo con `POST /v1/qr/resume`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"qr_amount_above_max_per_charge":{"summary":"qr_amount_above_max_per_charge","value":{"error":{"type":"conflict","code":"qr_amount_above_max_per_charge","message":"Supera el `max_amount_per_charge` que configuraste. Es TU tope, no el nuestro: se cambia con `PATCH /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"qr_daily_limit_reached":{"summary":"qr_daily_limit_reached","value":{"error":{"type":"conflict","code":"qr_daily_limit_reached","message":"Se agotó el `max_amount_per_day` que configuraste. Compara con `amount_paid_today`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"qr_too_many_pending_charges":{"summary":"qr_too_many_pending_charges","value":{"error":{"type":"conflict","code":"qr_too_many_pending_charges","message":"Demasiados cobros generados sin pagar acumulados. Deja que caduquen o cancélalos.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"qr_charge_unavailable":{"summary":"qr_charge_unavailable","value":{"error":{"type":"conflict","code":"qr_charge_unavailable","message":"No se pudo generar el cobro por otro motivo. Reintenta con la misma clave; si persiste, escríbenos con el `request_id`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Genera un cobro desde el QR","tags":["Cobro con QR"],"x-binkio-scopes":["qr:write"]},"get":{"description":"Del más reciente al más antiguo. Para recorrer el histórico completo, repite la llamada pasando `next_cursor` en `cursor` mientras `has_more` sea `true`.\n\n**Alcance requerido:** `qr:read`.","operationId":"list_qr_charges","parameters":[{"name":"qr_id","required":false,"in":"query","description":"El QR sobre el que operar. Hoy la cuenta tiene uno solo y se puede omitir; mandarlo desde el principio deja la terminal preparada para cuando haya varios.","schema":{"maxLength":32,"example":"qr_7Kd93Lm2Pq8Rt5Vw1Xy4Zb","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Cuántos cobros por página.","schema":{"minimum":1,"maximum":100,"format":"int32","default":25,"example":25,"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"El `next_cursor` de la respuesta anterior, tal cual. Es opaco: no lo interpretes ni lo construyas.","schema":{"maxLength":512,"example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wOFQxNzo1ODo0Mi40MzgyMzRaIn0","type":"string"}},{"name":"status","required":false,"in":"query","description":"Devuelve sólo los cobros en este estado.","schema":{"example":"paid","type":"string","enum":["active","processing","paid","cancelled","expired"]}},{"name":"created_after","required":false,"in":"query","description":"Sólo cobros creados en o después de esta fecha.","schema":{"format":"date-time","example":"2026-09-01T00:00:00Z","type":"string"}},{"name":"created_before","required":false,"in":"query","description":"Sólo cobros creados en o antes de esta fecha.","schema":{"format":"date-time","example":"2026-09-01T00:00:00Z","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"payment_link"},"qr_id":{"type":"string","example":"AShgI3mMYzIadVWN3maozr"},"code":{"type":"string","example":"PL-7C3D-1A2B-9E4F"},"status":{"type":"string","example":"paid"},"amount":{"type":"string","example":"350.50000000"},"currency":{"type":"string","example":"MXNB"},"description":{"type":"string","example":"ticket-77"},"metadata":{"type":"object","properties":{"order_id":{"type":"string","example":"4821"},"sucursal":{"type":"string","example":"centro"}}},"fee_bearer":{"type":"string","example":"merchant"},"accepted_methods":{"type":"array","items":{"type":"string","example":"SPEI"}},"url":{"type":"string","example":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F"},"checkout_url":{"type":"string","example":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F"},"created_at":{"type":"string","example":"2026-09-07T18:22:41.000Z"},"expires_at":{"type":"string","example":"2026-09-07T19:22:41.000Z"},"paid_at":{"type":"string","example":"2026-09-07T18:24:09.000Z","nullable":true},"paid_with_method":{"type":"string","example":"SPEI","nullable":true}}}},"has_more":{"type":"boolean","example":true},"next_cursor":{"type":"string","example":"eyJpZCI6IjdjM2QxYTJiIn0","nullable":true}}},"example":{"object":"list","data":[{"object":"payment_link","qr_id":"AShgI3mMYzIadVWN3maozr","code":"PL-7C3D-1A2B-9E4F","status":"paid","amount":"350.50000000","currency":"MXNB","description":"ticket-77","metadata":{"order_id":"4821","sucursal":"centro"},"fee_bearer":"merchant","accepted_methods":["SPEI","MXNB"],"url":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F","checkout_url":"https://app.binkio.com/pay/PL-7C3D-1A2B-9E4F","created_at":"2026-09-07T18:22:41.000Z","expires_at":"2026-09-07T19:22:41.000Z","paid_at":"2026-09-07T18:24:09.000Z","paid_with_method":"SPEI"}],"has_more":true,"next_cursor":"eyJpZCI6IjdjM2QxYTJiIn0"}}}},"400":{"description":"`invalid_cursor` — El cursor no es uno nuestro. Pasa el `next_cursor` tal cual, sin decodificarlo.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_cursor":{"summary":"invalid_cursor","value":{"error":{"type":"invalid_request","code":"invalid_cursor","message":"El cursor no es uno nuestro. Pasa el `next_cursor` tal cual, sin decodificarlo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`qr_not_found` — La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_not_found":{"summary":"qr_not_found","value":{"error":{"type":"not_found","code":"qr_not_found","message":"La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Cobros generados desde el QR, paginados por cursor","tags":["Cobro con QR"],"x-binkio-scopes":["qr:read"]}},"/v1/qr/stats":{"get":{"description":"Los importes de hoy y del mes se calculan sobre lo COBRADO (no sobre lo generado) y con días UTC.\n\nLa diferencia entre generados y pagados es la que interesa vigilar: un salto ahí suele ser un problema de mostrador —el QR tapado, el cliente que se fue— no de la API.\n\n**Alcance requerido:** `qr:read`.","operationId":"get_qr_stats","parameters":[{"name":"qr_id","required":false,"in":"query","description":"El QR sobre el que operar. Hoy la cuenta tiene uno solo y se puede omitir; mandarlo desde el principio deja la terminal preparada para cuando haya varios.","schema":{"maxLength":32,"example":"qr_7Kd93Lm2Pq8Rt5Vw1Xy4Zb","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"qr_stats"},"qr_id":{"type":"string","example":"AShgI3mMYzIadVWN3maozr"},"currency":{"type":"string","example":"MXNB"},"charges_generated":{"type":"integer","example":128},"charges_paid":{"type":"integer","example":119},"charges_pending":{"type":"integer","example":9},"amount_paid_today":{"type":"string","example":"1250.00000000"},"amount_paid_this_month":{"type":"string","example":"41830.75000000"}}},"example":{"object":"qr_stats","qr_id":"AShgI3mMYzIadVWN3maozr","currency":"MXNB","charges_generated":128,"charges_paid":119,"charges_pending":9,"amount_paid_today":"1250.00000000","amount_paid_this_month":"41830.75000000"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`qr_not_found` — La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"qr_not_found":{"summary":"qr_not_found","value":{"error":{"type":"not_found","code":"qr_not_found","message":"La cuenta no tiene un QR maestro, o el `qr_id` no es suyo. Se da de alta con `POST /v1/qr`.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Cobros y montos acumulados del QR","tags":["Cobro con QR"],"x-binkio-scopes":["qr:read"]}},"/v1/transactions":{"get":{"description":"Devuelve los movimientos del más reciente al más antiguo. Para recorrer el histórico completo, repite la llamada pasando `next_cursor` en `cursor` mientras `has_more` sea `true`. No te guíes por el número de elementos: una página puede venir con menos de `limit` y aun así tener más movimientos detrás.\n\n**Alcance requerido:** `transactions:read`.","operationId":"list_transactions","parameters":[{"name":"limit","required":false,"in":"query","description":"Cuántos movimientos por página.","schema":{"minimum":1,"maximum":100,"format":"int32","default":25,"example":25,"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"El `next_cursor` de la respuesta anterior, tal cual. Es opaco: no lo interpretes ni lo construyas.","schema":{"maxLength":512,"example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wOFQxNzo1ODo0Mi40MzgyMzRaIn0","type":"string"}},{"name":"asset","required":false,"in":"query","description":"Código del activo: `MXNB`, `USDC`, `USDT`, `COP`…","schema":{"pattern":"^[A-Za-z0-9]{2,10}$","example":"USDC","type":"string"}},{"name":"type","required":false,"in":"query","description":"Familia de movimiento.","schema":{"example":"withdrawal","type":"string","enum":["deposit","withdrawal","conversion","payment","transfer","p2p"]}},{"name":"status","required":false,"in":"query","description":"Estado del movimiento.","schema":{"example":"completed","type":"string","enum":["pending","completed","failed"]}},{"name":"created_after","required":false,"in":"query","description":"Sólo movimientos creados en o después de esta fecha.","schema":{"format":"date-time","example":"2026-09-01T00:00:00Z","type":"string"}},{"name":"created_before","required":false,"in":"query","description":"Sólo movimientos creados en o antes de esta fecha.","schema":{"format":"date-time","example":"2026-09-01T00:00:00Z","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"transaction"},"id":{"type":"string","example":"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"},"type":{"type":"string","enum":["deposit","withdrawal","conversion","payment","transfer","p2p"],"example":"payment"},"direction":{"type":"string","enum":["credit","debit"],"example":"credit"},"status":{"type":"string","enum":["pending","completed","failed"],"example":"completed"},"amount":{"type":"string","example":"1500.00000000"},"asset":{"type":"string","example":"MXNB"},"reference":{"type":"string","example":"BNK-4F2A9C"},"created_at":{"type":"string","example":"2026-08-04T14:32:10.000Z"}}}},"has_more":{"type":"boolean","example":true},"next_cursor":{"type":"string","example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOC0wNFQxNDozMjoxMC4xMjM0NTZaIn0","nullable":true}}},"example":{"object":"list","data":[{"object":"transaction","id":"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d","type":"payment","direction":"credit","status":"completed","amount":"1500.00000000","asset":"MXNB","reference":"BNK-4F2A9C","created_at":"2026-08-04T14:32:10.000Z"}],"has_more":true,"next_cursor":"eyJ2IjoxLCJ0IjoiMjAyNi0wOC0wNFQxNDozMjoxMC4xMjM0NTZaIn0"}}}},"400":{"description":"`invalid_cursor` — El `cursor` no es uno nuestro. Usa el `next_cursor` de la respuesta anterior, tal cual.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_cursor":{"summary":"invalid_cursor","value":{"error":{"type":"invalid_request","code":"invalid_cursor","message":"El `cursor` no es uno nuestro. Usa el `next_cursor` de la respuesta anterior, tal cual.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Movimientos de la cuenta, paginados por cursor","tags":["Movimientos"],"x-binkio-scopes":["transactions:read"]}},"/v1/transactions/{id}":{"get":{"description":"Añade al movimiento su comisión, su tasa y —cuando aplica— la red y el hash on-chain.\n\nLos campos opcionales se **omiten** cuando no aplican, en lugar de venir a `null`: un `\"fee\": null` obliga a cada cliente a distinguir «no hubo comisión» de «no lo sabemos», y casi ninguno lo hace bien.\n\nNo se publican los datos del tercero (destino de un retiro, quién pagó un enlace): que la operación sea de tu cuenta no los convierte en tuyos.\n\n**Alcance requerido:** `transactions:read`.","operationId":"get_transaction","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"transaction"},"id":{"type":"string","example":"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"},"type":{"type":"string","enum":["deposit","withdrawal","conversion","payment","transfer","p2p"],"example":"conversion"},"direction":{"type":"string","enum":["credit","debit"],"example":"debit"},"status":{"type":"string","enum":["pending","completed","failed"],"example":"completed"},"amount":{"type":"string","example":"1500.00000000"},"asset":{"type":"string","example":"MXNB"},"reference":{"type":"string","example":"BNK-4F2A9C"},"created_at":{"type":"string","example":"2026-08-04T14:32:10.000Z"},"completed_at":{"type":"string","example":"2026-08-04T14:32:44.000Z","nullable":true},"fee":{"type":"string","example":"12.50000000"},"net_amount":{"type":"string","example":"1487.50000000"},"exchange_rate":{"type":"string","example":"17.42000000"},"from_asset":{"type":"string","example":"MXNB"},"to_asset":{"type":"string","example":"USDC"},"from_amount":{"type":"string","example":"1500.00000000"},"to_amount":{"type":"string","example":"85.39000000","nullable":true},"network":{"type":"string","example":"ARBITRUM"},"tx_hash":{"type":"string","example":"0x4f2a9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f"},"payment_link_code":{"type":"string","example":"PL-4F2A-9C8B-7E1D"},"travel_rule_applied":{"type":"boolean","example":false}}},"example":{"object":"transaction","id":"1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d","type":"conversion","direction":"debit","status":"completed","amount":"1500.00000000","asset":"MXNB","reference":"BNK-4F2A9C","created_at":"2026-08-04T14:32:10.000Z","completed_at":"2026-08-04T14:32:44.000Z","fee":"12.50000000","net_amount":"1487.50000000","exchange_rate":"17.42000000","from_asset":"MXNB","to_asset":"USDC","from_amount":"1500.00000000","to_amount":"85.39000000","network":"ARBITRUM","tx_hash":"0x4f2a9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f","payment_link_code":"PL-4F2A-9C8B-7E1D","travel_rule_applied":false}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`transaction_not_found` — No hay ningún movimiento con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"transaction_not_found":{"summary":"transaction_not_found","value":{"error":{"type":"not_found","code":"transaction_not_found","message":"No hay ningún movimiento con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Detalle de un movimiento","tags":["Movimientos"],"x-binkio-scopes":["transactions:read"]}},"/v1/request_logs":{"get":{"description":"Devuelve las llamadas de la más reciente a la más antigua, de **todas** las credenciales de la cuenta. Para recorrer el histórico, repite la llamada pasando `next_cursor` en `cursor` mientras `has_more` sea `true`.\n\nEs el primer sitio donde mirar antes de abrir un ticket: si tu llamada no aparece aquí, no nos llegó.\n\nOjo con dos campos que se parecen: `call_request_id` es el `req_…` de la llamada REGISTRADA (el que abres en un ticket) y `request_id`, al nivel de la respuesta, es el de esta consulta.\n\n**Alcance requerido:** `logs:read`.","operationId":"list_request_logs","parameters":[{"name":"limit","required":false,"in":"query","description":"Cuántas llamadas por página.","schema":{"minimum":1,"maximum":100,"format":"int32","default":25,"example":25,"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"El `next_cursor` de la respuesta anterior, tal cual. Es opaco: no lo interpretes ni lo construyas.","schema":{"maxLength":512,"example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wOFQxNzo1ODo0Mi40MzgyMzRaIn0","type":"string"}},{"name":"api_key_id","required":false,"in":"query","description":"Sólo las llamadas hechas con ESTA credencial.","schema":{"format":"uuid","example":"d41f8a2c-9b73-4e15-a6c8-3f0e7b2d1a94","type":"string"}},{"name":"method","required":false,"in":"query","description":"Sólo las llamadas con este método HTTP.","schema":{"example":"POST","type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]}},{"name":"status","required":false,"in":"query","description":"Código HTTP exacto.","schema":{"minimum":100,"maximum":599,"format":"int32","example":429,"type":"number"}},{"name":"failed","required":false,"in":"query","description":"`true` devuelve sólo las llamadas que fallaron (400 o más); `false`, sólo las correctas.","schema":{"example":true,"type":"boolean"}},{"name":"created_after","required":false,"in":"query","description":"Sólo llamadas hechas en o después de esta fecha.","schema":{"format":"date-time","example":"2026-09-01T00:00:00Z","type":"string"}},{"name":"created_before","required":false,"in":"query","description":"Sólo llamadas hechas en o antes de esta fecha.","schema":{"format":"date-time","example":"2026-09-01T00:00:00Z","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"request_log"},"id":{"type":"string","example":"5c4b3a2f-1e0d-4c9b-8a76-5f4e3d2c1b0a"},"call_request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"},"api_key_id":{"type":"string","example":"7c1f0a4e-3d2b-4f9a-8b11-2e6c9d4a5f30"},"method":{"type":"string","example":"POST"},"path":{"type":"string","example":"/v1/payment_links"},"status":{"type":"integer","example":201},"error_code":{"type":"string","nullable":true},"duration_ms":{"type":"integer","example":184},"ip":{"type":"string","example":"187.190.12.44"},"idempotency_key":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"},"idempotent_replay":{"type":"boolean","example":false},"created_at":{"type":"string","example":"2026-08-04T14:30:00.000Z"}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"request_log","id":"5c4b3a2f-1e0d-4c9b-8a76-5f4e3d2c1b0a","call_request_id":"req_9f2a4c8b7e1d3a5f","api_key_id":"7c1f0a4e-3d2b-4f9a-8b11-2e6c9d4a5f30","method":"POST","path":"/v1/payment_links","status":201,"error_code":null,"duration_ms":184,"ip":"187.190.12.44","idempotency_key":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c","idempotent_replay":false,"created_at":"2026-08-04T14:30:00.000Z"}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`invalid_cursor` — El `cursor` no es uno nuestro. Usa el `next_cursor` de la respuesta anterior, tal cual.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_cursor":{"summary":"invalid_cursor","value":{"error":{"type":"invalid_request","code":"invalid_cursor","message":"El `cursor` no es uno nuestro. Usa el `next_cursor` de la respuesta anterior, tal cual.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Tus llamadas a la API, paginadas por cursor","tags":["Registro de llamadas"],"x-binkio-scopes":["logs:read"]}},"/v1/request_logs/{id}":{"get":{"description":"Añade al listado los parámetros y el **cuerpo** de la petición, redactados: los campos con nombre sensible (contraseñas, secretos, firmas, tarjetas) salen como `[REDACTED]` y los valores muy largos, truncados.\n\nEl cuerpo de la RESPUESTA no se guarda: lo que se conserva es `status` y `error_code`, que es lo que necesitas para decidir qué hacer.\n\n**Alcance requerido:** `logs:read`.","operationId":"get_request_log","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"request_log"},"id":{"type":"string","example":"5c4b3a2f-1e0d-4c9b-8a76-5f4e3d2c1b0a"},"call_request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"},"api_key_id":{"type":"string","example":"7c1f0a4e-3d2b-4f9a-8b11-2e6c9d4a5f30"},"method":{"type":"string","example":"POST"},"path":{"type":"string","example":"/v1/payment_links"},"status":{"type":"integer","example":422},"error_code":{"type":"string","example":"idempotency_key_reused","nullable":true},"duration_ms":{"type":"integer","example":41},"ip":{"type":"string","example":"187.190.12.44"},"idempotency_key":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"},"idempotent_replay":{"type":"boolean","example":false},"created_at":{"type":"string","example":"2026-08-04T14:30:00.000Z"},"query":{"type":"object","properties":{}},"request_body":{"type":"object","properties":{"amount":{"type":"string","example":"1500.00"},"currency":{"type":"string","example":"MXNB"},"description":{"type":"string","example":"Pedido #10432"},"webhook_secret":{"type":"string","example":"[REDACTED]"}}},"user_agent":{"type":"string","example":"binkio-node/1.4.2"}}},"example":{"object":"request_log","id":"5c4b3a2f-1e0d-4c9b-8a76-5f4e3d2c1b0a","call_request_id":"req_9f2a4c8b7e1d3a5f","api_key_id":"7c1f0a4e-3d2b-4f9a-8b11-2e6c9d4a5f30","method":"POST","path":"/v1/payment_links","status":422,"error_code":"idempotency_key_reused","duration_ms":41,"ip":"187.190.12.44","idempotency_key":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c","idempotent_replay":false,"created_at":"2026-08-04T14:30:00.000Z","query":{},"request_body":{"amount":"1500.00","currency":"MXNB","description":"Pedido #10432","webhook_secret":"[REDACTED]"},"user_agent":"binkio-node/1.4.2"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`request_log_not_found` — No hay ninguna llamada con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"request_log_not_found":{"summary":"request_log_not_found","value":{"error":{"type":"not_found","code":"request_log_not_found","message":"No hay ninguna llamada con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Detalle de una llamada, con lo que mandaste","tags":["Registro de llamadas"],"x-binkio-scopes":["logs:read"]}},"/v1/webhook_endpoints/event_types":{"get":{"description":"El catálogo completo, con los campos que viajan en `data` de cada uno. Esa lista de campos es la **lista blanca real**: no llega nada más, ni aunque el evento interno tenga más datos.\n\nPídelo antes de crear un destino en vez de escribir los tipos a mano: un evento mal escrito se rechaza con 400, no en silencio.\n\n**Alcance requerido:** `webhooks:manage`.","operationId":"list_webhook_event_types","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"webhook_event_type"},"type":{"type":"string","example":"payment_link.paid"},"description":{"type":"string","example":"Un enlace de pago se pagó por completo. `code` y `amount` son los mismos que devuelve `GET /v1/payment_links/{code}`: el importe que el comercio le puso al enlace. `net_amount` es lo que acabó en su saldo, ya sin comisión ni IVA, y `net_currency` el activo en que se acreditó (puede no ser la moneda del enlace). `link_code` es un alias en desuso de `code`; se sigue mandando por compatibilidad."},"fields":{"type":"array","items":{"type":"string","example":"code"}}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"webhook_event_type","type":"payment_link.paid","description":"Un enlace de pago se pagó por completo. `code` y `amount` son los mismos que devuelve `GET /v1/payment_links/{code}`: el importe que el comercio le puso al enlace. `net_amount` es lo que acabó en su saldo, ya sin comisión ni IVA, y `net_currency` el activo en que se acreditó (puede no ser la moneda del enlace). `link_code` es un alias en desuso de `code`; se sigue mandando por compatibilidad.","fields":["code","link_code","amount","currency","net_amount","net_currency","payment_method","metadata"]},{"object":"webhook_event_type","type":"deposit.completed","description":"Un depósito se confirmó y se abonó al saldo.","fields":["deposit_id","amount","asset","method"]}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Eventos a los que puedes suscribirte","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]}},"/v1/webhook_endpoints":{"get":{"description":"Del más reciente al más antiguo. Sin paginar: el tope por cuenta son 10 destinos, así que la lista cabe siempre en una respuesta.\n\nNunca incluye el secreto de firma, sólo sus últimos cuatro caracteres.\n\n**Alcance requerido:** `webhooks:manage`.","operationId":"list_webhook_endpoints","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"webhook_endpoint"},"id":{"type":"string","example":"3e8b1d24-6f70-4c19-b2a5-0d9e7f4c6a13"},"url":{"type":"string","example":"https://api.mitienda.mx/binkio/webhooks"},"description":{"type":"string","example":"Producción"},"enabled_events":{"type":"array","items":{"type":"string","example":"payment_link.paid"}},"secret_last_four":{"type":"string","example":"4f9c"},"enabled":{"type":"boolean","example":true},"live":{"type":"boolean","example":true},"disabled_at":{"type":"string","nullable":true},"disabled_reason":{"type":"string","nullable":true},"consecutive_failures":{"type":"integer","example":0},"last_success_at":{"type":"string","example":"2026-09-01T14:22:10.000Z","nullable":true},"last_failure_at":{"type":"string","nullable":true},"secret_rotated_at":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"webhook_endpoint","id":"3e8b1d24-6f70-4c19-b2a5-0d9e7f4c6a13","url":"https://api.mitienda.mx/binkio/webhooks","description":"Producción","enabled_events":["payment_link.paid"],"secret_last_four":"4f9c","enabled":true,"live":true,"disabled_at":null,"disabled_reason":null,"consecutive_failures":0,"last_success_at":"2026-09-01T14:22:10.000Z","last_failure_at":null,"secret_rotated_at":null,"created_at":"2026-06-14T11:05:23.000Z"}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Tus destinos de webhooks","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]},"post":{"description":"Única respuesta, junto con la rotación, que incluye `signing_secret`. **Se muestra una sola vez**: guárdalo al recibirlo, porque no se puede recuperar y perderlo obliga a rotar.\n\nCon él verificas cada envío: la firma es un HMAC-SHA256 sobre el momento y el cuerpo tal cual llegó. El contrato completo está en la guía de webhooks enlazada en la portada.\n\nEl destino nace **encendido**.\n\n**Alcance requerido:** `webhooks:manage`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"create_webhook_endpoint","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicWebhookEndpointDto"}}}},"responses":{"201":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}},"Location":{"description":"URL del recurso recién creado. Se puede seguir tal cual para consultarlo.","schema":{"type":"string","example":"/v1/webhook_endpoints/{id}"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"webhook_endpoint"},"id":{"type":"string","example":"3e8b1d24-6f70-4c19-b2a5-0d9e7f4c6a13"},"url":{"type":"string","example":"https://api.mitienda.mx/binkio/webhooks"},"description":{"type":"string","example":"Producción"},"enabled_events":{"type":"array","items":{"type":"string","example":"payment_link.paid"}},"secret_last_four":{"type":"string","example":"4f9c"},"enabled":{"type":"boolean","example":true},"live":{"type":"boolean","example":true},"disabled_at":{"type":"string","nullable":true},"disabled_reason":{"type":"string","nullable":true},"consecutive_failures":{"type":"integer","example":0},"last_success_at":{"type":"string","nullable":true},"last_failure_at":{"type":"string","nullable":true},"secret_rotated_at":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-01T10:00:00.000Z"},"signing_secret":{"type":"string","example":"whsec_7f3a9c2e5b1d8a406c93e2f7b5a1d4c8"}}},"example":{"object":"webhook_endpoint","id":"3e8b1d24-6f70-4c19-b2a5-0d9e7f4c6a13","url":"https://api.mitienda.mx/binkio/webhooks","description":"Producción","enabled_events":["payment_link.paid","deposit.completed"],"secret_last_four":"4f9c","enabled":true,"live":true,"disabled_at":null,"disabled_reason":null,"consecutive_failures":0,"last_success_at":null,"last_failure_at":null,"secret_rotated_at":null,"created_at":"2026-09-01T10:00:00.000Z","signing_secret":"whsec_7f3a9c2e5b1d8a406c93e2f7b5a1d4c8"}}}},"400":{"description":"`webhook_url_invalid_url` — La URL no se puede interpretar. Mándala completa, con esquema y nombre de servidor.\n\n`webhook_url_not_https` — La URL no es `https`. El secreto firma el cuerpo, no lo cifra: sobre `http` el importe de un cobro viaja en claro.\n\n`webhook_url_embedded_credentials` — La URL lleva usuario y contraseña dentro (`https://usuario:clave@…`). Quedarían guardadas en claro: autentícanos con una cabecera o un parámetro que tú valides.\n\n`webhook_url_private_host` — El nombre resuelve a una IP privada, de bucle o de enlace local. No podemos llamar a tu red interna.\n\n`webhook_url_dns_failure` — El nombre no resuelve. Comprueba el DNS antes de volver a intentarlo.\n\n`webhook_events_unknown` — Alguno de los `enabled_events` no está en el catálogo. Consúltalo en `GET /v1/webhook_endpoints/event_types`.\n\n`webhook_endpoints_limit_reached` — Ya tienes 10 destinos, que es el tope por cuenta. Da de baja alguno antes de añadir otro.\n\n`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_url_invalid_url":{"summary":"webhook_url_invalid_url","value":{"error":{"type":"invalid_request","code":"webhook_url_invalid_url","message":"La URL no se puede interpretar. Mándala completa, con esquema y nombre de servidor.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_url_not_https":{"summary":"webhook_url_not_https","value":{"error":{"type":"invalid_request","code":"webhook_url_not_https","message":"La URL no es `https`. El secreto firma el cuerpo, no lo cifra: sobre `http` el importe de un cobro viaja en claro.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_url_embedded_credentials":{"summary":"webhook_url_embedded_credentials","value":{"error":{"type":"invalid_request","code":"webhook_url_embedded_credentials","message":"La URL lleva usuario y contraseña dentro (`https://usuario:clave@…`). Quedarían guardadas en claro: autentícanos con una cabecera o un parámetro que tú valides.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_url_private_host":{"summary":"webhook_url_private_host","value":{"error":{"type":"invalid_request","code":"webhook_url_private_host","message":"El nombre resuelve a una IP privada, de bucle o de enlace local. No podemos llamar a tu red interna.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_url_dns_failure":{"summary":"webhook_url_dns_failure","value":{"error":{"type":"invalid_request","code":"webhook_url_dns_failure","message":"El nombre no resuelve. Comprueba el DNS antes de volver a intentarlo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_events_unknown":{"summary":"webhook_events_unknown","value":{"error":{"type":"invalid_request","code":"webhook_events_unknown","message":"Alguno de los `enabled_events` no está en el catálogo. Consúltalo en `GET /v1/webhook_endpoints/event_types`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_endpoints_limit_reached":{"summary":"webhook_endpoints_limit_reached","value":{"error":{"type":"invalid_request","code":"webhook_endpoints_limit_reached","message":"Ya tienes 10 destinos, que es el tope por cuenta. Da de baja alguno antes de añadir otro.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Registra un destino","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]}},"/v1/webhook_endpoints/{id}":{"get":{"description":"Útil para releer el estado sin descargarte la lista entera: `live` te dice si ahora mismo estás recibiendo avisos, y `disabled_reason` por qué no, si lo hemos apagado nosotros.\n\n**Alcance requerido:** `webhooks:manage`.","operationId":"get_webhook_endpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"webhook_endpoint"},"id":{"type":"string","example":"9a1f7c3e-2b4d-4a68-9e05-7c1b3d5a8f24"},"url":{"type":"string","example":"https://api.mitienda.mx/binkio/webhooks"},"description":{"type":"string","example":"Producción"},"enabled_events":{"type":"array","items":{"type":"string","example":"payment_link.paid"}},"secret_last_four":{"type":"string","example":"4f9c"},"enabled":{"type":"boolean","example":true},"live":{"type":"boolean","example":false},"disabled_at":{"type":"string","example":"2026-08-30T09:12:44.000Z","nullable":true},"disabled_reason":{"type":"string","example":"5 entregas agotadas seguidas","nullable":true},"consecutive_failures":{"type":"integer","example":5},"last_success_at":{"type":"string","example":"2026-08-29T18:41:02.000Z","nullable":true},"last_failure_at":{"type":"string","example":"2026-08-30T09:12:44.000Z","nullable":true},"secret_rotated_at":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"webhook_endpoint","id":"9a1f7c3e-2b4d-4a68-9e05-7c1b3d5a8f24","url":"https://api.mitienda.mx/binkio/webhooks","description":"Producción","enabled_events":["payment_link.paid","deposit.completed"],"secret_last_four":"4f9c","enabled":true,"live":false,"disabled_at":"2026-08-30T09:12:44.000Z","disabled_reason":"5 entregas agotadas seguidas","consecutive_failures":5,"last_success_at":"2026-08-29T18:41:02.000Z","last_failure_at":"2026-08-30T09:12:44.000Z","secret_rotated_at":null,"created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`webhook_endpoint_not_found` — No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_endpoint_not_found":{"summary":"webhook_endpoint_not_found","value":{"error":{"type":"not_found","code":"webhook_endpoint_not_found","message":"No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Un destino","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]},"patch":{"description":"Parcial: lo que no mandes, no se toca. El secreto de firma **no cambia** — para eso está la rotación.\n\nUna `description` vacía la borra; omitirla la deja como estaba.\n\n**Alcance requerido:** `webhooks:manage`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"update_webhook_endpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePublicWebhookEndpointDto"}}}},"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"webhook_endpoint"},"id":{"type":"string","example":"9a1f7c3e-2b4d-4a68-9e05-7c1b3d5a8f24"},"url":{"type":"string","example":"https://api.mitienda.mx/binkio/webhooks"},"description":{"type":"string","example":"Producción"},"enabled_events":{"type":"array","items":{"type":"string","example":"payment_link.paid"}},"secret_last_four":{"type":"string","example":"4f9c"},"enabled":{"type":"boolean","example":true},"live":{"type":"boolean","example":false},"disabled_at":{"type":"string","example":"2026-08-30T09:12:44.000Z","nullable":true},"disabled_reason":{"type":"string","example":"5 entregas agotadas seguidas","nullable":true},"consecutive_failures":{"type":"integer","example":5},"last_success_at":{"type":"string","example":"2026-08-29T18:41:02.000Z","nullable":true},"last_failure_at":{"type":"string","example":"2026-08-30T09:12:44.000Z","nullable":true},"secret_rotated_at":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"webhook_endpoint","id":"9a1f7c3e-2b4d-4a68-9e05-7c1b3d5a8f24","url":"https://api.mitienda.mx/binkio/webhooks","description":"Producción","enabled_events":["payment_link.paid","deposit.completed"],"secret_last_four":"4f9c","enabled":true,"live":false,"disabled_at":"2026-08-30T09:12:44.000Z","disabled_reason":"5 entregas agotadas seguidas","consecutive_failures":5,"last_success_at":"2026-08-29T18:41:02.000Z","last_failure_at":"2026-08-30T09:12:44.000Z","secret_rotated_at":null,"created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`webhook_url_invalid_url` — La URL no se puede interpretar. Mándala completa, con esquema y nombre de servidor.\n\n`webhook_url_not_https` — La URL no es `https`. El secreto firma el cuerpo, no lo cifra: sobre `http` el importe de un cobro viaja en claro.\n\n`webhook_url_embedded_credentials` — La URL lleva usuario y contraseña dentro (`https://usuario:clave@…`). Quedarían guardadas en claro: autentícanos con una cabecera o un parámetro que tú valides.\n\n`webhook_url_private_host` — El nombre resuelve a una IP privada, de bucle o de enlace local. No podemos llamar a tu red interna.\n\n`webhook_url_dns_failure` — El nombre no resuelve. Comprueba el DNS antes de volver a intentarlo.\n\n`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_url_invalid_url":{"summary":"webhook_url_invalid_url","value":{"error":{"type":"invalid_request","code":"webhook_url_invalid_url","message":"La URL no se puede interpretar. Mándala completa, con esquema y nombre de servidor.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_url_not_https":{"summary":"webhook_url_not_https","value":{"error":{"type":"invalid_request","code":"webhook_url_not_https","message":"La URL no es `https`. El secreto firma el cuerpo, no lo cifra: sobre `http` el importe de un cobro viaja en claro.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_url_embedded_credentials":{"summary":"webhook_url_embedded_credentials","value":{"error":{"type":"invalid_request","code":"webhook_url_embedded_credentials","message":"La URL lleva usuario y contraseña dentro (`https://usuario:clave@…`). Quedarían guardadas en claro: autentícanos con una cabecera o un parámetro que tú valides.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_url_private_host":{"summary":"webhook_url_private_host","value":{"error":{"type":"invalid_request","code":"webhook_url_private_host","message":"El nombre resuelve a una IP privada, de bucle o de enlace local. No podemos llamar a tu red interna.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"webhook_url_dns_failure":{"summary":"webhook_url_dns_failure","value":{"error":{"type":"invalid_request","code":"webhook_url_dns_failure","message":"El nombre no resuelve. Comprueba el DNS antes de volver a intentarlo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`webhook_endpoint_not_found` — No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_endpoint_not_found":{"summary":"webhook_endpoint_not_found","value":{"error":{"type":"not_found","code":"webhook_endpoint_not_found","message":"No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Cambia la URL, la descripción o los eventos","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]},"delete":{"description":"Dejamos de avisar a esa URL y su secreto se pierde. No se deshace.\n\nSi sólo quieres dejar de recibir un rato, usa `/disable`: conserva el destino, su secreto y sus eventos.\n\n**Alcance requerido:** `webhooks:manage`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"delete_webhook_endpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"responses":{"204":{"description":"Dado de baja. Sin cuerpo.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`webhook_endpoint_not_found` — No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_endpoint_not_found":{"summary":"webhook_endpoint_not_found","value":{"error":{"type":"not_found","code":"webhook_endpoint_not_found","message":"No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Da de baja el destino","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]}},"/v1/webhook_endpoints/{id}/enable":{"post":{"description":"Además del interruptor, **limpia la desactivación automática y su contador de fallos**. Por eso encender y apagar son dos operaciones y no un campo booleano: no son la misma al revés.\n\nSi lo apagamos nosotros porque tu servidor rechazaba los envíos, arréglalo antes de encenderlo: si sigue rechazando, se vuelve a apagar.\n\n**Alcance requerido:** `webhooks:manage`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"enable_webhook_endpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"webhook_endpoint"},"id":{"type":"string","example":"9a1f7c3e-2b4d-4a68-9e05-7c1b3d5a8f24"},"url":{"type":"string","example":"https://api.mitienda.mx/binkio/webhooks"},"description":{"type":"string","example":"Producción"},"enabled_events":{"type":"array","items":{"type":"string","example":"payment_link.paid"}},"secret_last_four":{"type":"string","example":"4f9c"},"enabled":{"type":"boolean","example":true},"live":{"type":"boolean","example":false},"disabled_at":{"type":"string","example":"2026-08-30T09:12:44.000Z","nullable":true},"disabled_reason":{"type":"string","example":"5 entregas agotadas seguidas","nullable":true},"consecutive_failures":{"type":"integer","example":5},"last_success_at":{"type":"string","example":"2026-08-29T18:41:02.000Z","nullable":true},"last_failure_at":{"type":"string","example":"2026-08-30T09:12:44.000Z","nullable":true},"secret_rotated_at":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"webhook_endpoint","id":"9a1f7c3e-2b4d-4a68-9e05-7c1b3d5a8f24","url":"https://api.mitienda.mx/binkio/webhooks","description":"Producción","enabled_events":["payment_link.paid","deposit.completed"],"secret_last_four":"4f9c","enabled":true,"live":false,"disabled_at":"2026-08-30T09:12:44.000Z","disabled_reason":"5 entregas agotadas seguidas","consecutive_failures":5,"last_success_at":"2026-08-29T18:41:02.000Z","last_failure_at":"2026-08-30T09:12:44.000Z","secret_rotated_at":null,"created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`webhook_endpoint_not_found` — No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_endpoint_not_found":{"summary":"webhook_endpoint_not_found","value":{"error":{"type":"not_found","code":"webhook_endpoint_not_found","message":"No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Enciende el destino","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]}},"/v1/webhook_endpoints/{id}/disable":{"post":{"description":"Deja de recibir avisos conservando el destino, su secreto y sus eventos. Es lo que quieres durante un mantenimiento: dar de baja y volver a crear cambiaría el secreto.\n\n**Alcance requerido:** `webhooks:manage`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"disable_webhook_endpoint","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"webhook_endpoint"},"id":{"type":"string","example":"9a1f7c3e-2b4d-4a68-9e05-7c1b3d5a8f24"},"url":{"type":"string","example":"https://api.mitienda.mx/binkio/webhooks"},"description":{"type":"string","example":"Producción"},"enabled_events":{"type":"array","items":{"type":"string","example":"payment_link.paid"}},"secret_last_four":{"type":"string","example":"4f9c"},"enabled":{"type":"boolean","example":true},"live":{"type":"boolean","example":false},"disabled_at":{"type":"string","example":"2026-08-30T09:12:44.000Z","nullable":true},"disabled_reason":{"type":"string","example":"5 entregas agotadas seguidas","nullable":true},"consecutive_failures":{"type":"integer","example":5},"last_success_at":{"type":"string","example":"2026-08-29T18:41:02.000Z","nullable":true},"last_failure_at":{"type":"string","example":"2026-08-30T09:12:44.000Z","nullable":true},"secret_rotated_at":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-06-14T11:05:23.000Z"}}},"example":{"object":"webhook_endpoint","id":"9a1f7c3e-2b4d-4a68-9e05-7c1b3d5a8f24","url":"https://api.mitienda.mx/binkio/webhooks","description":"Producción","enabled_events":["payment_link.paid","deposit.completed"],"secret_last_four":"4f9c","enabled":true,"live":false,"disabled_at":"2026-08-30T09:12:44.000Z","disabled_reason":"5 entregas agotadas seguidas","consecutive_failures":5,"last_success_at":"2026-08-29T18:41:02.000Z","last_failure_at":"2026-08-30T09:12:44.000Z","secret_rotated_at":null,"created_at":"2026-06-14T11:05:23.000Z"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`webhook_endpoint_not_found` — No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_endpoint_not_found":{"summary":"webhook_endpoint_not_found","value":{"error":{"type":"not_found","code":"webhook_endpoint_not_found","message":"No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Apaga el destino sin darlo de baja","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]}},"/v1/webhook_endpoints/{id}/rotate_secret":{"post":{"description":"**El secreto anterior deja de valer de inmediato.** Despliega el nuevo ANTES de rotar, o firmarás con uno que tu servidor todavía no conoce: los envíos que rechace se reintentan durante horas, pero no para siempre, y cinco entregas agotadas seguidas apagan el destino.\n\nComo en el alta, el secreto se devuelve una sola vez.\n\n**Alcance requerido:** `webhooks:manage`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"rotate_webhook_endpoint_secret","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"webhook_endpoint"},"id":{"type":"string","example":"3e8b1d24-6f70-4c19-b2a5-0d9e7f4c6a13"},"url":{"type":"string","example":"https://api.mitienda.mx/binkio/webhooks"},"description":{"type":"string","example":"Producción"},"enabled_events":{"type":"array","items":{"type":"string","example":"payment_link.paid"}},"secret_last_four":{"type":"string","example":"4f9c"},"enabled":{"type":"boolean","example":true},"live":{"type":"boolean","example":true},"disabled_at":{"type":"string","nullable":true},"disabled_reason":{"type":"string","nullable":true},"consecutive_failures":{"type":"integer","example":0},"last_success_at":{"type":"string","nullable":true},"last_failure_at":{"type":"string","nullable":true},"secret_rotated_at":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-01T10:00:00.000Z"},"signing_secret":{"type":"string","example":"whsec_7f3a9c2e5b1d8a406c93e2f7b5a1d4c8"}}},"example":{"object":"webhook_endpoint","id":"3e8b1d24-6f70-4c19-b2a5-0d9e7f4c6a13","url":"https://api.mitienda.mx/binkio/webhooks","description":"Producción","enabled_events":["payment_link.paid","deposit.completed"],"secret_last_four":"4f9c","enabled":true,"live":true,"disabled_at":null,"disabled_reason":null,"consecutive_failures":0,"last_success_at":null,"last_failure_at":null,"secret_rotated_at":null,"created_at":"2026-09-01T10:00:00.000Z","signing_secret":"whsec_7f3a9c2e5b1d8a406c93e2f7b5a1d4c8"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`webhook_endpoint_not_found` — No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_endpoint_not_found":{"summary":"webhook_endpoint_not_found","value":{"error":{"type":"not_found","code":"webhook_endpoint_not_found","message":"No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Rota el secreto de firma","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]}},"/v1/webhook_endpoints/{id}/test":{"post":{"description":"Devuelve el **desenlace real**, no un acuse de que lo intentamos: si tu servidor contestó 500, aquí lo ves con su `last_status_code` y su `last_error`.\n\nEs la forma de comprobar tu verificación de firma sin esperar a que ocurra un cobro de verdad. `webhook.test` no es suscribible: se manda a este destino aunque no lo tengas en `enabled_events`.\n\n**Alcance requerido:** `webhooks:manage`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"send_webhook_endpoint_test","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"webhook_delivery"},"id":{"type":"string","example":"c7d2e491-3a58-4b6f-8102-9e4d7a3c5b60"},"endpoint_id":{"type":"string","example":"3e8b1d24-6f70-4c19-b2a5-0d9e7f4c6a13"},"event_id":{"type":"string","example":"evt_5b1d8a406c93e2f7"},"event_type":{"type":"string","example":"webhook.test"},"status":{"type":"string","enum":["pending","delivering","succeeded","failed"],"example":"failed"},"attempt_count":{"type":"integer","example":1},"attempts":{"type":"array","items":{"type":"object","properties":{"attempt":{"type":"integer","example":1},"at":{"type":"string","example":"2026-09-06T12:30:11.482Z"},"status_code":{"type":"integer","example":500,"nullable":true},"duration_ms":{"type":"integer","example":214},"error_message":{"type":"string","example":"El destino respondió 500","nullable":true}}}},"next_retry_at":{"type":"string","example":"2026-09-06T12:31:11.482Z","nullable":true},"delivered_at":{"type":"string","nullable":true},"last_status_code":{"type":"integer","example":500,"nullable":true},"last_error":{"type":"string","example":"El destino respondió 500","nullable":true},"created_at":{"type":"string","example":"2026-09-06T12:30:11.201Z"}}},"example":{"object":"webhook_delivery","id":"c7d2e491-3a58-4b6f-8102-9e4d7a3c5b60","endpoint_id":"3e8b1d24-6f70-4c19-b2a5-0d9e7f4c6a13","event_id":"evt_5b1d8a406c93e2f7","event_type":"webhook.test","status":"failed","attempt_count":1,"attempts":[{"attempt":1,"at":"2026-09-06T12:30:11.482Z","status_code":500,"duration_ms":214,"error_message":"El destino respondió 500"}],"next_retry_at":"2026-09-06T12:31:11.482Z","delivered_at":null,"last_status_code":500,"last_error":"El destino respondió 500","created_at":"2026-09-06T12:30:11.201Z"}}}},"400":{"description":"`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`webhook_endpoint_not_found` — No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_endpoint_not_found":{"summary":"webhook_endpoint_not_found","value":{"error":{"type":"not_found","code":"webhook_endpoint_not_found","message":"No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Manda un `webhook.test` firmado y te cuenta qué pasó","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]}},"/v1/webhook_endpoints/{id}/deliveries":{"get":{"description":"Del intento más reciente al más antiguo. Es lo PRIMERO que hay que mirar cuando un aviso no llega: dice si salió, cuántas veces se intentó, qué respondió tu servidor en cada intento y cuándo toca el siguiente.\n\n`status` distingue los cuatro estados reales: `pending` (en cola), `delivering` (ahora mismo), `succeeded` y `failed`. Una entrega agotada se queda en `failed` con `next_retry_at` en `null`.\n\nPara recorrer el histórico completo, repite la llamada pasando `next_cursor` en `cursor` mientras `has_more` sea `true`.\n\n**Alcance requerido:** `webhooks:manage`.","operationId":"list_webhook_endpoint_deliveries","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Cuántas entregas por página.","schema":{"minimum":1,"maximum":100,"format":"int32","default":25,"example":25,"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"El `next_cursor` de la respuesta anterior, tal cual. Es opaco: no lo interpretes ni lo construyas.","schema":{"maxLength":512,"example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wOFQxNzo1ODo0Mi40MzgyMzRaIn0","type":"string"}},{"name":"status","required":false,"in":"query","description":"Devuelve sólo las entregas con este desenlace. Lo normal es venir a buscar `failed`.","schema":{"example":"failed","type":"string","enum":["pending","delivering","succeeded","failed"]}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"webhook_delivery"},"id":{"type":"string","example":"c3f1a9d4-2b8e-4a6f-9c1d-7e5b0a3f8d2c"},"endpoint_id":{"type":"string","example":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"},"event_id":{"type":"string","example":"evt_7c3d1a2b9e4f"},"event_type":{"type":"string","example":"payment_link.paid"},"status":{"type":"string","example":"failed"},"attempt_count":{"type":"integer","example":3},"attempts":{"type":"array","items":{"type":"object","properties":{"attempt":{"type":"integer","example":1},"at":{"type":"string","example":"2026-09-07T18:22:41.000Z"},"status_code":{"type":"integer","example":500,"nullable":true},"duration_ms":{"type":"integer","example":812},"error_message":{"type":"string","nullable":true}}}},"next_retry_at":{"type":"string","example":"2026-09-07T18:43:41.000Z","nullable":true},"delivered_at":{"type":"string","nullable":true},"last_status_code":{"type":"integer","nullable":true},"last_error":{"type":"string","example":"timeout","nullable":true},"created_at":{"type":"string","example":"2026-09-07T18:22:40.000Z"}}}},"has_more":{"type":"boolean","example":true},"next_cursor":{"type":"string","example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wN1QxNzowNToxMS4wMDBaIn0","nullable":true}}},"example":{"object":"list","data":[{"object":"webhook_delivery","id":"c3f1a9d4-2b8e-4a6f-9c1d-7e5b0a3f8d2c","endpoint_id":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d","event_id":"evt_7c3d1a2b9e4f","event_type":"payment_link.paid","status":"failed","attempt_count":3,"attempts":[{"attempt":1,"at":"2026-09-07T18:22:41.000Z","status_code":500,"duration_ms":812,"error_message":null},{"attempt":2,"at":"2026-09-07T18:23:41.000Z","status_code":500,"duration_ms":774,"error_message":null},{"attempt":3,"at":"2026-09-07T18:28:41.000Z","status_code":null,"duration_ms":10000,"error_message":"timeout"}],"next_retry_at":"2026-09-07T18:43:41.000Z","delivered_at":null,"last_status_code":null,"last_error":"timeout","created_at":"2026-09-07T18:22:40.000Z"},{"object":"webhook_delivery","id":"b2e0f8c3-1a7d-4b5e-8f0c-6d4a9e2b7f1a","endpoint_id":"a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d","event_id":"evt_4f2a8b1c7d3e","event_type":"deposit.completed","status":"succeeded","attempt_count":1,"attempts":[{"attempt":1,"at":"2026-09-07T17:05:12.000Z","status_code":200,"duration_ms":143,"error_message":null}],"next_retry_at":null,"delivered_at":"2026-09-07T17:05:12.000Z","last_status_code":200,"last_error":null,"created_at":"2026-09-07T17:05:11.000Z"}],"has_more":true,"next_cursor":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wN1QxNzowNToxMS4wMDBaIn0"}}}},"400":{"description":"`invalid_cursor` — El cursor no es uno nuestro. Pasa el `next_cursor` tal cual, sin decodificarlo.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_cursor":{"summary":"invalid_cursor","value":{"error":{"type":"invalid_request","code":"invalid_cursor","message":"El cursor no es uno nuestro. Pasa el `next_cursor` tal cual, sin decodificarlo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`webhook_endpoint_not_found` — No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"webhook_endpoint_not_found":{"summary":"webhook_endpoint_not_found","value":{"error":{"type":"not_found","code":"webhook_endpoint_not_found","message":"No hay ningún destino con ese identificador en esta cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Qué te hemos intentado entregar, y cómo fue","tags":["Webhooks"],"x-binkio-scopes":["webhooks:manage"]}},"/v1/payout_destinations":{"get":{"description":"Las cuentas bancarias dadas de alta en el panel, que son las únicas a las que la API puede enviar dinero. El `id` de una de ellas es lo que lleva `POST /v1/withdrawals`.\\n\\n**Mira `usable` antes de ordenar un retiro.** Una cuenta recién dada de alta está esperando al proveedor y no admite envíos todavía; ordenar contra ella falla más adelante, con el saldo ya apartado.\\n\\nDel número de cuenta se publican sólo los últimos cuatro dígitos: sirven para reconocerla en una pantalla, y para ordenar el retiro se usa el `id`.\n\n**Alcance requerido:** `withdrawals:read`.","operationId":"list_payout_destinations","parameters":[{"name":"rail","required":false,"in":"query","description":"Devuelve sólo los destinos de este riel.","schema":{"example":"spei","type":"string","enum":["spei","wire"]}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"payout_destination"},"id":{"type":"string","example":"d41f8a2c-9b73-4e15-a6c8-3f0e7b2d1a94"},"rail":{"type":"string","example":"spei"},"alias":{"type":"string","example":"Cuenta principal","nullable":true},"beneficiary_name":{"type":"string","example":"Tienda Ejemplo SA de CV"},"bank_name":{"type":"string","example":"BBVA México"},"last_four":{"type":"string","example":"3456"},"currency":{"type":"string","example":"MXN"},"usable":{"type":"boolean","example":true},"created_at":{"type":"string","example":"2026-07-02T09:14:03.000Z"}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"payout_destination","id":"d41f8a2c-9b73-4e15-a6c8-3f0e7b2d1a94","rail":"spei","alias":"Cuenta principal","beneficiary_name":"Tienda Ejemplo SA de CV","bank_name":"BBVA México","last_four":"3456","currency":"MXN","usable":true,"created_at":"2026-07-02T09:14:03.000Z"},{"object":"payout_destination","id":"e58c0b19-4d2f-4a7e-b91c-5a3d8f0e2b76","rail":"wire","alias":null,"beneficiary_name":"Ejemplo Corp","bank_name":"Bank of Example","last_four":"7788","currency":"USD","usable":false,"created_at":"2026-09-06T16:40:22.000Z"}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Las cuentas a las que puedes retirar","tags":["Retiros"],"x-binkio-scopes":["withdrawals:read"]}},"/v1/withdrawals":{"post":{"description":"Saca dinero de tu saldo hacia una de tus cuentas. El riel —SPEI o transferencia internacional— lo decide el destino, no tú.\\n\\n**Esta llamada no se deshace.** Usa como `Idempotency-Key` un identificador tuyo y estable (el número de la orden de pago, el del lote), nunca un aleatorio: un aleatorio hace que cada reintento sea un retiro nuevo.\\n\\n`fee_mode` decide quién pone la comisión. Con `net_out` (por defecto) pides 1.000 y llegan 1.000 menos comisión; con `gross_up` llegan 1.000 exactos y de tu saldo sale algo más.\\n\\nLa respuesta llega en `processing`: el dinero está en camino, no entregado. El desenlace llega por el webhook `withdrawal.completed` o `withdrawal.failed`, y también se puede consultar aquí.\n\n**Alcance requerido:** `withdrawals:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"create_withdrawal","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicWithdrawalDto"}}}},"responses":{"201":{"description":"Retiro aceptado y en camino.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}},"Location":{"description":"URL del recurso recién creado. Se puede seguir tal cual para consultarlo.","schema":{"type":"string","example":"/v1/withdrawals/{id}"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"withdrawal"},"id":{"type":"string","example":"9f3b1c7e-2a4d-4e8f-b0c6-1d5a2e9f4b83"},"status":{"type":"string","example":"processing"},"rail":{"type":"string","example":"spei"},"destination_last_four":{"type":"string","example":"3456"},"amount":{"type":"string","example":"5015.50000000"},"net_amount":{"type":"string","example":"5000.00000000"},"fee":{"type":"string","example":"15.50000000"},"asset":{"type":"string","example":"MXNB"},"concept":{"type":"string","example":"Liquidacion semana 36"},"provider_reference":{"type":"string","nullable":true},"receipt_url":{"type":"string","nullable":true},"failure_reason":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-07T19:02:11.000Z"},"completed_at":{"type":"string","nullable":true}}},"example":{"object":"withdrawal","id":"9f3b1c7e-2a4d-4e8f-b0c6-1d5a2e9f4b83","status":"processing","rail":"spei","destination_last_four":"3456","amount":"5015.50000000","net_amount":"5000.00000000","fee":"15.50000000","asset":"MXNB","concept":"Liquidacion semana 36","provider_reference":null,"receipt_url":null,"failure_reason":null,"created_at":"2026-09-07T19:02:11.000Z","completed_at":null}}}},"400":{"description":"`below_minimum` — El importe no llega al mínimo del riel. El mensaje dice cuál es.\n\n`amount_below_minimum` — El importe no llega al mínimo del riel o de tu cuenta. El `message` dice cuál es y en qué activo.\n\n`amount_above_maximum` — El importe pasa del máximo por operación.\n\n`daily_limit_exceeded` — Se agotó tu cupo DIARIO de retiros. Mañana vuelve a haber; el `message` dice cuánto llevas y cuánto es el tope.\n\n`monthly_limit_exceeded` — Se agotó tu cupo MENSUAL de retiros.\n\n`insufficient_balance` — No hay saldo disponible suficiente. Es distinto de un límite: aquí el dinero no está.\n\n`destination_not_authorized` — El destino no está dado de alta, no está verificado, o le falta el registro con el proveedor. Vuelve a listar `GET /v1/payout_destinations`.\n\n`provider_rejected` — Lo rechazó el proveedor del riel, no nosotros, con un motivo sobre el que puedes actuar. El `message` es suyo y puede cambiar sin aviso: ramifica por este `code`.\n\n`invalid_amount` — El importe no tiene forma de importe (cero, negativo, o texto que no es un decimal).\n\n`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"below_minimum":{"summary":"below_minimum","value":{"error":{"type":"invalid_request","code":"below_minimum","message":"El importe no llega al mínimo del riel. El mensaje dice cuál es.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"amount_below_minimum":{"summary":"amount_below_minimum","value":{"error":{"type":"invalid_request","code":"amount_below_minimum","message":"El importe no llega al mínimo del riel o de tu cuenta. El `message` dice cuál es y en qué activo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"amount_above_maximum":{"summary":"amount_above_maximum","value":{"error":{"type":"invalid_request","code":"amount_above_maximum","message":"El importe pasa del máximo por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"daily_limit_exceeded":{"summary":"daily_limit_exceeded","value":{"error":{"type":"invalid_request","code":"daily_limit_exceeded","message":"Se agotó tu cupo DIARIO de retiros. Mañana vuelve a haber; el `message` dice cuánto llevas y cuánto es el tope.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"monthly_limit_exceeded":{"summary":"monthly_limit_exceeded","value":{"error":{"type":"invalid_request","code":"monthly_limit_exceeded","message":"Se agotó tu cupo MENSUAL de retiros.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_balance":{"summary":"insufficient_balance","value":{"error":{"type":"invalid_request","code":"insufficient_balance","message":"No hay saldo disponible suficiente. Es distinto de un límite: aquí el dinero no está.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"destination_not_authorized":{"summary":"destination_not_authorized","value":{"error":{"type":"invalid_request","code":"destination_not_authorized","message":"El destino no está dado de alta, no está verificado, o le falta el registro con el proveedor. Vuelve a listar `GET /v1/payout_destinations`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"provider_rejected":{"summary":"provider_rejected","value":{"error":{"type":"invalid_request","code":"provider_rejected","message":"Lo rechazó el proveedor del riel, no nosotros, con un motivo sobre el que puedes actuar. El `message` es suyo y puede cambiar sin aviso: ramifica por este `code`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"invalid_amount":{"summary":"invalid_amount","value":{"error":{"type":"invalid_request","code":"invalid_amount","message":"El importe no tiene forma de importe (cero, negativo, o texto que no es un decimal).","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`account_suspended` — La cuenta está suspendida. Escríbenos: no se resuelve desde la API.\n\n`account_blocked` — La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.\n\n`email_not_verified` — El correo de la cuenta no está verificado. Se hace desde el panel.\n\n`phone_not_verified` — El teléfono de la cuenta no está verificado. Se hace desde el panel.\n\n`kyb_not_started` — La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.\n\n`kyb_incomplete` — La verificación de la empresa está a medias. El panel dice qué paso falta.\n\n`kyb_pending_review` — La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.\n\n`kyc_not_started` — La persona titular no ha empezado su verificación.\n\n`kyc_incomplete` — La verificación de la persona titular está a medias.\n\n`user_not_found` — La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.\n\n`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"account_suspended":{"summary":"account_suspended","value":{"error":{"type":"permission_error","code":"account_suspended","message":"La cuenta está suspendida. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"account_blocked":{"summary":"account_blocked","value":{"error":{"type":"permission_error","code":"account_blocked","message":"La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"email_not_verified":{"summary":"email_not_verified","value":{"error":{"type":"permission_error","code":"email_not_verified","message":"El correo de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"phone_not_verified":{"summary":"phone_not_verified","value":{"error":{"type":"permission_error","code":"phone_not_verified","message":"El teléfono de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_not_started":{"summary":"kyb_not_started","value":{"error":{"type":"permission_error","code":"kyb_not_started","message":"La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_incomplete":{"summary":"kyb_incomplete","value":{"error":{"type":"permission_error","code":"kyb_incomplete","message":"La verificación de la empresa está a medias. El panel dice qué paso falta.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_pending_review":{"summary":"kyb_pending_review","value":{"error":{"type":"permission_error","code":"kyb_pending_review","message":"La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_not_started":{"summary":"kyc_not_started","value":{"error":{"type":"permission_error","code":"kyc_not_started","message":"La persona titular no ha empezado su verificación.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_incomplete":{"summary":"kyc_incomplete","value":{"error":{"type":"permission_error","code":"kyc_incomplete","message":"La verificación de la persona titular está a medias.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"user_not_found":{"summary":"user_not_found","value":{"error":{"type":"permission_error","code":"user_not_found","message":"La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`payout_destination_not_found` — Ese destino no existe en tu cuenta. Sácalo de `GET /v1/payout_destinations`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"payout_destination_not_found":{"summary":"payout_destination_not_found","value":{"error":{"type":"not_found","code":"payout_destination_not_found","message":"Ese destino no existe en tu cuenta. Sácalo de `GET /v1/payout_destinations`.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`payout_destination_not_usable` — El destino existe pero todavía no está verificado por el proveedor. Mira `usable` antes de ordenar.\n\n`payout_destination_rail_unsupported` — Ese destino es de un riel que la API todavía no cubre. Los retiros a una dirección de cadena se hacen desde el panel.\n\n`wallet_insufficient_balance` — No hay saldo suficiente para el importe más su comisión.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"payout_destination_not_usable":{"summary":"payout_destination_not_usable","value":{"error":{"type":"conflict","code":"payout_destination_not_usable","message":"El destino existe pero todavía no está verificado por el proveedor. Mira `usable` antes de ordenar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"payout_destination_rail_unsupported":{"summary":"payout_destination_rail_unsupported","value":{"error":{"type":"conflict","code":"payout_destination_rail_unsupported","message":"Ese destino es de un riel que la API todavía no cubre. Los retiros a una dirección de cadena se hacen desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"wallet_insufficient_balance":{"summary":"wallet_insufficient_balance","value":{"error":{"type":"conflict","code":"wallet_insufficient_balance","message":"No hay saldo suficiente para el importe más su comisión.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Ordena un retiro a una cuenta dada de alta","tags":["Retiros"],"x-binkio-scopes":["withdrawals:write"]},"get":{"description":"Para conciliar: `amount` es lo que salió de tu saldo y `net_amount` lo que recibió el destino. La diferencia es la comisión.\\n\\n`receipt_url` trae el CEP —el comprobante oficial de Banxico— en cuanto el proveedor lo publica. Es lo que vale como prueba ante quien cobró.\n\n**Alcance requerido:** `withdrawals:read`.","operationId":"list_withdrawals","parameters":[{"name":"limit","required":false,"in":"query","description":"Cuántos retiros por página.","schema":{"minimum":1,"maximum":100,"format":"int32","default":25,"example":25,"type":"number"}},{"name":"cursor","required":false,"in":"query","description":"El `next_cursor` de la respuesta anterior, tal cual. Es opaco: no lo interpretes ni lo construyas.","schema":{"maxLength":512,"example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wOFQxNzo1ODo0Mi40MzgyMzRaIn0","type":"string"}},{"name":"status","required":false,"in":"query","description":"Devuelve sólo los retiros en este estado.","schema":{"example":"completed","type":"string","enum":["processing","completed","failed","cancelled"]}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"withdrawal"},"id":{"type":"string","example":"9f3b1c7e-2a4d-4e8f-b0c6-1d5a2e9f4b83"},"status":{"type":"string","example":"processing"},"rail":{"type":"string","example":"spei"},"destination_last_four":{"type":"string","example":"3456"},"amount":{"type":"string","example":"5015.50000000"},"net_amount":{"type":"string","example":"5000.00000000"},"fee":{"type":"string","example":"15.50000000"},"asset":{"type":"string","example":"MXNB"},"concept":{"type":"string","example":"Liquidacion semana 36"},"provider_reference":{"type":"string","nullable":true},"receipt_url":{"type":"string","nullable":true},"failure_reason":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-07T19:02:11.000Z"},"completed_at":{"type":"string","nullable":true}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"withdrawal","id":"9f3b1c7e-2a4d-4e8f-b0c6-1d5a2e9f4b83","status":"processing","rail":"spei","destination_last_four":"3456","amount":"5015.50000000","net_amount":"5000.00000000","fee":"15.50000000","asset":"MXNB","concept":"Liquidacion semana 36","provider_reference":null,"receipt_url":null,"failure_reason":null,"created_at":"2026-09-07T19:02:11.000Z","completed_at":null},{"object":"withdrawal","id":"4c8e2f1a-7b3d-4956-8a2e-0f6c1b9d3e57","status":"completed","rail":"spei","destination_last_four":"3456","amount":"12030.00000000","net_amount":"12000.00000000","fee":"30.00000000","asset":"MXNB","concept":"Liquidacion semana 35","provider_reference":"BNK7C3D1A2B","receipt_url":"https://www.banxico.org.mx/cep/go?i=90646&s=20260831&d=ejemplo","failure_reason":null,"created_at":"2026-08-31T19:02:11.000Z","completed_at":"2026-08-31T19:04:38.000Z"}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Tus retiros, del más reciente al más antiguo","tags":["Retiros"],"x-binkio-scopes":["withdrawals:read"]}},"/v1/withdrawals/{id}":{"get":{"description":"El estado real, sin depender de que el webhook haya llegado.\\n\\nCuatro estados: `processing` (en camino), `completed` (llegó), `failed` (no salió, el saldo volvió a tu cuenta) y `cancelled`. **`processing` no es un fallo**: un SPEI tarda minutos y una transferencia internacional, días.\n\n**Alcance requerido:** `withdrawals:read`.","operationId":"get_withdrawal","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"withdrawal"},"id":{"type":"string","example":"9f3b1c7e-2a4d-4e8f-b0c6-1d5a2e9f4b83"},"status":{"type":"string","example":"processing"},"rail":{"type":"string","example":"spei"},"destination_last_four":{"type":"string","example":"3456"},"amount":{"type":"string","example":"5015.50000000"},"net_amount":{"type":"string","example":"5000.00000000"},"fee":{"type":"string","example":"15.50000000"},"asset":{"type":"string","example":"MXNB"},"concept":{"type":"string","example":"Liquidacion semana 36"},"provider_reference":{"type":"string","nullable":true},"receipt_url":{"type":"string","nullable":true},"failure_reason":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-07T19:02:11.000Z"},"completed_at":{"type":"string","nullable":true}}},"example":{"object":"withdrawal","id":"9f3b1c7e-2a4d-4e8f-b0c6-1d5a2e9f4b83","status":"processing","rail":"spei","destination_last_four":"3456","amount":"5015.50000000","net_amount":"5000.00000000","fee":"15.50000000","asset":"MXNB","concept":"Liquidacion semana 36","provider_reference":null,"receipt_url":null,"failure_reason":null,"created_at":"2026-09-07T19:02:11.000Z","completed_at":null}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`withdrawal_not_found` — No hay ese retiro en tu cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"withdrawal_not_found":{"summary":"withdrawal_not_found","value":{"error":{"type":"not_found","code":"withdrawal_not_found","message":"No hay ese retiro en tu cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"El detalle de un retiro","tags":["Retiros"],"x-binkio-scopes":["withdrawals:read"]}},"/v1/withdrawals/crypto":{"post":{"description":"El destino va en el cuerpo y **no se valida contra ninguna lista**: no hay direcciones dadas de alta que comprobar. Es lo que separa esta llamada de `POST /v1/withdrawals`, y por eso lleva su propio alcance.\n\n:::danger Esto no se deshace, y no hay a quién reclamar\nUna dirección equivocada, o la red equivocada, pierde el dinero **para siempre**. No lo recupera soporte, ni el proveedor, ni nosotros. Valida la dirección en tu lado antes de llamar, y no la construyas concatenando cadenas.\n:::\n\n**`network` es obligatorio y no tiene valor por defecto.** El mismo activo vive en varias redes y la dirección no dice en cuál: deducirla por ti sería acertar casi siempre y perder el dinero el resto de las veces.\n\nA partir de cierto importe hace falta `beneficiary` (Regla de Viaje, FATF R.16). Se pide ANTES de mover nada: sin esos datos el proveedor rechaza el envío, y para entonces el saldo ya está apartado.\n\n**Alcance requerido:** `withdrawals:crypto`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"create_crypto_withdrawal","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicCryptoWithdrawalDto"}}}},"responses":{"201":{"description":"Envío aceptado y en camino a la red.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}},"Location":{"description":"URL del recurso recién creado. Se puede seguir tal cual para consultarlo.","schema":{"type":"string","example":"/v1/withdrawals/{id}"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"withdrawal"},"id":{"type":"string","example":"9f3b1c7e-2a4d-4e8f-b0c6-1d5a2e9f4b83"},"status":{"type":"string","example":"processing"},"rail":{"type":"string","example":"spei"},"destination_last_four":{"type":"string","example":"3456"},"amount":{"type":"string","example":"5015.50000000"},"net_amount":{"type":"string","example":"5000.00000000"},"fee":{"type":"string","example":"15.50000000"},"asset":{"type":"string","example":"MXNB"},"concept":{"type":"string","example":"Liquidacion semana 36"},"provider_reference":{"type":"string","nullable":true},"receipt_url":{"type":"string","nullable":true},"failure_reason":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-07T19:02:11.000Z"},"completed_at":{"type":"string","nullable":true}}},"example":{"object":"withdrawal","id":"9f3b1c7e-2a4d-4e8f-b0c6-1d5a2e9f4b83","status":"processing","rail":"spei","destination_last_four":"3456","amount":"5015.50000000","net_amount":"5000.00000000","fee":"15.50000000","asset":"MXNB","concept":"Liquidacion semana 36","provider_reference":null,"receipt_url":null,"failure_reason":null,"created_at":"2026-09-07T19:02:11.000Z","completed_at":null}}}},"400":{"description":"`network_unavailable` — Esa red no está disponible ahora mismo para ese activo. El `message` enumera las que sí.\n\n`invalid_address` — La dirección no tiene la forma de esa red. **No se comprueba que exista ni que sea tuya**: sólo la forma.\n\n`travel_rule_data_required` — El importe supera el umbral de la Regla de Viaje (FATF R.16) y falta `beneficiary`. Mándalo y repite.\n\n`amount_below_minimum` — El importe no llega al mínimo de ese activo, o no cubre la comisión de red.\n\n`amount_above_maximum` — El importe pasa del máximo por operación para ese activo.\n\n`insufficient_balance` — No hay saldo disponible suficiente en ese activo.\n\n`daily_limit_exceeded` — Se agotó tu cupo diario de retiros.\n\n`below_minimum` — El importe no llega al mínimo del activo en esa red.\n\n`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"network_unavailable":{"summary":"network_unavailable","value":{"error":{"type":"invalid_request","code":"network_unavailable","message":"Esa red no está disponible ahora mismo para ese activo. El `message` enumera las que sí.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"invalid_address":{"summary":"invalid_address","value":{"error":{"type":"invalid_request","code":"invalid_address","message":"La dirección no tiene la forma de esa red. **No se comprueba que exista ni que sea tuya**: sólo la forma.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"travel_rule_data_required":{"summary":"travel_rule_data_required","value":{"error":{"type":"invalid_request","code":"travel_rule_data_required","message":"El importe supera el umbral de la Regla de Viaje (FATF R.16) y falta `beneficiary`. Mándalo y repite.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"amount_below_minimum":{"summary":"amount_below_minimum","value":{"error":{"type":"invalid_request","code":"amount_below_minimum","message":"El importe no llega al mínimo de ese activo, o no cubre la comisión de red.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"amount_above_maximum":{"summary":"amount_above_maximum","value":{"error":{"type":"invalid_request","code":"amount_above_maximum","message":"El importe pasa del máximo por operación para ese activo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_balance":{"summary":"insufficient_balance","value":{"error":{"type":"invalid_request","code":"insufficient_balance","message":"No hay saldo disponible suficiente en ese activo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"daily_limit_exceeded":{"summary":"daily_limit_exceeded","value":{"error":{"type":"invalid_request","code":"daily_limit_exceeded","message":"Se agotó tu cupo diario de retiros.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"below_minimum":{"summary":"below_minimum","value":{"error":{"type":"invalid_request","code":"below_minimum","message":"El importe no llega al mínimo del activo en esa red.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`account_suspended` — La cuenta está suspendida. Escríbenos: no se resuelve desde la API.\n\n`account_blocked` — La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.\n\n`email_not_verified` — El correo de la cuenta no está verificado. Se hace desde el panel.\n\n`phone_not_verified` — El teléfono de la cuenta no está verificado. Se hace desde el panel.\n\n`kyb_not_started` — La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.\n\n`kyb_incomplete` — La verificación de la empresa está a medias. El panel dice qué paso falta.\n\n`kyb_pending_review` — La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.\n\n`kyc_not_started` — La persona titular no ha empezado su verificación.\n\n`kyc_incomplete` — La verificación de la persona titular está a medias.\n\n`user_not_found` — La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.\n\n`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"account_suspended":{"summary":"account_suspended","value":{"error":{"type":"permission_error","code":"account_suspended","message":"La cuenta está suspendida. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"account_blocked":{"summary":"account_blocked","value":{"error":{"type":"permission_error","code":"account_blocked","message":"La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"email_not_verified":{"summary":"email_not_verified","value":{"error":{"type":"permission_error","code":"email_not_verified","message":"El correo de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"phone_not_verified":{"summary":"phone_not_verified","value":{"error":{"type":"permission_error","code":"phone_not_verified","message":"El teléfono de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_not_started":{"summary":"kyb_not_started","value":{"error":{"type":"permission_error","code":"kyb_not_started","message":"La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_incomplete":{"summary":"kyb_incomplete","value":{"error":{"type":"permission_error","code":"kyb_incomplete","message":"La verificación de la empresa está a medias. El panel dice qué paso falta.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_pending_review":{"summary":"kyb_pending_review","value":{"error":{"type":"permission_error","code":"kyb_pending_review","message":"La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_not_started":{"summary":"kyc_not_started","value":{"error":{"type":"permission_error","code":"kyc_not_started","message":"La persona titular no ha empezado su verificación.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_incomplete":{"summary":"kyc_incomplete","value":{"error":{"type":"permission_error","code":"kyc_incomplete","message":"La verificación de la persona titular está a medias.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"user_not_found":{"summary":"user_not_found","value":{"error":{"type":"permission_error","code":"user_not_found","message":"La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`wallet_insufficient_balance` — No hay saldo suficiente para el importe más su comisión de red.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"wallet_insufficient_balance":{"summary":"wallet_insufficient_balance","value":{"error":{"type":"conflict","code":"wallet_insufficient_balance","message":"No hay saldo suficiente para el importe más su comisión de red.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Envía activos a una dirección de blockchain","tags":["Retiros"],"x-binkio-scopes":["withdrawals:crypto"]}},"/v1/conversions/quote":{"post":{"description":"Devuelve cuánto recibirías, a qué tasa y hasta cuándo vale ese precio. **No mueve dinero** y no consume nada: cotizar dos veces devuelve dos precios distintos si el mercado se movió, que es lo correcto.\\n\\n**Exige `Idempotency-Key`**, como todo `POST` de la API. Ojo a la consecuencia: repetir la misma clave devuelve la cotización GUARDADA, no una nueva. Para pedir precio otra vez, clave nueva.\\n\\nGuarda el `quote_id`: es lo único que `POST /v1/conversions` acepta para ejecutar ESTE precio.\\n\\n`to_amount` ya trae la comisión descontada — es lo que de verdad entra en tu cuenta, no el bruto.\\n\\nSi `off_market` viene en `true`, el mercado del par está cerrado (fin de semana, festivo) y la tasa es peor de lo habitual. Es la única explicación de por qué el precio de un domingo no es el del martes.\n\n**Alcance requerido:** `conversions:read`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"create_conversion_quote","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePublicConversionQuoteDto"}}}},"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"conversion_quote"},"quote_id":{"type":"string","example":"cq_7f3a2b9c1d4e8a6f"},"from_asset":{"type":"string","example":"MXNB"},"to_asset":{"type":"string","example":"USDC"},"from_amount":{"type":"string","example":"30000.00000000"},"to_amount":{"type":"string","example":"1738.52000000","nullable":true},"exchange_rate":{"type":"string","example":"17.25000000"},"fee":{"type":"string","example":"17.39000000"},"fee_percentage":{"type":"string","example":"1.00"},"expires_at":{"type":"string","example":"2026-09-08T14:32:10.000Z"},"off_market":{"type":"boolean","example":false}}},"example":{"object":"conversion_quote","quote_id":"cq_7f3a2b9c1d4e8a6f","from_asset":"MXNB","to_asset":"USDC","from_amount":"30000.00000000","to_amount":"1738.52000000","exchange_rate":"17.25000000","fee":"17.39000000","fee_percentage":"1.00","expires_at":"2026-09-08T14:32:10.000Z","off_market":false}}}},"400":{"description":"`pair_not_supported` — Ese par no se convierte, ni con otro importe. No todos los activos tienen ruta entre sí.\n\n`same_asset` — `from_asset` y `to_asset` son el mismo activo.\n\n`amount_below_minimum` — El importe no llega al mínimo de la ruta. El `message` dice cuál es y en qué activo: depende del par y de si va por vía directa o por mercado.\n\n`amount_above_maximum` — El importe pasa del máximo de la ruta.\n\n`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"pair_not_supported":{"summary":"pair_not_supported","value":{"error":{"type":"invalid_request","code":"pair_not_supported","message":"Ese par no se convierte, ni con otro importe. No todos los activos tienen ruta entre sí.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"same_asset":{"summary":"same_asset","value":{"error":{"type":"invalid_request","code":"same_asset","message":"`from_asset` y `to_asset` son el mismo activo.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"amount_below_minimum":{"summary":"amount_below_minimum","value":{"error":{"type":"invalid_request","code":"amount_below_minimum","message":"El importe no llega al mínimo de la ruta. El `message` dice cuál es y en qué activo: depende del par y de si va por vía directa o por mercado.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"amount_above_maximum":{"summary":"amount_above_maximum","value":{"error":{"type":"invalid_request","code":"amount_above_maximum","message":"El importe pasa del máximo de la ruta.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`account_suspended` — La cuenta está suspendida. Escríbenos: no se resuelve desde la API.\n\n`account_blocked` — La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.\n\n`email_not_verified` — El correo de la cuenta no está verificado. Se hace desde el panel.\n\n`phone_not_verified` — El teléfono de la cuenta no está verificado. Se hace desde el panel.\n\n`kyb_not_started` — La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.\n\n`kyb_incomplete` — La verificación de la empresa está a medias. El panel dice qué paso falta.\n\n`kyb_pending_review` — La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.\n\n`kyc_not_started` — La persona titular no ha empezado su verificación.\n\n`kyc_incomplete` — La verificación de la persona titular está a medias.\n\n`user_not_found` — La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.\n\n`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"account_suspended":{"summary":"account_suspended","value":{"error":{"type":"permission_error","code":"account_suspended","message":"La cuenta está suspendida. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"account_blocked":{"summary":"account_blocked","value":{"error":{"type":"permission_error","code":"account_blocked","message":"La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"email_not_verified":{"summary":"email_not_verified","value":{"error":{"type":"permission_error","code":"email_not_verified","message":"El correo de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"phone_not_verified":{"summary":"phone_not_verified","value":{"error":{"type":"permission_error","code":"phone_not_verified","message":"El teléfono de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_not_started":{"summary":"kyb_not_started","value":{"error":{"type":"permission_error","code":"kyb_not_started","message":"La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_incomplete":{"summary":"kyb_incomplete","value":{"error":{"type":"permission_error","code":"kyb_incomplete","message":"La verificación de la empresa está a medias. El panel dice qué paso falta.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_pending_review":{"summary":"kyb_pending_review","value":{"error":{"type":"permission_error","code":"kyb_pending_review","message":"La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_not_started":{"summary":"kyc_not_started","value":{"error":{"type":"permission_error","code":"kyc_not_started","message":"La persona titular no ha empezado su verificación.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_incomplete":{"summary":"kyc_incomplete","value":{"error":{"type":"permission_error","code":"kyc_incomplete","message":"La verificación de la persona titular está a medias.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"user_not_found":{"summary":"user_not_found","value":{"error":{"type":"permission_error","code":"user_not_found","message":"La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Pide precio para una conversión","tags":["Conversiones"],"x-binkio-scopes":["conversions:read"]}},"/v1/conversions":{"post":{"description":"Convierte al precio que devolvió `POST /v1/conversions/quote`. El `quote_id` es obligatorio: no se puede ejecutar «lo último que cotizaste», porque entonces no habría forma de saber qué precio aceptaste.\\n\\n`from_asset`, `to_asset` y `amount` van ADEMÁS del `quote_id` y se contrastan con lo que guardamos al cotizar. Si no cuadran, se rechaza — es lo que impide que reusar por error un `quote_id` de otro par convierta algo distinto de lo que aceptaste.\\n\\n`max_slippage_bps` acota cuánto puede empeorar la tasa entre las dos llamadas. Entre cotizar y ejecutar pasa tiempo real y el mercado se mueve: sin tope, una ejecución tardía se liquida a un precio que nadie aceptó.\\n\\nLa respuesta puede llegar en `processing`: las rutas de dos patas —vender y emitir— no terminan en la misma llamada. **`processing` no es un fallo.**\n\n**Alcance requerido:** `conversions:write`.\n\nExige la cabecera `Idempotency-Key`.","operationId":"execute_conversion","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}},{"name":"Idempotency-Key","in":"header","description":"Clave única de la operación (uuid o cadena de ≤255). Reintentar con la misma clave y el mismo cuerpo devuelve la respuesta guardada, con `Idempotent-Replay: true`, sin volver a ejecutar.","required":true,"schema":{"type":"string","example":"9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecutePublicConversionDto"}}}},"responses":{"201":{"description":"Conversión aceptada.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}},"Idempotent-Replay":{"description":"`true` cuando la respuesta salió del almacén de idempotencia y la operación **no se volvió a ejecutar**. Ausente en la ejecución real.","schema":{"type":"string","example":"true"}},"RateLimit-Money-Limit":{"description":"Operaciones de dinero por día que admite esta credencial.","schema":{"type":"integer","example":5000}},"RateLimit-Money-Remaining":{"description":"Operaciones de dinero que quedan hoy.","schema":{"type":"integer","example":4987}},"RateLimit-Money-Reset":{"description":"Segundos hasta que la cuota diaria se reinicia.","schema":{"type":"integer","example":30512}},"Location":{"description":"URL del recurso recién creado. Se puede seguir tal cual para consultarlo.","schema":{"type":"string","example":"/v1/conversions/{id}"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"conversion"},"id":{"type":"string","example":"a7c2e910-4b6d-4f83-9e21-c5b8a0d3f742"},"status":{"type":"string","example":"completed"},"from_asset":{"type":"string","example":"MXNB"},"to_asset":{"type":"string","example":"USDC"},"from_amount":{"type":"string","example":"30000.00000000"},"to_amount":{"type":"string","example":"1738.52000000","nullable":true},"exchange_rate":{"type":"string","example":"17.25000000"},"fee":{"type":"string","example":"17.39000000"},"failure_reason":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-08T14:30:04.000Z"},"completed_at":{"type":"string","example":"2026-09-08T14:30:21.000Z","nullable":true}}},"example":{"object":"conversion","id":"a7c2e910-4b6d-4f83-9e21-c5b8a0d3f742","status":"completed","from_asset":"MXNB","to_asset":"USDC","from_amount":"30000.00000000","to_amount":"1738.52000000","exchange_rate":"17.25000000","fee":"17.39000000","failure_reason":null,"created_at":"2026-09-08T14:30:04.000Z","completed_at":"2026-09-08T14:30:21.000Z"}}}},"400":{"description":"`quote_expired` — La cotización caducó o ya no está. Pide otra con `POST /v1/conversions/quote` y ejecútala: las cotizaciones viven poco a propósito, porque el precio se mueve.\n\n`quote_required` — Falta `quote_id`. Una conversión no se ejecuta sin una cotización que hayas visto y aceptado.\n\n`quote_mismatch` — La cotización no es de esta cuenta, o el par y el importe que mandas no son los que se cotizaron. Es lo que impide que reusar un `quote_id` convierta algo distinto de lo que aceptaste.\n\n`slippage_exceeded` — La tasa empeoró más de lo que permite `max_slippage_bps` entre cotizar y ejecutar. No se convirtió nada: vuelve a cotizar.\n\n`insufficient_balance` — No hay saldo disponible suficiente en `from_asset`.\n\n`below_minimum` — El importe no llega al mínimo de la ruta.\n\n`idempotency_key_required` — Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.\n\n`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"quote_expired":{"summary":"quote_expired","value":{"error":{"type":"invalid_request","code":"quote_expired","message":"La cotización caducó o ya no está. Pide otra con `POST /v1/conversions/quote` y ejecútala: las cotizaciones viven poco a propósito, porque el precio se mueve.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"quote_required":{"summary":"quote_required","value":{"error":{"type":"invalid_request","code":"quote_required","message":"Falta `quote_id`. Una conversión no se ejecuta sin una cotización que hayas visto y aceptado.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"quote_mismatch":{"summary":"quote_mismatch","value":{"error":{"type":"invalid_request","code":"quote_mismatch","message":"La cotización no es de esta cuenta, o el par y el importe que mandas no son los que se cotizaron. Es lo que impide que reusar un `quote_id` convierta algo distinto de lo que aceptaste.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"slippage_exceeded":{"summary":"slippage_exceeded","value":{"error":{"type":"invalid_request","code":"slippage_exceeded","message":"La tasa empeoró más de lo que permite `max_slippage_bps` entre cotizar y ejecutar. No se convirtió nada: vuelve a cotizar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_balance":{"summary":"insufficient_balance","value":{"error":{"type":"invalid_request","code":"insufficient_balance","message":"No hay saldo disponible suficiente en `from_asset`.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"below_minimum":{"summary":"below_minimum","value":{"error":{"type":"invalid_request","code":"below_minimum","message":"El importe no llega al mínimo de la ruta.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_key_required":{"summary":"idempotency_key_required","value":{"error":{"type":"invalid_request","code":"idempotency_key_required","message":"Falta la cabecera `Idempotency-Key`. Es obligatoria en todo método que crea o modifica.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`account_suspended` — La cuenta está suspendida. Escríbenos: no se resuelve desde la API.\n\n`account_blocked` — La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.\n\n`email_not_verified` — El correo de la cuenta no está verificado. Se hace desde el panel.\n\n`phone_not_verified` — El teléfono de la cuenta no está verificado. Se hace desde el panel.\n\n`kyb_not_started` — La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.\n\n`kyb_incomplete` — La verificación de la empresa está a medias. El panel dice qué paso falta.\n\n`kyb_pending_review` — La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.\n\n`kyc_not_started` — La persona titular no ha empezado su verificación.\n\n`kyc_incomplete` — La verificación de la persona titular está a medias.\n\n`user_not_found` — La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.\n\n`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"account_suspended":{"summary":"account_suspended","value":{"error":{"type":"permission_error","code":"account_suspended","message":"La cuenta está suspendida. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"account_blocked":{"summary":"account_blocked","value":{"error":{"type":"permission_error","code":"account_blocked","message":"La cuenta está bloqueada. Escríbenos: no se resuelve desde la API.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"email_not_verified":{"summary":"email_not_verified","value":{"error":{"type":"permission_error","code":"email_not_verified","message":"El correo de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"phone_not_verified":{"summary":"phone_not_verified","value":{"error":{"type":"permission_error","code":"phone_not_verified","message":"El teléfono de la cuenta no está verificado. Se hace desde el panel.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_not_started":{"summary":"kyb_not_started","value":{"error":{"type":"permission_error","code":"kyb_not_started","message":"La empresa no ha empezado la verificación (KYB). Hasta terminarla no se puede cobrar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_incomplete":{"summary":"kyb_incomplete","value":{"error":{"type":"permission_error","code":"kyb_incomplete","message":"La verificación de la empresa está a medias. El panel dice qué paso falta.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyb_pending_review":{"summary":"kyb_pending_review","value":{"error":{"type":"permission_error","code":"kyb_pending_review","message":"La verificación está completa y esperando nuestra revisión. No hay nada que hacer salvo esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_not_started":{"summary":"kyc_not_started","value":{"error":{"type":"permission_error","code":"kyc_not_started","message":"La persona titular no ha empezado su verificación.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"kyc_incomplete":{"summary":"kyc_incomplete","value":{"error":{"type":"permission_error","code":"kyc_incomplete","message":"La verificación de la persona titular está a medias.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"user_not_found":{"summary":"user_not_found","value":{"error":{"type":"permission_error","code":"user_not_found","message":"La cuenta dueña de la credencial ya no existe. Emite una credencial nueva.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"409":{"description":"`wallet_insufficient_balance` — No hay saldo suficiente en el activo de origen.\n\n`idempotency_request_in_progress` — Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"wallet_insufficient_balance":{"summary":"wallet_insufficient_balance","value":{"error":{"type":"conflict","code":"wallet_insufficient_balance","message":"No hay saldo suficiente en el activo de origen.","request_id":"req_9f2a4c8b7e1d3a5f"}}},"idempotency_request_in_progress":{"summary":"idempotency_request_in_progress","value":{"error":{"type":"conflict","code":"idempotency_request_in_progress","message":"Hay otra petición con la MISMA clave ejecutándose ahora. Reintenta en unos segundos con la misma clave.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"422":{"description":"`idempotency_key_reused` — La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"idempotency_key_reused":{"summary":"idempotency_key_reused","value":{"error":{"type":"invalid_request","code":"idempotency_key_reused","message":"La misma clave con un cuerpo DISTINTO. Ejecutarla sería cobrar dos veces con nuestra bendición: usa una clave nueva por operación.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Ejecuta una cotización","tags":["Conversiones"],"x-binkio-scopes":["conversions:write"]},"get":{"description":"Para conciliar: `from_amount` es lo que salió del activo de origen y `to_amount` lo que entró en el de destino. La diferencia contra la tasa es la comisión.\n\n**Alcance requerido:** `conversions:read`.","operationId":"list_conversions","parameters":[{"name":"cursor","required":false,"in":"query","description":"El `next_cursor` de la respuesta anterior, tal cual. Es opaco: no lo interpretes ni lo construyas.","schema":{"maxLength":512,"example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wOFQxNzo1ODo0Mi40MzgyMzRaIn0","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Cuántas conversiones por página.","schema":{"minimum":1,"maximum":100,"format":"int32","default":25,"example":25,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Devuelve sólo las conversiones en este estado.","schema":{"example":"completed","type":"string","enum":["processing","completed","failed"]}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"conversion"},"id":{"type":"string","example":"a7c2e910-4b6d-4f83-9e21-c5b8a0d3f742"},"status":{"type":"string","example":"completed"},"from_asset":{"type":"string","example":"MXNB"},"to_asset":{"type":"string","example":"USDC"},"from_amount":{"type":"string","example":"30000.00000000"},"to_amount":{"type":"string","example":"1738.52000000","nullable":true},"exchange_rate":{"type":"string","example":"17.25000000"},"fee":{"type":"string","example":"17.39000000"},"failure_reason":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-08T14:30:04.000Z"},"completed_at":{"type":"string","example":"2026-09-08T14:30:21.000Z","nullable":true}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"conversion","id":"a7c2e910-4b6d-4f83-9e21-c5b8a0d3f742","status":"completed","from_asset":"MXNB","to_asset":"USDC","from_amount":"30000.00000000","to_amount":"1738.52000000","exchange_rate":"17.25000000","fee":"17.39000000","failure_reason":null,"created_at":"2026-09-08T14:30:04.000Z","completed_at":"2026-09-08T14:30:21.000Z"},{"object":"conversion","id":"b93f1d05-8e2a-4c71-b6f4-2d90a7e13c68","status":"failed","from_asset":"USDC","to_asset":"MXNB","from_amount":"2000.00000000","to_amount":null,"exchange_rate":"17.10000000","fee":"20.00000000","failure_reason":"issuance rejected by provider","created_at":"2026-09-05T11:02:44.000Z","completed_at":null}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Tus conversiones, de la más reciente a la más antigua","tags":["Conversiones"],"x-binkio-scopes":["conversions:read"]}},"/v1/conversions/{id}":{"get":{"description":"Tres estados: `processing` (en marcha), `completed` (el saldo ya está en el activo de destino) y `failed`.\\n\\nCuando falla, `failure_reason` dice QUÉ paso falló. Importa: una conversión por la vía de mercado tiene dos patas —vender y emitir— y saber cuál se cayó es lo que decide si tiene sentido reintentar.\n\n**Alcance requerido:** `conversions:read`.","operationId":"get_conversion","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"conversion"},"id":{"type":"string","example":"a7c2e910-4b6d-4f83-9e21-c5b8a0d3f742"},"status":{"type":"string","example":"completed"},"from_asset":{"type":"string","example":"MXNB"},"to_asset":{"type":"string","example":"USDC"},"from_amount":{"type":"string","example":"30000.00000000"},"to_amount":{"type":"string","example":"1738.52000000","nullable":true},"exchange_rate":{"type":"string","example":"17.25000000"},"fee":{"type":"string","example":"17.39000000"},"failure_reason":{"type":"string","nullable":true},"created_at":{"type":"string","example":"2026-09-08T14:30:04.000Z"},"completed_at":{"type":"string","example":"2026-09-08T14:30:21.000Z","nullable":true}}},"example":{"object":"conversion","id":"a7c2e910-4b6d-4f83-9e21-c5b8a0d3f742","status":"completed","from_asset":"MXNB","to_asset":"USDC","from_amount":"30000.00000000","to_amount":"1738.52000000","exchange_rate":"17.25000000","fee":"17.39000000","failure_reason":null,"created_at":"2026-09-08T14:30:04.000Z","completed_at":"2026-09-08T14:30:21.000Z"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`conversion_not_found` — No hay esa conversión en tu cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"conversion_not_found":{"summary":"conversion_not_found","value":{"error":{"type":"not_found","code":"conversion_not_found","message":"No hay esa conversión en tu cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"El detalle de una conversión","tags":["Conversiones"],"x-binkio-scopes":["conversions:read"]}},"/v1/deposit_instructions":{"get":{"description":"Todos los sitios a los que tu cuenta puede recibir: la CLABE para SPEI, la llave Bre-B para Colombia y las direcciones on-chain, cada una con su red.\\n\\n**Mira `usable`.** Una vía recién aprovisionada puede estar todavía en trámite con el proveedor; enseñársela a un pagador antes de tiempo es perder el dinero que mande.\\n\\n:::danger La red importa más que la dirección\\nEn las instrucciones de cripto, `network` es la red EXACTA. Mandar el mismo activo por otra red pierde el dinero y no se recupera. Enséñala junto a la dirección, siempre.\\n:::\\n\\nEstos datos son **estables**: la CLABE de una cuenta no cambia. Se pueden guardar, pero conviene refrescarlos cuando aparezca un activo nuevo.\n\n**Alcance requerido:** `deposits:read`.","operationId":"list_deposit_instructions","parameters":[{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"deposit_instruction"},"rail":{"type":"string","example":"spei"},"asset":{"type":"string","example":"MXNB"},"currency":{"type":"string","example":"MXN"},"usable":{"type":"boolean","example":true},"clabe":{"type":"string","example":"710969000000123456"},"bank_name":{"type":"string","example":"Nvio"},"address":{"type":"string","example":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b"},"network":{"type":"string","example":"ETHEREUM"},"breb_key":{"type":"string","example":"@CB5LU67NI"}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"deposit_instruction","rail":"spei","asset":"MXNB","currency":"MXN","usable":true,"clabe":"710969000000123456","bank_name":"Nvio"},{"object":"deposit_instruction","rail":"crypto","asset":"USDC","currency":"USDC","usable":true,"address":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b","network":"ETHEREUM"},{"object":"deposit_instruction","rail":"crypto","asset":"USDC","currency":"USDC","usable":true,"address":"0x4f2a8b1c7d3e5a9f0b6c2d8e1a3f7b5c9d0e2a4f","network":"BASE"},{"object":"deposit_instruction","rail":"breb","asset":"COP","currency":"COP","usable":false,"breb_key":"@CB5LU67NI"}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Dónde te pueden mandar dinero","tags":["Depósitos"],"x-binkio-scopes":["deposits:read"]}},"/v1/deposits":{"get":{"description":"Del más reciente al más antiguo, con el riel por el que llegó y de dónde vino cuando el proveedor lo informa.\\n\\nPara enterarte de un depósito EN CUANTO llega, suscríbete a `deposit.completed` en vez de sondear aquí. → `/v1/webhook_endpoints`\n\n**Alcance requerido:** `deposits:read`.","operationId":"list_deposits","parameters":[{"name":"cursor","required":false,"in":"query","description":"El `next_cursor` de la respuesta anterior, tal cual. Es opaco: no lo interpretes ni lo construyas.","schema":{"maxLength":512,"example":"eyJ2IjoxLCJ0IjoiMjAyNi0wOS0wOFQxNzo1ODo0Mi40MzgyMzRaIn0","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Cuántos depósitos por página.","schema":{"minimum":1,"maximum":100,"format":"int32","default":25,"example":25,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Devuelve sólo los depósitos en este estado. El filtro se aplica en la consulta, así que la página viene llena y se puede paginar.","schema":{"example":"completed","type":"string","enum":["processing","completed","failed"]}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"list"},"data":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"deposit"},"id":{"type":"string","example":"e2f8a1c4-6b09-4d73-8e5a-1c7f3b90d426"},"status":{"type":"string","example":"completed"},"rail":{"type":"string","example":"spei"},"amount":{"type":"string","example":"25000.00000000"},"asset":{"type":"string","example":"MXNB"},"source":{"type":"string","example":"012180001234567890"},"provider_reference":{"type":"string","example":"JUNO-ISS-7C3D1A2B","nullable":true},"created_at":{"type":"string","example":"2026-09-08T10:14:02.000Z"},"completed_at":{"type":"string","example":"2026-09-08T10:14:37.000Z","nullable":true}}}},"has_more":{"type":"boolean","example":false},"next_cursor":{"type":"string","nullable":true}}},"example":{"object":"list","data":[{"object":"deposit","id":"e2f8a1c4-6b09-4d73-8e5a-1c7f3b90d426","status":"completed","rail":"spei","amount":"25000.00000000","asset":"MXNB","source":"012180001234567890","provider_reference":"JUNO-ISS-7C3D1A2B","created_at":"2026-09-08T10:14:02.000Z","completed_at":"2026-09-08T10:14:37.000Z"},{"object":"deposit","id":"c5b1d704-9a3e-4f28-b6c0-7d2e8a1f403b","status":"processing","rail":"crypto","amount":"500.00000000","asset":"USDC","source":"0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b","provider_reference":null,"created_at":"2026-09-08T09:51:18.000Z","completed_at":null}],"has_more":false,"next_cursor":null}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"Lo que ha entrado en tu cuenta","tags":["Depósitos"],"x-binkio-scopes":["deposits:read"]}},"/v1/deposits/{id}":{"get":{"description":"Tres estados: `processing` (llegó y se está confirmando), `completed` (acreditado en tu saldo) y `failed`.\\n\\n**`processing` no es un fallo**: un depósito en cadena espera confirmaciones y uno por transferencia espera al banco.\n\n**Alcance requerido:** `deposits:read`.","operationId":"get_deposit","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"deposit"},"id":{"type":"string","example":"e2f8a1c4-6b09-4d73-8e5a-1c7f3b90d426"},"status":{"type":"string","example":"completed"},"rail":{"type":"string","example":"spei"},"amount":{"type":"string","example":"25000.00000000"},"asset":{"type":"string","example":"MXNB"},"source":{"type":"string","example":"012180001234567890"},"provider_reference":{"type":"string","example":"JUNO-ISS-7C3D1A2B","nullable":true},"created_at":{"type":"string","example":"2026-09-08T10:14:02.000Z"},"completed_at":{"type":"string","example":"2026-09-08T10:14:37.000Z","nullable":true}}},"example":{"object":"deposit","id":"e2f8a1c4-6b09-4d73-8e5a-1c7f3b90d426","status":"completed","rail":"spei","amount":"25000.00000000","asset":"MXNB","source":"012180001234567890","provider_reference":"JUNO-ISS-7C3D1A2B","created_at":"2026-09-08T10:14:02.000Z","completed_at":"2026-09-08T10:14:37.000Z"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"403":{"description":"`insufficient_scope` — La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"insufficient_scope":{"summary":"insufficient_scope","value":{"error":{"type":"permission_error","code":"insufficient_scope","message":"La credencial es válida pero no tiene el alcance que exige este endpoint. Aquí SÍ se dice cuál falta: quien pregunta ya demostró tener una credencial buena.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`deposit_not_found` — No hay ese depósito en tu cuenta. Mismo error si no existe que si es de otra cuenta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"deposit_not_found":{"summary":"deposit_not_found","value":{"error":{"type":"not_found","code":"deposit_not_found","message":"No hay ese depósito en tu cuenta. Mismo error si no existe que si es de otra cuenta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[{"api-key":[]}],"summary":"El detalle de un depósito","tags":["Depósitos"],"x-binkio-scopes":["deposits:read"]}},"/v1/checkout/{code}":{"get":{"description":"Público: la credencial es el propio código del enlace. Devuelve el importe, quién cobra, las instrucciones de cada método y **hasta cuándo vale cada importe**. Un método con la cotización vencida no trae ni importe ni instrucciones: enviar dinero contra un importe caducado no acredita.\n\n**Alcance requerido:** ninguno. Basta una credencial válida — es una comprobación, y exigir un alcance para ella empujaría a emitir claves más permisivas de lo necesario.","operationId":"get_checkout","parameters":[{"name":"code","required":true,"in":"path","schema":{"example":"PL-A1B2-C3D4-E5F6","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"checkout"},"return_url":{"type":"string","example":"https://tutienda.com/pedido/4821/gracias","nullable":true},"code":{"type":"string","example":"PL-A1B2-C3D4-E5F6"},"status":{"type":"string","example":"active"},"payable":{"type":"boolean","example":true},"unpayable_reason":{"type":"string","nullable":true},"amount":{"type":"string","example":"1500.00000000"},"currency":{"type":"string","example":"MXNB"},"description":{"type":"string","example":"Pedido #10432"},"merchant":{"type":"object","properties":{"object":{"type":"string","example":"checkout_merchant"},"name":{"type":"string","example":"Tienda Ejemplo"}}},"server_time":{"type":"string","example":"2026-09-07T18:30:00.000Z"},"expires_at":{"type":"string","example":"2026-09-08T18:30:00.000Z"},"expires_in":{"type":"integer","example":86400},"paid_at":{"type":"string","nullable":true},"checkout_url":{"type":"string","example":"https://app.binkio.com/pay/PL-A1B2-C3D4-E5F6"},"qr":{"type":"object","properties":{"object":{"type":"string","example":"checkout_qr"},"format":{"type":"string","example":"svg"},"encodes":{"type":"string","example":"https://app.binkio.com/pay/PL-A1B2-C3D4-E5F6"},"svg":{"type":"string","example":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"}}},"methods":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","example":"checkout_method"},"method":{"type":"string","example":"SPEI"},"asset":{"type":"string","example":"MXN"},"requires_conversion":{"type":"boolean","example":true},"payable":{"type":"boolean","example":true},"quote":{"type":"object","properties":{"object":{"type":"string","example":"checkout_quote"},"status":{"type":"string","example":"locked"},"amount_due":{"type":"string","example":"1522.50"},"fee":{"type":"string","example":"0.00"},"exchange_rate":{"type":"string","example":"1.00000000"},"expires_at":{"type":"string","example":"2026-09-07T18:45:00.000Z"},"expires_in":{"type":"integer","example":900}}},"instructions":{"type":"object","properties":{"clabe":{"type":"string","example":"710969000000123456"},"beneficiary":{"type":"string","example":"Binkio SA de CV"},"reference":{"type":"string","example":"BNKA1B2C3"},"address":{"type":"string","example":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b"},"network":{"type":"string","example":"ARBITRUM"}}}}}},"realtime":{"type":"object","properties":{"object":{"type":"string","example":"checkout_realtime"},"transport":{"type":"string","example":"socket.io"},"url":{"type":"string","example":"https://api.binkio.com"},"namespace":{"type":"string","example":"/checkout"},"path":{"type":"string","example":"/socket.io"},"join":{"type":"object","properties":{"event":{"type":"string","example":"checkout:join"},"payload":{"type":"object","properties":{"code":{"type":"string","example":"PL-A1B2-C3D4-E5F6"}}}}},"notify_events":{"type":"array","items":{"type":"string","example":"payment_link:paid"}},"status_url":{"type":"string","example":"https://api.binkio.com/v1/checkout/PL-A1B2-C3D4-E5F6/status"},"poll_interval_seconds":{"type":"integer","example":5}}}}},"example":{"object":"checkout","return_url":"https://tutienda.com/pedido/4821/gracias","code":"PL-A1B2-C3D4-E5F6","status":"active","payable":true,"unpayable_reason":null,"amount":"1500.00000000","currency":"MXNB","description":"Pedido #10432","merchant":{"object":"checkout_merchant","name":"Tienda Ejemplo"},"server_time":"2026-09-07T18:30:00.000Z","expires_at":"2026-09-08T18:30:00.000Z","expires_in":86400,"paid_at":null,"checkout_url":"https://app.binkio.com/pay/PL-A1B2-C3D4-E5F6","qr":{"object":"checkout_qr","format":"svg","encodes":"https://app.binkio.com/pay/PL-A1B2-C3D4-E5F6","svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29 29\" shape-rendering=\"crispEdges\"><path fill=\"#fff\" d=\"M0 0h29v29H0z\"/><path stroke=\"#000\" d=\"M1 1.5h7m2 0h1m1 0h7\"/></svg>"},"methods":[{"object":"checkout_method","method":"SPEI","asset":"MXN","requires_conversion":true,"payable":true,"quote":{"object":"checkout_quote","status":"locked","amount_due":"1522.50","fee":"0.00","exchange_rate":"1.00000000","expires_at":"2026-09-07T18:45:00.000Z","expires_in":900},"instructions":{"clabe":"710969000000123456","beneficiary":"Binkio SA de CV","reference":"BNKA1B2C3"}},{"object":"checkout_method","method":"MXNB","asset":"MXNB","requires_conversion":false,"payable":true,"quote":{"object":"checkout_quote","status":"native","amount_due":"1500.00000000","fee":"0.00000000"},"instructions":{"address":"0x9c8b7e1d3a5f6c2b0a9d8e7f6a5b4c3d2e1f0a9b","network":"ARBITRUM"}}],"realtime":{"object":"checkout_realtime","transport":"socket.io","url":"https://api.binkio.com","namespace":"/checkout","path":"/socket.io","join":{"event":"checkout:join","payload":{"code":"PL-A1B2-C3D4-E5F6"}},"notify_events":["payment_link:paid","payment_link:quotes_updated"],"status_url":"https://api.binkio.com/v1/checkout/PL-A1B2-C3D4-E5F6/status","poll_interval_seconds":5}}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`checkout_not_found` — No existe un cobro con ese código. Suele ser un código incompleto o mal copiado.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"checkout_not_found":{"summary":"checkout_not_found","value":{"error":{"type":"not_found","code":"checkout_not_found","message":"No existe un cobro con ese código. Suele ser un código incompleto o mal copiado.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[],"summary":"El cobro tal como lo ve quien va a pagar","tags":["Checkout"],"x-binkio-scopes":[]}},"/v1/checkout/{code}/status":{"get":{"description":"Respuesta mínima y sin QR. Pensado para llamarse tras un aviso del canal en tiempo real, o cada `poll_interval_seconds` si no se puede usar. Es la FUENTE DE VERDAD del estado: la carga útil de los eventos del socket no forma parte de este contrato.\n\n**Alcance requerido:** ninguno. Basta una credencial válida — es una comprobación, y exigir un alcance para ella empujaría a emitir claves más permisivas de lo necesario.","operationId":"get_checkout_status","parameters":[{"name":"code","required":true,"in":"path","schema":{"example":"PL-A1B2-C3D4-E5F6","type":"string"}},{"name":"Binkio-Version","in":"header","description":"Versión del contrato para esta llamada. Sin ella se aplica la que tiene fijada tu credencial, que no cambia sola. Sirve para probar una versión nueva en una llamada suelta antes de adoptarla. Una versión que no existe se rechaza con `400 unknown_api_version`: no se cae en silencio a la actual.","required":false,"schema":{"type":"string","example":"2026-09-09"}}],"responses":{"200":{"description":"Operación correcta.","headers":{"Binkio-Version":{"description":"Versión del contrato con la que se construyó ESTA respuesta. Va siempre, se haya pedido o no: es cómo se descubre en qué versión está uno sin leer nada.","schema":{"type":"string","example":"2026-09-09"}},"X-Request-Id":{"description":"Identificador de ESTA llamada (`req_…`). Va también en el cuerpo, y es lo primero que pide soporte. Aparece en `GET /v1/request_logs`.","schema":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}},"RateLimit-Limit":{"description":"Peticiones por minuto que admite esta credencial.","schema":{"type":"integer","example":120}},"RateLimit-Remaining":{"description":"Peticiones que quedan en la ventana actual.","schema":{"type":"integer","example":118}},"RateLimit-Reset":{"description":"Segundos hasta que la ventana se reinicia.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","example":"checkout_status"},"code":{"type":"string","example":"PL-A1B2-C3D4-E5F6"},"status":{"type":"string","example":"active"},"payable":{"type":"boolean","example":true},"unpayable_reason":{"type":"string","nullable":true},"paid_at":{"type":"string","nullable":true},"server_time":{"type":"string","example":"2026-09-07T18:30:00.000Z"}}},"example":{"object":"checkout_status","code":"PL-A1B2-C3D4-E5F6","status":"active","payable":true,"unpayable_reason":null,"paid_at":null,"server_time":"2026-09-07T18:30:00.000Z"}}}},"400":{"description":"`unknown_api_version` — La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"unknown_api_version":{"summary":"unknown_api_version","value":{"error":{"type":"invalid_request","code":"unknown_api_version","message":"La cabecera `Binkio-Version` trae una versión que no existe. El mensaje enumera las válidas.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"401":{"description":"`invalid_api_key` — La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"invalid_api_key":{"summary":"invalid_api_key","value":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"La credencial no sirve. Un solo motivo publicado para todos los casos (inexistente, revocada, caducada, de otro entorno, IP no permitida, cuenta sin verificación de empresa aprobada); el real queda en nuestro registro interno.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"404":{"description":"`checkout_not_found` — No existe un cobro con ese código. Suele ser un código incompleto o mal copiado.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"checkout_not_found":{"summary":"checkout_not_found","value":{"error":{"type":"not_found","code":"checkout_not_found","message":"No existe un cobro con ese código. Suele ser un código incompleto o mal copiado.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"429":{"description":"`rate_limit_exceeded` — Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","headers":{"Retry-After":{"description":"Segundos que hay que esperar antes de volver a intentarlo. Espera esto, no un valor inventado: reintentar antes vuelve a dar 429 y consume otro hueco de la ventana.","schema":{"type":"integer","example":41}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"rate_limit_exceeded":{"summary":"rate_limit_exceeded","value":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Se superó el límite por minuto de la credencial, o la cuota diaria de operaciones de dinero. La cabecera `Retry-After` dice cuántos segundos esperar.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}},"500":{"description":"`internal_error` — Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","conflict","rate_limit_error","api_error"],"example":"invalid_request"},"code":{"type":"string","example":"insufficient_balance"},"message":{"type":"string","example":"No hay saldo suficiente para esta operación."},"param":{"type":"string","example":"amount"},"request_id":{"type":"string","example":"req_9f2a4c8b7e1d3a5f"}}}}},"examples":{"internal_error":{"summary":"internal_error","value":{"error":{"type":"api_error","code":"internal_error","message":"Fallamos nosotros. El `request_id` de la respuesta identifica la llamada exacta.","request_id":"req_9f2a4c8b7e1d3a5f"}}}}}}}},"security":[],"summary":"Estado del cobro, para sondear mientras se espera el pago","tags":["Checkout"],"x-binkio-scopes":[]}}},"info":{"title":"Binkio API","description":"La API de Binkio para mover dinero desde tu propio sistema: consultar saldos y\nmovimientos, crear cobros y recibir avisos cuando se pagan.\n\nBase: `https://api.binkio.com/v1`. Todo lo de esta referencia cuelga de ahí.\n\n---\n\n## Autenticación\n\nCabecera `Authorization`, con el secreto de tu credencial:\n\n```\nAuthorization: Bearer bk_live_sec_7f3a…\n```\n\nEl prefijo declara el entorno: `bk_test_…` contra el entorno de pruebas,\n`bk_live_…` contra el real. Se distinguen a simple vista en un log, en una\ncaptura o en un ticket — es la defensa más barata contra configurar la\ncredencial equivocada.\n\nEl secreto se muestra **una sola vez**, al crearlo. Si se pierde, se rota; no\nse recupera. Puedes tener **dos credenciales activas a la vez**: ése es el\nprocedimiento de rotación sin cortar servicio (crea la nueva, despliégala,\ncomprueba que la vieja dejó de usarse, revócala).\n\n**Todos los fallos de autenticación devuelven el mismo `401`**, con el mismo\ncuerpo: no distinguimos «revocada» de «IP no permitida» de «no existe». No es\nuna carencia de la documentación; distinguirlos le diría a quien está probando\ncredenciales que acertó una y sólo le falta cambiar de red.\n\n### Alcances\n\nCada credencial lleva los permisos que le diste, por recurso y acción\n(`balances:read`, `links:write`, `logs:read`…). Cada endpoint declara el\nsuyo. Emite claves con lo mínimo: una terminal de mostrador necesita crear\ncobros, no leer el histórico de la empresa — si esa terminal se compromete, el\ndaño queda acotado a lo que su clave podía hacer.\n\nSi a la credencial le falta el alcance, la respuesta es `403` y **sí dice\ncuál falta**: quien pregunta ya demostró tener una credencial válida.\n\n---\n\n## Idempotencia\n\nObligatoria en **todo método que crea o modifica** (`POST`, `PUT`,\n`PATCH`, `DELETE`). Sin la cabecera, `400`.\n\n```\nIdempotency-Key: 9f2a4c8b-7e1d-4a5f-8c3b-2d1e0f9a8b7c\n```\n\nUna clave por **operación**, no por reintento: los reintentos de la misma\noperación repiten la clave, y eso es justo lo que impide el cobro duplicado\ncuando una terminal con mala cobertura no llega a ver la respuesta.\n\n| Situación | Respuesta |\n|---|---|\n| Clave nueva | Se ejecuta y se guarda la respuesta. |\n| Misma clave, mismo cuerpo, ya terminada | La respuesta **guardada**, con `Idempotent-Replay: true`. **No se vuelve a ejecutar.** |\n| Misma clave, mismo cuerpo, en curso | `409 idempotency_request_in_progress`. Reintenta en unos segundos con la misma clave. |\n| Misma clave, **cuerpo distinto** | `422 idempotency_key_reused`. Es el caso peligroso: significa que reutilizaste la clave para otra operación. Ejecutarla sería cobrar dos veces con nuestra bendición. |\n| Clave de hace más de 24 h | Se trata como nueva. |\n\nCómo comprobar que tu manejo es correcto sin mover un peso: llama dos veces a\n`POST /v1/ping` con la misma clave. Si el `execution_id` es el mismo y\nllega `Idempotent-Replay: true`, tu reintento no duplicó nada. Si cambia,\nejecutaste dos veces — y más vale descubrirlo ahí que con un cobro.\n\n---\n\n## Versiones\n\nEl contrato lleva fecha. La RUTA sigue siendo `/v1` —eso identifica la API—\npero lo que decide la forma de cada respuesta es una **versión con fecha**, y\nva en la cabecera `Binkio-Version` de toda respuesta, la hayas\npedido o no.\n\nSe resuelve en este orden:\n\n| Orden | De dónde sale |\n|---|---|\n| 1 | La cabecera `Binkio-Version` de tu petición. |\n| 2 | La versión FIJADA en tu credencial al emitirla. **No cambia sola.** |\n| 3 | La actual — sólo en el checkout, que no lleva credencial. |\n\nQue el paso 2 no cambie solo es el punto entero: una integración escrita hoy\nsigue recibiendo la forma de hoy cuando publiquemos la siguiente. Subir de\nversión es una decisión tuya.\n\nManda la cabecera para probar una versión nueva **en una llamada suelta**,\ndesde `curl`, antes de tocar nada. Una versión que no existe se rechaza con\n`400 unknown_api_version` y el mensaje enumera las válidas: no se cae en\nsilencio a la actual, porque un dedazo que cambia el comportamiento en silencio\nes peor que un error.\n\n| Versión | Qué trae |\n|---|---|\n| `2026-09-09` | Línea de salida del contrato versionado. Incluye los eventos de enlace de pago con `code` y `amount` alineados con la API REST, y el neto del comercio en `net_amount` / `net_currency`. |\n\n---\n\n## Límites\n\nDos, y hacen falta los dos: **peticiones por minuto** (abuso técnico) y\n**operaciones de dinero por día** (abuso económico — una credencial robada que\nrespete el límite por minuto puede crear cientos de miles de cobros al día).\n\nLos límites son **por credencial**, no por IP: detrás de un comercio hay\nmuchas terminales tras la misma salida a internet, y un cubo por IP dejaría a\ntodas sin servicio por culpa de una.\n\nCada respuesta trae con qué autorregularte:\n\n| Cabecera | Qué dice |\n|---|---|\n| `RateLimit-Limit` | Peticiones por minuto de esta credencial. |\n| `RateLimit-Remaining` | Cuántas quedan en la ventana actual. |\n| `RateLimit-Reset` | Segundos hasta que la ventana se reinicia. |\n| `RateLimit-Money-*` | Lo mismo para la cuota diaria de operaciones de dinero (sólo en métodos que mutan). |\n\nAl pasarte: `429` y `Retry-After` con los segundos que faltan. Usa las\ncabeceras y no llegarás a verlo.\n\n---\n\n## Errores\n\nMismo sobre en toda la API:\n\n```json\n{\n  \"error\": {\n    \"type\": \"invalid_request\",\n    \"code\": \"insufficient_balance\",\n    \"message\": \"No hay saldo suficiente para esta operación.\",\n    \"param\": \"amount\",\n    \"request_id\": \"req_9f2a4c8b7e1d3a5f\"\n  }\n}\n```\n\n- **`type`** — familia estable y corta. Es con lo que decides qué hacer\n  (reintentar, arreglar la petición, avisar a una persona) sin conocer el\n  catálogo completo.\n- **`code`** — el caso concreto. **Es lo que debes comparar en tu código.**\n  No compares `message`: cambia, se traduce y se reescribe.\n- **`param`** — qué campo lo provocó, cuando se puede determinar.\n- **`request_id`** — identifica esta llamada exacta.\n\n### `request_id`\n\nVa **siempre**: en la cabecera `X-Request-Id` y en el cuerpo, tanto en éxito\ncomo en error. Guárdalo. Es lo primero que pide soporte, y es la clave con la\nque encuentras tu propia llamada en `GET /v1/request_logs`.\n\n---\n\n## Paginación\n\nPor **cursor**, no por número de página: un histórico al que se le añaden\nfilas por delante hace que la página 2 de un listado por desplazamiento\ncontenga cosas que ya viste en la página 1.\n\n```\nGET /v1/transactions?limit=50\nGET /v1/transactions?limit=50&cursor=eyJ2IjoxLCJ0Ijoi…\n```\n\nRepite mientras `has_more` sea `true`, pasando el `next_cursor` de la\nrespuesta anterior. **No te guíes por el número de elementos**: una página\npuede venir con menos de `limit` y aún tener más detrás.\n\nEl cursor es **opaco**. No lo interpretes ni lo construyas: su contenido no\nforma parte del contrato y puede cambiar.\n\n---\n\n## Importes\n\nSiempre **cadena decimal**, nunca número:\n\n```json\n{ \"amount\": \"1500.00000000\" }\n```\n\nUn `float` de JSON no representa `0.1` exactamente. Un cliente que hace\n`JSON.parse` sobre `{\"amount\": 1234567.89}` ya perdió precisión antes de\ntocar el dato. La cadena es lo único que sobrevive intacto a cualquier\nlenguaje. Mándalos igual: un número en el cuerpo recibe `400`.\n\n---\n\n## Avisos (webhooks)\n\nPara no tener que sondear, registra un destino en el panel y te enviamos un\naviso firmado cuando algo pasa en tu cuenta. El contrato de firma —qué se\nfirma exactamente, cómo se verifica y por qué **no debes reserializar el\ncuerpo** antes de comprobarlo— está en la guía de webhooks:\n\nhttps://docs.binkio.com/api/webhooks\n\nEsa guía es la única fuente del contrato de firma. No se reproduce aquí a\npropósito: dos copias de un contrato criptográfico acaban diciendo cosas\ndistintas, y la que leas será la equivocada.\n\n---\n\n## Tu tráfico\n\n`GET /v1/request_logs` devuelve **tus propias llamadas**: qué pediste, qué\nrespondimos, cuándo, desde qué IP y con qué credencial. Es el sitio donde\nmirar antes de abrir un ticket.","version":"v1 (2026-09-09)","contact":{},"license":{"name":"Uso sujeto a los Términos de Servicio de Binkio","url":"https://binkio.com/terminos"}},"tags":[{"name":"Cuenta","description":"Comprobación de vida, verificación de la credencial y saldos por activo."},{"name":"Enlaces de pago","description":"Crear, consultar y cancelar cobros. Es el motor: multimoneda, multirriel y con conversión cuando la moneda del pagador no es la tuya."},{"name":"Cobro con QR","description":"El QR fijo de mostrador y los cargos que se generan contra él."},{"name":"Movimientos","description":"Histórico de la cuenta y detalle de cada movimiento."},{"name":"Webhooks","description":"Destinos a los que te avisamos cuando algo pasa en tu cuenta, y su secreto de firma."},{"name":"Registro de llamadas","description":"Tus propias llamadas a la API: qué pediste, qué respondimos y cuándo. Es lo primero que hay que mirar cuando algo no cuadra."},{"name":"Depósitos","description":"Dónde te pueden mandar dinero —CLABE, llave Bre-B, direcciones on-chain— y qué ha entrado. Sólo lectura: un depósito lo inicia quien envía."},{"name":"Conversiones","description":"Cambiar el saldo de un activo a otro. Dos pasos: pedir precio y ejecutarlo, porque el precio caduca."},{"name":"Retiros","description":"Sacar el dinero cobrado hacia tus cuentas bancarias. Sólo a destinos ya dados de alta: la API no puede añadir uno nuevo."},{"name":"Checkout","description":"La pantalla que ve el PAGADOR. Sin credencial, a propósito: quien paga no tiene cuenta con nosotros."}],"servers":[{"url":"https://api.binkio.com","description":"Producción"}],"components":{"securitySchemes":{"api-key":{"type":"http","scheme":"bearer","description":"El secreto de tu credencial, tal cual: `bk_live_sec_…`. Es una cadena opaca, no un JWT — no hay nada que descomponer dentro.\n\nLa credencial pertenece al entorno donde se emitió. **No hay un entorno de pruebas separado**: para ensayar, usa importes pequeños con una credencial de alcances mínimos."}},"schemas":{"CreatePublicPaymentLinkDto":{"type":"object","properties":{"amount":{"type":"string","description":"Importe que recibirá la cuenta, en la divisa indicada en `currency`. El mínimo y el máximo dependen de la divisa.","example":"1500.25","pattern":"^\\d{1,12}(\\.\\d{1,8})?$"},"currency":{"type":"string","enum":["MXNB","USDC","COP"],"description":"Divisa que recibe la cuenta. Un enlace en `COP` se liquida 1:1 en pesos colombianos y sólo admite el método `COP`.","example":"MXNB"},"description":{"type":"string","description":"Concepto. Es lo que ve el pagador.","minLength":1,"maxLength":255,"example":"Factura A-1042"},"accepted_methods":{"type":"array","description":"Métodos que el enlace admitirá. Si se omite, el sistema determina los viables a partir de la divisa y el importe (pisos de conversión, mínimos de los rieles fiat) — es la opción recomendada: pedir un método que el importe no soporta devuelve 400.","minItems":1,"maxItems":5,"uniqueItems":true,"example":["SPEI","USDC"],"items":{"type":"string","enum":["SPEI","WIRE","MXNB","USDC","USDT","COP"]}},"fee_bearer":{"type":"string","enum":["payer","merchant"],"description":"Quién asume la comisión. Con `payer` (por defecto) el comercio recibe el importe íntegro.","default":"payer","example":"payer"},"expires_at":{"type":"string","format":"date-time","description":"Caducidad del enlace. Debe estar en el futuro. Si se omite, se aplica la caducidad por defecto de la plataforma.","example":"2026-12-31T23:59:00Z"},"return_url":{"type":"string","description":"A dónde devolver al pagador cuando termina. Tiene que ser `https:`. Si se omite, la página de cobro no ofrece vuelta.","maxLength":2000,"pattern":"^https:\\/\\/[^\\s]+$","example":"https://tutienda.com/pedido/4821/gracias"},"metadata":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"description":"Pares clave-valor tuyos. Se devuelven tal cual aquí y en el webhook, y no los interpretamos nunca: úsalos para atar este cobro a tu pedido sin mantener una tabla aparte. Máximo 50 claves, clave de 40 caracteres y valor de 500; los valores son cadenas (un número se rechaza, no se convierte). **No metas datos personales**: esto acaba en tus registros, en los nuestros y en correos de soporte.","example":{"order_id":"4821","sucursal":"centro"}}},"required":["amount","currency","description"]},"CreatePublicQrDto":{"type":"object","properties":{"display_name":{"type":"string","description":"Nombre comercial que ve el pagador. Si se omite, se usa el de la cuenta.","maxLength":80,"example":"Cafeteria Central"},"currency":{"type":"string","enum":["MXNB","USDC","COP"],"description":"Divisa en la que se generarán los cobros. Si se omite, se deduce de los activos que la cuenta tenga aprobados.","example":"MXNB"}}},"UpdatePublicQrDto":{"type":"object","properties":{"qr_id":{"type":"string","description":"El QR sobre el que operar. Hoy la cuenta tiene uno solo y se puede omitir; mandarlo desde el principio deja la terminal preparada para cuando haya varios.","maxLength":32,"example":"qr_7Kd93Lm2Pq8Rt5Vw1Xy4Zb"},"display_name":{"type":"string","description":"Nombre comercial que ve el pagador. `null` lo borra y vuelve al de la cuenta; omitirlo lo deja como está.","maxLength":80,"nullable":true,"example":"Cafeteria Central"},"currency":{"type":"string","enum":["MXNB","USDC","COP"],"description":"Divisa en la que se generarán los cobros. Si se omite, se deduce de los activos que la cuenta tenga aprobados.","example":"MXNB"},"max_amount_per_charge":{"type":"string","description":"Tope por cobro. `null` lo quita.","example":"50000.00","pattern":"^\\d{1,12}(\\.\\d{1,8})?$","nullable":true},"max_amount_per_day":{"type":"string","description":"Tope diario agregado sobre lo COBRADO en el día. `null` lo quita.","example":"200000.00","pattern":"^\\d{1,12}(\\.\\d{1,8})?$","nullable":true}}},"PublicQrRefDto":{"type":"object","properties":{"qr_id":{"type":"string","description":"El QR sobre el que operar. Hoy la cuenta tiene uno solo y se puede omitir; mandarlo desde el principio deja la terminal preparada para cuando haya varios.","maxLength":32,"example":"qr_7Kd93Lm2Pq8Rt5Vw1Xy4Zb"}}},"CreatePublicQrChargeDto":{"type":"object","properties":{"qr_id":{"type":"string","description":"El QR sobre el que operar. Hoy la cuenta tiene uno solo y se puede omitir; mandarlo desde el principio deja la terminal preparada para cuando haya varios.","maxLength":32,"example":"qr_7Kd93Lm2Pq8Rt5Vw1Xy4Zb"},"amount":{"type":"string","description":"Importe a cobrar, en la divisa del QR.","example":"350.50","pattern":"^\\d{1,12}(\\.\\d{1,8})?$"},"reference":{"type":"string","description":"Concepto libre del cobro («Mesa 5», «Pedido 12»). Admite letras, números, espacios y `.,#-_/()'\"&:`","maxLength":80,"pattern":"^[\\p{L}\\p{N}\\s.,#\\-_/()'\"&:]+$","example":"Mesa 5"}},"required":["amount"]},"CreatePublicWebhookEndpointDto":{"type":"object","properties":{"url":{"type":"string","description":"URL a la que enviaremos los avisos. Tiene que ser `https:` y resolver a una dirección pública: se comprueba al darla de alta y antes de CADA envío, y no se sigue ninguna redirección.","minLength":1,"maxLength":2000,"example":"https://api.tucomercio.com/binkio/webhooks"},"description":{"type":"string","description":"Etiqueta para distinguirlos cuando tienes varios.","maxLength":200,"example":"Produccion — cobros"},"enabled_events":{"description":"Eventos a los que se suscribe. Los válidos salen de `GET /v1/webhook_endpoints/event_types`.","minItems":1,"maxItems":50,"uniqueItems":true,"example":["payment_link.paid","withdrawal.completed"],"type":"array","items":{"type":"string"}}},"required":["url","enabled_events"]},"UpdatePublicWebhookEndpointDto":{"type":"object","properties":{"url":{"type":"string","description":"URL a la que enviaremos los avisos. Tiene que ser `https:` y resolver a una dirección pública: se comprueba al darla de alta y antes de CADA envío, y no se sigue ninguna redirección.","minLength":1,"maxLength":2000,"example":"https://api.tucomercio.com/binkio/webhooks"},"description":{"type":"string","description":"Etiqueta del destino. La cadena vacía la QUITA; omitir el campo la deja como está.","maxLength":200,"example":"Produccion — cobros"},"enabled_events":{"description":"Eventos a los que se suscribe. Los válidos salen de `GET /v1/webhook_endpoints/event_types`.","minItems":1,"maxItems":50,"uniqueItems":true,"example":["payment_link.paid","withdrawal.completed"],"type":"array","items":{"type":"string"}}}},"CreatePublicWithdrawalDto":{"type":"object","properties":{"destination_id":{"type":"string","format":"uuid","description":"El destino al que enviar, tomado de `GET /v1/payout_destinations`. El riel (SPEI o WIRE) lo determina el destino, no el cuerpo.","example":"d41f8a2c-9b73-4e15-a6c8-3f0e7b2d1a94"},"amount":{"type":"string","description":"Importe a retirar, en la divisa del destino.","example":"1500.00","pattern":"^\\d{1,12}(\\.\\d{1,8})?$"},"concept":{"type":"string","description":"Lo que verá el beneficiario en su estado de cuenta. El tope de 40 caracteres lo impone SPEI.","minLength":1,"maxLength":40,"example":"Liquidacion septiembre"},"fee_mode":{"type":"string","enum":["net_out","gross_up"],"description":"Quién asume la comisión. `net_out` (por defecto) la descuenta del importe: pides 1000 y llegan 1000 menos comisión. `gross_up` la suma: llegan 1000 exactos y de tu saldo sale algo más.","default":"net_out","example":"net_out"}},"required":["destination_id","amount","concept"]},"TravelRuleBeneficiaryDto":{"type":"object","properties":{"first_name":{"type":"string","description":"Nombre del beneficiario.","minLength":1,"maxLength":80,"example":"Ana"},"last_name":{"type":"string","description":"Apellidos del beneficiario.","minLength":1,"maxLength":80,"example":"Martinez"},"country":{"type":"string","description":"País del beneficiario, ISO 3166-1 alfa-2.","minLength":2,"maxLength":2,"example":"MX"},"vasp_name":{"type":"string","description":"Nombre de la plataforma de destino, si el envío va a otra (Binance, Coinbase…). Se omite cuando el destino es una cartera propia.","maxLength":80,"example":"Binance"},"vasp_country":{"type":"string","description":"País de esa plataforma, ISO 3166-1 alfa-2.","minLength":2,"maxLength":2,"example":"MT"}},"required":["first_name","last_name","country"]},"CreatePublicCryptoWithdrawalDto":{"type":"object","properties":{"asset":{"type":"string","enum":["MXNB","USDC","USDT"],"description":"Activo a enviar.","example":"USDC"},"amount":{"type":"string","description":"Importe a enviar, en el activo indicado.","example":"500.00","pattern":"^\\d{1,12}(\\.\\d{1,8})?$"},"address":{"type":"string","description":"Dirección de destino. **No se valida contra ninguna lista**: sólo se comprueba la forma. Que sea la dirección correcta es cosa tuya, y el envío no tiene vuelta atrás.","minLength":20,"maxLength":128,"example":"0x742d35Cc6634C0532925a3b844Bc454e4438f44e"},"network":{"type":"string","description":"Red por la que enviar. **Obligatorio y sin valor por defecto**: el mismo activo vive en varias redes, la dirección se parece, y enviarlo por la equivocada lo pierde. Las redes disponibles para cada activo salen de lo que el proveedor admita en ese momento.","minLength":2,"maxLength":32,"example":"arbitrum"},"fee_mode":{"type":"string","enum":["net_out","gross_up"],"description":"Quién asume la comisión. `net_out` (por defecto) la descuenta del importe: pides 1000 y llegan 1000 menos comisión. `gross_up` la suma: llegan 1000 exactos y de tu saldo sale algo más.","default":"net_out","example":"net_out"},"beneficiary":{"description":"Datos del beneficiario, exigidos por la Regla de Viaje a partir de cierto importe (FATF R.16). Por debajo del umbral se ignoran.","allOf":[{"$ref":"#/components/schemas/TravelRuleBeneficiaryDto"}]}},"required":["asset","amount","address","network"]},"CreatePublicConversionQuoteDto":{"type":"object","properties":{"from_asset":{"type":"string","enum":["MXNB","USDC","USDT","COP"],"description":"Activo de origen.","example":"USDC"},"to_asset":{"type":"string","enum":["MXNB","USDC","USDT","COP"],"description":"Activo de destino.","example":"MXNB"},"amount":{"type":"string","description":"Cuánto convertir, expresado en `from_asset`.","example":"1500.00","pattern":"^\\d{1,12}(\\.\\d{1,8})?$"}},"required":["from_asset","to_asset","amount"]},"ExecutePublicConversionDto":{"type":"object","properties":{"quote_id":{"type":"string","description":"El `id` que devolvió `POST /v1/conversions/quote`.","example":"qt_9f2a4c8b7e1d3a5f"},"from_asset":{"type":"string","enum":["MXNB","USDC","USDT","COP"],"description":"Activo de origen. Debe coincidir con el de la cotización: si no, se rechaza sin convertir nada.","example":"USDC"},"to_asset":{"type":"string","enum":["MXNB","USDC","USDT","COP"],"description":"Activo de destino. Debe coincidir con el de la cotización.","example":"MXNB"},"amount":{"type":"string","description":"Importe a convertir. Debe coincidir con el de la cotización.","example":"1500.00","pattern":"^\\d{1,12}(\\.\\d{1,8})?$"},"max_slippage_bps":{"type":"number","format":"int32","description":"Cuánto puede empeorar la tasa entre cotizar y ejecutar, en puntos básicos (100 bps = 1 %). Si se supera, la conversión falla en vez de liquidarse a un precio que nadie aceptó.","minimum":0,"maximum":1000,"example":50}},"required":["quote_id","from_asset","to_asset","amount"]}}},"externalDocs":{"description":"Webhooks salientes: verificación de firma","url":"https://docs.binkio.com/api/webhooks"}}