# Construye con IA (/docs/ai)
Tu asistente de código (Claude, ChatGPT, Cursor, Copilot…) escribe mejor una integración cuando lee la fuente correcta. Te la damos en el formato que entiende.
} title="Skill para agentes" href="#skill">
Las reglas de una integración correcta, para instalar en tu agente.
} title="Servidor MCP" href="#mcp">
Tu agente busca y lee esta documentación en vivo.
} title="llms.txt" href="#llmstxt">
Toda la documentación en texto, para cualquier modelo.
} title="Copiar para IA" href="#cada-página">
Cada página en Markdown, a un clic.
## Skill [#skill]
Una Skill le enseña a tu agente cómo se integra Caibo Pay: descubrir con capabilities, idempotencia, montos como texto, firmas de webhooks, estados asíncronos y los pasos para cobrar y pagar.
```bash
mkdir -p ~/.claude/skills/caibo-pay
curl -fsSL https://docs.caibopay.app/skills/caibo-pay/SKILL.md -o ~/.claude/skills/caibo-pay/SKILL.md
```
Para un solo proyecto, guárdala en `.claude/skills/caibo-pay/SKILL.md` dentro del repositorio. Tu agente la usa cuando trabajas con Caibo Pay.
Descarga [`SKILL.md`](/skills/caibo-pay/SKILL.md) y agrégala a las instrucciones de tu agente: `AGENTS.md`, las reglas de Cursor (`.cursor/rules`) o las instrucciones de Copilot.
## MCP [#mcp]
El servidor MCP de esta documentación le da a tu agente herramientas para listar, buscar y leer cada guía y cada endpoint, siempre al día.
```txt
https://docs.caibopay.app/api/mcp
```
```bash
claude mcp add --transport http caibo-pay-docs https://docs.caibopay.app/api/mcp
```
```json title=".cursor/mcp.json"
{
"mcpServers": {
"caibo-pay-docs": { "url": "https://docs.caibopay.app/api/mcp" }
}
}
```
Cualquier cliente MCP con transporte HTTP (streamable HTTP): usa la URL de arriba.
El servidor MCP solo lee la documentación: no tiene tus claves ni llama a la API por ti.
## llms.txt [#llmstxt]
| Archivo | Contiene |
| --- | --- |
| [`/llms.txt`](/llms.txt) | El índice: cada página con su descripción. |
| [`/llms-full.txt`](/llms-full.txt) | Toda la documentación en un solo texto. |
| [`/openapi.json`](/openapi.json) | El contrato OpenAPI completo, para generar clientes y para tu agente. |
## Cada página [#cada-página]
Arriba de cada página tienes **Copiar para IA** (la página en Markdown) y **Abrir con IA** (la abre en ChatGPT, Claude o Cursor con la pregunta lista). También puedes agregar `.md` a cualquier URL:
```txt
https://docs.caibopay.app/docs/collect-one-payment.md
```
"Lee https://docs.caibopay.app/llms-full.txt. Integra Caibo Pay en mi backend para cobrar con PIX un monto exacto, con idempotencia, verificación de la firma de los webhooks y pruebas contra sandbox."
# Autenticación (/docs/authentication)
Cada solicitud lleva tu clave en el encabezado `Authorization`:
```bash
curl https://api-sandbox.caibopay.app/v1/account \
-H "Authorization: Bearer psp_test_..."
```
## Tus claves [#tus-claves]
| | Sandbox | Live |
| --- | --- | --- |
| Formato | `psp_test__` | `psp_live__` |
| Funciona en | `api-sandbox.caibopay.app` | `api.caibopay.app` |
- **Las emite Caibo.** Al abrir tu cuenta recibes tus claves; no se crean desde el panel ni desde la API. Para una clave nueva, o para revocar una, pídela a Caibo.
- **Se muestran una sola vez.** Caibo guarda solo una huella de la clave, no la clave. Guárdala en tu gestor de secretos.
- **Una clave, un entorno.** Una clave de sandbox enviada a live (o al revés) se rechaza igual que una clave inválida.
- El **prefijo** (los 12 caracteres después de `psp_test_`) identifica la clave sin revelarla: es lo que ves en `GET /v1/account` y en el panel, en Desarrolladores.
## Permisos (scopes) [#permisos-scopes]
| Scope | Permite |
| --- | --- |
| `read` | Todas las consultas (`GET`). |
| `write` | Crear, cambiar y mover dinero. |
Una clave puede tener uno o los dos. Usa una clave de solo lectura para tableros y reportes.
## La clave que estás usando [#la-clave-que-estás-usando]
`GET /v1/account` devuelve tu cuenta (`environment`, `primary_treasury_asset`…) y, en `credential`, la clave que hizo la solicitud: su `prefix`, sus `scopes` y su `expires_at` si tiene vencimiento. El secreto nunca se devuelve.
## Errores de autenticación [#errores-de-autenticación]
```json title="401 — clave ausente, inválida, revocada, vencida o de otro entorno"
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The API key is missing or not valid.",
"request_id": "req_6d665507f62a5773882fc053"
}
}
```
```json title="403 — la clave no tiene el scope"
{
"error": {
"type": "permission_error",
"code": "insufficient_scope",
"message": "This API key does not have the write scope.",
"request_id": "req_6d665507f62a5773882fc053"
}
}
```
Tu clave mueve dinero. Úsala solo desde tu servidor. Si necesitas que tu cliente pague desde su navegador, crea el cobro en tu servidor y muéstrale las instrucciones, o usa una [página alojada](/docs/hosted-pages).
# Saldos (/docs/balances)
```json
{
"data": [
{
"currency": "USDT",
"primary": true,
"available": "1250.000000",
"pending": "0.000000",
"reserved": "100.500000",
"in_settlement": "0.000000",
"earnings": "12.400000",
"total": "1350.500000",
"as_of": "2026-10-18T14:05:00Z"
}
]
}
```
| Campo | Qué es |
| --- | --- |
| `available` | Lo que puedes usar ahora: pagar, retirar, reembolsar. |
| `reserved` | Apartado para pagos y retiros en curso. |
| `pending` | Acreditado pero todavía no disponible. |
| `in_settlement` | En camino a tu cuenta en una liquidación. |
| `earnings` | Tus márgenes acumulados (`tenant_markup`). Se muestran aparte y **no** suman en `total`. |
| `total` | `available + pending + reserved + in_settlement`. |
| `primary` | Marca el saldo en tu moneda principal (`primary_treasury_asset`). |
Una moneda que nunca tuviste no aparece en la lista.
## Movimientos [#movimientos]
Cada movimiento de tu saldo, del más nuevo al más antiguo (se pagina con `after`):
```json
{
"id": "ent_01m3sgb1...",
"journal_id": "jrn_01m3sgb1...",
"purpose": "payout_reserve",
"account": "available",
"direction": "debit",
"amount": "100.500000",
"currency": "USDT",
"origin": { "type": "payout", "id": "pout_01m3sgb02af7nb0jf73vwv2sd4" },
"occurred_at": "2026-10-18T14:00:20Z"
}
```
- `account` dice qué parte del saldo se movió: `available`, `pending`, `reserved`, `in_settlement` o `earnings`.
- `direction` es `credit` o `debit`, y `amount` siempre es positivo.
- Dos movimientos con el mismo `journal_id` son los dos lados de una misma operación: por ejemplo, un pago mueve fondos de `available` a `reserved`.
- `origin` apunta a la operación: un cobro (`pin_`), un pago (`pout_`), un reembolso (`rfd_`), un retiro (`wdr_`), una liquidación (`stl_`) o un ajuste (`adj_`).
# Beneficiarios (/docs/beneficiaries)
| Campo | Obligatorio | Qué es |
| --- | --- | --- |
| `method` | Sí | El método de pago: `bank_transfer`, `pix`, `mobile_payment`… |
| `currency` | Sí | La moneda que recibe. |
| `details` | Sí | Los datos de la cuenta, según `beneficiary_fields` en capabilities. Nunca se devuelven. |
| `customer_id` | Según el país | El remitente. |
| `holder` | No | El nombre del titular, para mostrar. |
| `label` | No | Tu etiqueta, hasta 100 caracteres. |
| `metadata` | No | Tus datos. |
Validamos `details` al registrar. Un dato inválido responde `400 invalid_parameter` con `param: "details."`. Si registras dos veces la misma cuenta para el mismo cliente, recibes el beneficiario existente (`200`).
## Datos por país [#datos-por-país]
Método `bank_transfer`, a una cuenta por su **CCI**.
| Campo | Formato | Ejemplo |
| --- | --- | --- |
| `cci` | 20 dígitos | `00219100123456780123` |
| `document_number` | DNI (8 dígitos) o RUC (11 dígitos que empiezan con 10, 15 o 20) | `45678912` |
| `first_name` | Nombres del titular, como en su documento | `Rosa Elena` |
| `last_name` | Apellidos del titular | `Quispe Mamani` |
Necesita un **remitente** completo: ver [Clientes](/docs/customers).
Método `pix`.
| Campo | Formato | Ejemplo |
| --- | --- | --- |
| `name` | Nombre del titular, 2 a 140 caracteres | `Ana Souza` |
| `pix_key` | CPF (11 dígitos), CNPJ (14), teléfono `+55…`, correo o clave aleatoria (UUID) | `ana@example.com` |
Los dígitos verificadores de CPF y CNPJ se comprueban.
Métodos `mobile_payment` (pago móvil) y `bank_transfer`.
| Campo | Método | Formato | Ejemplo |
| --- | --- | --- | --- |
| `phone` | `mobile_payment` | `0412`, `0414`, `0416`, `0422`, `0424` o `0426` + 7 dígitos | `04121234567` |
| `account_number` | `bank_transfer` | 20 dígitos | `01020123450000012345` |
| `bank_code` | Ambos | 4 dígitos | `0102` |
| `document.type` | Ambos | `V`, `E`, `J`, `G`, `P`, `C` o `R` | `V` |
| `document.number` | Ambos | El número del documento | `12345678` |
| `name` | Ambos, opcional | Nombre del titular | `María Pérez` |
```json
{
"method": "mobile_payment",
"currency": "VES",
"details": {
"phone": "04121234567",
"bank_code": "0102",
"document": { "type": "V", "number": "12345678" }
}
}
```
Esta tabla es una guía. La fuente de verdad es `beneficiary_fields` en `GET /v1/capabilities?product=payout`: cada campo trae su `pattern`, así que puedes validar en tu formulario lo mismo que valida la API.
## Respuesta [#respuesta]
```json
{
"id": "ben_01m3sgazybenxvqfw0h5bnszk4",
"method": "bank_transfer",
"currency": "PEN",
"country": "PE",
"customer_id": "cus_01m3sgb02af7nb0jf73vwv2sd4",
"holder": "Rosa Elena Quispe Mamani",
"status": "active",
"verification_status": "unverified",
"created_at": "2026-10-18T14:00:05Z",
"updated_at": "2026-10-18T14:00:05Z"
}
```
`verification_status` pasa a `verified` cuando Caibo verifica la cuenta (`beneficiary.verified`). El país lo fija el método.
# Qué puedes hacer (/docs/capabilities)
Cada elemento de la respuesta es algo que tu cuenta puede hacer: un **producto** (`payin` para cobrar, `payout` para pagar, `remittance` para un corredor completo) por un **método** y en una **moneda**. Trae también los campos que pide, cómo se cobra y si puedes usarlo ahora.
Arma tus formularios con esta respuesta y no tendrás que cambiar código cuando Caibo abra un país o un método nuevo: simplemente aparecerá en la lista.
## Filtros [#filtros]
Todos son opcionales y se combinan:
| Parámetro | Ejemplo |
| --- | --- |
| `product` | `payin`, `payout`, `remittance` |
| `country` | `BR`, `PE` (ISO 3166-1 alfa-2) |
| `currency` | `BRL`, `PEN` |
| `method` | `pix`, `bank_transfer` |
```bash
curl "$CAIBO_API/v1/capabilities?product=payin¤cy=BRL" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
```json
{
"data": [
{
"product": "payin",
"operation": "payin",
"method": "pix",
"currency": "BRL",
"country": "BR",
"payment_currency": "BRL",
"settlement_currencies": ["USDT"],
"settlement_asset": "USDT",
"collection": ["payment"],
"payment_method_fields": [
{
"name": "payer.name",
"type": "string",
"required": true,
"pattern": "^.{2,140}$",
"description": "The payer's full name.",
"example": "Ana Souza"
},
{
"name": "settlement_currency",
"type": "enum",
"required": false,
"enum": ["USDT"],
"description": "The currency the balance is credited in."
}
],
"customer_fields": [
{ "name": "type", "type": "enum", "required": true, "enum": ["individual", "business"], "description": "…" },
{ "name": "country", "type": "string", "required": true, "pattern": "^[A-Z]{2}$", "description": "…" }
],
"available": true
}
],
"has_more": false
}
```
## Los campos [#los-campos]
### FieldSpec: cómo describir un campo [#fieldspec-cómo-describir-un-campo]
Cada campo trae `name`, `type` (`string`, `number`, `iban`, `phone`, `email`, `date`, `enum`), `required` y `description`, y puede traer `pattern` (una expresión regular), `enum`, `example` y `note`. Con eso puedes validar en tu formulario lo mismo que valida la API.
Un nombre con punto indica un objeto anidado en los `details` de un beneficiario: `document.type` es `{"document": {"type": "V"}}`. En `payer`, en cambio, la clave es el nombre completo: `{"payer": {"payer.name": "Ana Souza"}}`.
## Disponible y no disponible [#disponible-y-no-disponible]
| `reason` | Qué significa | Qué hacer |
| --- | --- | --- |
| `suspended` | Caibo detuvo la operación temporalmente, para todos o para tu cuenta. | Reintenta más tarde. Si lo intentas, la API responde `503 operation_suspended`. |
| `not_enabled` | El producto no está activado para tu cuenta. | Pide la activación a Caibo. |
| `no_provider` | No hay ruta disponible para tu cuenta. | Pide la activación a Caibo. |
Si pides un método o una moneda que no aparece en la lista, la API responde `422 unsupported_method`.
La activación ocurre del lado de Caibo: por país para todos, o solo para tu cuenta. Cuando algo se activa, empieza a aparecer con `available: true`. Tu integración lee la lista y lo usa.
# Cobrar un monto exacto (/docs/collect-one-payment)
Con `amount`, la cuenta de cobro es un **pago único**: tu cliente paga exactamente ese monto, en la moneda de `currency`, y la cuenta se cierra cuando el pago termina.
| Campo | Obligatorio | Qué es |
| --- | --- | --- |
| `method` | Sí | `pix`, `bank_transfer`… |
| `currency` | Sí | Lo que paga tu cliente: `BRL`, `PEN`… |
| `amount` | Sí, en un pago único | El monto de tu orden. |
| `payer` | Según el método | Los datos del pagador que pide `payment_method_fields` en capabilities. |
| `settlement_currency` | No | En qué moneda se acredita tu saldo. Por defecto, el `settlement_asset` de capabilities. |
PIX pide el nombre del pagador. La clave de `payer` es el nombre completo del campo, tal como lo da capabilities: `payer.name`.
```bash
curl "$CAIBO_API/v1/funding-accounts" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: cobro-orden-8812" \
-H "Content-Type: application/json" \
-d '{
"method": "pix",
"currency": "BRL",
"amount": "250.00",
"payer": { "payer.name": "Ana Souza" }
}'
```
```json title="201"
{
"id": "fa_01m3sg9w0000000000000000",
"status": "pending",
"method": "pix",
"currency": "BRL",
"settlement_currency": "USDT",
"amount": "250.00",
"created_at": "2026-10-18T12:00:00Z"
}
```
Cuando está `active`:
```json
{
"id": "fa_01m3sg9w0000000000000000",
"status": "active",
"method": "pix",
"currency": "BRL",
"settlement_currency": "USDT",
"amount": "250.00",
"instructions": {
"copy_paste_code": "00020126580014br.gov.bcb.pix...",
"qr_code_image_base64": "iVBORw0KGgoAAAANSUhEUgAA...",
"amount": "250.00",
"currency": "BRL"
},
"created_at": "2026-10-18T12:00:00Z"
}
```
Muestra el QR (`qr_code_image_base64`, una imagen PNG en base64) y el código **PIX copia e cola** (`copy_paste_code`) para que tu cliente pague desde su banco.
En soles no hace falta ningún dato del pagador.
```bash
curl "$CAIBO_API/v1/funding-accounts" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: cobro-orden-8813" \
-H "Content-Type: application/json" \
-d '{ "method": "bank_transfer", "currency": "PEN", "amount": "1000.00" }'
```
Cuando está `active`:
```json
{
"id": "fa_01m3sgaa0000000000000000",
"status": "active",
"method": "bank_transfer",
"currency": "PEN",
"settlement_currency": "USDT",
"amount": "1000.00",
"instructions": {
"bank_account": "Banco … · Cuenta …",
"expires_at": "2026-10-18T12:25:00Z",
"amount": "1000.00",
"currency": "PEN"
},
"created_at": "2026-10-18T12:00:00Z"
}
```
Muestra `bank_account` y el monto. Tu cliente debe transferir **el monto exacto**, antes de `expires_at`. Si `instructions` trae `reference`, pídele que la incluya en la transferencia.
## Las instrucciones [#las-instrucciones]
`instructions` es un mapa de texto cuyas claves dependen del método. Muéstralas tal cual a quien va a pagar:
| Clave | Qué es |
| --- | --- |
| `amount`, `currency` | Lo que se paga: siempre el monto de tu orden. |
| `copy_paste_code` | El código para pegar en la app del banco (PIX copia e cola). |
| `qr_code_image_base64` | El QR, como imagen PNG en base64. |
| `bank_account` | La cuenta a la que transferir. |
| `reference` | La referencia que debe incluir la transferencia. |
| `payment_url` | Un enlace para pagar. |
| `expires_at` | Hasta cuándo se puede pagar, si el método vence. |
Puede aparecer una clave nueva en el futuro. Muéstrala o ignórala, pero no falles por ella.
`instructions.amount` es siempre el monto de tu orden. Si el banco cobra por recibir, Caibo absorbe esa comisión: tu cliente paga 1,000.00 y no 1,002.70, y tu saldo recibe lo que valen los 1,000.00 completos.
## Esperar el pago [#esperar-el-pago]
Escucha los webhooks, o consulta la cuenta y sus eventos:
1. `funding_account.active` trae `instructions`. El monto está en `instructions.amount`; el `amount` de la cuenta está en `GET /v1/funding-accounts/{id}`.
2. `payin.completed` llega cuando el banco confirma el pago. Su `data` es el [cobro acreditado](/docs/payins), con lo que entró a tu saldo.
3. Si el pago vence o no se concreta, llega `payin.failed` y la cuenta pasa a `closed`.
```bash
curl "$CAIBO_API/v1/events?resource_id=fa_01m3sg9w0000000000000000" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
## Errores al crear [#errores-al-crear]
| HTTP | `code` | Por qué |
| --- | --- | --- |
| 400 | `invalid_parameter` · `payer` | Falta un dato del pagador, no se reconoce o tiene mal formato. O enviaste `payer` sin `amount`. |
| 400 | `invalid_request` | `amount` no es un decimal positivo o la moneda no existe. |
| 422 | `amount_required` | Ese método y moneda se cobran con monto: envía `amount`. |
| 422 | `one_payment_unavailable` | Ese método y moneda abren una cuenta sin monto: no envíes `amount`. |
| 422 | `unsupported_method` | Ese método y moneda no están disponibles para cobrar. |
| 503 | `operation_suspended` | Está suspendido por ahora. |
Si la cuenta no se puede abrir, se crea igual y pasa a `failed` con `failure_code` (`provider_rejected`, `provider_unavailable`, `provider_amount_mismatch`, `no_route`). En ese caso crea otra, con un `Idempotency-Key` nuevo.
# Cómo cobrar (/docs/collect)
Para cobrar creas una **cuenta de cobro** (`funding account`). Caibo la abre con el banco del país y te devuelve las instrucciones que le muestras a tu cliente: un código PIX, una cuenta para transferir. Cuando el banco confirma el pago, lo acreditamos a tu saldo y te avisamos.
>C: POST /v1/funding-accounts
C-->>T: 201 pending
C-->>T: webhook funding_account.active con instrucciones
T->>P: Muestra las instrucciones
P->>C: Paga
C-->>T: webhook payin.completed
T->>C: GET /v1/balances`} />
## Dos formas de cobrar [#dos-formas-de-cobrar]
[Capabilities](/docs/capabilities) dice, para cada método y moneda, cuál se usa (`collection`):
| `collection` | Cómo se pide | Para qué |
| --- | --- | --- |
| `payment` | **Con** `amount` | Un pago único por un monto exacto: una orden, una factura. Se cierra cuando se paga. |
| `account` | **Sin** `amount` | Una cuenta que recibe cualquier depósito, de cualquier monto, mientras esté abierta. |
Si pides la forma equivocada, la API te lo dice: `422 amount_required` (ese cobro necesita un monto) o `422 one_payment_unavailable` (ese cobro no admite monto).
En un pago único, lo que ve tu cliente es **exactamente el monto de tu orden**: una orden de 1,000.00 PEN se paga con 1,000.00 PEN. Si el banco cobra una comisión por recibir, la cubre Caibo; tu cliente no la ve ni la paga.
## Estados de una cuenta de cobro [#estados-de-una-cuenta-de-cobro]
| `status` | Qué significa |
| --- | --- |
| `pending` | La estamos abriendo con el banco. |
| `active` | Lista: `instructions` trae lo que el pagador necesita. |
| `failed` | No se pudo abrir; `failure_code` dice por qué. No se muestran instrucciones. |
| `closed` | Ya no recibe depósitos. Un pago único se cierra cuando su cobro termina. |
| Evento | Cuándo |
| --- | --- |
| `funding_account.active` | La cuenta está lista, con sus instrucciones. |
| `funding_account.failed` | No se pudo abrir. |
| `payin.completed` | Un pago entró y se acreditó a tu saldo. |
| `payin.failed` | Un pago no se concretó (por ejemplo, venció sin pagarse). |
## Dónde termina el dinero [#dónde-termina-el-dinero]
Cada cobro se acredita en tu saldo en su `settlement_currency`: la moneda de liquidación que indica capabilities (`settlement_asset`) o la que elijas entre `settlement_currencies`. No hay etapa intermedia: el dinero se registra recién cuando el banco confirma, y entonces ya está **disponible**.
PIX en Brasil, transferencia en Perú.
El recurso payin y sus estados.
# Países y métodos (/docs/coverage)
## Próximamente [#próximamente]
Lo que tu cuenta puede usar ahora mismo, en cada entorno, lo dice `GET /v1/capabilities`: los métodos, las monedas, si cada uno sirve para cobrar o para pagar, y los datos que pide. Cuando activamos un país o un método para tu cuenta, aparece ahí con `available: true`, sin que cambies tu integración.
## Consultar un país [#consultar-un-país]
```bash
curl "$CAIBO_API/v1/capabilities?country=CO" -H "Authorization: Bearer $CAIBO_API_KEY"
```
Devuelve cada producto disponible para ese país (`payin` para cobrar, `payout` para pagar) con sus métodos y los campos que pide cada uno.
## En sandbox [#en-sandbox]
Sandbox tiene además una cuenta de cobro en USD que recibe cualquier depósito y que puedes pagar tú mismo con `POST /v1/sandbox/deposits`. Ver [Sandbox y live](/docs/sandbox).
# Clientes (/docs/customers)
Un cliente se registra con **tu propio identificador** (`external_id`), así lo encuentras siempre desde tu sistema.
| Campo | Obligatorio | Qué es |
| --- | --- | --- |
| `external_id` | Sí | Tu id, hasta 128 caracteres. |
| `type` | Sí | `individual` o `business`. |
| `country` | Sí | País de residencia o constitución (ISO alfa-2). |
| `display_name` | Sí | Nombre, hasta 200 caracteres. |
| `profile` | Según el país | Datos de identidad (abajo). |
| `metadata` | No | Hasta 20 claves tuyas. Nunca datos personales. |
## El perfil [#el-perfil]
| Campo | Para |
| --- | --- |
| `first_name`, `last_name` | Personas. Van juntos. |
| `date_of_birth` | Personas, `AAAA-MM-DD`. |
| `identity_document_type`, `identity_document` | Van juntos. Tipos: `DNI`, `RUC`, `CE`, `PAS`, `PTP`, `PASSPORT`, `NATIONAL_ID`, `RESIDENCE_PERMIT`, `TAX_ID`, `DRIVER_LICENSE`. |
| `identity_document_country` | País que emitió el documento. |
| `email`, `phone`, `tax_id` | Contacto e impuestos. |
| `registration_number` | Empresas. |
| `address` | `line1`, `line2`, `city`, `state`, `postal_code`, `country`. |
**Qué pide cada país** lo dice `customer_fields` en capabilities. Por ejemplo, un pago en soles pide que el remitente sea una persona (`individual`) con nombre, apellidos, fecha de nacimiento, documento y ciudad.
Los datos del remitente se validan cuando el pago sale al banco, no al crearlo. Un pago con un remitente incompleto se acepta y luego falla con `failure_code: invalid_instruction`. Valida el perfil contra `customer_fields` antes de pagar.
## Repetir el registro [#repetir-el-registro]
Si envías otra vez el mismo `external_id` con los mismos datos, recibes el cliente existente (`200`). Con otros datos, `409 external_id_conflict`.
## Estados [#estados]
| `status` | Qué significa |
| --- | --- |
| `active` | Normal. |
| `blocked` | Caibo lo detuvo: no se paga a sus beneficiarios. |
| `closed` | Cerrado, definitivo. |
Con cambias `metadata` o lo cierras (`status: closed`). `compliance_status` (`unverified`, `pending`, `verified`, `rejected`, `review`) lo cambian solo las verificaciones de Caibo.
Eventos: `customer.created`, `customer.updated`, `customer.status_changed`. Los eventos nunca incluyen el perfil.
# Errores (/docs/errors)
Todos los errores tienen la misma forma:
```json
{
"error": {
"type": "invalid_request",
"code": "invalid_parameter",
"message": "amount must be a positive decimal with at most 2 decimals for PEN.",
"param": "amount",
"request_id": "req_6d665507f62a5773882fc053"
}
}
```
| Campo | Qué es |
| --- | --- |
| `type` | El tipo de error. Estable. |
| `code` | El motivo concreto. Estable. **Decide por `type` y `code`.** |
| `message` | Texto para personas. Puede cambiar: no lo interpretes. |
| `param` | El campo o encabezado con el problema, cuando hay uno. |
| `reasons` | Motivos cerrados, en los códigos que los tienen (`risk_blocked`, `payout_not_cancellable`). |
| `request_id` | El mismo valor del encabezado `X-Request-Id`. Dáselo a soporte. |
## Tipos [#tipos]
| `type` | HTTP | Qué pasó | ¿Reintentar? |
| --- | --- | --- | --- |
| `invalid_request` | 400, 405, 413, 415, 422 | La solicitud está mal formada (400) o no se puede ejecutar (422). | Solo después de corregirla. |
| `authentication_error` | 401 | Falta la clave o no es válida. | No. |
| `permission_error` | 403 | La clave no tiene el scope. | No. |
| `not_found` | 404 | No existe, o es de otra cuenta. | No. |
| `conflict` | 409 | Choca con algo que ya existe. | No. |
| `rate_limited` | 429 | Demasiadas solicitudes. | Sí, después de `Retry-After`. |
| `unavailable` | 503 | No disponible por ahora. | Sí, con el mismo `Idempotency-Key`. |
| `internal_error` | 500 | Un error de nuestro lado. | Sí, con el mismo `Idempotency-Key`. |
## Códigos frecuentes [#códigos-frecuentes]
### Solicitud mal formada (400) [#solicitud-mal-formada-400]
| `code` | Cuándo |
| --- | --- |
| `invalid_parameter` | Un campo o parámetro no es válido. `param` dice cuál: `amount`, `currency`, `details.cci`, `payer`, `Idempotency-Key`… |
| `invalid_body` | El cuerpo no es JSON, tiene un campo desconocido o un tipo equivocado (por ejemplo, un monto como número). |
| `invalid_request` | La solicitud no es válida en general. |
| `idempotency_key_required` | Falta `Idempotency-Key` donde es obligatoria. |
| `body_too_large` (413) | El cuerpo supera 64 KiB. |
| `unsupported_media_type` (415) | El `Content-Type` no es `application/json`. |
### No se puede ejecutar (422) [#no-se-puede-ejecutar-422]
| `code` | Cuándo |
| --- | --- |
| `unsupported_method` | Ese método y moneda no están en [capabilities](/docs/capabilities). |
| `amount_required` | Ese cobro es de pago único: envía `amount`. |
| `one_payment_unavailable` | Ese cobro es una cuenta que recibe cualquier depósito: no envíes `amount`. |
| `insufficient_funds` | Tu saldo disponible no alcanza. |
| `quote_expired` | La cotización venció: pide otra. |
| `quote_mismatch` | La cotización no es para el método o la moneda del beneficiario. |
| `pricing_unavailable` | No hay precio para esa operación ahora. |
| `amount_too_small` | El monto está por debajo del mínimo. |
| `same_currency` | La conversión pedida es a la misma moneda. |
| `limit_exceeded` | Supera un límite de tu cuenta. |
| `customer_not_active` | El cliente del beneficiario no está activo. |
| `risk_blocked` | Lo detuvieron las reglas de riesgo; mira `reasons`. |
| `refund_not_supported` | Ese cobro no admite reembolso. |
| `too_many_endpoints` | Ya tienes 10 webhooks. |
### Conflicto (409) [#conflicto-409]
| `code` | Cuándo |
| --- | --- |
| `idempotency_key_reused` | Usaste la misma `Idempotency-Key` con otra solicitud. |
| `quote_already_used` | La cotización ya financió otra operación. |
| `external_id_conflict` | Ya tienes un cliente con ese `external_id` y otros datos. |
| `customer_closed`, `customer_blocked` | El cliente está cerrado o bloqueado. |
| `payout_not_cancellable` | El pago ya no se puede cancelar; mira `reasons`. |
### No disponible (503) [#no-disponible-503]
| `code` | Cuándo |
| --- | --- |
| `operation_suspended` | La operación está suspendida por ahora (en capabilities aparece `reason: suspended`). |
| `temporarily_unavailable` | Un problema momentáneo. Reintenta con la misma clave. |
La lista completa de cada endpoint está en su página de la [referencia](/docs/api/payouts/create-payout).
## Límite de solicitudes [#límite-de-solicitudes]
Hay un límite de solicitudes por clave. Al superarlo recibes `429 rate_limited` con `Retry-After`, el número de segundos que debes esperar. Distribuye tus consultas y prefiere los webhooks a consultar en bucle.
## Encabezados útiles [#encabezados-útiles]
| Encabezado | Sentido | Para qué |
| --- | --- | --- |
| `X-Request-Id` | Respuesta | Identifica la solicitud (`req_…`). Guárdalo en tus registros. |
| `X-Correlation-Id` | Solicitud y respuesta | Tu propio identificador (8 a 128 caracteres de `A-Z a-z 0-9 . _ : -`); te lo devolvemos. |
| `Retry-After` | Respuesta | En un `429`, cuántos segundos esperar. |
| `Idempotent-Replayed` | Respuesta | `true` cuando la respuesta es la repetición de una solicitud anterior. |
Los estados, motivos y códigos son listas cerradas, pero pueden crecer. Trata un valor que no conoces como "desconocido", no como un error de tu integración.
# Eventos (/docs/events)
Cada cambio importante genera un evento. Llega por [webhook](/docs/webhooks) y queda en `GET /v1/events`, con la misma forma:
```json
{
"id": "evt_01m3sgb02af7nb0jf73vwv2sd5",
"type": "payin.completed",
"schema_version": 1,
"occurred_at": "2026-10-18T12:03:12.418Z",
"livemode": false,
"data": {
"id": "pin_01m3sg9x0000000000000000",
"status": "completed",
"funding_account_id": "fa_01m3sg9w0000000000000000",
"amount": "45.871200",
"currency": "USDT",
"created_at": "2026-10-18T12:03:10Z",
"completed_at": "2026-10-18T12:03:12Z"
}
}
```
| Campo | Qué es |
| --- | --- |
| `id` | El id del evento. Úsalo para no procesar dos veces el mismo. |
| `type` | Qué pasó. |
| `schema_version` | La versión de la forma de `data` para ese tipo. Hoy, `1`. |
| `occurred_at` | Cuándo pasó. |
| `livemode` | `true` en live, `false` en sandbox. |
| `data` | El recurso, con la forma de la API. Puede ganar campos nuevos. |
Los eventos nunca traen datos de cuentas de beneficiarios ni datos personales de tus clientes.
## Leer el registro [#leer-el-registro]
```bash
curl "$CAIBO_API/v1/events?after=$CURSOR&limit=100" -H "Authorization: Bearer $CAIBO_API_KEY"
```
- Del **más antiguo al más nuevo**. Guarda `next_cursor` (viene siempre) y continúa desde ahí: nunca te saltas un evento.
- `type` filtra por un tipo exacto (`payout.completed`) o por una familia terminada en punto (`payout.`).
- `resource_id` trae la historia de un recurso: `?resource_id=pout_…`.
- Un evento recién ocurrido puede tardar un instante en aparecer en la lista; el webhook no espera.
## Catálogo [#catálogo]
`funding_account.active`, `funding_account.failed`, `payin.completed`, `payin.failed`
`payout.created`, `payout.completed`, `payout.failed`, `payout.cancelled`, `payout.returned`, `payout.return_settled`
`payout_batch.created`, `payout_batch.completed`, `payout_batch.cancellation_requested`, `payout_batch.cancellation_finished`
`remittance.created`, `remittance.processing`, `remittance.review`, `remittance.completed`, `remittance.failed`, `remittance.returned`
`refund.created`, `refund.approved`, `refund.processing`, `refund.completed`, `refund.failed`
`withdrawal.created`, `withdrawal.pending_approval`, `withdrawal.approved`, `withdrawal.submitted`, `withdrawal.completed`, `withdrawal.failed`, `withdrawal.cancelled`
`settlement.created`, `settlement.processing`, `settlement.on_hold`, `settlement.completed`, `settlement.failed`, `settlement_schedule.activated`, `settlement_schedule.blocked`
`customer.created`, `customer.updated`, `customer.status_changed`, `beneficiary.created`, `beneficiary.verified`
`hosted_session.created`, `hosted_session.payment_reported`
`risk.review_required`, `reconciliation.exception_created`, `reconciliation.exception_resolved`
`webhook.ping`
La lista puede crecer. Ignora los tipos que no conoces; no fallen tu integración.
# Pasar a producción (/docs/go-live)
### Pide tu clave live [#pide-tu-clave-live]
Caibo emite tu clave `psp_live_…` cuando tu cuenta de producción está lista. Guárdala en un gestor de secretos. Si una clave se expone, pide a Caibo que la revoque y emita otra.
### Cambia host y clave [#cambia-host-y-clave]
Usa `https://api.caibopay.app` y tu `psp_live_…`. El resto de tu integración no cambia.
### Registra tu webhook en live [#registra-tu-webhook-en-live]
Los webhooks son de cada entorno: registra tu URL de nuevo en live y guarda el nuevo `secret`.
### Lee capabilities en live [#lee-capabilities-en-live]
Lo disponible depende del entorno y de tu cuenta. Arma tus formularios con el `GET /v1/capabilities` de live, no con lo que viste en sandbox.
## Comprueba tu integración [#comprueba-tu-integración]
- [ ] Cada `POST` que mueve dinero envía un `Idempotency-Key` propio de la operación, y cada reintento usa **el mismo**. Ver [Idempotencia](/docs/idempotency).
- [ ] Verificas la firma `Psp-Signature` de cada webhook sobre el cuerpo **sin modificar**. Ver [Firmas](/docs/webhook-signatures).
- [ ] Respondes `2xx` en menos de 10 segundos y procesas después.
- [ ] Descartas eventos repetidos por su `id`.
- [ ] Tratas `processing` y `verification_pending` como "todavía no", sin crear otro pago para lo mismo.
- [ ] Decides por `error.type` y `error.code`, nunca por `message`.
- [ ] Guardas el `X-Request-Id` de las respuestas con error, para soporte.
- [ ] Aceptas valores nuevos en estados y códigos sin romperte.
- [ ] Respetas `Retry-After` cuando recibes `429`.
- [ ] Manejas los montos como texto decimal, nunca como número de punto flotante.
# Página alojada (/docs/hosted-pages)
La página alojada es el flujo de **remesas** listo para usar: tu cliente cotiza, ingresa remitente y destinatario, confirma, ve cómo pagar y sigue el estado de su envío. Tú no construyes formularios ni manejas datos de pago.
- Funciona en español, portugués e inglés; pensada para móvil, y también funciona sin JavaScript.
- Tres modos de marca: `caibo`, `co_branded` (tu marca junto a la nuestra) y `white_label` (solo tu marca, si tu contrato lo incluye).
- El mismo enlace sirve para pagar y para seguir el envío.
La página alojada usa corredores de remesa, que requieren cobros de tipo `account`. Revisa `GET /v1/capabilities?product=remittance` en tu entorno: si la lista está vacía, la página todavía no tiene corredores que ofrecer.
## Configura tu página [#configura-tu-página]
```json
{
"enabled": true,
"branding_mode": "co_branded",
"brand_name": "Mi Empresa",
"logo_url": "https://mi-empresa.com/logo.svg",
"colors": { "primary": "#12c7b0" },
"radius": "md",
"support": { "email": "soporte@mi-empresa.com" }
}
```
`PUT` reemplaza toda la configuración: un campo que omites vuelve a su valor por defecto.
## Crea una sesión [#crea-una-sesión]
```bash
curl "$CAIBO_API/v1/hosted-sessions" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: sesion-cliente-8812" \
-H "Content-Type: application/json" \
-d '{ "customer_id": "cus_01m3sgb0...", "expires_in": 86400 }'
```
La respuesta trae `token` y `path`: el enlace es `https://pay.caibopay.app` + `path`. **Solo vienen en esta respuesta** (una repetición no los devuelve): guárdalos.
- `customer_id` fija al remitente.
- `expires_in` va de 300 segundos a 7 días; por defecto, 24 horas.
- `prefill` precarga monto, moneda, país y método.
"Ya pagué" en la página es solo un aviso (`hosted_session.payment_reported`). La confirmación real es `payin.completed` y luego `remittance.processing`.
## Tu dominio [#tu-dominio]
Registra `pagos.mi-empresa.com` y apúntalo con un **CNAME a `pay.caibopay.app`**. El dominio empieza `pending`, con un `verification_token`; el equipo de Caibo lo verifica y emite el certificado. Escríbenos cuando lo registres.
# Idempotencia (/docs/idempotency)
Una red puede cortarse justo después de que enviaste un pago. ¿Llegó o no? Con `Idempotency-Key` no importa: reenvías **la misma solicitud con la misma clave** y recibes el resultado original, sin un segundo efecto.
```bash
curl https://api-sandbox.caibopay.app/v1/payouts \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: pago-orden-5531" \
-H "Content-Type: application/json" \
-d '{ "beneficiary_id": "ben_...", "quote_id": "quo_..." }'
```
## Cómo se comporta [#cómo-se-comporta]
| Envías | Recibes |
| --- | --- |
| Una clave nueva | `201` y el recurso creado. |
| La misma clave con la misma solicitud | `200`, el mismo recurso en su estado actual y el encabezado `Idempotent-Replayed: true`. Nada se repite. |
| La misma clave con otra solicitud | `409 idempotency_key_reused`. |
| Sin clave, donde es obligatoria | `400 idempotency_key_required`. |
Si dos solicitudes con la misma clave llegan a la vez, la segunda espera a la primera y devuelve su resultado.
## Dónde es obligatoria [#dónde-es-obligatoria]
En todas las creaciones que mueven dinero o fijan un precio:
El resto de las operaciones ignoran el encabezado. Registrar dos veces el mismo beneficiario o la misma cuenta de destino ya devuelve el registro existente.
## Buenas prácticas [#buenas-prácticas]
- **Una clave por operación de negocio**, derivada de tu propio identificador: `pago-orden-5531`, `cobro-factura-F-2201`. Así un reintento, incluso días después o desde otro proceso, usa la misma.
- Entre **8 y 128 caracteres** de `A-Z a-z 0-9 . _ : -`.
- **Las claves no vencen.** Una clave usada sigue amarrada a su solicitud original para siempre.
- Una solicitud rechazada (`4xx`) no gasta la clave: corrige y reenvía con la misma.
- Ante `500` o `503`, reintenta **con la misma clave**.
Si tu saldo no alcanza, `POST /v1/payouts` responde `201` con `status: failed` y `failure_code: insufficient_funds`. Ese pago existe y su clave quedó usada. Para reintentar cuando tengas fondos, usa una clave nueva (y una cotización nueva si usaste una).
# Introducción (/docs)
Caibo Pay es la infraestructura de pagos para empresas que cobran y pagan en varios países. Te integras **una vez** y, desde la misma API, cobras y pagas por PIX, ACH, wire, FedNow, SPEI, Bre-B, Faster Payments, transferencias y pago móvil, y consultas un solo saldo. Ver [Países y métodos](/docs/coverage).
} title="Inicio rápido" href="/docs/quickstart">
Tu primera llamada y tu primer cobro de prueba en minutos.
} title="Qué puedes hacer" href="/docs/capabilities">
El mapa de países, métodos y monedas, leído de la propia API.
} title="Cobrar" href="/docs/collect">
Pagos únicos por un monto exacto: el pagador paga la orden y nada más.
} title="Pagar" href="/docs/pay-out">
Pagos a cuentas bancarias, PIX y pago móvil, uno a uno o en lotes.
## Una API para todo [#una-api-para-todo]
No hay un endpoint por país ni por proveedor. Los mismos recursos sirven para todos:
| Quieres… | Usas |
| --- | --- |
| Saber qué tienes disponible | `GET /v1/capabilities` |
| Cobrar | `POST /v1/funding-accounts` |
| Pagar | `POST /v1/payouts` |
| Saber qué pasó | Un webhook, o `GET /v1/events` |
| Ver tu dinero | `GET /v1/balances` |
Lo que cambia entre un país y otro es `currency` y `method`, y lo que pide cada uno te lo dice `GET /v1/capabilities`. Cuando Caibo abre un país nuevo, aparece ahí: **tu integración no cambia**.
|una clave| B(Caibo Pay API)
B --> C[Cobros: PIX, transferencias]
B --> D[Pagos: cuentas, PIX, pago móvil]
B --> E[(Un saldo)]
B -.->|un webhook| A`} />
## Cómo funciona [#cómo-funciona]
### Consulta qué puedes hacer [#consulta-qué-puedes-hacer]
`GET /v1/capabilities` lista cada producto (`payin`, `payout`, `remittance`), con su método, moneda y país, los campos que pide y si está disponible ahora para tu cuenta.
### Cobra o paga [#cobra-o-paga]
Creas un cobro o un pago con una sola llamada. Cada llamada que mueve dinero lleva un `Idempotency-Key`, así un reintento nunca cobra ni paga dos veces.
### Recibe el resultado [#recibe-el-resultado]
El dinero se mueve de forma asíncrona. Te avisamos por webhook (`payin.completed`, `payout.completed`…) y cada evento queda también en `GET /v1/events`.
## Entornos [#entornos]
| Entorno | Host | Clave |
| --- | --- | --- |
| Sandbox (pruebas) | `https://api-sandbox.caibopay.app` | `psp_test_…` |
| Live (producción) | `https://api.caibopay.app` | `psp_live_…` |
Son despliegues separados, con datos y claves separados: una clave solo funciona en su entorno. Empieza en sandbox; pasar a live es cambiar el host y la clave. Ver [Sandbox y live](/docs/sandbox).
Esta documentación está hecha también para agentes: cada página tiene **Copiar para IA**, hay un [`llms.txt`](/llms.txt), un servidor MCP y una Skill lista para instalar. Ver [Construye con IA](/docs/ai).
# Montos y monedas (/docs/money)
```json
{ "amount": "1500.50", "currency": "PEN" }
```
- Un monto es un **texto** con dígitos y, si hace falta, un punto decimal: `"100"`, `"100.5"`, `"100.50"`.
- Sin signo, sin separadores de miles, sin notación científica.
- No más decimales de los que tiene la moneda.
- La API siempre responde con **exactamente** los decimales de la moneda: envías `"100.5"` en PEN y recibes `"100.50"`.
- Un monto enviado como número (`100.5`) se rechaza con `400 invalid_body`.
`0.1 + 0.2` no es `0.3` en coma flotante. Guarda los montos como texto o en un tipo decimal (`BigDecimal`, `decimal.Decimal`, `NUMERIC`), o en unidades mínimas como enteros.
## Monedas [#monedas]
| Código | Decimales | Moneda |
| --- | --- | --- |
| `BRL` | 2 | Real brasileño |
| `PEN` | 2 | Sol peruano |
| `VES` | 2 | Bolívar venezolano |
| `USD` | 2 | Dólar estadounidense |
| `MXN` | 2 | Peso mexicano |
| `COP` | 2 | Peso colombiano |
| `EUR` | 2 | Euro |
| `USDT` | 6 | Tether |
| `USDC` | 6 | USD Coin |
Que una moneda esté en esta tabla no significa que puedas cobrar o pagar en ella: lo que tienes disponible lo dice [capabilities](/docs/capabilities).
## Tipos de cambio [#tipos-de-cambio]
Cuando un pago convierte de una moneda a otra, la [cotización](/docs/quotes) te dice todo antes de pagar:
- `source.principal`: lo que se convierte.
- `source.platform_fee`: la comisión de la plataforma.
- `source.tenant_markup`: tu propio margen, si tienes uno; se acredita en tus ganancias (`earnings`).
- `source.total`: lo que se descuenta de tu saldo (`principal + platform_fee + tenant_markup`).
- `destination.amount`: lo que recibe el beneficiario.
- `rate`: unidades de destino por unidad de origen, con los márgenes incluidos.
## Fechas [#fechas]
Todas las fechas van en RFC 3339 y en UTC: `2026-10-18T14:00:20Z`. La cantidad de decimales de los segundos puede variar.
## Identificadores [#identificadores]
Cada recurso tiene un id opaco con un prefijo que dice qué es: `pout_` un pago, `pin_` un cobro acreditado, `fa_` una cuenta de cobro, `ben_` un beneficiario, `cus_` un cliente, `quo_` una cotización, `evt_` un evento. No interpretes lo que viene después del prefijo.
# Listas y paginación (/docs/pagination)
## Listas de recursos [#listas-de-recursos]
Pagos, cobros, clientes, beneficiarios y demás se devuelven del **más nuevo al más antiguo**, en páginas:
```json
{
"data": [ { "id": "pout_01m3sgb0..." }, { "id": "pout_01m3sga9..." } ],
"has_more": true,
"next_cursor": "pout_01m3sga9..."
}
```
| Parámetro | Qué hace |
| --- | --- |
| `limit` | Cuántos por página: de 1 a 100. Por defecto 25. |
| `starting_after` | El `next_cursor` de la página anterior. |
Sigue pidiendo mientras `has_more` sea `true`:
```js
let cursor;
do {
const url = new URL("https://api-sandbox.caibopay.app/v1/payouts");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("starting_after", cursor);
const page = await fetch(url, { headers: { Authorization: `Bearer ${key}` } }).then((r) => r.json());
for (const payout of page.data) handle(payout);
cursor = page.has_more ? page.next_cursor : undefined;
} while (cursor);
```
Un recorrido devuelve **exactamente una vez** cada elemento que existía al empezar, aunque se creen otros mientras paginas.
### Filtros [#filtros]
| Filtro | Ejemplo |
| --- | --- |
| `status` | `?status=completed` |
| `created_after` (incluido) | `?created_after=2026-10-01T00:00:00Z` |
| `created_before` (excluido) | `?created_before=2026-11-01T00:00:00Z` |
| Relaciones | `?beneficiary_id=ben_…`, `?customer_id=cus_…`, `?funding_account_id=fa_…` |
- Los filtros se combinan con **Y**.
- Las fechas van en RFC 3339. Codifica el `+` de una zona horaria como `%2B`.
- Un valor que el filtro no admite responde `400` con `param` igual al nombre del filtro.
- Un id con buena forma que no es tuyo devuelve una lista vacía.
## Registros: eventos y movimientos [#registros-eventos-y-movimientos]
`GET /v1/events` y `GET /v1/balances/{currency}/entries` se paginan con `after`, y nunca saltan ni repiten. Los eventos se leen del **más antiguo al más nuevo**; los movimientos del saldo, del **más nuevo al más antiguo**.
| Parámetro | Qué hace |
| --- | --- |
| `limit` | De 1 a 100. Por defecto 50. |
| `after` | El `next_cursor` de tu última lectura. |
En los eventos, `next_cursor` viene siempre, también en una página vacía. Guárdalo y vuelve a consultar desde ahí: así nunca te saltas un evento. Ver [Eventos](/docs/events).
# Cómo pagar (/docs/pay-out)
Un pago (`payout`) sale de tu saldo y llega a un **beneficiario**: la cuenta de la persona o empresa a la que pagas. El recorrido completo:
B[cliente
remitente]
B --> C[beneficiario]
C --> D[cotización]
D --> E[pago]
E -.-> F[webhook
payout.completed]`} />
### Mira qué pide el país [#mira-qué-pide-el-país]
```bash
curl "$CAIBO_API/v1/capabilities?product=payout¤cy=PEN" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
`beneficiary_fields` dice qué datos de la cuenta necesitas; `customer_fields`, qué datos del remitente. Ver [Qué puedes hacer](/docs/capabilities).
### Registra al remitente, si el país lo pide [#registra-al-remitente-si-el-país-lo-pide]
Algunos países piden saber quién envía. El remitente es un [cliente](/docs/customers) tuyo:
```bash
curl "$CAIBO_API/v1/customers" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: cliente-crm-8812" \
-H "Content-Type: application/json" \
-d '{
"external_id": "crm-8812",
"type": "individual",
"country": "PE",
"display_name": "Carlos Mendoza",
"profile": {
"first_name": "Carlos",
"last_name": "Mendoza Rojas",
"date_of_birth": "1988-04-12",
"identity_document_type": "DNI",
"identity_document": "41234567",
"identity_document_country": "PE",
"address": { "city": "Lima", "country": "PE" }
}
}'
```
### Registra al beneficiario [#registra-al-beneficiario]
```bash
curl "$CAIBO_API/v1/beneficiaries" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"method": "bank_transfer",
"currency": "PEN",
"customer_id": "cus_01m3sgb02af7nb0jf73vwv2sd4",
"holder": "Rosa Elena Quispe Mamani",
"details": {
"cci": "00219100123456780123",
"document_number": "45678912",
"first_name": "Rosa Elena",
"last_name": "Quispe Mamani"
}
}'
```
Lo registras una vez y le pagas las veces que quieras. `details` nunca se devuelve. Ver [Beneficiarios](/docs/beneficiaries).
### Fija el precio [#fija-el-precio]
```bash
curl "$CAIBO_API/v1/quotes" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: cotizacion-orden-5531" \
-H "Content-Type: application/json" \
-d '{ "source_currency": "USDT", "destination_currency": "PEN", "method": "bank_transfer", "amount": "350.00", "amount_side": "destination" }'
```
```json
{
"id": "quo_01m3sgaz0000000000000000",
"status": "open",
"method": "bank_transfer",
"source": { "currency": "USDT", "principal": "100.000000", "platform_fee": "0.500000", "tenant_markup": "0.000000", "total": "100.500000" },
"destination": { "amount": "350.00", "currency": "PEN" },
"rate": "3.500000000000000000",
"created_at": "2026-10-18T14:00:10Z",
"expires_at": "2026-10-18T14:01:40Z"
}
```
`amount_side: destination` fija lo que **recibe** el beneficiario; `source`, lo que **sale** de tu saldo. La cotización vale hasta `expires_at`. Ver [Cotizaciones](/docs/quotes).
### Paga [#paga]
```bash
curl "$CAIBO_API/v1/payouts" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: pago-orden-5531" \
-H "Content-Type: application/json" \
-d '{ "beneficiary_id": "ben_01m3sgazybenxvqfw0h5bnszk4", "quote_id": "quo_01m3sgaz0000000000000000", "description": "Orden 5531" }'
```
Responde `201` con `status: processing`: los fondos (`source.total`) quedaron reservados y el pago está en camino.
### Recibe el resultado [#recibe-el-resultado]
Te llega `payout.completed` cuando el beneficiario recibió el dinero, o `payout.failed` con `failure_code` si no se pudo pagar; en ese caso los fondos vuelven a tu saldo disponible. Ver [Pagos](/docs/payouts).
También puedes pagar sin cotizar antes: envía `source_currency`, `amount` y `amount_side` en lugar de `quote_id`, y el pago se cotiza al crearse.
# Cobros acreditados (/docs/payins)
Cada vez que un pago entra a una cuenta de cobro, aparece un **payin**. El aviso del banco no basta para acreditar: Caibo confirma cada pago con el banco antes de acreditarlo, y cada pago se acredita **una sola vez**.
```json
{
"id": "pin_01m3sg9x0000000000000000",
"status": "completed",
"funding_account_id": "fa_01m3sg9w0000000000000000",
"amount": "45.871200",
"currency": "USDT",
"created_at": "2026-10-18T12:03:10Z",
"completed_at": "2026-10-18T12:03:12Z"
}
```
| Campo | Qué es |
| --- | --- |
| `amount`, `currency` | **Lo que se acreditó a tu saldo**, en la moneda de liquidación. |
| `paid` | Lo que pagó el cliente en su moneda, cuando el banco lo informa por separado. |
| `funding_account_id` | La cuenta de cobro. El monto de tu orden está en su `amount`. |
| `failure_code` | Por qué falló, si falló. |
| `refunded`, `refundable` | Cuánto se reembolsó y cuánto queda por reembolsar (solo en `GET /v1/payins/{id}`). |
## Estados [#estados]
| `status` | Qué significa | Evento |
| --- | --- | --- |
| `processing` | Lo vimos y lo estamos confirmando con el banco. | — |
| `completed` | Confirmado y acreditado: el dinero está disponible. | `payin.completed` |
| `failed` | No se concretó. | `payin.failed` |
## Filtros [#filtros]
`GET /v1/payins?status=completed&funding_account_id=fa_…`, más `created_after` y `created_before`. Ver [Listas y paginación](/docs/pagination).
Un pago con un monto distinto al pedido o que el banco revierte nunca mueve tu saldo automáticamente: lo revisa el equipo de Caibo y lo ves en `GET /v1/reconciliation-exceptions`.
# Pagos en lote (/docs/payout-batches)
```bash
curl "$CAIBO_API/v1/payout-batches" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: nomina-2026-10" \
-H "Content-Type: application/json" \
-d '{
"label": "Nómina octubre",
"items": [
{ "beneficiary_id": "ben_01...", "source_currency": "USDT", "amount": "350.00", "amount_side": "destination", "reference": "emp-001" },
{ "beneficiary_id": "ben_02...", "quote_id": "quo_01...", "reference": "emp-002" }
]
}'
```
- De **1 a 1000** elementos; el cuerpo puede pesar hasta 2 MiB.
- Cada elemento lleva `beneficiary_id` y una `quote_id`, o `source_currency`, `amount` y `amount_side`. Opcional: `description` y `reference` (tu id, hasta 64 caracteres).
- Primero se revisa la forma de **todos**: un elemento mal formado rechaza el lote entero con `400` y `param: items[i].campo`, y no se crea nada.
- Después, cada elemento se convierte en un pago normal, en orden, con sus propios eventos `payout.*`. Un elemento que no se puede pagar no detiene a los demás.
## El lote [#el-lote]
`GET /v1/payout-batches/{id}` trae `summary` (cuántos hay en cada estado) y `totals` por moneda (`principal`, `platform_fee`, `tenant_markup`, `total`, `completed_total`).
| `status` | Qué significa |
| --- | --- |
| `accepted` | Recibido. |
| `processing` | Pagando. |
| `completed` | Todos terminaron bien. |
| `completed_with_failures` | Terminó, con algunos fallidos. |
| `cancelled`, `partially_cancelled` | Cancelado, completo o en parte. |
## Los elementos [#los-elementos]
Cada elemento trae `index`, `status`, `payout_id` y tu `reference`. Si nunca llegó a ser un pago queda en `refused`, con `error_code`: `beneficiary_not_found`, `quote_expired`, `limit_exceeded`, `customer_not_active`…
## Cancelar [#cancelar]
Cancela los pagos del lote que todavía no salieron. Eventos: `payout_batch.created`, `payout_batch.cancellation_requested`, `payout_batch.cancellation_finished`, `payout_batch.completed`.
# Pagos (/docs/payouts)
| Campo | Qué es |
| --- | --- |
| `beneficiary_id` | Obligatorio. A quién pagas; el método y la moneda salen del beneficiario. |
| `quote_id` | Una [cotización](/docs/quotes) vigente. |
| `source_currency`, `amount`, `amount_side` | O, en lugar de `quote_id`, estos tres: el pago se cotiza al crearse. |
| `description` | Hasta 500 caracteres, para ti. |
Lleva siempre un `Idempotency-Key`: repetir la solicitud con la misma clave devuelve el mismo pago y **nunca paga dos veces**.
```json title="201"
{
"id": "pout_01m3sgb02af7nb0jf73vwv2sd4",
"status": "processing",
"method": "bank_transfer",
"beneficiary_id": "ben_01m3sgazybenxvqfw0h5bnszk4",
"source": { "currency": "USDT", "principal": "100.000000", "platform_fee": "0.500000", "tenant_markup": "0.000000", "total": "100.500000" },
"destination": { "amount": "350.00", "currency": "PEN" },
"rate": "3.500000000000000000",
"quote_id": "quo_01m3sgaz0000000000000000",
"created_at": "2026-10-18T14:00:20Z",
"updated_at": "2026-10-18T14:00:20Z"
}
```
## Estados [#estados]
processing
processing --> completed
processing --> failed
processing --> cancelled
processing --> verification_pending
verification_pending --> completed
verification_pending --> failed
completed --> returned`} />
| `status` | Qué significa | Evento |
| --- | --- | --- |
| `processing` | Aceptado, fondos reservados, en camino. | `payout.created` |
| `verification_pending` | Enviado, pero el resultado aún no es seguro. Los fondos siguen reservados; **nunca se reenvía**. Termina en `completed` o `failed`. | — |
| `completed` | El beneficiario recibió el dinero. | `payout.completed` |
| `failed` | No se pagó; los fondos vuelven a tu saldo disponible. | `payout.failed` |
| `cancelled` | Cancelado antes de salir. | `payout.cancelled` |
| `returned` | Se pagó y luego el banco lo devolvió; mira `refund`. | `payout.returned`, `payout.return_settled` |
`processing` y `verification_pending` significan "todavía no". No crees otro pago para lo mismo: el original se está resolviendo y terminará en un estado final. `verification_pending` no tiene evento propio; consulta el pago si tarda.
## Cuando no alcanza el saldo [#cuando-no-alcanza-el-saldo]
El pago se crea igual (`201`) con `status: failed` y `failure_code: insufficient_funds`. No reserva nada y llega solo `payout.failed`, sin `payout.created`. Su `Idempotency-Key` y su cotización quedan usados: para reintentar, usa una clave nueva y una cotización nueva.
## failure_code [#failure_code]
| Código | Qué pasó |
| --- | --- |
| `insufficient_funds` | Tu saldo no alcanzaba. |
| `invalid_instruction` | El banco rechazó los datos: cuenta, banco no soportado o remitente incompleto. |
| `no_route` | No había ruta para pagar. |
| `not_submitted` | No llegó a enviarse. |
| `resolved_not_executed` | Se confirmó que no se ejecutó. |
| `risk_rejected` | Lo rechazó la revisión de riesgo. |
| `cancelled_before_submission` | Se canceló antes de salir. |
Puede aparecer también un código propio del banco. Trata cualquier código que no conozcas como "falló y no se pagó".
## Cancelar [#cancelar]
Puedes cancelar mientras el pago está `processing`, no salió al banco, no está en revisión y no es parte de un lote ni de una remesa.
| Respuesta | Qué significa |
| --- | --- |
| `202` | Pedido: `cancellation.status: requested`. Decidimos antes de enviarlo. |
| `200` | Ya está cancelado. |
| `409 payout_not_cancellable` | No se puede; `reasons` dice por qué: `submitted`, `outcome_uncertain`, `already_completed`, `already_failed`, `already_returned`, `in_review`, `managed_by_batch`, `managed_by_remittance`. |
Si el pago salió mientras la cancelación estaba pendiente, `cancellation.status` queda en `refused`.
## Revisión de riesgo [#revisión-de-riesgo]
Un pago puede quedar en revisión (`risk_status: in_review`): sigue en `processing`, con los fondos reservados, y llega `risk.review_required`. Si se aprueba, continúa; si se rechaza, falla con `risk_rejected`.
## Consultar [#consultar]
`GET /v1/payouts/{id}` agrega `beneficiary` (con `account_hint`, los últimos dígitos de la cuenta), `description`, `country` y las fechas `completed_at`, `failed_at`, `returned_at`, `cancelled_at`. La lista se filtra por `status`, `beneficiary_id`, `risk_status` y fechas.
# Inicio rápido (/docs/quickstart)
En esta guía haces en sandbox el recorrido completo: te autenticas, ves qué tienes disponible, abres un cobro, simulas el depósito del pagador y ves el dinero en tu saldo.
Necesitas una clave de **sandbox** (`psp_test_…`). Caibo emite las claves al abrir tu cuenta; si aún no tienes una, pídela a tu contacto en Caibo. La clave se muestra una sola vez: guárdala en tu gestor de secretos, nunca en el código.
### Configura tu clave [#configura-tu-clave]
```bash
export CAIBO_API_KEY="psp_test_..."
export CAIBO_API="https://api-sandbox.caibopay.app"
```
### Comprueba la conexión [#comprueba-la-conexión]
```bash
curl "$CAIBO_API/v1/account" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
```json
{
"id": "acct_01m3sg8r0000000000000000",
"name": "Mi Empresa",
"status": "active",
"environment": "sandbox",
"primary_treasury_asset": "USDT",
"credential": {
"type": "api_key",
"id": "key_01m3sg8s0000000000000000",
"prefix": "abc123def456",
"scopes": ["read", "write"],
"created_at": "2026-10-18T12:00:00Z"
},
"created_at": "2026-10-01T09:00:00Z"
}
```
`environment` confirma dónde estás. `scopes` dice qué puede hacer la clave: `read` para consultar, `write` para crear y mover dinero.
### Mira qué puedes cobrar [#mira-qué-puedes-cobrar]
```bash
curl "$CAIBO_API/v1/capabilities?product=payin" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
Cada elemento describe algo que puedes hacer: `method`, `currency`, `country`, los campos que pide, cómo se cobra (`collection`) y si está disponible ahora para ti (`available`). Ver [Qué puedes hacer](/docs/capabilities).
### Registra tu webhook [#registra-tu-webhook]
Así te enteras de cada cobro sin tener que consultar. La URL debe ser `https` y pública.
```bash
curl "$CAIBO_API/v1/webhook-endpoints" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://tu-empresa.com/webhooks/caibo", "event_types": ["payin.completed", "funding_account.active"] }'
```
La respuesta trae `secret` (`whsec_…`) **una sola vez**. Guárdalo: con él [verificas la firma](/docs/webhook-signatures) de cada aviso.
### Abre un cobro [#abre-un-cobro]
Sandbox tiene una cuenta de prueba en USD que recibe cualquier depósito y que puedes "pagar" tú mismo. Cada creación lleva un `Idempotency-Key` único por operación.
```bash
curl "$CAIBO_API/v1/funding-accounts" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: quickstart-cobro-001" \
-H "Content-Type: application/json" \
-d '{ "method": "bank_transfer", "currency": "USD" }'
```
```json
{
"id": "fa_01m3sg9w0000000000000000",
"status": "pending",
"method": "bank_transfer",
"currency": "USD",
"settlement_currency": "USDT",
"created_at": "2026-10-18T12:00:00Z"
}
```
En segundos pasa a `active`, te llega `funding_account.active` y la cuenta trae en `instructions` los datos para el pagador:
```bash
curl "$CAIBO_API/v1/funding-accounts/fa_01m3sg9w0000000000000000" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
### Simula el depósito del pagador [#simula-el-depósito-del-pagador]
Solo en sandbox: deposita en la cuenta como lo haría tu cliente. El monto va en la moneda de tu saldo (`settlement_currency`).
```bash
curl "$CAIBO_API/v1/sandbox/deposits" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "funding_account_id": "fa_01m3sg9w0000000000000000", "amount": "100.00" }'
```
Responde `202`. El depósito recorre el mismo camino que uno real y, cuando se confirma, recibes `payin.completed`.
### Mira tu saldo [#mira-tu-saldo]
```bash
curl "$CAIBO_API/v1/balances" -H "Authorization: Bearer $CAIBO_API_KEY"
```
```json
{
"data": [
{
"currency": "USDT",
"primary": true,
"available": "100.000000",
"pending": "0.000000",
"reserved": "0.000000",
"in_settlement": "0.000000",
"earnings": "0.000000",
"total": "100.000000",
"as_of": "2026-10-18T12:01:00Z"
}
]
}
```
## Siguientes pasos [#siguientes-pasos]
PIX en Brasil y transferencia en Perú.
Cliente, beneficiario, cotización y pago.
Reintentos, orden y buenas prácticas.
La lista de verificación.
# Cotizaciones (/docs/quotes)
| Campo | Obligatorio | Qué es |
| --- | --- | --- |
| `source_currency` | Sí | La moneda que sale de tu saldo. |
| `destination_currency` | Sí | La moneda que recibe el beneficiario. |
| `amount` | Sí | El monto. |
| `amount_side` | Sí | `destination`: el monto es lo que **recibe** el beneficiario. `source`: es lo que **sale** de tu saldo. |
| `method` | Para un pago | El método del beneficiario. |
```json title="201"
{
"id": "quo_01m3sgaz0000000000000000",
"status": "open",
"method": "bank_transfer",
"source": {
"currency": "USDT",
"principal": "100.000000",
"platform_fee": "0.500000",
"tenant_markup": "0.000000",
"total": "100.500000"
},
"destination": { "amount": "350.00", "currency": "PEN" },
"rate": "3.500000000000000000",
"created_at": "2026-10-18T14:00:10Z",
"expires_at": "2026-10-18T14:01:40Z"
}
```
| Campo | Qué es |
| --- | --- |
| `source.total` | Lo que se descontará de tu saldo: `principal + platform_fee + tenant_markup`. |
| `source.tenant_markup` | Tu margen, si tienes uno configurado. Se acredita en tus `earnings`. |
| `destination.amount` | Lo que recibe el beneficiario. |
| `rate` | Unidades de destino por unidad de origen, con los márgenes incluidos. |
| `expires_at` | Hasta cuándo vale el precio. |
## Reglas [#reglas]
- **Una cotización paga una sola operación.** Al usarla pasa a `used`; usarla otra vez responde `409 quote_already_used`.
- **Vence.** Normalmente en unos 90 segundos, a veces antes. Usa `expires_at`, no una cuenta fija. Vencida responde `422 quote_expired`: pide otra.
- **Debe coincidir con el beneficiario.** Su `method` y su `destination_currency` deben ser los del beneficiario, o recibes `422 quote_mismatch`.
- Si el pago falla por falta de fondos, la cotización ya quedó usada: pide una nueva para reintentar.
Errores de precio: `pricing_unavailable` (no hay precio ahora), `amount_too_small`, `same_currency`.
# Reembolsos (/docs/refunds)
Un cobro admite reembolso cuando su método lo permite: capabilities lo indica en `features` (`refund`, `partial_refund`). Si no lo permite, `POST /v1/refunds` responde `422 refund_not_supported`.
```bash
curl "$CAIBO_API/v1/refunds" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: reembolso-orden-8812" \
-H "Content-Type: application/json" \
-d '{ "payin_id": "pin_01m3sg9x...", "reason_code": "requested_by_customer", "amount": "10.000000" }'
```
| Campo | Obligatorio | Qué es |
| --- | --- | --- |
| `payin_id` | Sí | El cobro a reembolsar. |
| `reason_code` | Sí | `requested_by_customer`, `duplicate`, `fraud` u `other`. |
| `amount` | No | En la moneda del cobro (la que se acreditó). Si lo omites, se reembolsa todo lo que queda. |
| `note` | No | Hasta 500 caracteres, sin datos personales. |
El reembolso sale de tu saldo disponible y se envía de forma asíncrona.
| `status` | Qué significa |
| --- | --- |
| `pending_review` | En revisión de riesgo. |
| `processing` | Enviado. |
| `completed` | Devuelto al pagador. |
| `failed` | No se pudo devolver; `failure_code` dice por qué. |
Eventos: `refund.created`, `refund.approved`, `refund.processing`, `refund.completed`, `refund.failed`.
Errores: `refund_not_supported`, `refund_exceeds_refundable` (pides más de lo que queda), `payin_not_refundable`, `insufficient_funds`, `risk_blocked`. `GET /v1/payins/{id}` te dice cuánto queda en `refundable`.
# Remesas (/docs/remittances)
Una remesa une un cobro y un pago: el pagador deposita en su moneda, se convierte y el beneficiario recibe en la suya. Todo con **una cotización** y **exactamente un pago**.
B[Tu saldo]
B --> C[Pago al beneficiario]`} />
Los corredores disponibles los lista `GET /v1/capabilities?product=remittance`.
| Campo | Obligatorio | Qué es |
| --- | --- | --- |
| `quote_id` | Sí | La cotización; su método y moneda de destino deben ser los del beneficiario. |
| `beneficiary_id` | Sí | Quién recibe. |
| `source` | Sí | De dónde sale el dinero: `funding_account_id` (el próximo depósito en esa cuenta, antes de que venza la cotización) o `payin_id` (un cobro ya acreditado; cada cobro financia una sola remesa). |
| `customer_id` | No | El remitente. |
## Estados [#estados]
| `status` | Qué significa |
| --- | --- |
| `awaiting_funds` | Esperando el depósito. |
| `processing` | Fondeada y pagando. |
| `review` | En revisión; `review_reason` dice por qué: `underfunded` (el depósito fue menor al total), `screening` o `payout_unknown`. |
| `verification_pending` | El pago salió y su resultado aún no es seguro. |
| `completed` | El beneficiario recibió el dinero. |
| `failed` | No se pagó; lo depositado queda en tu saldo. |
| `returned` | Se pagó y el banco lo devolvió. |
Eventos: `remittance.created`, `remittance.processing`, `remittance.review`, `remittance.completed`, `remittance.failed`, `remittance.returned`.
El pago de una remesa no se cancela por separado (`409` con `managed_by_remittance`).
# Reportes (/docs/reports)
```bash
curl "$CAIBO_API/v1/reports/payouts?from=2026-10-01T00:00:00Z&to=2026-11-01T00:00:00Z&format=csv" \
-H "Authorization: Bearer $CAIBO_API_KEY" -o pagos-octubre.csv
```
| Reporte | Contiene |
| --- | --- |
| `transactions` | Todos los movimientos. |
| `payins` | Cobros. |
| `payouts` | Pagos, con principal, comisión, margen, total, monto de destino y tipo de cambio. |
| `remittances` | Remesas. |
| `refunds` | Reembolsos. |
| `withdrawals` | Retiros. |
| `settlements` | Liquidaciones. |
| `fees` | Comisiones cobradas y devueltas por operación. |
| `fx` | Conversiones, con el tipo de mercado (`market_rate`) y el margen (`margin_bps`). |
| `balances` | Saldo inicial, créditos, débitos y saldo final por moneda. Cuadra: `inicial + créditos − débitos = final`. |
| Parámetro | |
| --- | --- |
| `from`, `to` | Obligatorios, RFC 3339. El periodo incluye `from` y excluye `to`; hasta 366 días. |
| `currency` | Filtra por moneda. |
| `format` | `json` (por defecto) o `csv`. |
| `after` | Para la página siguiente en JSON. |
El CSV sigue RFC 4180 y viene con su nombre de archivo (`payouts__.csv`).
# Sandbox y live (/docs/sandbox)
| | Sandbox | Live |
| --- | --- | --- |
| Host | `https://api-sandbox.caibopay.app` | `https://api.caibopay.app` |
| Clave | `psp_test_…` | `psp_live_…` |
| Dinero | De prueba | Real |
| `livemode` en los eventos | `false` | `true` |
| `environment` en `GET /v1/account` | `sandbox` | `live` |
Son despliegues separados: cada uno tiene sus propios datos, clientes, beneficiarios, webhooks y claves. Una clave enviada al entorno equivocado se rechaza con `401 invalid_api_key`, igual que una clave inválida.
## Lo que solo existe en sandbox [#lo-que-solo-existe-en-sandbox]
- **Depósitos simulados.** deposita en una cuenta de cobro del banco de prueba, la cuenta USD de `bank_transfer`. El depósito recorre el camino real (aviso, verificación, acreditación) y te llega `payin.completed`. En live esta ruta no existe.
- **Un banco de prueba** que ejecuta los pagos, para recorrerlos de punta a punta.
- En sandbox, los cobros con PIX y en soles van al entorno de pruebas del banco real y **no** se pueden pagar con `POST /v1/sandbox/deposits`.
- En sandbox, el banco de prueba también acepta pagos PIX **sin validar los datos**, por eso `pix_key` y `name` aparecen como opcionales. En live los dos son obligatorios y se validan. Envía siempre los datos completos.
## Recomendaciones [#recomendaciones]
- Guarda el host y la clave en tu configuración, no en el código: pasar a live es cambiar esas dos variables.
- Usa el `livemode` de cada evento para no mezclar datos de prueba con datos reales.
- Antes de salir, recorre la [lista de verificación](/docs/go-live).
# SDKs (/docs/sdks)
Los SDKs hacen por ti lo que toda integración debe hacer bien:
- **Eligen el entorno por tu clave**: `psp_test_…` va a sandbox, `psp_live_…` a live.
- **Reintentan sin duplicar**: ante un corte de red, un `429`, un `500` o un `503`, reintentan con el **mismo** `Idempotency-Key`. Si no pasas uno, generan uno por llamada.
- **Respetan `Retry-After`** cuando la API pide esperar.
- **Errores tipados**, con `type`, `code`, `param` y `request_id`.
- **Paginación automática**: recorres una lista entera con un `for`.
- **Verifican webhooks**: firma, tiempo y lectura del evento en una sola función.
- **Tipos completos** de cada recurso, generados del contrato OpenAPI. Cada endpoint de la [referencia](/docs/api/payouts/create-payout) muestra su ejemplo en los tres lenguajes.
## Instalar [#instalar]
```bash
npm install caibopay
```
Node.js 18 o superior. Sin dependencias. ESM y CommonJS, con tipos de TypeScript incluidos.
```bash
pip install caibopay
```
Python 3.8 o superior. Con anotaciones de tipos (`py.typed`).
```bash
go get go.caibopay.app/caibopay
```
Go 1.23 o superior. Sin dependencias.
## Tu primera llamada [#tu-primera-llamada]
```ts
import { Caibo } from "caibopay";
const caibo = new Caibo(process.env.CAIBO_API_KEY!);
const account = await caibo.account.retrieve();
console.log(account.environment); // "sandbox"
```
```python
import os
import caibopay
client = caibopay.Client(os.environ["CAIBO_API_KEY"])
account = client.account.retrieve()
print(account["environment"]) # "sandbox"
```
```go
client, err := caibopay.NewClient(os.Getenv("CAIBO_API_KEY"))
if err != nil {
log.Fatal(err)
}
account, err := client.Account.Retrieve(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Println(account.Environment) // "sandbox"
```
## Cobrar un monto exacto [#cobrar-un-monto-exacto]
```ts
const fa = await caibo.fundingAccounts.create(
{ method: "pix", currency: "BRL", amount: "250.00", payer: { "payer.name": "Ana Souza" } },
{ idempotencyKey: "cobro-orden-8812" },
);
```
```python
fa = client.funding_accounts.create(
method="pix",
currency="BRL",
amount="250.00",
payer={"payer.name": "Ana Souza"},
idempotency_key="cobro-orden-8812",
)
```
```go
fa, err := client.FundingAccounts.Create(ctx, &caibopay.FundingAccountCreate{
Method: "pix",
Currency: "BRL",
Amount: "250.00",
Payer: map[string]string{"payer.name": "Ana Souza"},
}, caibopay.WithIdempotencyKey("cobro-orden-8812"))
```
## Pagar [#pagar]
```ts
const quote = await caibo.quotes.create(
{ source_currency: "USDT", destination_currency: "PEN", method: "bank_transfer", amount: "350.00", amount_side: "destination" },
{ idempotencyKey: "cotizacion-orden-5531" },
);
const payout = await caibo.payouts.create(
{ beneficiary_id: "ben_01m3sgazybenxvqfw0h5bnszk4", quote_id: quote.id },
{ idempotencyKey: "pago-orden-5531" },
);
```
```python
quote = client.quotes.create(
source_currency="USDT", destination_currency="PEN", method="bank_transfer",
amount="350.00", amount_side="destination", idempotency_key="cotizacion-orden-5531",
)
payout = client.payouts.create(
beneficiary_id="ben_01m3sgazybenxvqfw0h5bnszk4", quote_id=quote["id"], idempotency_key="pago-orden-5531",
)
```
```go
quote, err := client.Quotes.Create(ctx, &caibopay.QuoteCreate{
SourceCurrency: "USDT", DestinationCurrency: "PEN", Method: "bank_transfer",
Amount: "350.00", AmountSide: caibopay.QuoteCreateAmountSideDestination,
}, caibopay.WithIdempotencyKey("cotizacion-orden-5531"))
if err != nil {
return err
}
payout, err := client.Payouts.Create(ctx, &caibopay.PayoutCreate{
BeneficiaryID: "ben_01m3sgazybenxvqfw0h5bnszk4", QuoteID: quote.ID,
}, caibopay.WithIdempotencyKey("pago-orden-5531"))
```
## Recorrer una lista [#recorrer-una-lista]
```ts
for await (const payout of caibo.payouts.list({ status: "completed" })) {
console.log(payout.id, payout.destination.amount);
}
```
```python
for payout in client.payouts.list(status="completed"):
print(payout["id"], payout["destination"]["amount"])
```
```go
for payout, err := range client.Payouts.ListAll(ctx, &caibopay.ListPayoutsParams{Status: "completed"}) {
if err != nil {
return err
}
fmt.Println(payout.ID, payout.Destination.Amount)
}
```
## Errores [#errores]
```ts
import { CaiboError } from "caibopay";
try {
await caibo.payouts.create({ beneficiary_id: "ben_...", quote_id: "quo_..." });
} catch (err) {
if (err instanceof CaiboError && err.code === "quote_expired") {
// pide otra cotización
}
throw err;
}
```
```python
try:
client.payouts.create(beneficiary_id="ben_...", quote_id="quo_...")
except caibopay.InvalidRequestError as e:
if e.code == "quote_expired":
... # pide otra cotización
raise
```
```go
_, err := client.Payouts.Create(ctx, &caibopay.PayoutCreate{BeneficiaryID: "ben_...", QuoteID: "quo_..."})
if caibopay.IsCode(err, "quote_expired") {
// pide otra cotización
}
```
## Webhooks [#webhooks]
```ts
import express from "express";
import { constructEvent } from "caibopay";
app.post("/webhooks/caibo", express.raw({ type: "application/json" }), (req, res) => {
try {
const event = constructEvent(req.body, req.get("Psp-Signature"), process.env.CAIBO_WEBHOOK_SECRET!);
queue.push(event); // procesa después; descarta repetidos por event.id
res.sendStatus(200);
} catch {
res.sendStatus(400);
}
});
```
```python
@app.post("/webhooks/caibo")
def webhook():
try:
event = caibopay.construct_event(request.get_data(), request.headers.get("Psp-Signature"), secret)
except caibopay.SignatureVerificationError:
return "", 400
enqueue(event) # procesa después; descarta repetidos por event["id"]
return "", 200
```
```go
http.HandleFunc("/webhooks/caibo", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
event, err := caibopay.ConstructEvent(body, r.Header.Get(caibopay.SignatureHeader), secret)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
enqueue(event) // procesa después; descarta repetidos por event.ID
w.WriteHeader(http.StatusOK)
})
```
## Opciones [#opciones]
| | Node.js | Python | Go |
| --- | --- | --- | --- |
| Reintentos (2 por defecto) | `{ maxRetries }` | `max_retries=` | `WithMaxRetries(n)` |
| Tiempo por intento (30 s) | `{ timeout }` | `timeout=` | `WithHTTPClient(...)` |
| Otro host | `{ baseUrl }` | `base_url=` | `WithBaseURL(u)` |
| Tu Idempotency-Key | `{ idempotencyKey }` | `idempotency_key=` | `WithIdempotencyKey(k)` |
| Tu id de seguimiento | `{ correlationId }` | `request_options={"correlation_id": …}` | `WithCorrelationID(id)` |
Cualquier lenguaje puede usar la API con HTTP y JSON, o generar su propio cliente desde [`/openapi.json`](/openapi.json). Escríbenos si necesitas un SDK oficial para otro lenguaje.
# Liquidaciones (/docs/settlements)
Además de los [retiros](/docs/withdrawals) a pedido, Caibo puede liquidar tu saldo periódicamente: cada día, cada semana, cada mes o al llegar a un monto. El calendario es parte de tu contrato; lo fija Caibo y tú lo consultas.
| Endpoint | Qué devuelve |
| --- | --- |
| | Si tienes liquidación automática y para qué monedas. `unconfigured`: nada se liquida solo y el saldo queda disponible hasta que retires. |
| | Tus calendarios por moneda: `frequency` (`manual`, `daily`, `weekly`, `monthly`, `threshold`), corte, mínimo y comisión (`fee_bps`, `fee_fixed`). |
| | Tus liquidaciones. |
## Una liquidación [#una-liquidación]
| Campo | Qué es |
| --- | --- |
| `gross` | Lo que entró en el periodo. |
| `fees` | Las comisiones. |
| `adjustments` | Ajustes, con signo. |
| `net` | `gross - fees + adjustments`: lo que se envía. |
| `period_start`, `period_end` | El periodo. |
| `hold_reason` | Por qué está detenida: `insufficient_available`, `no_route`, `no_destination`, `operator`. |
`GET /v1/settlements/{id}` agrega `items`, el detalle de cada movimiento incluido.
| `status` | |
| --- | --- |
| `pending`, `ready` | En preparación. |
| `processing` | Enviándose. |
| `settled` | Llegó. |
| `on_hold` | Detenida; mira `hold_reason`. |
| `failed`, `disputed` | Falló o está en disputa. |
Eventos: `settlement.created`, `settlement.processing`, `settlement.on_hold`, `settlement.completed`, `settlement.failed`, y `settlement_schedule.activated`, `settlement_schedule.blocked`.
# Verificar la firma (/docs/webhook-signatures)
Cada webhook trae `Psp-Signature`:
```
Psp-Signature: t=1790769600,v1=c0c9eaafdea23b0f8c992b380b286917c6459b0729b2496b8452fa695215e6b8
```
- `t` es el momento de la firma, en segundos Unix.
- `v1` es `HMAC-SHA256` en hexadecimal, con tu secreto como clave, sobre `t` + `.` + el cuerpo **exacto** que recibiste.
- La clave es el secreto **completo**, incluido el prefijo `whsec_`.
- Puede venir más de un `v1` (durante una rotación). Basta con que uno coincida.
Para aceptar un webhook:
1. Calcula el HMAC con el cuerpo sin tocar: no lo parsees ni lo vuelvas a serializar antes.
2. Compara con cada `v1` en **tiempo constante**.
3. Rechaza si `t` difiere de tu hora en más de **5 minutos**: así nadie puede reenviarte un aviso viejo.
```js
const crypto = require("crypto");
// rawBody: the exact bytes received (a Buffer).
function verifyCaiboSignature(secret, header, rawBody, toleranceSeconds = 300) {
let t = null;
const signatures = [];
for (const part of String(header || "").split(",")) {
const [key, value] = part.trim().split("=", 2);
if (key === "t") {
if (t !== null || !/^\d+$/.test(value)) return false;
t = value;
} else if (key === "v1" && /^[0-9a-f]{64}$/i.test(value)) {
signatures.push(Buffer.from(value, "hex"));
}
}
if (t === null || signatures.length === 0) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.`).update(rawBody).digest();
if (!signatures.some((s) => crypto.timingSafeEqual(s, expected))) return false;
return Math.abs(Date.now() / 1000 - Number(t)) <= toleranceSeconds;
}
// Express: read the body raw, verify, then parse.
app.post("/webhooks/caibo", express.raw({ type: "application/json" }), (req, res) => {
if (!verifyCaiboSignature(process.env.CAIBO_WEBHOOK_SECRET, req.get("Psp-Signature"), req.body)) {
return res.sendStatus(400);
}
const event = JSON.parse(req.body);
queue.push(event); // process later; dedupe on event.id
res.sendStatus(200);
});
```
```python
import hashlib
import hmac
import re
import time
_HEX64 = re.compile(r"^[0-9a-fA-F]{64}$")
def verify_caibo_signature(secret: str, header: str, raw_body: bytes, tolerance: int = 300) -> bool:
t, signatures = None, []
for part in (header or "").split(","):
key, _, value = part.strip().partition("=")
if key == "t":
if t is not None or not value.isdigit():
return False
t = value
elif key == "v1" and _HEX64.match(value):
signatures.append(bytes.fromhex(value))
if t is None or not signatures:
return False
expected = hmac.new(secret.encode(), t.encode() + b"." + raw_body, hashlib.sha256).digest()
if not any(hmac.compare_digest(s, expected) for s in signatures):
return False
return abs(time.time() - int(t)) <= tolerance
# Flask: request.get_data() is the raw body.
@app.post("/webhooks/caibo")
def caibo_webhook():
if not verify_caibo_signature(os.environ["CAIBO_WEBHOOK_SECRET"], request.headers.get("Psp-Signature"), request.get_data()):
return "", 400
event = request.get_json()
enqueue(event) # process later; dedupe on event["id"]
return "", 200
```
```go
package caibo
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"strconv"
"strings"
"time"
)
// VerifySignature reports whether header signs body with secret, within tolerance.
func VerifySignature(secret, header string, body []byte, tolerance time.Duration) bool {
var ts string
var signatures [][]byte
for _, part := range strings.Split(header, ",") {
key, value, _ := strings.Cut(strings.TrimSpace(part), "=")
switch key {
case "t":
if ts != "" {
return false
}
ts = value
case "v1":
if s, err := hex.DecodeString(value); err == nil && len(s) == sha256.Size {
signatures = append(signatures, s)
}
}
}
t, err := strconv.ParseInt(ts, 10, 64)
if err != nil || len(signatures) == 0 {
return false
}
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(ts + "."))
mac.Write(body)
expected := mac.Sum(nil)
ok := false
for _, s := range signatures {
ok = ok || hmac.Equal(s, expected)
}
age := time.Since(time.Unix(t, 0))
return ok && age <= tolerance && age >= -tolerance
}
```
## Prueba tu código [#prueba-tu-código]
Con estos valores tu función debe aceptar la firma (ignorando la tolerancia, porque `t` es una fecha pasada):
| | |
| --- | --- |
| Secreto | `whsec_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef` |
| Cuerpo (exacto, sin salto de línea final) | `{"id":"evt_1","type":"payout.completed","data":{"amount":"10.00"}}` |
| `t` | `1790769600` |
| Firma esperada | `t=1790769600,v1=c0c9eaafdea23b0f8c992b380b286917c6459b0729b2496b8452fa695215e6b8` |
Para probar contra tu servidor real, usa .
Muchos frameworks parsean el JSON antes de que lo veas. Si firmas `JSON.stringify(req.body)` en lugar del cuerpo original, la firma no coincide. Lee el cuerpo **crudo**.
# Webhooks (/docs/webhooks)
```bash
curl "$CAIBO_API/v1/webhook-endpoints" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://tu-empresa.com/webhooks/caibo",
"description": "Producción",
"event_types": ["payin.completed", "payout.completed", "payout.failed"]
}'
```
- `url`: `https`, pública, en el puerto 443.
- `event_types`: los tipos que quieres recibir. Vacío u omitido: **todos**.
- La respuesta trae `secret` (`whsec_…`) **una sola vez**. Si lo pierdes, [rótalo](#rotar-el-secreto).
- Hasta 10 webhooks por cuenta y por entorno.
## Lo que recibes [#lo-que-recibes]
```http
POST /webhooks/caibo HTTP/1.1
Content-Type: application/json
User-Agent: psp-webhooks/1 (live)
Psp-Signature: t=1790769600,v1=c0c9eaafdea23b0f8c992b380b286917c6459b0729b2496b8452fa695215e6b8
Psp-Event-Id: evt_01m3sgb02af7nb0jf73vwv2sd5
Psp-Delivery-Id: whd_01m3sgb03a...
Psp-Delivery-Attempt: 1
```
```json
{
"id": "evt_01m3sgb02af7nb0jf73vwv2sd5",
"type": "payout.completed",
"schema_version": 1,
"occurred_at": "2026-10-18T14:00:41.126938Z",
"livemode": true,
"data": { "id": "pout_01m3sgb02af7nb0jf73vwv2sd4", "status": "completed" }
}
```
`data` es el recurso completo, con la misma forma que te da la API. Ver [Eventos](/docs/events).
## Cómo responder [#cómo-responder]
### Verifica la firma [#verifica-la-firma]
Con el cuerpo **tal como llegó**, antes de parsearlo. Ver [Firmas](/docs/webhook-signatures).
### Responde 2xx enseguida [#responde-2xx-enseguida]
Tienes **10 segundos**. Guarda el evento y procésalo después, en una cola. El cuerpo de tu respuesta se ignora. Una redirección (`3xx`) cuenta como fallo.
### Descarta repetidos [#descarta-repetidos]
La entrega es "al menos una vez": el mismo evento puede llegar dos veces. Usa `Psp-Event-Id` (el `id` del evento) para no procesarlo dos veces.
## Reintentos [#reintentos]
Si no respondes `2xx` a tiempo, reintentamos hasta **10 veces** en unas 23 horas:
| Intento | Espera antes | | Intento | Espera antes |
| --- | --- | --- | --- | --- |
| 2 | 30 s | | 7 | 2 h |
| 3 | 2 min | | 8 | 4 h |
| 4 | 10 min | | 9 | 8 h |
| 5 | 30 min | | 10 | 8 h |
| 6 | 1 h | | | |
Cada espera varía ±20 %. Después de 10 fallos seguidos, el webhook pasa a `failing` y le enviamos una entrega de prueba cada 15 minutos; la primera que responde bien lo devuelve a `active`. Ningún evento se pierde: siempre está en `GET /v1/events`.
**Orden:** una entrega a la vez por webhook, y los eventos de un mismo recurso llegan en orden.
## Herramientas [#herramientas]
| | |
| --- | --- |
| | Envía un `webhook.ping` de prueba (hasta 5 por minuto). |
| | El historial de entregas, con su estado y error. |
| | Reenvía un evento a todos tus webhooks, o solo a `endpoint_id`. |
| | Cambia `url`, `description`, `event_types` o pausa con `active: false`. |
## Rotar el secreto [#rotar-el-secreto]
Devuelve un `secret` nuevo. Durante **24 horas** firmamos con los dos (el nuevo primero), así actualizas tu servidor sin perder avisos. `previous_secret_expires_at` dice cuándo deja de valer el anterior.
# Retiros (/docs/withdrawals)
Un retiro envía fondos de tu saldo a una **cuenta de destino** tuya, por los mismos rieles que un pago.
## 1. Registra tu cuenta de destino [#1-registra-tu-cuenta-de-destino]
```json
{
"method": "bank_transfer",
"currency": "PEN",
"details": { "cci": "00219100123456780123", "document_number": "20123456789", "first_name": "Mi", "last_name": "Empresa SAC" }
}
```
`details` usa los mismos `beneficiary_fields` que un pago de ese método y moneda. Registrar dos veces la misma cuenta devuelve la existente.
## 2. Retira [#2-retira]
```bash
curl "$CAIBO_API/v1/withdrawals" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: retiro-2026-10-18" \
-H "Content-Type: application/json" \
-d '{ "destination_id": "dest_01m3sgc0...", "amount": "5000.00" }'
```
- `amount` es lo que recibe la cuenta, en su moneda.
- `fee` se fija al crear el retiro, y `total = amount + fee` es lo que sale de tu saldo.
- Si el saldo no alcanza, el retiro se crea con `status: failed` y `failure_code: insufficient_funds`.
| `status` | Qué significa |
| --- | --- |
| `pending_approval` | Supera tu umbral y espera la aprobación de Caibo. Los fondos quedan apartados. |
| `processing` | En camino. |
| `completed` | Llegó. |
| `failed` | No se pudo; los fondos vuelven. |
| `cancelled` | Rechazado mientras esperaba aprobación. |
Eventos: `withdrawal.created`, `withdrawal.pending_approval`, `withdrawal.approved`, `withdrawal.submitted`, `withdrawal.completed`, `withdrawal.failed`, `withdrawal.cancelled`.
# Retrieve the account of the credential (/docs/api/account/get-account)
Who the credential is: the account it belongs to, the environment that answered (sandbox or live) and the credential itself, without its secret. Use it to check a key and to show which account and environment a client is working in. The credential is an API key: there are no user identities (people, roles, single sign-on) yet, so nothing here describes a person.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/account",
"description": "Who the credential is: the account it belongs to, the environment that answered (sandbox or live) and the credential itself, without its secret. Use it to check a key and to show which account and environment a client is working in. The credential is an API key: there are no user identities (people, roles, single sign-on) yet, so nothing here describes a person.",
"operationId": "getAccount",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve the account of the credential",
"tags": [
"Account"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.account.retrieve();"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.account.retrieve()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Account.Retrieve(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Who is calling (/docs/api/account/get-me)
Who the credential of the request is: an API key (kind api_key) or a member of the account, a person signed in to the dashboard through its identity provider (kind member), with the account it acts for and its scopes. A member's role and scopes are the platform's: a client reads them here, never from the identity provider. For a member it also lists every account the person may act for; send the Caibo-Account header (acct_…) to act for another one. A person signed in to the dashboard who is no active member of an active account is answered 403 no_membership, one answer whatever the reason; this route binds the person's open invitations first. A dashboard session token is accepted only by this API, an operator console's never.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/me",
"description": "Who the credential of the request is: an API key (kind api_key) or a member of the account, a person signed in to the dashboard through its identity provider (kind member), with the account it acts for and its scopes. A member's role and scopes are the platform's: a client reads them here, never from the identity provider. For a member it also lists every account the person may act for; send the Caibo-Account header (acct_…) to act for another one. A person signed in to the dashboard who is no active member of an active account is answered 403 no_membership, one answer whatever the reason; this route binds the person's open invitations first. A dashboard session token is accepted only by this API, an operator console's never.",
"operationId": "getMe",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Me"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Who is calling",
"tags": [
"Account"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.account.me();"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.account.me()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Account.Me(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List balances (/docs/api/balances/list-balances)
The account's money per currency, by how usable it is. Every figure is read from the ledger; total = available + pending + reserved + in_settlement. Earnings are shown apart and not added.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/balances",
"description": "The account's money per currency, by how usable it is. Every figure is read from the ledger; total = available + pending + reserved + in_settlement. Earnings are shown apart and not added.",
"operationId": "listBalances",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Balance"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List balances",
"tags": [
"Balances"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.balances.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.balances.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Balances.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List the statement of a currency (/docs/api/balances/list-balance-entries)
Every movement on the account's balances in a currency, newest first: one entry per ledger posting on one of the account's own balances, with the operation it belongs to. Pass next_cursor as after to continue; the statement is walked without gaps or repeats.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/balances/{currency}/entries",
"description": "Every movement on the account's balances in a currency, newest first: one entry per ledger posting on one of the account's own balances, with the operation it belongs to. Pass next_cursor as after to continue; the statement is walked without gaps or repeats.",
"operationId": "listBalanceEntries",
"parameters": [
{
"in": "path",
"name": "currency",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "The id of the last entry received (the next_cursor of the previous page).",
"in": "query",
"name": "after",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/BalanceEntry"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List the statement of a currency",
"tags": [
"Balances"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.balances.listEntries(\"USDT\")) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.balances.list_entries(\"USDT\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Balances.ListEntriesAll(ctx, \"USDT\", nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# List beneficiaries (/docs/api/beneficiaries/list-beneficiaries)
Newest first.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/beneficiaries",
"description": "Newest first.",
"operationId": "listBeneficiaries",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"active",
"archived"
],
"type": "string"
}
},
{
"description": "Only the beneficiaries of this customer.",
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"pattern": "^cus_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Beneficiary"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List beneficiaries",
"tags": [
"Beneficiaries"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.beneficiaries.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.beneficiaries.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Beneficiaries.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a beneficiary (/docs/api/beneficiaries/create-beneficiary)
Registers who is paid. The same account registered twice for the same customer is the same beneficiary (200 with the existing one). Account details are write-only. The country is the method's when the method has one.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/beneficiaries",
"description": "Registers who is paid. The same account registered twice for the same customer is the same beneficiary (200 with the existing one). Account details are write-only. The country is the method's when the method has one.",
"operationId": "createBeneficiary",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BeneficiaryCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Beneficiary"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Beneficiary"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a beneficiary",
"tags": [
"Beneficiaries"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.beneficiaries.create({\n currency: \"PEN\",\n details: {},\n method: \"bank_transfer\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.beneficiaries.create(currency=\"PEN\", details={}, method=\"bank_transfer\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Beneficiaries.Create(ctx, &caibopay.BeneficiaryCreate{\n\tCurrency: \"PEN\",\n\tMethod: \"bank_transfer\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a beneficiary (/docs/api/beneficiaries/get-beneficiary)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/beneficiaries/{id}",
"operationId": "getBeneficiary",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Beneficiary"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a beneficiary",
"tags": [
"Beneficiaries"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.beneficiaries.retrieve(\"ben_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.beneficiaries.retrieve(\"ben_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Beneficiaries.Retrieve(ctx, \"ben_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List what the account can do (/docs/api/capabilities/list-capabilities)
The products (payin, payout, remittance), methods, currencies and countries available to the account, with the fields each one requires and whether it can be used right now. Countries and rails are discovered here; they never have endpoints of their own.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/capabilities",
"description": "The products (payin, payout, remittance), methods, currencies and countries available to the account, with the fields each one requires and whether it can be used right now. Countries and rails are discovered here; they never have endpoints of their own.",
"operationId": "listCapabilities",
"parameters": [
{
"description": "Only this product: payin, payout or remittance.",
"in": "query",
"name": "product",
"required": false,
"schema": {
"enum": [
"payin",
"payout",
"remittance"
],
"type": "string"
}
},
{
"description": "Only this country (ISO 3166-1 alpha-2). For a remittance, the destination's.",
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only this currency. For a remittance, the destination's.",
"in": "query",
"name": "currency",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only this method. For a remittance, the payout method.",
"in": "query",
"name": "method",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Capability"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List what the account can do",
"tags": [
"Capabilities"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.capabilities.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.capabilities.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Capabilities.List(ctx, nil)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List customers (/docs/api/customers/list-customers)
Newest first. The profile is not in a list; retrieve a customer for it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/customers",
"description": "Newest first. The profile is not in a list; retrieve a customer for it.",
"operationId": "listCustomers",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"active",
"blocked",
"closed"
],
"type": "string"
}
},
{
"description": "Only the customer with this external_id: your own id for it.",
"in": "query",
"name": "external_id",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Customer"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List customers",
"tags": [
"Customers"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.customers.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.customers.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Customers.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a customer (/docs/api/customers/create-customer)
Registers a person or business you act for, under your own external_id. The same external_id sent again with the same identity (type, country, display_name, profile) returns the existing customer (200); with a different identity it is a 409 conflict. metadata is yours and is not compared.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/customers",
"description": "Registers a person or business you act for, under your own external_id. The same external_id sent again with the same identity (type, country, display_name, profile) returns the existing customer (200); with a different identity it is a 409 conflict. metadata is yours and is not compared.",
"operationId": "createCustomer",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomerCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a customer",
"tags": [
"Customers"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.customers.create({\n country: \"...\",\n display_name: \"...\",\n external_id: \"id_...\",\n type: \"individual\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.customers.create(country=\"...\", display_name=\"...\", external_id=\"id_...\", type=\"individual\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Customers.Create(ctx, &caibopay.CustomerCreate{\n\tCountry: \"...\",\n\tDisplayName: \"...\",\n\tExternalID: \"id_...\",\n\tType: \"individual\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a customer (/docs/api/customers/get-customer)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/customers/{id}",
"operationId": "getCustomer",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a customer",
"tags": [
"Customers"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.customers.retrieve(\"cus_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.customers.retrieve(\"cus_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Customers.Retrieve(ctx, \"cus_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Update a customer's metadata or close it (/docs/api/customers/update-customer)
metadata replaces the whole object. status takes active or closed; closed is final. A blocked customer is blocked by the platform and cannot be reactivated here.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "PATCH",
"path": "/v1/customers/{id}",
"description": "metadata replaces the whole object. status takes active or closed; closed is final. A blocked customer is blocked by the platform and cannot be reactivated here.",
"operationId": "updateCustomer",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomerUpdate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Update a customer's metadata or close it",
"tags": [
"Customers"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.customers.update(\"cus_...\", {});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.customers.update(\"cus_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Customers.Update(ctx, \"cus_...\", &caibopay.CustomerUpdate{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List events (/docs/api/events/list-events)
Events in the order they became visible. Store next_cursor and pass it as after to poll; no event is ever skipped. With resource_id the list is the story of one resource, oldest first: every status it went through, from its creation to its outcome. Filters combine, and the cursor works the same with them.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/events",
"description": "Events in the order they became visible. Store next_cursor and pass it as after to poll; no event is ever skipped. With resource_id the list is the story of one resource, oldest first: every status it went through, from its creation to its outcome. Filters combine, and the cursor works the same with them.",
"operationId": "listEvents",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "The next_cursor of the previous page.",
"in": "query",
"name": "after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only events of this type (payout.completed), or of this family of types when it ends in a dot (payout.). A type the platform does not publish is a 400.",
"in": "query",
"name": "type",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only events about this resource, by its id: a payout, a pay-in, a funding account, a refund, a withdrawal, a remittance, a settlement, a customer, a beneficiary, a payout batch, a reconciliation exception, a risk decision or a webhook endpoint.",
"in": "query",
"name": "resource_id",
"required": false,
"schema": {
"pattern": "^[a-z]+_[0-9a-z]+$",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Event"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List events",
"tags": [
"Events"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.events.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.events.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Events.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Retrieve an event (/docs/api/events/get-event)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/events/{id}",
"operationId": "getEvent",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Event"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve an event",
"tags": [
"Events"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.events.retrieve(\"evt_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.events.retrieve(\"evt_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Events.Retrieve(ctx, \"evt_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Send an event to webhook endpoints again (/docs/api/webhooks/redeliver-event)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/events/{id}/redeliver",
"operationId": "redeliverEvent",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EventRedeliver"
}
}
},
"required": false
},
"responses": {
"202": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/WebhookDelivery"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "Accepted"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Send an event to webhook endpoints again",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.events.redeliver(\"evt_...\", {})) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.events.redeliver(\"evt_...\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Events.Redeliver(ctx, \"evt_...\", &caibopay.EventRedeliver{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List webhook endpoints (/docs/api/webhooks/list-webhook-endpoints)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/webhook-endpoints",
"operationId": "listWebhookEndpoints",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/WebhookEndpoint"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List webhook endpoints",
"tags": [
"Webhooks"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.webhookEndpoints.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.webhook_endpoints.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Create a webhook endpoint (/docs/api/webhooks/create-webhook-endpoint)
The response carries the signing secret. It is shown only here and after a rotation.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/webhook-endpoints",
"description": "The response carries the signing secret. It is shown only here and after a rotation.",
"operationId": "createWebhookEndpoint",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpointCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a webhook endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.create({\n url: \"https://example.com/webhooks/caibo\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.create(url=\"https://example.com/webhooks/caibo\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.Create(ctx, &caibopay.WebhookEndpointCreate{\n\tURL: \"https://example.com/webhooks/caibo\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a webhook endpoint (/docs/api/webhooks/get-webhook-endpoint)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/webhook-endpoints/{id}",
"operationId": "getWebhookEndpoint",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a webhook endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.retrieve(\"we_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.retrieve(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.Retrieve(ctx, \"we_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Update, pause or resume a webhook endpoint (/docs/api/webhooks/update-webhook-endpoint)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "PATCH",
"path": "/v1/webhook-endpoints/{id}",
"operationId": "updateWebhookEndpoint",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpointUpdate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Update, pause or resume a webhook endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.update(\"we_...\", {});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.update(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.Update(ctx, \"we_...\", &caibopay.WebhookEndpointUpdate{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Delete a webhook endpoint (/docs/api/webhooks/delete-webhook-endpoint)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "DELETE",
"path": "/v1/webhook-endpoints/{id}",
"operationId": "deleteWebhookEndpoint",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Delete a webhook endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nawait caibo.webhookEndpoints.delete(\"we_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nclient.webhook_endpoints.delete(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nif err := client.WebhookEndpoints.Delete(ctx, \"we_...\"); err != nil {\n\treturn err\n}"
}
]
}
```
# List recent deliveries to an endpoint (/docs/api/webhooks/list-webhook-deliveries)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/webhook-endpoints/{id}/deliveries",
"operationId": "listWebhookDeliveries",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/WebhookDelivery"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List recent deliveries to an endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.webhookEndpoints.listDeliveries(\"we_...\")) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.webhook_endpoints.list_deliveries(\"we_...\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.ListDeliveries(ctx, \"we_...\", nil)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Send a test event (/docs/api/webhooks/ping-webhook-endpoint)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/webhook-endpoints/{id}/ping",
"operationId": "pingWebhookEndpoint",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"202": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookDelivery"
}
}
},
"description": "Accepted"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Send a test event",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.ping(\"we_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.ping(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.Ping(ctx, \"we_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Rotate the signing secret (/docs/api/webhooks/rotate-webhook-secret)
Returns the new secret. For a grace period deliveries are signed with both the new and the previous secret.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/webhook-endpoints/{id}/rotate-secret",
"description": "Returns the new secret. For a grace period deliveries are signed with both the new and the previous secret.",
"operationId": "rotateWebhookSecret",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Rotate the signing secret",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.rotateSecret(\"we_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.rotate_secret(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.RotateSecret(ctx, \"we_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Create a funding account (/docs/api/funding/create-funding-account)
An account the balance is funded through. It is created pending; its payment instructions are available once it is active (event funding_account.active). With amount it is one payment of exactly that amount (collection payment in GET /v1/capabilities): the payer pays the amount and nothing more, and the account closes once it is paid; the pay-in that credits it is payin.completed.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/funding-accounts",
"description": "An account the balance is funded through. It is created pending; its payment instructions are available once it is active (event funding_account.active). With amount it is one payment of exactly that amount (collection payment in GET /v1/capabilities): the payer pays the amount and nothing more, and the account closes once it is paid; the pay-in that credits it is payin.completed.",
"operationId": "createFundingAccount",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FundingAccountCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FundingAccount"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FundingAccount"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a funding account",
"tags": [
"Funding"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.fundingAccounts.create({\n currency: \"PEN\",\n method: \"bank_transfer\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.funding_accounts.create(currency=\"PEN\", method=\"bank_transfer\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.FundingAccounts.Create(ctx, &caibopay.FundingAccountCreate{\n\tCurrency: \"PEN\",\n\tMethod: \"bank_transfer\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a funding account (/docs/api/funding/get-funding-account)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/funding-accounts/{id}",
"operationId": "getFundingAccount",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FundingAccount"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a funding account",
"tags": [
"Funding"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.fundingAccounts.retrieve(\"fa_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.funding_accounts.retrieve(\"fa_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.FundingAccounts.Retrieve(ctx, \"fa_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List pay-ins (/docs/api/funding/list-pay-ins)
Newest first. refunded and refundable are not in a list; retrieve a pay-in for them.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payins",
"description": "Newest first. refunded and refundable are not in a list; retrieve a pay-in for them.",
"operationId": "listPayIns",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"processing",
"completed",
"failed"
],
"type": "string"
}
},
{
"description": "Only the pay-ins into this funding account.",
"in": "query",
"name": "funding_account_id",
"required": false,
"schema": {
"pattern": "^fa_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/PayIn"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List pay-ins",
"tags": [
"Funding"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.payins.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.payins.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Payins.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Retrieve a pay-in (/docs/api/funding/get-pay-in)
A credited pay-in also says what it has given back (refunded) and what can still be refunded (refundable).
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payins/{id}",
"description": "A credited pay-in also says what it has given back (refunded) and what can still be refunded (refundable).",
"operationId": "getPayIn",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayIn"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a pay-in",
"tags": [
"Funding"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payins.retrieve(\"pin_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payins.retrieve(\"pin_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Payins.Retrieve(ctx, \"pin_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List hosted domains (/docs/api/hosted-pages/list-hosted-domains)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-domains",
"operationId": "listHostedDomains",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/HostedDomain"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List hosted domains",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.hostedDomains.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.hosted_domains.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedDomains.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Claim a hostname for the hosted page (/docs/api/hosted-pages/create-hosted-domain)
Claims a hostname the page should be served at. The claim starts pending, with a verification_token to publish; the hostname serves the page only once the platform has verified it. A hostname with a live claim, yours or anybody's, is refused with hostname_taken.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/hosted-domains",
"description": "Claims a hostname the page should be served at. The claim starts pending, with a verification_token to publish; the hostname serves the page only once the platform has verified it. A hostname with a live claim, yours or anybody's, is refused with hostname_taken.",
"operationId": "createHostedDomain",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedDomainCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedDomain"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedDomain"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Claim a hostname for the hosted page",
"tags": [
"Hosted pages"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedDomains.create({\n hostname: \"...\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_domains.create(hostname=\"...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedDomains.Create(ctx, &caibopay.HostedDomainCreate{\n\tHostname: \"...\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a hosted domain (/docs/api/hosted-pages/get-hosted-domain)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-domains/{id}",
"operationId": "getHostedDomain",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedDomain"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a hosted domain",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedDomains.retrieve(\"hd_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_domains.retrieve(\"hd_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedDomains.Retrieve(ctx, \"hd_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Remove a hosted domain (/docs/api/hosted-pages/delete-hosted-domain)
The hostname stops serving the page at once and can be claimed again.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "DELETE",
"path": "/v1/hosted-domains/{id}",
"description": "The hostname stops serving the page at once and can be claimed again.",
"operationId": "deleteHostedDomain",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Remove a hosted domain",
"tags": [
"Hosted pages"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nawait caibo.hostedDomains.delete(\"hd_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nclient.hosted_domains.delete(\"hd_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nif err := client.HostedDomains.Delete(ctx, \"hd_...\"); err != nil {\n\treturn err\n}"
}
]
}
```
# Retrieve the hosted page configuration (/docs/api/hosted-pages/get-hosted-page)
How the account's hosted remittance page is configured. An account that never configured it gets the defaults, with no id.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-page",
"description": "How the account's hosted remittance page is configured. An account that never configured it gets the defaults, with no id.",
"operationId": "getHostedPage",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedPage"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve the hosted page configuration",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedPage.retrieve();"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_page.retrieve()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedPage.Retrieve(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Replace the hosted page configuration (/docs/api/hosted-pages/put-hosted-page)
Replaces the whole configuration; a field left out is reset to its default. The theme is data, validated here: colours are #rrggbb, the radius is one of a fixed scale, the font is the key of a font the page ships, and URLs are https. branding_mode white_label needs the entitlement (white_label_entitled), which the platform grants; it is refused with white_label_not_entitled otherwise.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "PUT",
"path": "/v1/hosted-page",
"description": "Replaces the whole configuration; a field left out is reset to its default. The theme is data, validated here: colours are #rrggbb, the radius is one of a fixed scale, the font is the key of a font the page ships, and URLs are https. branding_mode white_label needs the entitlement (white_label_entitled), which the platform grants; it is refused with white_label_not_entitled otherwise.",
"operationId": "putHostedPage",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedPageUpdate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedPage"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Replace the hosted page configuration",
"tags": [
"Hosted pages"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedPage.update({});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_page.update()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedPage.Update(ctx, &caibopay.HostedPageUpdate{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List hosted sessions (/docs/api/hosted-pages/list-hosted-sessions)
Newest first, those your customers started from the page included. Never with a token. A session's status is read off its remittance and its expiry when you ask, so the list is not filtered by it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-sessions",
"description": "Newest first, those your customers started from the page included. Never with a token. A session's status is read off its remittance and its expiry when you ask, so the list is not filtered by it.",
"operationId": "listHostedSessions",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only the sessions of this customer.",
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"pattern": "^cus_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the session this remittance was created from.",
"in": "query",
"name": "remittance_id",
"required": false,
"schema": {
"pattern": "^rem_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/HostedSession"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List hosted sessions",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.hostedSessions.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.hosted_sessions.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.HostedSessions.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a hosted session (/docs/api/hosted-pages/create-hosted-session)
Starts a session of the hosted remittance flow for one of your customers. The response carries the session token and the path the hosted page serves it at (/s/); they are shown only here. Send the customer to that path on your page's host: the same link is where they follow the remittance afterwards. A session creates at most one remittance, ever. Repeating the request with the same Idempotency-Key returns the same session, without the token. The hosted page must be enabled.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/hosted-sessions",
"description": "Starts a session of the hosted remittance flow for one of your customers. The response carries the session token and the path the hosted page serves it at (/s/); they are shown only here. Send the customer to that path on your page's host: the same link is where they follow the remittance afterwards. A session creates at most one remittance, ever. Repeating the request with the same Idempotency-Key returns the same session, without the token. The hosted page must be enabled.",
"operationId": "createHostedSession",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedSessionCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedSession"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedSession"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a hosted session",
"tags": [
"Hosted pages"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedSessions.create({}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_sessions.create(idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedSessions.Create(ctx, &caibopay.HostedSessionCreate{}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a hosted session (/docs/api/hosted-pages/get-hosted-session)
With the ids of what the session holds: its customer, beneficiary, quote, funding account and remittance. payment_reported_at is when the customer said they paid; it is a statement, not a confirmation: follow the remittance and its pay-in for that.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-sessions/{id}",
"description": "With the ids of what the session holds: its customer, beneficiary, quote, funding account and remittance. payment_reported_at is when the customer said they paid; it is a statement, not a confirmation: follow the remittance and its pay-in for that.",
"operationId": "getHostedSession",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedSession"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a hosted session",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedSessions.retrieve(\"hs_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_sessions.retrieve(\"hs_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedSessions.Retrieve(ctx, \"hs_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List the account's members (/docs/api/members/list-members)
The people who act for the account through the dashboard, and the open invitations, newest first. A member's role maps to scopes: owner, admin and developer hold read and write, viewer read.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/members",
"description": "The people who act for the account through the dashboard, and the open invitations, newest first. A member's role maps to scopes: owner, admin and developer hold read and write, viewer read.",
"operationId": "listMembers",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Member"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List the account's members",
"tags": [
"Members"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.members.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.members.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Members.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Invite a person (/docs/api/members/create-member)
Invites an e-mail address with a role. The invitation expires after 7 days; it is bound at the person's first signed-in call to the person whose verified primary address it is, and the member becomes active. Inviting an address that was invited and never signed in renews its invitation (200). Only a signed-in owner or admin invites, and only an owner invites an owner: an API key does not manage people (403 insufficient_role). An address that is already a member is 409 member_exists.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/members",
"description": "Invites an e-mail address with a role. The invitation expires after 7 days; it is bound at the person's first signed-in call to the person whose verified primary address it is, and the member becomes active. Inviting an address that was invited and never signed in renews its invitation (200). Only a signed-in owner or admin invites, and only an owner invites an owner: an API key does not manage people (403 insufficient_role). An address that is already a member is 409 member_exists.",
"operationId": "createMember",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MemberCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Member"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Member"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Invite a person",
"tags": [
"Members"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.members.create({\n email: \"...\",\n role: \"owner\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.members.create(email=\"...\", role=\"owner\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Members.Create(ctx, &caibopay.MemberCreate{\n\tEmail: \"...\",\n\tRole: \"owner\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Change a member's role or disable it (/docs/api/members/update-member)
status disabled refuses the member's next request at once, whatever its session; active enables it again (only a member that signed in once). Only a signed-in owner or admin changes members, not their own; only an owner touches an owner; the account keeps at least one active owner (409 last_owner). Withdraw an invitation by disabling it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "PATCH",
"path": "/v1/members/{id}",
"description": "status disabled refuses the member's next request at once, whatever its session; active enables it again (only a member that signed in once). Only a signed-in owner or admin changes members, not their own; only an owner touches an owner; the account keeps at least one active owner (409 last_owner). Withdraw an invitation by disabling it.",
"operationId": "updateMember",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MemberUpdate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Member"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Change a member's role or disable it",
"tags": [
"Members"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.members.update(\"mem_...\", {});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.members.update(\"mem_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Members.Update(ctx, \"mem_...\", &caibopay.MemberUpdate{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List payout batches (/docs/api/payouts/list-payout-batches)
Newest first, each with its summary, totals and cancellation as they are now. A batch accepted while you page never shifts or repeats the pages that follow.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payout-batches",
"description": "Newest first, each with its summary, totals and cancellation as they are now. A batch accepted while you page never shifts or repeats the pages that follow.",
"operationId": "listPayoutBatches",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"accepted",
"processing",
"completed",
"completed_with_failures",
"cancelled",
"partially_cancelled"
],
"type": "string"
}
},
{
"description": "Only batches with exactly this label.",
"in": "query",
"name": "label",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/PayoutBatch"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List payout batches",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.payoutBatches.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.payout_batches.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.PayoutBatches.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a payout batch (/docs/api/payouts/create-payout-batch)
Accepts up to 1000 payouts in one request. Every item is checked for form first: one malformed item refuses the whole batch (400, param items[i].field) and nothing is created. The batch is then accepted and each item becomes, asynchronously and at most once, an ordinary payout with its own status and events, in index order. An item that cannot be paid does not stop the others: it is refused (status refused, error_code) when it never became a payout, or its payout fails (insufficient_funds) as a single payout would. A quote named by an item is used by that item from the moment the batch is accepted. A payout kill switch for the account refuses the whole batch (503). Repeating the request with the same Idempotency-Key returns the same batch and creates nothing.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/payout-batches",
"description": "Accepts up to 1000 payouts in one request. Every item is checked for form first: one malformed item refuses the whole batch (400, param items[i].field) and nothing is created. The batch is then accepted and each item becomes, asynchronously and at most once, an ordinary payout with its own status and events, in index order. An item that cannot be paid does not stop the others: it is refused (status refused, error_code) when it never became a payout, or its payout fails (insufficient_funds) as a single payout would. A quote named by an item is used by that item from the moment the batch is accepted. A payout kill switch for the account refuses the whole batch (503). Repeating the request with the same Idempotency-Key returns the same batch and creates nothing.",
"operationId": "createPayoutBatch",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatchCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatch"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatch"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a payout batch",
"tags": [
"Payouts"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payoutBatches.create({\n items: [],\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payout_batches.create(items=[], idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.PayoutBatches.Create(ctx, &caibopay.PayoutBatchCreate{}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a payout batch (/docs/api/payouts/get-payout-batch)
With its summary and totals, computed from its payouts as they are now. A payout whose outcome is not yet certain is counted as uncertain (its item is verification_pending) and keeps the batch processing; it is never sent again.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payout-batches/{id}",
"description": "With its summary and totals, computed from its payouts as they are now. A payout whose outcome is not yet certain is counted as uncertain (its item is verification_pending) and keeps the batch processing; it is never sent again.",
"operationId": "getPayoutBatch",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatch"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a payout batch",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payoutBatches.retrieve(\"pbat_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payout_batches.retrieve(\"pbat_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.PayoutBatches.Retrieve(ctx, \"pbat_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Cancel a payout batch (/docs/api/payouts/cancel-payout-batch)
Asks for the batch to be cancelled. Nothing that was sent is reversed. The request is recorded at once and carried out asynchronously, item by item: an item not yet issued is cancelled; an item whose payout has provably not reached a provider is cancelled with its payout (the payout fails with failure_code cancelled_before_submission and its funds are available again); every other item keeps its state, with not_cancelled_reason saying why (in_review, submitted, outcome_uncertain, already_completed, already_failed, already_returned, already_refused). A payout whose outcome is uncertain is never cancelled and never sent again. The answer is the batch as it is now: cancellation.status is in_progress until every item has its decision (event payout_batch.cancellation_finished); the batch then ends cancelled (no payout was executed), partially_cancelled (some were) or, when nothing could be cancelled, completed or completed_with_failures. Asking again, or for a batch that is already finished, changes nothing and returns the batch as it is.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/payout-batches/{id}/cancel",
"description": "Asks for the batch to be cancelled. Nothing that was sent is reversed. The request is recorded at once and carried out asynchronously, item by item: an item not yet issued is cancelled; an item whose payout has provably not reached a provider is cancelled with its payout (the payout fails with failure_code cancelled_before_submission and its funds are available again); every other item keeps its state, with not_cancelled_reason saying why (in_review, submitted, outcome_uncertain, already_completed, already_failed, already_returned, already_refused). A payout whose outcome is uncertain is never cancelled and never sent again. The answer is the batch as it is now: cancellation.status is in_progress until every item has its decision (event payout_batch.cancellation_finished); the batch then ends cancelled (no payout was executed), partially_cancelled (some were) or, when nothing could be cancelled, completed or completed_with_failures. Asking again, or for a batch that is already finished, changes nothing and returns the batch as it is.",
"operationId": "cancelPayoutBatch",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatch"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Cancel a payout batch",
"tags": [
"Payouts"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payoutBatches.cancel(\"pbat_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payout_batches.cancel(\"pbat_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.PayoutBatches.Cancel(ctx, \"pbat_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List the items of a payout batch (/docs/api/payouts/list-payout-batch-items)
In index order, each with its payout's status now, why it was refused, or what the batch's cancellation decided about it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payout-batches/{id}/items",
"description": "In index order, each with its payout's status now, why it was refused, or what the batch's cancellation decided about it.",
"operationId": "listPayoutBatchItems",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "The index of the last item received (the next_cursor of the previous page).",
"in": "query",
"name": "after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status: queued, refused, cancelled, processing, verification_pending, completed, failed or returned.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"queued",
"refused",
"cancelled",
"processing",
"verification_pending",
"completed",
"failed",
"returned"
],
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/PayoutBatchItem"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List the items of a payout batch",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.payoutBatches.listItems(\"pbat_...\")) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.payout_batches.list_items(\"pbat_...\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.PayoutBatches.ListItemsAll(ctx, \"pbat_...\", nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# List payouts (/docs/api/payouts/list-payouts)
Newest first. A list carries the payout without its detail (description, country, completed_at, failed_at, returned_at); retrieve a payout for it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payouts",
"description": "Newest first. A list carries the payout without its detail (description, country, completed_at, failed_at, returned_at); retrieve a payout for it.",
"operationId": "listPayouts",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"processing",
"verification_pending",
"completed",
"failed",
"returned",
"cancelled"
],
"type": "string"
}
},
{
"description": "Only the payouts to this beneficiary.",
"in": "query",
"name": "beneficiary_id",
"required": false,
"schema": {
"pattern": "^ben_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the payouts whose risk_status is this: allowed, in_review (funds held, waiting for a person), approved or rejected. A payout without a risk decision has no risk_status and matches none.",
"in": "query",
"name": "risk_status",
"required": false,
"schema": {
"enum": [
"allowed",
"in_review",
"approved",
"rejected"
],
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Payout"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List payouts",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.payouts.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.payouts.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Payouts.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a payout (/docs/api/payouts/create-payout)
Reserves the funds and accepts the payout; it is executed asynchronously. A payout the balance cannot fund is created with status failed and failure_code insufficient_funds. Repeating the request with the same Idempotency-Key returns the same payout and never pays twice.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/payouts",
"description": "Reserves the funds and accepts the payout; it is executed asynchronously. A payout the balance cannot fund is created with status failed and failure_code insufficient_funds. Repeating the request with the same Idempotency-Key returns the same payout and never pays twice.",
"operationId": "createPayout",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a payout",
"tags": [
"Payouts"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payouts.create({\n beneficiary_id: \"ben_...\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payouts.create(beneficiary_id=\"ben_...\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Payouts.Create(ctx, &caibopay.PayoutCreate{\n\tBeneficiaryID: \"ben_...\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a payout (/docs/api/payouts/get-payout)
With its detail: your own description, the country of the beneficiary's account, when it completed, failed, was returned or was cancelled, and its latest cancellation if one was asked for. Its story, step by step, is GET /v1/events?resource_id={id}. A payout whose submission's outcome is uncertain is verification_pending: its funds stay reserved, it is being verified with the provider, and nothing sends it again or in its place; it ends completed or failed on the provider's evidence. No request retries or cancels it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payouts/{id}",
"description": "With its detail: your own description, the country of the beneficiary's account, when it completed, failed, was returned or was cancelled, and its latest cancellation if one was asked for. Its story, step by step, is GET /v1/events?resource_id={id}. A payout whose submission's outcome is uncertain is verification_pending: its funds stay reserved, it is being verified with the provider, and nothing sends it again or in its place; it ends completed or failed on the provider's evidence. No request retries or cancels it.",
"operationId": "getPayout",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a payout",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payouts.retrieve(\"pout_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payouts.retrieve(\"pout_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Payouts.Retrieve(ctx, \"pout_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Cancel a payout that was never sent (/docs/api/payouts/cancel-payout)
Asks for a payout to be cancelled. Only a payout nothing of which can have reached a provider is cancelled: it is processing, it was never sent (or every send is proven never to have left) and it is not waiting for a risk review. A payout that was sent, may have been sent (verification_pending), is final, waits for a risk review, or belongs to a payout batch or a remittance is refused with 409 payout_not_cancellable, reasons saying why (submitted, outcome_uncertain, already_completed, already_failed, already_returned, in_review, managed_by_batch, managed_by_remittance); nothing changes. The request is recorded at once and decided by the platform, under the payout's lock, before the payout would be sent: the answer is 202 with cancellation.status requested. Once cancelled, the payout's status is cancelled (failure_code cancelled_before_submission), its funds are available again and payout.cancelled is published; asking again, with any key, answers 200 with the cancelled payout. If the payout was sent in the meantime, cancellation.status becomes refused with not_cancelled_reason, and the payout goes on. Repeating the request with the same Idempotency-Key never cancels twice; the same key for another payout is 409 idempotency_key_reused.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/payouts/{id}/cancel",
"description": "Asks for a payout to be cancelled. Only a payout nothing of which can have reached a provider is cancelled: it is processing, it was never sent (or every send is proven never to have left) and it is not waiting for a risk review. A payout that was sent, may have been sent (verification_pending), is final, waits for a risk review, or belongs to a payout batch or a remittance is refused with 409 payout_not_cancellable, reasons saying why (submitted, outcome_uncertain, already_completed, already_failed, already_returned, in_review, managed_by_batch, managed_by_remittance); nothing changes. The request is recorded at once and decided by the platform, under the payout's lock, before the payout would be sent: the answer is 202 with cancellation.status requested. Once cancelled, the payout's status is cancelled (failure_code cancelled_before_submission), its funds are available again and payout.cancelled is published; asking again, with any key, answers 200 with the cancelled payout. If the payout was sent in the meantime, cancellation.status becomes refused with not_cancelled_reason, and the payout goes on. Repeating the request with the same Idempotency-Key never cancels twice; the same key for another payout is 409 idempotency_key_reused.",
"operationId": "cancelPayout",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "The payout is cancelled: by this request's decision or an earlier one."
},
"202": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "Accepted"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Cancel a payout that was never sent",
"tags": [
"Payouts"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payouts.cancel(\"pout_...\", { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payouts.cancel(\"pout_...\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Payouts.Cancel(ctx, \"pout_...\", caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Create a quote (/docs/api/quotes/create-quote)
Freezes a price for a short time. A quote is used by at most one payout.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/quotes",
"description": "Freezes a price for a short time. A quote is used by at most one payout.",
"operationId": "createQuote",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuoteCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Quote"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Quote"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a quote",
"tags": [
"Quotes"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.quotes.create({\n amount: \"100.00\",\n amount_side: \"source\",\n destination_currency: \"PEN\",\n source_currency: \"USDT\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.quotes.create(amount=\"100.00\", amount_side=\"source\", destination_currency=\"PEN\", source_currency=\"USDT\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Quotes.Create(ctx, &caibopay.QuoteCreate{\n\tAmount: \"100.00\",\n\tAmountSide: \"source\",\n\tDestinationCurrency: \"PEN\",\n\tSourceCurrency: \"USDT\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a quote (/docs/api/quotes/get-quote)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/quotes/{id}",
"operationId": "getQuote",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Quote"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a quote",
"tags": [
"Quotes"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.quotes.retrieve(\"quo_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.quotes.retrieve(\"quo_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Quotes.Retrieve(ctx, \"quo_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List reconciliation exceptions (/docs/api/reconciliation/list-reconciliation-exceptions)
Inconsistencies the platform found about your own operations (a pay-in, a payout, a withdrawal, a refund, a settlement or a remittance) and is working on, newest first. Read-only: the platform's operators investigate and close them.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/reconciliation-exceptions",
"description": "Inconsistencies the platform found about your own operations (a pay-in, a payout, a withdrawal, a refund, a settlement or a remittance) and is working on, newest first. Read-only: the platform's operators investigate and close them.",
"operationId": "listReconciliationExceptions",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/ReconciliationException"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List reconciliation exceptions",
"tags": [
"Reconciliation"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.reconciliationExceptions.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.reconciliation_exceptions.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.ReconciliationExceptions.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Retrieve a reconciliation exception (/docs/api/reconciliation/get-reconciliation-exception)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/reconciliation-exceptions/{id}",
"operationId": "getReconciliationException",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReconciliationException"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a reconciliation exception",
"tags": [
"Reconciliation"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.reconciliationExceptions.retrieve(\"rex_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.reconciliation_exceptions.retrieve(\"rex_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.ReconciliationExceptions.Retrieve(ctx, \"rex_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List refunds (/docs/api/refunds/list-refunds)
Newest first.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/refunds",
"description": "Newest first.",
"operationId": "listRefunds",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"pending_review",
"processing",
"completed",
"failed"
],
"type": "string"
}
},
{
"description": "Only the refunds of this pay-in.",
"in": "query",
"name": "payin_id",
"required": false,
"schema": {
"pattern": "^pin_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Refund"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List refunds",
"tags": [
"Refunds"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.refunds.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.refunds.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Refunds.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Refund a pay-in (/docs/api/refunds/create-refund)
Sends part or all of a credited pay-in back to its payer, from the available balance, through the provider that received it. Reserves the funds and accepts the refund; it is executed asynchronously. A refund the platform's risk controls hold for a review is created with status pending_review: its funds are reserved and it counts against what is left to refund, but nothing is sent until it is approved; a refund they refuse is a 422 risk_blocked. Omit amount to refund everything that is left. Repeating the request with the same Idempotency-Key returns the same refund and never refunds twice.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/refunds",
"description": "Sends part or all of a credited pay-in back to its payer, from the available balance, through the provider that received it. Reserves the funds and accepts the refund; it is executed asynchronously. A refund the platform's risk controls hold for a review is created with status pending_review: its funds are reserved and it counts against what is left to refund, but nothing is sent until it is approved; a refund they refuse is a 422 risk_blocked. Omit amount to refund everything that is left. Repeating the request with the same Idempotency-Key returns the same refund and never refunds twice.",
"operationId": "createRefund",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RefundCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Refund"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Refund"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Refund a pay-in",
"tags": [
"Refunds"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.refunds.create({\n payin_id: \"pin_...\",\n reason_code: \"requested_by_customer\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.refunds.create(payin_id=\"pin_...\", reason_code=\"requested_by_customer\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Refunds.Create(ctx, &caibopay.RefundCreate{\n\tPayinID: \"pin_...\",\n\tReasonCode: \"requested_by_customer\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a refund (/docs/api/refunds/get-refund)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/refunds/{id}",
"operationId": "getRefund",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Refund"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a refund",
"tags": [
"Refunds"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.refunds.retrieve(\"rfd_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.refunds.retrieve(\"rfd_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Refunds.Retrieve(ctx, \"rfd_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List remittances (/docs/api/remittances/list-remittances)
Newest first. payin_id and payout_id find the remittance a pay-in funded or a payout pays: at most one.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/remittances",
"description": "Newest first. payin_id and payout_id find the remittance a pay-in funded or a payout pays: at most one.",
"operationId": "listRemittances",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"awaiting_funds",
"processing",
"verification_pending",
"review",
"completed",
"failed",
"returned"
],
"type": "string"
}
},
{
"description": "Only the remittances sent by this customer.",
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"pattern": "^cus_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the remittances to this beneficiary.",
"in": "query",
"name": "beneficiary_id",
"required": false,
"schema": {
"pattern": "^ben_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the remittance this pay-in funded.",
"in": "query",
"name": "payin_id",
"required": false,
"schema": {
"pattern": "^pin_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the remittance this payout pays.",
"in": "query",
"name": "payout_id",
"required": false,
"schema": {
"pattern": "^pout_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Remittance"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List remittances",
"tags": [
"Remittances"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.remittances.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.remittances.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Remittances.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a remittance (/docs/api/remittances/create-remittance)
Sends a quote's destination amount to a beneficiary, funded by a deposit: either the next deposit into a funding account (source.funding_account_id; the remittance awaits it and the deposit must be credited before the quote expires) or a pay-in that already credited the balance (source.payin_id; a pay-in funds at most one remittance). The quote is used by the remittance from the moment it is created. The remittance never spends more than its pay-in credited. It is executed asynchronously and makes exactly one payout; while that payout's outcome is uncertain the remittance stays processing or review, and no second payout is ever made.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/remittances",
"description": "Sends a quote's destination amount to a beneficiary, funded by a deposit: either the next deposit into a funding account (source.funding_account_id; the remittance awaits it and the deposit must be credited before the quote expires) or a pay-in that already credited the balance (source.payin_id; a pay-in funds at most one remittance). The quote is used by the remittance from the moment it is created. The remittance never spends more than its pay-in credited. It is executed asynchronously and makes exactly one payout; while that payout's outcome is uncertain the remittance stays processing or review, and no second payout is ever made.",
"operationId": "createRemittance",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RemittanceCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Remittance"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Remittance"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a remittance",
"tags": [
"Remittances"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.remittances.create({\n beneficiary_id: \"ben_...\",\n quote_id: \"quo_...\",\n source: {},\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.remittances.create(beneficiary_id=\"ben_...\", quote_id=\"quo_...\", source={}, idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Remittances.Create(ctx, &caibopay.RemittanceCreate{\n\tBeneficiaryID: \"ben_...\",\n\tQuoteID: \"quo_...\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a remittance (/docs/api/remittances/get-remittance)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/remittances/{id}",
"operationId": "getRemittance",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Remittance"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a remittance",
"tags": [
"Remittances"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.remittances.retrieve(\"rem_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.remittances.retrieve(\"rem_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Remittances.Retrieve(ctx, \"rem_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Run a report (/docs/api/reports/get-report)
A read-only view of a period, never the authority for money (the ledger is). The answer says what it was computed from (source) and the instant it is complete up to (as_of). name is one of transactions, payins, payouts, remittances, refunds, withdrawals, settlements, fees, fx, balances. Row reports list what was created in [from, to), oldest first, in pages (pass next_cursor as after); balances is returned whole: per currency and balance, the opening at from, the credits and debits of the period and the closing at to, with opening + credits - debits = closing exactly. Every value is a string (amounts as decimal strings in the currency's precision, timestamps in UTC) or null. With format=csv the whole report is streamed as RFC 4180 CSV with a header row, as an attachment.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/reports/{name}",
"description": "A read-only view of a period, never the authority for money (the ledger is). The answer says what it was computed from (source) and the instant it is complete up to (as_of). name is one of transactions, payins, payouts, remittances, refunds, withdrawals, settlements, fees, fx, balances. Row reports list what was created in [from, to), oldest first, in pages (pass next_cursor as after); balances is returned whole: per currency and balance, the opening at from, the credits and debits of the period and the closing at to, with opening + credits - debits = closing exactly. Every value is a string (amounts as decimal strings in the currency's precision, timestamps in UTC) or null. With format=csv the whole report is streamed as RFC 4180 CSV with a header row, as an attachment.",
"operationId": "getReport",
"parameters": [
{
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Required. The start of the period, inclusive (RFC 3339).",
"in": "query",
"name": "from",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Required. The end of the period, exclusive (RFC 3339). At most 366 days after from.",
"in": "query",
"name": "to",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only this currency.",
"in": "query",
"name": "currency",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "json (the default) or csv.",
"in": "query",
"name": "format",
"required": false,
"schema": {
"enum": [
"json",
"csv"
],
"type": "string"
}
},
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "The next_cursor of the previous page (JSON only; not for balances).",
"in": "query",
"name": "after",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"as_of": {
"description": "The instant the rows are complete up to: everything recorded before it is in them. Each page is computed on its own and has its own as_of; a CSV export is one snapshot.",
"format": "date-time",
"type": "string"
},
"data": {
"items": {
"$ref": "#/components/schemas/ReportRow"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
},
"source": {
"description": "What the rows were read from. live: the operations and the ledger themselves, in the snapshot of this request. view: a view over them, in the snapshot of this request. materialized: a stored copy, as fresh as as_of.",
"enum": [
"live",
"view",
"materialized"
],
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
},
"text/csv": {
"schema": {
"description": "RFC 4180 CSV: a header row with the column names, then one record per row; CRLF line endings.",
"type": "string"
}
}
},
"description": "OK",
"headers": {
"Content-Disposition": {
"description": "With format=csv: attachment; filename=\"__.csv\".",
"schema": {
"type": "string"
}
},
"Report-As-Of": {
"description": "With format=csv: the instant the export is complete up to (the as_of of a JSON page).",
"schema": {
"format": "date-time",
"type": "string"
}
},
"Report-Source": {
"description": "With format=csv: what the export was read from (the source of a JSON page).",
"schema": {
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Run a report",
"tags": [
"Reports"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.reports.retrieve(\"payouts\")) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.reports.retrieve(\"payouts\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Reports.RetrieveAll(ctx, \"payouts\", nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Simulate a deposit into a funding account (/docs/api/sandbox/simulate-deposit)
Sandbox only. The simulated provider reports a deposit; it is verified and credited through the same path as a real one. Not served in live.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/sandbox/deposits",
"description": "Sandbox only. The simulated provider reports a deposit; it is verified and credited through the same path as a real one. Not served in live.",
"operationId": "simulateDeposit",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SandboxDeposit"
}
}
},
"required": true
},
"responses": {
"202": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SandboxDepositAccepted"
}
}
},
"description": "Accepted"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Simulate a deposit into a funding account",
"tags": [
"Sandbox"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.sandbox.simulateDeposit({\n amount: \"100.00\",\n funding_account_id: \"fa_...\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.sandbox.simulate_deposit(amount=\"100.00\", funding_account_id=\"fa_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Sandbox.SimulateDeposit(ctx, &caibopay.SandboxDeposit{\n\tAmount: \"100.00\",\n\tFundingAccountID: \"fa_...\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Read how the account is settled (/docs/api/settlements/get-settlement-configuration)
Whether and how settlements are generated, for the account and per currency. The account's state is unconfigured when no schedule is in force in any currency: nothing is settled automatically and the balance stays available until you withdraw it or the platform puts a schedule in force. Per currency, state is unconfigured (no schedule in force), active (the schedule in force generates settlements as its frequency says; automatic is false for a manual schedule, whose settlements are generated only on request to the platform) or unexecutable (a schedule is in force but cannot be executed now; reason says why, e.g. no_destination; settlements that fall due wait and are generated once it can). currencies lists every currency the account holds a balance in or has a schedule for; with the currency parameter, that currency alone, whatever the account holds.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlement-configuration",
"description": "Whether and how settlements are generated, for the account and per currency. The account's state is unconfigured when no schedule is in force in any currency: nothing is settled automatically and the balance stays available until you withdraw it or the platform puts a schedule in force. Per currency, state is unconfigured (no schedule in force), active (the schedule in force generates settlements as its frequency says; automatic is false for a manual schedule, whose settlements are generated only on request to the platform) or unexecutable (a schedule is in force but cannot be executed now; reason says why, e.g. no_destination; settlements that fall due wait and are generated once it can). currencies lists every currency the account holds a balance in or has a schedule for; with the currency parameter, that currency alone, whatever the account holds.",
"operationId": "getSettlementConfiguration",
"parameters": [
{
"description": "Only this currency. A currency without a schedule is answered as unconfigured.",
"in": "query",
"name": "currency",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementConfiguration"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Read how the account is settled",
"tags": [
"Settlements"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.settlements.configuration();"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.settlements.configuration()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Settlements.Configuration(ctx, nil)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List settlement schedules (/docs/api/settlements/list-settlement-schedules)
The account's settlement terms per currency, as agreed in its contract: the one in force (status active) and those it replaced (closed), newest first. Read-only: a schedule carries the fee and the destination and is set by the platform; a change is a new schedule and applies from the period that is open: settlements that exist do not change. An empty list means no schedule was ever in force; GET /v1/settlement-configuration says so explicitly (unconfigured).
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlement-schedules",
"description": "The account's settlement terms per currency, as agreed in its contract: the one in force (status active) and those it replaced (closed), newest first. Read-only: a schedule carries the fee and the destination and is set by the platform; a change is a new schedule and applies from the period that is open: settlements that exist do not change. An empty list means no schedule was ever in force; GET /v1/settlement-configuration says so explicitly (unconfigured).",
"operationId": "listSettlementSchedules",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/SettlementSchedule"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List settlement schedules",
"tags": [
"Settlements"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.settlements.listSchedules()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.settlements.list_schedules():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Settlements.ListSchedules(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List settlements (/docs/api/settlements/list-settlements)
The periodic statements of what the account is owed, newest first. Each one is a closed (or still open) period of one currency: what accrued to the balance, the fee, the adjustments, and the net that is or was transferred to the account's settlement destination.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlements",
"description": "The periodic statements of what the account is owed, newest first. Each one is a closed (or still open) period of one currency: what accrued to the balance, the fee, the adjustments, and the net that is or was transferred to the account's settlement destination.",
"operationId": "listSettlements",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only settlements in this currency.",
"in": "query",
"name": "currency",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only periods ending after this RFC 3339 timestamp.",
"in": "query",
"name": "period_from",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only periods starting before this RFC 3339 timestamp.",
"in": "query",
"name": "period_to",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"pending",
"ready",
"processing",
"settled",
"on_hold",
"failed",
"disputed"
],
"type": "string"
}
},
{
"description": "Only settlements generated under this schedule.",
"in": "query",
"name": "schedule_id",
"required": false,
"schema": {
"pattern": "^stls_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Settlement"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List settlements",
"tags": [
"Settlements"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.settlements.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.settlements.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Settlements.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Retrieve a settlement (/docs/api/settlements/get-settlement)
With its items: the ledger journals its figures are made of.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlements/{id}",
"description": "With its items: the ledger journals its figures are made of.",
"operationId": "getSettlement",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Settlement"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a settlement",
"tags": [
"Settlements"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.settlements.retrieve(\"stl_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.settlements.retrieve(\"stl_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Settlements.Retrieve(ctx, \"stl_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List settlement destinations (/docs/api/withdrawals/list-settlement-destinations)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlement-destinations",
"operationId": "listSettlementDestinations",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/SettlementDestination"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List settlement destinations",
"tags": [
"Withdrawals"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.settlementDestinations.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.settlement_destinations.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.SettlementDestinations.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Create a settlement destination (/docs/api/withdrawals/create-settlement-destination)
Registers an account of your own that withdrawals go to. The same account registered twice is the same destination (200 with the existing one). Account details are write-only.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/settlement-destinations",
"description": "Registers an account of your own that withdrawals go to. The same account registered twice is the same destination (200 with the existing one). Account details are write-only.",
"operationId": "createSettlementDestination",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementDestinationCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementDestination"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementDestination"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a settlement destination",
"tags": [
"Withdrawals"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.settlementDestinations.create({\n currency: \"PEN\",\n details: {},\n method: \"bank_transfer\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.settlement_destinations.create(currency=\"PEN\", details={}, method=\"bank_transfer\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.SettlementDestinations.Create(ctx, &caibopay.SettlementDestinationCreate{\n\tCurrency: \"PEN\",\n\tMethod: \"bank_transfer\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a settlement destination (/docs/api/withdrawals/get-settlement-destination)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlement-destinations/{id}",
"operationId": "getSettlementDestination",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementDestination"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a settlement destination",
"tags": [
"Withdrawals"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.settlementDestinations.retrieve(\"dest_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.settlement_destinations.retrieve(\"dest_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.SettlementDestinations.Retrieve(ctx, \"dest_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List withdrawals (/docs/api/withdrawals/list-withdrawals)
Newest first.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/withdrawals",
"description": "Newest first.",
"operationId": "listWithdrawals",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"pending_approval",
"processing",
"completed",
"failed",
"cancelled"
],
"type": "string"
}
},
{
"description": "Only the withdrawals to this settlement destination.",
"in": "query",
"name": "destination_id",
"required": false,
"schema": {
"pattern": "^dest_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Withdrawal"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List withdrawals",
"tags": [
"Withdrawals"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.withdrawals.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.withdrawals.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Withdrawals.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a withdrawal (/docs/api/withdrawals/create-withdrawal)
Holds the amount plus the fee from the available balance and sends it to one of your settlement destinations, in the destination's currency, asynchronously. The fee is fixed when the withdrawal is created and stated in the response (fee, total); the balance must cover both. A withdrawal the balance cannot fund is created with status failed and failure_code insufficient_funds. Above the account's approval threshold it is created pending_approval and waits for the platform's operators. Repeating the request with the same Idempotency-Key returns the same withdrawal and never sends twice.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/withdrawals",
"description": "Holds the amount plus the fee from the available balance and sends it to one of your settlement destinations, in the destination's currency, asynchronously. The fee is fixed when the withdrawal is created and stated in the response (fee, total); the balance must cover both. A withdrawal the balance cannot fund is created with status failed and failure_code insufficient_funds. Above the account's approval threshold it is created pending_approval and waits for the platform's operators. Repeating the request with the same Idempotency-Key returns the same withdrawal and never sends twice.",
"operationId": "createWithdrawal",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WithdrawalCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Withdrawal"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Withdrawal"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a withdrawal",
"tags": [
"Withdrawals"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.withdrawals.create({\n amount: \"100.00\",\n destination_id: \"dest_...\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.withdrawals.create(amount=\"100.00\", destination_id=\"dest_...\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Withdrawals.Create(ctx, &caibopay.WithdrawalCreate{\n\tAmount: \"100.00\",\n\tDestinationID: \"dest_...\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a withdrawal (/docs/api/withdrawals/get-withdrawal)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/withdrawals/{id}",
"operationId": "getWithdrawal",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Withdrawal"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a withdrawal",
"tags": [
"Withdrawals"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.withdrawals.retrieve(\"wdr_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.withdrawals.retrieve(\"wdr_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Withdrawals.Retrieve(ctx, \"wdr_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Build with AI (/en/docs/ai)
Your coding assistant (Claude, ChatGPT, Cursor, Copilot…) writes a better integration when it reads the right source. We give it to you in a format it understands.
} title="Agent Skill" href="#skill">
The rules of a correct integration, ready to install in your agent.
} title="MCP server" href="#mcp">
Your agent searches and reads these docs live.
} title="llms.txt" href="#llmstxt">
All the documentation as text, for any model.
} title="Copy for AI" href="#every-page">
Every page in Markdown, one click away.
## Skill [#skill]
A Skill teaches your agent how to integrate Caibo Pay: discovery through capabilities, idempotency, amounts as strings, webhook signatures, asynchronous statuses, and the steps to collect and pay out.
```bash
mkdir -p ~/.claude/skills/caibo-pay
curl -fsSL https://docs.caibopay.app/skills/caibo-pay/SKILL.md -o ~/.claude/skills/caibo-pay/SKILL.md
```
For a single project, save it to `.claude/skills/caibo-pay/SKILL.md` inside the repository. Your agent uses it when you work with Caibo Pay.
Download [`SKILL.md`](/skills/caibo-pay/SKILL.md) and add it to your agent's instructions: `AGENTS.md`, Cursor rules (`.cursor/rules`), or Copilot instructions.
## MCP [#mcp]
The MCP server for these docs gives your agent tools to list, search, and read every guide and every endpoint, always up to date.
```txt
https://docs.caibopay.app/api/mcp
```
```bash
claude mcp add --transport http caibo-pay-docs https://docs.caibopay.app/api/mcp
```
```json title=".cursor/mcp.json"
{
"mcpServers": {
"caibo-pay-docs": { "url": "https://docs.caibopay.app/api/mcp" }
}
}
```
Any MCP client with HTTP transport (streamable HTTP): use the URL above.
The MCP server only reads the documentation: it doesn't have your keys and doesn't call the API for you.
## llms.txt [#llmstxt]
| File | Contains |
| --- | --- |
| [`/llms.txt`](/llms.txt) | The index: every page with its description. |
| [`/llms-full.txt`](/llms-full.txt) | All the documentation in a single text file. |
| [`/openapi.json`](/openapi.json) | The full OpenAPI contract, for generating clients and for your agent. |
## Every page [#every-page]
At the top of every page you have **Copy for AI** (the page in Markdown) and **Open with AI** (opens it in ChatGPT, Claude, or Cursor with the question ready). You can also append `.md` to any URL:
```txt
https://docs.caibopay.app/docs/collect-one-payment.md
```
"Read https://docs.caibopay.app/llms-full.txt. Integrate Caibo Pay into my backend to collect an exact amount with PIX, with idempotency, webhook signature verification, and tests against sandbox."
# Authentication (/en/docs/authentication)
Every request carries your key in the `Authorization` header:
```bash
curl https://api-sandbox.caibopay.app/v1/account \
-H "Authorization: Bearer psp_test_..."
```
## Your keys [#your-keys]
| | Sandbox | Live |
| --- | --- | --- |
| Format | `psp_test__` | `psp_live__` |
| Works on | `api-sandbox.caibopay.app` | `api.caibopay.app` |
- **Caibo issues them.** You receive your keys when your account is opened; they aren't created from the dashboard or the API. To get a new key, or to revoke one, ask Caibo.
- **They're shown only once.** Caibo stores only a fingerprint of the key, not the key itself. Store it in your secrets manager.
- **One key, one environment.** A sandbox key sent to live (or the other way around) is rejected just like an invalid key.
- The **prefix** (the 12 characters after `psp_test_`) identifies the key without revealing it: it's what you see in `GET /v1/account` and in the dashboard, under Developers.
## Permissions (scopes) [#permissions-scopes]
| Scope | Allows |
| --- | --- |
| `read` | All queries (`GET`). |
| `write` | Creating, changing, and moving money. |
A key can have one or both. Use a read-only key for dashboards and reports.
## The key you're using [#the-key-youre-using]
`GET /v1/account` returns your account (`environment`, `primary_treasury_asset`…) and, in `credential`, the key that made the request: its `prefix`, its `scopes`, and its `expires_at` if it expires. The secret is never returned.
## Authentication errors [#authentication-errors]
```json title="401 — key missing, invalid, revoked, expired, or from another environment"
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "The API key is missing or not valid.",
"request_id": "req_6d665507f62a5773882fc053"
}
}
```
```json title="403 — the key doesn't have the scope"
{
"error": {
"type": "permission_error",
"code": "insufficient_scope",
"message": "This API key does not have the write scope.",
"request_id": "req_6d665507f62a5773882fc053"
}
}
```
Your key moves money. Use it only from your server. If your customer needs to pay from their browser, create the pay-in on your server and show them the instructions, or use a [hosted page](/docs/hosted-pages).
# Balances (/en/docs/balances)
```json
{
"data": [
{
"currency": "USDT",
"primary": true,
"available": "1250.000000",
"pending": "0.000000",
"reserved": "100.500000",
"in_settlement": "0.000000",
"earnings": "12.400000",
"total": "1350.500000",
"as_of": "2026-10-18T14:05:00Z"
}
]
}
```
| Field | Description |
| --- | --- |
| `available` | What you can use now: pay out, withdraw, refund. |
| `reserved` | Set aside for payouts and withdrawals in progress. |
| `pending` | Credited but not yet available. |
| `in_settlement` | On its way to your account in a settlement. |
| `earnings` | Your accumulated markups (`tenant_markup`). Shown separately and **not** included in `total`. |
| `total` | `available + pending + reserved + in_settlement`. |
| `primary` | Marks the balance in your primary currency (`primary_treasury_asset`). |
A currency you've never held doesn't appear in the list.
## Entries [#entries]
Every movement in your balance, newest first (paged with `after`):
```json
{
"id": "ent_01m3sgb1...",
"journal_id": "jrn_01m3sgb1...",
"purpose": "payout_reserve",
"account": "available",
"direction": "debit",
"amount": "100.500000",
"currency": "USDT",
"origin": { "type": "payout", "id": "pout_01m3sgb02af7nb0jf73vwv2sd4" },
"occurred_at": "2026-10-18T14:00:20Z"
}
```
- `account` says which part of the balance moved: `available`, `pending`, `reserved`, `in_settlement`, or `earnings`.
- `direction` is `credit` or `debit`, and `amount` is always positive.
- Two entries with the same `journal_id` are the two sides of the same operation: for example, a payout moves funds from `available` to `reserved`.
- `origin` points to the operation: a pay-in (`pin_`), a payout (`pout_`), a refund (`rfd_`), a withdrawal (`wdr_`), a settlement (`stl_`), or an adjustment (`adj_`).
# Beneficiaries (/en/docs/beneficiaries)
| Field | Required | Description |
| --- | --- | --- |
| `method` | Yes | The payment method: `bank_transfer`, `pix`, `mobile_payment`… |
| `currency` | Yes | The currency it receives. |
| `details` | Yes | The account details, per `beneficiary_fields` in capabilities. Never returned. |
| `customer_id` | Depends on the country | The sender. |
| `holder` | No | The account holder's name, for display. |
| `label` | No | Your label, up to 100 characters. |
| `metadata` | No | Your data. |
We validate `details` at registration. An invalid value responds `400 invalid_parameter` with `param: "details."`. If you register the same account twice for the same customer, you get the existing beneficiary (`200`).
## Details by country [#details-by-country]
Method `bank_transfer`, to an account by its **CCI**.
| Field | Format | Example |
| --- | --- | --- |
| `cci` | 20 digits | `00219100123456780123` |
| `document_number` | DNI (8 digits) or RUC (11 digits starting with 10, 15, or 20) | `45678912` |
| `first_name` | Holder's first names, as on their document | `Rosa Elena` |
| `last_name` | Holder's last names | `Quispe Mamani` |
Requires a complete **sender**: see [Customers](/docs/customers).
Method `pix`.
| Field | Format | Example |
| --- | --- | --- |
| `name` | Holder's name, 2 to 140 characters | `Ana Souza` |
| `pix_key` | CPF (11 digits), CNPJ (14), phone `+55…`, email, or random key (UUID) | `ana@example.com` |
CPF and CNPJ check digits are verified.
Methods `mobile_payment` (mobile payment, *pago móvil*) and `bank_transfer`.
| Field | Method | Format | Example |
| --- | --- | --- | --- |
| `phone` | `mobile_payment` | `0412`, `0414`, `0416`, `0422`, `0424`, or `0426` + 7 digits | `04121234567` |
| `account_number` | `bank_transfer` | 20 digits | `01020123450000012345` |
| `bank_code` | Both | 4 digits | `0102` |
| `document.type` | Both | `V`, `E`, `J`, `G`, `P`, `C`, or `R` | `V` |
| `document.number` | Both | The document number | `12345678` |
| `name` | Both, optional | Holder's name | `María Pérez` |
```json
{
"method": "mobile_payment",
"currency": "VES",
"details": {
"phone": "04121234567",
"bank_code": "0102",
"document": { "type": "V", "number": "12345678" }
}
}
```
This table is a guide. The source of truth is `beneficiary_fields` in `GET /v1/capabilities?product=payout`: each field includes its `pattern`, so your form can validate exactly what the API validates.
## Response [#response]
```json
{
"id": "ben_01m3sgazybenxvqfw0h5bnszk4",
"method": "bank_transfer",
"currency": "PEN",
"country": "PE",
"customer_id": "cus_01m3sgb02af7nb0jf73vwv2sd4",
"holder": "Rosa Elena Quispe Mamani",
"status": "active",
"verification_status": "unverified",
"created_at": "2026-10-18T14:00:05Z",
"updated_at": "2026-10-18T14:00:05Z"
}
```
`verification_status` changes to `verified` when Caibo verifies the account (`beneficiary.verified`). The country is determined by the method.
# What you can do (/en/docs/capabilities)
Each item in the response is something your account can do: a **product** (`payin` to collect, `payout` to pay out, `remittance` for a full corridor) through a **method** and in a **currency**. It also includes the fields it requires, how it's collected, and whether you can use it right now.
Build your forms from this response and you won't have to change code when Caibo opens a new country or method: it simply shows up in the list.
## Filters [#filters]
All are optional and can be combined:
| Parameter | Example |
| --- | --- |
| `product` | `payin`, `payout`, `remittance` |
| `country` | `BR`, `PE` (ISO 3166-1 alpha-2) |
| `currency` | `BRL`, `PEN` |
| `method` | `pix`, `bank_transfer` |
```bash
curl "$CAIBO_API/v1/capabilities?product=payin¤cy=BRL" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
```json
{
"data": [
{
"product": "payin",
"operation": "payin",
"method": "pix",
"currency": "BRL",
"country": "BR",
"payment_currency": "BRL",
"settlement_currencies": ["USDT"],
"settlement_asset": "USDT",
"collection": ["payment"],
"payment_method_fields": [
{
"name": "payer.name",
"type": "string",
"required": true,
"pattern": "^.{2,140}$",
"description": "The payer's full name.",
"example": "Ana Souza"
},
{
"name": "settlement_currency",
"type": "enum",
"required": false,
"enum": ["USDT"],
"description": "The currency the balance is credited in."
}
],
"customer_fields": [
{ "name": "type", "type": "enum", "required": true, "enum": ["individual", "business"], "description": "…" },
{ "name": "country", "type": "string", "required": true, "pattern": "^[A-Z]{2}$", "description": "…" }
],
"available": true
}
],
"has_more": false
}
```
## The fields [#the-fields]
### FieldSpec: how a field is described [#fieldspec-how-a-field-is-described]
Each field has `name`, `type` (`string`, `number`, `iban`, `phone`, `email`, `date`, `enum`), `required`, and `description`, and may have `pattern` (a regular expression), `enum`, `example`, and `note`. With that you can validate in your form exactly what the API validates.
A dotted name indicates a nested object in a beneficiary's `details`: `document.type` is `{"document": {"type": "V"}}`. In `payer`, by contrast, the key is the full name: `{"payer": {"payer.name": "Ana Souza"}}`.
## Available and unavailable [#available-and-unavailable]
| `reason` | What it means | What to do |
| --- | --- | --- |
| `suspended` | Caibo has temporarily paused the operation, for everyone or for your account. | Retry later. If you try, the API responds `503 operation_suspended`. |
| `not_enabled` | The product isn't enabled for your account. | Ask Caibo to enable it. |
| `no_provider` | There's no route available for your account. | Ask Caibo to enable it. |
If you request a method or currency that isn't in the list, the API responds `422 unsupported_method`.
Enabling happens on Caibo's side: per country for everyone, or just for your account. When something is enabled, it starts appearing with `available: true`. Your integration reads the list and uses it.
# Collect an exact amount (/en/docs/collect-one-payment)
With `amount`, the funding account is a **one-time payment**: your customer pays exactly that amount, in the `currency`, and the account closes when the payment completes.
| Field | Required | What it is |
| --- | --- | --- |
| `method` | Yes | `pix`, `bank_transfer`… |
| `currency` | Yes | What your customer pays: `BRL`, `PEN`… |
| `amount` | Yes, for a one-time payment | Your order amount. |
| `payer` | Depends on the method | The payer details that `payment_method_fields` asks for in capabilities. |
| `settlement_currency` | No | The currency your balance is credited in. Defaults to the `settlement_asset` from capabilities. |
PIX requires the payer's name. The key in `payer` is the field's full name, exactly as capabilities gives it: `payer.name`.
```bash
curl "$CAIBO_API/v1/funding-accounts" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: payin-order-8812" \
-H "Content-Type: application/json" \
-d '{
"method": "pix",
"currency": "BRL",
"amount": "250.00",
"payer": { "payer.name": "Ana Souza" }
}'
```
```json title="201"
{
"id": "fa_01m3sg9w0000000000000000",
"status": "pending",
"method": "pix",
"currency": "BRL",
"settlement_currency": "USDT",
"amount": "250.00",
"created_at": "2026-10-18T12:00:00Z"
}
```
Once it's `active`:
```json
{
"id": "fa_01m3sg9w0000000000000000",
"status": "active",
"method": "pix",
"currency": "BRL",
"settlement_currency": "USDT",
"amount": "250.00",
"instructions": {
"copy_paste_code": "00020126580014br.gov.bcb.pix...",
"qr_code_image_base64": "iVBORw0KGgoAAAANSUhEUgAA...",
"amount": "250.00",
"currency": "BRL"
},
"created_at": "2026-10-18T12:00:00Z"
}
```
Show the QR code (`qr_code_image_base64`, a base64-encoded PNG image) and the **PIX copia e cola** code (`copy_paste_code`) so your customer can pay from their bank.
For soles, no payer details are needed.
```bash
curl "$CAIBO_API/v1/funding-accounts" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: payin-order-8813" \
-H "Content-Type: application/json" \
-d '{ "method": "bank_transfer", "currency": "PEN", "amount": "1000.00" }'
```
Once it's `active`:
```json
{
"id": "fa_01m3sgaa0000000000000000",
"status": "active",
"method": "bank_transfer",
"currency": "PEN",
"settlement_currency": "USDT",
"amount": "1000.00",
"instructions": {
"bank_account": "Bank … · Account …",
"expires_at": "2026-10-18T12:25:00Z",
"amount": "1000.00",
"currency": "PEN"
},
"created_at": "2026-10-18T12:00:00Z"
}
```
Show `bank_account` and the amount. Your customer must transfer **the exact amount** before `expires_at`. If `instructions` includes `reference`, ask them to include it in the transfer.
## The instructions [#the-instructions]
`instructions` is a map of strings whose keys depend on the method. Show them as-is to whoever is paying:
| Key | What it is |
| --- | --- |
| `amount`, `currency` | What gets paid: always your order amount. |
| `copy_paste_code` | The code to paste into the banking app (PIX copia e cola). |
| `qr_code_image_base64` | The QR code, as a base64-encoded PNG image. |
| `bank_account` | The account to transfer to. |
| `reference` | The reference the transfer must include. |
| `payment_url` | A link to pay. |
| `expires_at` | Until when payment is possible, if the method expires. |
A new key may appear in the future. Show it or ignore it, but don't fail because of it.
`instructions.amount` is always your order amount. If the bank charges to receive, Caibo absorbs that fee: your customer pays 1,000.00, not 1,002.70, and your balance receives the value of the full 1,000.00.
## Wait for the payment [#wait-for-the-payment]
Listen for webhooks, or query the account and its events:
1. `funding_account.active` includes `instructions`. The amount is in `instructions.amount`; the account's `amount` is in `GET /v1/funding-accounts/{id}`.
2. `payin.completed` arrives when the bank confirms the payment. Its `data` is the [credited pay-in](/docs/payins), with what was credited to your balance.
3. If the payment expires or doesn't go through, `payin.failed` arrives and the account moves to `closed`.
```bash
curl "$CAIBO_API/v1/events?resource_id=fa_01m3sg9w0000000000000000" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
## Errors on create [#errors-on-create]
| HTTP | `code` | Why |
| --- | --- | --- |
| 400 | `invalid_parameter` · `payer` | A payer detail is missing, unrecognized, or malformed. Or you sent `payer` without `amount`. |
| 400 | `invalid_request` | `amount` isn't a positive decimal, or the currency doesn't exist. |
| 422 | `amount_required` | That method and currency are collected with an amount: send `amount`. |
| 422 | `one_payment_unavailable` | That method and currency open an account without an amount: don't send `amount`. |
| 422 | `unsupported_method` | That method and currency aren't available for collecting. |
| 503 | `operation_suspended` | It's suspended for now. |
If the account can't be opened, it's still created and moves to `failed` with a `failure_code` (`provider_rejected`, `provider_unavailable`, `provider_amount_mismatch`, `no_route`). In that case, create another one with a new `Idempotency-Key`.
# How to collect (/en/docs/collect)
To collect, you create a **funding account**. Caibo opens it with the local bank and returns the instructions you show your customer: a PIX code, an account to transfer to. When the bank confirms the payment, we credit it to your balance and notify you.
>C: POST /v1/funding-accounts
C-->>T: 201 pending
C-->>T: webhook funding_account.active with instructions
T->>P: Shows the instructions
P->>C: Pays
C-->>T: webhook payin.completed
T->>C: GET /v1/balances`} />
## Two ways to collect [#two-ways-to-collect]
For each method and currency, [Capabilities](/docs/capabilities) tells you which one applies (`collection`):
| `collection` | How you request it | What it's for |
| --- | --- | --- |
| `payment` | **With** `amount` | A one-time payment for an exact amount: an order, an invoice. It closes once it's paid. |
| `account` | **Without** `amount` | An account that accepts any deposit, of any amount, while it stays open. |
If you request the wrong one, the API tells you: `422 amount_required` (that pay-in needs an amount) or `422 one_payment_unavailable` (that pay-in doesn't accept an amount).
In a one-time payment, what your customer sees is **exactly your order amount**: a 1,000.00 PEN order is paid with 1,000.00 PEN. If the bank charges a fee to receive, Caibo covers it; your customer never sees it or pays it.
## Funding account statuses [#funding-account-statuses]
| `status` | What it means |
| --- | --- |
| `pending` | We're opening it with the bank. |
| `active` | Ready: `instructions` contains what the payer needs. |
| `failed` | It couldn't be opened; `failure_code` tells you why. No instructions are shown. |
| `closed` | It no longer accepts deposits. A one-time payment closes when its pay-in completes. |
| Event | When |
| --- | --- |
| `funding_account.active` | The account is ready, with its instructions. |
| `funding_account.failed` | It couldn't be opened. |
| `payin.completed` | A payment came in and was credited to your balance. |
| `payin.failed` | A payment didn't go through (for example, it expired unpaid). |
## Where the money ends up [#where-the-money-ends-up]
Each pay-in is credited to your balance in its `settlement_currency`: the settlement currency that capabilities indicates (`settlement_asset`) or the one you choose from `settlement_currencies`. There's no intermediate stage: the money is recorded only once the bank confirms, and at that point it's already **available**.
PIX in Brazil, bank transfer in Peru.
The payin resource and its statuses.
# Countries and methods (/en/docs/coverage)
## Coming soon [#coming-soon]
What your account can use right now, in each environment, is what `GET /v1/capabilities` returns: the methods, the currencies, whether each one collects or pays out, and the fields it needs. When we enable a country or a method for your account, it appears there with `available: true`, with no change to your integration.
## Look up a country [#look-up-a-country]
```bash
curl "$CAIBO_API/v1/capabilities?country=CO" -H "Authorization: Bearer $CAIBO_API_KEY"
```
It returns every product available for that country (`payin` to collect, `payout` to pay out), with its methods and the fields each one needs.
## In sandbox [#in-sandbox]
Sandbox also has a USD funding account that takes any deposit and that you can pay into yourself with `POST /v1/sandbox/deposits`. See [Sandbox and live](/docs/sandbox).
# Customers (/en/docs/customers)
You register a customer with **your own identifier** (`external_id`), so you can always find it from your system.
| Field | Required | Description |
| --- | --- | --- |
| `external_id` | Yes | Your id, up to 128 characters. |
| `type` | Yes | `individual` or `business`. |
| `country` | Yes | Country of residence or incorporation (ISO alpha-2). |
| `display_name` | Yes | Name, up to 200 characters. |
| `profile` | Depends on the country | Identity details (below). |
| `metadata` | No | Up to 20 keys of your own. Never personal data. |
## The profile [#the-profile]
| Field | For |
| --- | --- |
| `first_name`, `last_name` | Individuals. Sent together. |
| `date_of_birth` | Individuals, `YYYY-MM-DD`. |
| `identity_document_type`, `identity_document` | Sent together. Types: `DNI`, `RUC`, `CE`, `PAS`, `PTP`, `PASSPORT`, `NATIONAL_ID`, `RESIDENCE_PERMIT`, `TAX_ID`, `DRIVER_LICENSE`. |
| `identity_document_country` | Country that issued the document. |
| `email`, `phone`, `tax_id` | Contact and tax details. |
| `registration_number` | Businesses. |
| `address` | `line1`, `line2`, `city`, `state`, `postal_code`, `country`. |
**What each country requires** is described by `customer_fields` in capabilities. For example, a payout in soles requires the sender to be an `individual` with first name, last names, date of birth, document, and city.
Sender details are validated when the payout goes out to the bank, not when it's created. A payout with an incomplete sender is accepted and then fails with `failure_code: invalid_instruction`. Validate the profile against `customer_fields` before paying.
## Repeating a registration [#repeating-a-registration]
If you send the same `external_id` again with the same data, you get the existing customer (`200`). With different data, `409 external_id_conflict`.
## Statuses [#statuses]
| `status` | Meaning |
| --- | --- |
| `active` | Normal. |
| `blocked` | Caibo stopped it: its beneficiaries can't be paid. |
| `closed` | Closed, permanently. |
With you change `metadata` or close the customer (`status: closed`). `compliance_status` (`unverified`, `pending`, `verified`, `rejected`, `review`) is changed only by Caibo's verifications.
Events: `customer.created`, `customer.updated`, `customer.status_changed`. Events never include the profile.
# Errors (/en/docs/errors)
Every error has the same shape:
```json
{
"error": {
"type": "invalid_request",
"code": "invalid_parameter",
"message": "amount must be a positive decimal with at most 2 decimals for PEN.",
"param": "amount",
"request_id": "req_6d665507f62a5773882fc053"
}
}
```
| Field | What it is |
| --- | --- |
| `type` | The error type. Stable. |
| `code` | The specific reason. Stable. **Decide based on `type` and `code`.** |
| `message` | Human-readable text. It can change: don't parse it. |
| `param` | The field or header with the problem, when there is one. |
| `reasons` | Closed list of reasons, on the codes that have them (`risk_blocked`, `payout_not_cancellable`). |
| `request_id` | The same value as the `X-Request-Id` header. Give it to support. |
## Types [#types]
| `type` | HTTP | What happened | Retry? |
| --- | --- | --- | --- |
| `invalid_request` | 400, 405, 413, 415, 422 | The request is malformed (400) or can't be executed (422). | Only after fixing it. |
| `authentication_error` | 401 | The key is missing or invalid. | No. |
| `permission_error` | 403 | The key doesn't have the scope. | No. |
| `not_found` | 404 | It doesn't exist, or it belongs to another account. | No. |
| `conflict` | 409 | It conflicts with something that already exists. | No. |
| `rate_limited` | 429 | Too many requests. | Yes, after `Retry-After`. |
| `unavailable` | 503 | Unavailable for now. | Yes, with the same `Idempotency-Key`. |
| `internal_error` | 500 | An error on our side. | Yes, with the same `Idempotency-Key`. |
## Common codes [#common-codes]
### Malformed request (400) [#malformed-request-400]
| `code` | When |
| --- | --- |
| `invalid_parameter` | A field or parameter isn't valid. `param` tells you which one: `amount`, `currency`, `details.cci`, `payer`, `Idempotency-Key`… |
| `invalid_body` | The body isn't JSON, has an unknown field, or has the wrong type (for example, an amount as a number). |
| `invalid_request` | The request isn't valid in general. |
| `idempotency_key_required` | `Idempotency-Key` is missing where it's required. |
| `body_too_large` (413) | The body exceeds 64 KiB. |
| `unsupported_media_type` (415) | The `Content-Type` isn't `application/json`. |
### Can't be executed (422) [#cant-be-executed-422]
| `code` | When |
| --- | --- |
| `unsupported_method` | That method and currency aren't in [capabilities](/docs/capabilities). |
| `amount_required` | That pay-in is a one-time payment: send `amount`. |
| `one_payment_unavailable` | That pay-in is an account that accepts any deposit: don't send `amount`. |
| `insufficient_funds` | Your available balance isn't enough. |
| `quote_expired` | The quote expired: request a new one. |
| `quote_mismatch` | The quote isn't for the beneficiary's method or currency. |
| `pricing_unavailable` | There's no price for that operation right now. |
| `amount_too_small` | The amount is below the minimum. |
| `same_currency` | The requested conversion is to the same currency. |
| `limit_exceeded` | It exceeds a limit on your account. |
| `customer_not_active` | The beneficiary's customer isn't active. |
| `risk_blocked` | Risk rules stopped it; see `reasons`. |
| `refund_not_supported` | That pay-in doesn't support refunds. |
| `too_many_endpoints` | You already have 10 webhooks. |
### Conflict (409) [#conflict-409]
| `code` | When |
| --- | --- |
| `idempotency_key_reused` | You used the same `Idempotency-Key` with a different request. |
| `quote_already_used` | The quote already funded another operation. |
| `external_id_conflict` | You already have a customer with that `external_id` and different details. |
| `customer_closed`, `customer_blocked` | The customer is closed or blocked. |
| `payout_not_cancellable` | The payout can no longer be canceled; see `reasons`. |
### Unavailable (503) [#unavailable-503]
| `code` | When |
| --- | --- |
| `operation_suspended` | The operation is suspended for now (capabilities shows `reason: suspended`). |
| `temporarily_unavailable` | A momentary problem. Retry with the same key. |
The full list for each endpoint is on its page in the [reference](/docs/api/payouts/create-payout).
## Rate limits [#rate-limits]
There's a request limit per key. When you exceed it you receive `429 rate_limited` with `Retry-After`, the number of seconds you must wait. Spread out your queries and prefer webhooks over polling in a loop.
## Useful headers [#useful-headers]
| Header | Direction | Purpose |
| --- | --- | --- |
| `X-Request-Id` | Response | Identifies the request (`req_…`). Store it in your logs. |
| `X-Correlation-Id` | Request and response | Your own identifier (8 to 128 characters from `A-Z a-z 0-9 . _ : -`); we echo it back. |
| `Retry-After` | Response | On a `429`, how many seconds to wait. |
| `Idempotent-Replayed` | Response | `true` when the response is a replay of an earlier request. |
Statuses, reasons, and codes are closed lists, but they can grow. Treat a value you don't recognize as "unknown", not as an error in your integration.
# Events (/en/docs/events)
Every important change generates an event. It arrives by [webhook](/docs/webhooks) and stays in `GET /v1/events`, in the same shape:
```json
{
"id": "evt_01m3sgb02af7nb0jf73vwv2sd5",
"type": "payin.completed",
"schema_version": 1,
"occurred_at": "2026-10-18T12:03:12.418Z",
"livemode": false,
"data": {
"id": "pin_01m3sg9x0000000000000000",
"status": "completed",
"funding_account_id": "fa_01m3sg9w0000000000000000",
"amount": "45.871200",
"currency": "USDT",
"created_at": "2026-10-18T12:03:10Z",
"completed_at": "2026-10-18T12:03:12Z"
}
}
```
| Field | Description |
| --- | --- |
| `id` | The event id. Use it to avoid processing the same event twice. |
| `type` | What happened. |
| `schema_version` | The version of the `data` shape for that type. Currently `1`. |
| `occurred_at` | When it happened. |
| `livemode` | `true` in live, `false` in sandbox. |
| `data` | The resource, in the API's shape. It may gain new fields. |
Events never include beneficiary account details or your customers' personal data.
## Reading the log [#reading-the-log]
```bash
curl "$CAIBO_API/v1/events?after=$CURSOR&limit=100" -H "Authorization: Bearer $CAIBO_API_KEY"
```
- From **oldest to newest**. Store `next_cursor` (always present) and continue from there: you never skip an event.
- `type` filters by an exact type (`payout.completed`) or by a family ending in a dot (`payout.`).
- `resource_id` returns the history of one resource: `?resource_id=pout_…`.
- A brand-new event may take a moment to appear in the list; the webhook doesn't wait.
## Catalog [#catalog]
`funding_account.active`, `funding_account.failed`, `payin.completed`, `payin.failed`
`payout.created`, `payout.completed`, `payout.failed`, `payout.cancelled`, `payout.returned`, `payout.return_settled`
`payout_batch.created`, `payout_batch.completed`, `payout_batch.cancellation_requested`, `payout_batch.cancellation_finished`
`remittance.created`, `remittance.processing`, `remittance.review`, `remittance.completed`, `remittance.failed`, `remittance.returned`
`refund.created`, `refund.approved`, `refund.processing`, `refund.completed`, `refund.failed`
`withdrawal.created`, `withdrawal.pending_approval`, `withdrawal.approved`, `withdrawal.submitted`, `withdrawal.completed`, `withdrawal.failed`, `withdrawal.cancelled`
`settlement.created`, `settlement.processing`, `settlement.on_hold`, `settlement.completed`, `settlement.failed`, `settlement_schedule.activated`, `settlement_schedule.blocked`
`customer.created`, `customer.updated`, `customer.status_changed`, `beneficiary.created`, `beneficiary.verified`
`hosted_session.created`, `hosted_session.payment_reported`
`risk.review_required`, `reconciliation.exception_created`, `reconciliation.exception_resolved`
`webhook.ping`
The list may grow. Ignore types you don't recognize; they shouldn't break your integration.
# Go live (/en/docs/go-live)
### Request your live key [#request-your-live-key]
Caibo issues your `psp_live_…` key when your production account is ready. Store it in a secrets manager. If a key is exposed, ask Caibo to revoke it and issue a new one.
### Change the host and key [#change-the-host-and-key]
Use `https://api.caibopay.app` and your `psp_live_…`. The rest of your integration doesn't change.
### Register your webhook in live [#register-your-webhook-in-live]
Webhooks belong to each environment: register your URL again in live and store the new `secret`.
### Read capabilities in live [#read-capabilities-in-live]
What's available depends on the environment and your account. Build your forms from the live `GET /v1/capabilities`, not from what you saw in sandbox.
## Check your integration [#check-your-integration]
- [ ] Every `POST` that moves money sends an `Idempotency-Key` unique to the operation, and every retry uses **the same one**. See [Idempotency](/docs/idempotency).
- [ ] You verify the `Psp-Signature` of every webhook against the **unmodified** body. See [Signatures](/docs/webhook-signatures).
- [ ] You respond `2xx` in under 10 seconds and process afterwards.
- [ ] You discard repeated events by their `id`.
- [ ] You treat `processing` and `verification_pending` as "not yet", without creating another payment for the same thing.
- [ ] You decide based on `error.type` and `error.code`, never on `message`.
- [ ] You store the `X-Request-Id` of error responses, for support.
- [ ] You accept new values in statuses and codes without breaking.
- [ ] You honor `Retry-After` when you receive `429`.
- [ ] You handle amounts as decimal strings, never as floating-point numbers.
# Hosted page (/en/docs/hosted-pages)
The hosted page is the ready-to-use **remittance** flow: your customer gets a quote, enters the sender and recipient, confirms, sees how to pay, and tracks the status of their transfer. You don't build forms or handle payment data.
- It works in Spanish, Portuguese, and English; it's designed for mobile, and it also works without JavaScript.
- Three branding modes: `caibo`, `co_branded` (your brand alongside ours), and `white_label` (only your brand, if your contract includes it).
- The same link is used to pay and to track the transfer.
The hosted page uses remittance corridors, which require `account` pay-ins. Check `GET /v1/capabilities?product=remittance` in your environment: if the list is empty, the page doesn't have any corridors to offer yet.
## Configure your page [#configure-your-page]
```json
{
"enabled": true,
"branding_mode": "co_branded",
"brand_name": "My Company",
"logo_url": "https://mi-empresa.com/logo.svg",
"colors": { "primary": "#12c7b0" },
"radius": "md",
"support": { "email": "soporte@mi-empresa.com" }
}
```
`PUT` replaces the entire configuration: any field you omit goes back to its default value.
## Create a session [#create-a-session]
```bash
curl "$CAIBO_API/v1/hosted-sessions" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: session-customer-8812" \
-H "Content-Type: application/json" \
-d '{ "customer_id": "cus_01m3sgb0...", "expires_in": 86400 }'
```
The response includes `token` and `path`: the link is `https://pay.caibopay.app` + `path`. **They're only returned in this response** (a replay doesn't return them): store them.
- `customer_id` sets the sender.
- `expires_in` ranges from 300 seconds to 7 days; defaults to 24 hours.
- `prefill` pre-populates amount, currency, country, and method.
"I've paid" on the page is only a notice (`hosted_session.payment_reported`). The real confirmation is `payin.completed` followed by `remittance.processing`.
## Your domain [#your-domain]
Register `pagos.mi-empresa.com` and point it with a **CNAME to `pay.caibopay.app`**. The domain starts as `pending`, with a `verification_token`; the Caibo team verifies it and issues the certificate. Let us know when you register it.
# Idempotency (/en/docs/idempotency)
A network can drop right after you send a payout. Did it go through or not? With `Idempotency-Key` it doesn't matter: you resend **the same request with the same key** and get the original result, with no second effect.
```bash
curl https://api-sandbox.caibopay.app/v1/payouts \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: payout-order-5531" \
-H "Content-Type: application/json" \
-d '{ "beneficiary_id": "ben_...", "quote_id": "quo_..." }'
```
## How it behaves [#how-it-behaves]
| You send | You receive |
| --- | --- |
| A new key | `201` and the created resource. |
| The same key with the same request | `200`, the same resource in its current state, and the `Idempotent-Replayed: true` header. Nothing is repeated. |
| The same key with a different request | `409 idempotency_key_reused`. |
| No key, where it's required | `400 idempotency_key_required`. |
If two requests with the same key arrive at the same time, the second waits for the first and returns its result.
## Where it's required [#where-its-required]
On every create call that moves money or locks in a price:
All other operations ignore the header. Registering the same beneficiary or the same destination account twice already returns the existing record.
## Best practices [#best-practices]
- **One key per business operation**, derived from your own identifier: `payout-order-5531`, `payin-invoice-F-2201`. That way a retry, even days later or from another process, uses the same one.
- Between **8 and 128 characters** from `A-Z a-z 0-9 . _ : -`.
- **Keys don't expire.** A used key stays bound to its original request forever.
- A rejected request (`4xx`) doesn't consume the key: fix it and resend with the same one.
- On `500` or `503`, retry **with the same key**.
If your balance isn't enough, `POST /v1/payouts` responds `201` with `status: failed` and `failure_code: insufficient_funds`. That payout exists and its key has been used. To retry once you have funds, use a new key (and a new quote if you used one).
# Introduction (/en/docs)
Caibo Pay is the payments infrastructure for businesses that collect and pay out in many countries. You integrate **once** and, from the same API, collect and pay out by PIX, ACH, wire, FedNow, SPEI, Bre-B, Faster Payments, bank transfers and mobile payments, and check a single balance. See [Countries and methods](/docs/coverage).
} title="Quickstart" href="/docs/quickstart">
Your first call and your first test pay-in in minutes.
} title="What you can do" href="/docs/capabilities">
The map of countries, methods, and currencies, read from the API itself.
} title="Collect" href="/docs/collect">
One-time payments for an exact amount: the payer pays the order and nothing else.
} title="Pay out" href="/docs/pay-out">
Payouts to bank accounts, PIX, and mobile payment, one at a time or in batches.
## One API for everything [#one-api-for-everything]
There is no endpoint per country or per provider. The same resources work everywhere:
| You want to… | You use |
| --- | --- |
| Know what's available to you | `GET /v1/capabilities` |
| Collect | `POST /v1/funding-accounts` |
| Pay out | `POST /v1/payouts` |
| Know what happened | A webhook, or `GET /v1/events` |
| See your money | `GET /v1/balances` |
What changes from one country to another is `currency` and `method`, and `GET /v1/capabilities` tells you what each one requires. When Caibo opens a new country, it shows up there: **your integration doesn't change**.
|one key| B(Caibo Pay API)
B --> C[Pay-ins: PIX, bank transfers]
B --> D[Payouts: accounts, PIX, mobile payment]
B --> E[(One balance)]
B -.->|one webhook| A`} />
## How it works [#how-it-works]
### Check what you can do [#check-what-you-can-do]
`GET /v1/capabilities` lists every product (`payin`, `payout`, `remittance`), with its method, currency, and country, the fields it requires, and whether it's available to your account right now.
### Collect or pay out [#collect-or-pay-out]
You create a pay-in or a payout with a single call. Every call that moves money carries an `Idempotency-Key`, so a retry never collects or pays twice.
### Receive the result [#receive-the-result]
Money moves asynchronously. We notify you by webhook (`payin.completed`, `payout.completed`…) and every event is also available in `GET /v1/events`.
## Environments [#environments]
| Environment | Host | Key |
| --- | --- | --- |
| Sandbox (testing) | `https://api-sandbox.caibopay.app` | `psp_test_…` |
| Live (production) | `https://api.caibopay.app` | `psp_live_…` |
They are separate deployments, with separate data and keys: a key only works in its own environment. Start in sandbox; going live means changing the host and the key. See [Sandbox and live](/docs/sandbox).
These docs are built for agents too: every page has **Copy for AI**, there's an [`llms.txt`](/llms.txt), an MCP server, and a Skill ready to install. See [Build with AI](/docs/ai).
# Amounts and currencies (/en/docs/money)
```json
{ "amount": "1500.50", "currency": "PEN" }
```
- An amount is a **string** of digits with, if needed, a decimal point: `"100"`, `"100.5"`, `"100.50"`.
- No sign, no thousands separators, no scientific notation.
- No more decimal places than the currency has.
- The API always responds with **exactly** the currency's decimal places: you send `"100.5"` in PEN and receive `"100.50"`.
- An amount sent as a number (`100.5`) is rejected with `400 invalid_body`.
`0.1 + 0.2` isn't `0.3` in floating point. Store amounts as strings or in a decimal type (`BigDecimal`, `decimal.Decimal`, `NUMERIC`), or as integers in minor units.
## Currencies [#currencies]
| Code | Decimals | Currency |
| --- | --- | --- |
| `BRL` | 2 | Brazilian real |
| `PEN` | 2 | Peruvian sol |
| `VES` | 2 | Venezuelan bolívar |
| `USD` | 2 | US dollar |
| `MXN` | 2 | Mexican peso |
| `COP` | 2 | Colombian peso |
| `EUR` | 2 | Euro |
| `USDT` | 6 | Tether |
| `USDC` | 6 | USD Coin |
A currency being in this table doesn't mean you can collect or pay out in it: [capabilities](/docs/capabilities) tells you what's available to you.
## Exchange rates [#exchange-rates]
When a payout converts from one currency to another, the [quote](/docs/quotes) tells you everything before you pay:
- `source.principal`: what gets converted.
- `source.platform_fee`: the platform fee.
- `source.tenant_markup`: your own markup, if you have one; it's credited to your earnings (`earnings`).
- `source.total`: what's debited from your balance (`principal + platform_fee + tenant_markup`).
- `destination.amount`: what the beneficiary receives.
- `rate`: destination units per source unit, with markups included.
## Dates [#dates]
All dates are in RFC 3339 and UTC: `2026-10-18T14:00:20Z`. The number of fractional-second digits can vary.
## Identifiers [#identifiers]
Every resource has an opaque id with a prefix that tells you what it is: `pout_` a payout, `pin_` a credited pay-in, `fa_` a funding account, `ben_` a beneficiary, `cus_` a customer, `quo_` a quote, `evt_` an event. Don't interpret what comes after the prefix.
# Lists and pagination (/en/docs/pagination)
## Resource lists [#resource-lists]
Payouts, pay-ins, customers, beneficiaries, and the rest are returned **newest first**, in pages:
```json
{
"data": [ { "id": "pout_01m3sgb0..." }, { "id": "pout_01m3sga9..." } ],
"has_more": true,
"next_cursor": "pout_01m3sga9..."
}
```
| Parameter | What it does |
| --- | --- |
| `limit` | How many per page: 1 to 100. Defaults to 25. |
| `starting_after` | The `next_cursor` from the previous page. |
Keep requesting while `has_more` is `true`:
```js
let cursor;
do {
const url = new URL("https://api-sandbox.caibopay.app/v1/payouts");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("starting_after", cursor);
const page = await fetch(url, { headers: { Authorization: `Bearer ${key}` } }).then((r) => r.json());
for (const payout of page.data) handle(payout);
cursor = page.has_more ? page.next_cursor : undefined;
} while (cursor);
```
A full pass returns **exactly once** every item that existed when you started, even if others are created while you paginate.
### Filters [#filters]
| Filter | Example |
| --- | --- |
| `status` | `?status=completed` |
| `created_after` (inclusive) | `?created_after=2026-10-01T00:00:00Z` |
| `created_before` (exclusive) | `?created_before=2026-11-01T00:00:00Z` |
| Relations | `?beneficiary_id=ben_…`, `?customer_id=cus_…`, `?funding_account_id=fa_…` |
- Filters are combined with **AND**.
- Dates are in RFC 3339. Encode the `+` of a time zone offset as `%2B`.
- A value the filter doesn't accept responds `400` with `param` set to the filter's name.
- A well-formed id that isn't yours returns an empty list.
## Logs: events and entries [#logs-events-and-entries]
`GET /v1/events` and `GET /v1/balances/{currency}/entries` page with `after`, never skipping or repeating. Events read **oldest first**; balance entries **newest first**.
| Parameter | What it does |
| --- | --- |
| `limit` | 1 to 100. Defaults to 50. |
| `after` | The `next_cursor` from your last read. |
For events, `next_cursor` is always present, even on an empty page. Store it and query again from there: that way you never skip an event. See [Events](/docs/events).
# How to pay out (/en/docs/pay-out)
A `payout` leaves your balance and reaches a **beneficiary**: the account of the person or business you're paying. The full flow:
B[customer
sender]
B --> C[beneficiary]
C --> D[quote]
D --> E[payout]
E -.-> F[webhook
payout.completed]`} />
### Check what the country requires [#check-what-the-country-requires]
```bash
curl "$CAIBO_API/v1/capabilities?product=payout¤cy=PEN" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
`beneficiary_fields` tells you which account details you need; `customer_fields`, which sender details. See [What you can do](/docs/capabilities).
### Register the sender, if the country requires it [#register-the-sender-if-the-country-requires-it]
Some countries require knowing who is sending. The sender is one of your [customers](/docs/customers):
```bash
curl "$CAIBO_API/v1/customers" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: cliente-crm-8812" \
-H "Content-Type: application/json" \
-d '{
"external_id": "crm-8812",
"type": "individual",
"country": "PE",
"display_name": "Carlos Mendoza",
"profile": {
"first_name": "Carlos",
"last_name": "Mendoza Rojas",
"date_of_birth": "1988-04-12",
"identity_document_type": "DNI",
"identity_document": "41234567",
"identity_document_country": "PE",
"address": { "city": "Lima", "country": "PE" }
}
}'
```
### Register the beneficiary [#register-the-beneficiary]
```bash
curl "$CAIBO_API/v1/beneficiaries" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"method": "bank_transfer",
"currency": "PEN",
"customer_id": "cus_01m3sgb02af7nb0jf73vwv2sd4",
"holder": "Rosa Elena Quispe Mamani",
"details": {
"cci": "00219100123456780123",
"document_number": "45678912",
"first_name": "Rosa Elena",
"last_name": "Quispe Mamani"
}
}'
```
You register it once and pay it as many times as you want. `details` is never returned. See [Beneficiaries](/docs/beneficiaries).
### Lock the price [#lock-the-price]
```bash
curl "$CAIBO_API/v1/quotes" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: cotizacion-orden-5531" \
-H "Content-Type: application/json" \
-d '{ "source_currency": "USDT", "destination_currency": "PEN", "method": "bank_transfer", "amount": "350.00", "amount_side": "destination" }'
```
```json
{
"id": "quo_01m3sgaz0000000000000000",
"status": "open",
"method": "bank_transfer",
"source": { "currency": "USDT", "principal": "100.000000", "platform_fee": "0.500000", "tenant_markup": "0.000000", "total": "100.500000" },
"destination": { "amount": "350.00", "currency": "PEN" },
"rate": "3.500000000000000000",
"created_at": "2026-10-18T14:00:10Z",
"expires_at": "2026-10-18T14:01:40Z"
}
```
`amount_side: destination` fixes what the beneficiary **receives**; `source`, what **leaves** your balance. The quote is valid until `expires_at`. See [Quotes](/docs/quotes).
### Pay [#pay]
```bash
curl "$CAIBO_API/v1/payouts" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: pago-orden-5531" \
-H "Content-Type: application/json" \
-d '{ "beneficiary_id": "ben_01m3sgazybenxvqfw0h5bnszk4", "quote_id": "quo_01m3sgaz0000000000000000", "description": "Order 5531" }'
```
It responds `201` with `status: processing`: the funds (`source.total`) are reserved and the payout is on its way.
### Get the result [#get-the-result]
You receive `payout.completed` when the beneficiary has received the money, or `payout.failed` with a `failure_code` if it couldn't be paid; in that case the funds return to your available balance. See [Payouts](/docs/payouts).
You can also pay without quoting first: send `source_currency`, `amount`, and `amount_side` instead of `quote_id`, and the payout is quoted when it's created.
# Credited pay-ins (/en/docs/payins)
Every time a payment comes into a funding account, a **payin** appears. The bank's notification isn't enough to credit it: Caibo confirms each payment with the bank before crediting it, and each payment is credited **only once**.
```json
{
"id": "pin_01m3sg9x0000000000000000",
"status": "completed",
"funding_account_id": "fa_01m3sg9w0000000000000000",
"amount": "45.871200",
"currency": "USDT",
"created_at": "2026-10-18T12:03:10Z",
"completed_at": "2026-10-18T12:03:12Z"
}
```
| Field | What it is |
| --- | --- |
| `amount`, `currency` | **What was credited to your balance**, in the settlement currency. |
| `paid` | What the customer paid in their currency, when the bank reports it separately. |
| `funding_account_id` | The funding account. Your order amount is in its `amount`. |
| `failure_code` | Why it failed, if it failed. |
| `refunded`, `refundable` | How much was refunded and how much is left to refund (only in `GET /v1/payins/{id}`). |
## Statuses [#statuses]
| `status` | What it means | Event |
| --- | --- | --- |
| `processing` | We've seen it and are confirming it with the bank. | — |
| `completed` | Confirmed and credited: the money is available. | `payin.completed` |
| `failed` | It didn't go through. | `payin.failed` |
## Filters [#filters]
`GET /v1/payins?status=completed&funding_account_id=fa_…`, plus `created_after` and `created_before`. See [Lists and pagination](/docs/pagination).
A payment for a different amount than requested, or one the bank reverses, never moves your balance automatically: the Caibo team reviews it and you see it in `GET /v1/reconciliation-exceptions`.
# Payout batches (/en/docs/payout-batches)
```bash
curl "$CAIBO_API/v1/payout-batches" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: nomina-2026-10" \
-H "Content-Type: application/json" \
-d '{
"label": "October payroll",
"items": [
{ "beneficiary_id": "ben_01...", "source_currency": "USDT", "amount": "350.00", "amount_side": "destination", "reference": "emp-001" },
{ "beneficiary_id": "ben_02...", "quote_id": "quo_01...", "reference": "emp-002" }
]
}'
```
- From **1 to 1000** items; the body can be up to 2 MiB.
- Each item includes `beneficiary_id` and either a `quote_id` or `source_currency`, `amount`, and `amount_side`. Optional: `description` and `reference` (your id, up to 64 characters).
- The shape of **all** items is checked first: one malformed item rejects the whole batch with `400` and `param: items[i].field`, and nothing is created.
- Then each item becomes a regular payout, in order, with its own `payout.*` events. An item that can't be paid doesn't stop the others.
## The batch [#the-batch]
`GET /v1/payout-batches/{id}` returns `summary` (how many items are in each status) and `totals` per currency (`principal`, `platform_fee`, `tenant_markup`, `total`, `completed_total`).
| `status` | Meaning |
| --- | --- |
| `accepted` | Received. |
| `processing` | Paying. |
| `completed` | All finished successfully. |
| `completed_with_failures` | Finished, with some failures. |
| `cancelled`, `partially_cancelled` | Cancelled, fully or in part. |
## The items [#the-items]
Each item includes `index`, `status`, `payout_id`, and your `reference`. If it never became a payout it stays `refused`, with an `error_code`: `beneficiary_not_found`, `quote_expired`, `limit_exceeded`, `customer_not_active`…
## Cancel [#cancel]
Cancels the batch's payouts that haven't gone out yet. Events: `payout_batch.created`, `payout_batch.cancellation_requested`, `payout_batch.cancellation_finished`, `payout_batch.completed`.
# Payouts (/en/docs/payouts)
| Field | Description |
| --- | --- |
| `beneficiary_id` | Required. Who you're paying; the method and currency come from the beneficiary. |
| `quote_id` | A valid [quote](/docs/quotes). |
| `source_currency`, `amount`, `amount_side` | Or, instead of `quote_id`, these three: the payout is quoted when it's created. |
| `description` | Up to 500 characters, for you. |
Always send an `Idempotency-Key`: repeating the request with the same key returns the same payout and **never pays twice**.
```json title="201"
{
"id": "pout_01m3sgb02af7nb0jf73vwv2sd4",
"status": "processing",
"method": "bank_transfer",
"beneficiary_id": "ben_01m3sgazybenxvqfw0h5bnszk4",
"source": { "currency": "USDT", "principal": "100.000000", "platform_fee": "0.500000", "tenant_markup": "0.000000", "total": "100.500000" },
"destination": { "amount": "350.00", "currency": "PEN" },
"rate": "3.500000000000000000",
"quote_id": "quo_01m3sgaz0000000000000000",
"created_at": "2026-10-18T14:00:20Z",
"updated_at": "2026-10-18T14:00:20Z"
}
```
## Statuses [#statuses]
processing
processing --> completed
processing --> failed
processing --> cancelled
processing --> verification_pending
verification_pending --> completed
verification_pending --> failed
completed --> returned`} />
| `status` | Meaning | Event |
| --- | --- | --- |
| `processing` | Accepted, funds reserved, on its way. | `payout.created` |
| `verification_pending` | Sent, but the outcome isn't certain yet. The funds stay reserved; **it's never resent**. Ends in `completed` or `failed`. | — |
| `completed` | The beneficiary received the money. | `payout.completed` |
| `failed` | Not paid; the funds return to your available balance. | `payout.failed` |
| `cancelled` | Cancelled before it went out. | `payout.cancelled` |
| `returned` | It was paid and then the bank returned it; see `refund`. | `payout.returned`, `payout.return_settled` |
`processing` and `verification_pending` mean "not yet". Don't create another payout for the same thing: the original is being resolved and will end in a final status. `verification_pending` has no event of its own; retrieve the payout if it takes a while.
## When your balance isn't enough [#when-your-balance-isnt-enough]
The payout is still created (`201`) with `status: failed` and `failure_code: insufficient_funds`. Nothing is reserved and only `payout.failed` is sent, without `payout.created`. Its `Idempotency-Key` and its quote are used up: to retry, use a new key and a new quote.
## failure_code [#failure_code]
| Code | What happened |
| --- | --- |
| `insufficient_funds` | Your balance wasn't enough. |
| `invalid_instruction` | The bank rejected the details: account, unsupported bank, or incomplete sender. |
| `no_route` | There was no route to pay. |
| `not_submitted` | It was never sent. |
| `resolved_not_executed` | Confirmed as not executed. |
| `risk_rejected` | Rejected by risk review. |
| `cancelled_before_submission` | Cancelled before it went out. |
A bank-specific code may also appear. Treat any code you don't recognize as "failed and not paid".
## Cancel [#cancel]
You can cancel while the payout is `processing`, hasn't gone out to the bank, isn't under review, and isn't part of a batch or a remittance.
| Response | Meaning |
| --- | --- |
| `202` | Requested: `cancellation.status: requested`. We decide before sending it. |
| `200` | It's already cancelled. |
| `409 payout_not_cancellable` | It can't be cancelled; `reasons` says why: `submitted`, `outcome_uncertain`, `already_completed`, `already_failed`, `already_returned`, `in_review`, `managed_by_batch`, `managed_by_remittance`. |
If the payout went out while the cancellation was pending, `cancellation.status` ends up `refused`.
## Risk review [#risk-review]
A payout can be placed under review (`risk_status: in_review`): it stays `processing`, with the funds reserved, and you receive `risk.review_required`. If approved, it continues; if rejected, it fails with `risk_rejected`.
## Retrieve [#retrieve]
`GET /v1/payouts/{id}` adds `beneficiary` (with `account_hint`, the last digits of the account), `description`, `country`, and the timestamps `completed_at`, `failed_at`, `returned_at`, `cancelled_at`. The list can be filtered by `status`, `beneficiary_id`, `risk_status`, and dates.
# Quickstart (/en/docs/quickstart)
In this guide you walk through the full flow in sandbox: you authenticate, see what's available to you, open a pay-in, simulate the payer's deposit, and see the money in your balance.
You need a **sandbox** key (`psp_test_…`). Caibo issues keys when your account is opened; if you don't have one yet, ask your Caibo contact. The key is shown only once: store it in your secrets manager, never in code.
### Set up your key [#set-up-your-key]
```bash
export CAIBO_API_KEY="psp_test_..."
export CAIBO_API="https://api-sandbox.caibopay.app"
```
### Check the connection [#check-the-connection]
```bash
curl "$CAIBO_API/v1/account" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
```json
{
"id": "acct_01m3sg8r0000000000000000",
"name": "My Company",
"status": "active",
"environment": "sandbox",
"primary_treasury_asset": "USDT",
"credential": {
"type": "api_key",
"id": "key_01m3sg8s0000000000000000",
"prefix": "abc123def456",
"scopes": ["read", "write"],
"created_at": "2026-10-18T12:00:00Z"
},
"created_at": "2026-10-01T09:00:00Z"
}
```
`environment` confirms where you are. `scopes` tells you what the key can do: `read` to query, `write` to create and move money.
### See what you can collect [#see-what-you-can-collect]
```bash
curl "$CAIBO_API/v1/capabilities?product=payin" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
Each item describes something you can do: `method`, `currency`, `country`, the fields it requires, how it's collected (`collection`), and whether it's available to you right now (`available`). See [What you can do](/docs/capabilities).
### Register your webhook [#register-your-webhook]
This way you learn about every pay-in without polling. The URL must be `https` and public.
```bash
curl "$CAIBO_API/v1/webhook-endpoints" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://tu-empresa.com/webhooks/caibo", "event_types": ["payin.completed", "funding_account.active"] }'
```
The response includes `secret` (`whsec_…`) **only once**. Store it: you use it to [verify the signature](/docs/webhook-signatures) of every notification.
### Open a pay-in [#open-a-pay-in]
Sandbox has a test USD account that accepts any deposit and that you can "pay" yourself. Every create call carries an `Idempotency-Key` unique to the operation.
```bash
curl "$CAIBO_API/v1/funding-accounts" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: quickstart-payin-001" \
-H "Content-Type: application/json" \
-d '{ "method": "bank_transfer", "currency": "USD" }'
```
```json
{
"id": "fa_01m3sg9w0000000000000000",
"status": "pending",
"method": "bank_transfer",
"currency": "USD",
"settlement_currency": "USDT",
"created_at": "2026-10-18T12:00:00Z"
}
```
Within seconds it moves to `active`, you receive `funding_account.active`, and the account's `instructions` contain the details for the payer:
```bash
curl "$CAIBO_API/v1/funding-accounts/fa_01m3sg9w0000000000000000" \
-H "Authorization: Bearer $CAIBO_API_KEY"
```
### Simulate the payer's deposit [#simulate-the-payers-deposit]
Sandbox only: deposit into the account the way your customer would. The amount is in your balance currency (`settlement_currency`).
```bash
curl "$CAIBO_API/v1/sandbox/deposits" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "funding_account_id": "fa_01m3sg9w0000000000000000", "amount": "100.00" }'
```
It responds `202`. The deposit follows the same path as a real one and, once it's confirmed, you receive `payin.completed`.
### Check your balance [#check-your-balance]
```bash
curl "$CAIBO_API/v1/balances" -H "Authorization: Bearer $CAIBO_API_KEY"
```
```json
{
"data": [
{
"currency": "USDT",
"primary": true,
"available": "100.000000",
"pending": "0.000000",
"reserved": "0.000000",
"in_settlement": "0.000000",
"earnings": "0.000000",
"total": "100.000000",
"as_of": "2026-10-18T12:01:00Z"
}
]
}
```
## Next steps [#next-steps]
PIX in Brazil and bank transfer in Peru.
Customer, beneficiary, quote, and payout.
Retries, ordering, and best practices.
The checklist.
# Quotes (/en/docs/quotes)
| Field | Required | Description |
| --- | --- | --- |
| `source_currency` | Yes | The currency that leaves your balance. |
| `destination_currency` | Yes | The currency the beneficiary receives. |
| `amount` | Yes | The amount. |
| `amount_side` | Yes | `destination`: the amount is what the beneficiary **receives**. `source`: it's what **leaves** your balance. |
| `method` | For a payout | The beneficiary's method. |
```json title="201"
{
"id": "quo_01m3sgaz0000000000000000",
"status": "open",
"method": "bank_transfer",
"source": {
"currency": "USDT",
"principal": "100.000000",
"platform_fee": "0.500000",
"tenant_markup": "0.000000",
"total": "100.500000"
},
"destination": { "amount": "350.00", "currency": "PEN" },
"rate": "3.500000000000000000",
"created_at": "2026-10-18T14:00:10Z",
"expires_at": "2026-10-18T14:01:40Z"
}
```
| Field | Description |
| --- | --- |
| `source.total` | What will be debited from your balance: `principal + platform_fee + tenant_markup`. |
| `source.tenant_markup` | Your markup, if you have one configured. It's credited to your `earnings`. |
| `destination.amount` | What the beneficiary receives. |
| `rate` | Destination units per source unit, markups included. |
| `expires_at` | Until when the price is valid. |
## Rules [#rules]
- **A quote pays for a single operation.** Once used it becomes `used`; using it again responds `409 quote_already_used`.
- **It expires.** Usually in about 90 seconds, sometimes sooner. Rely on `expires_at`, not a fixed countdown. An expired quote responds `422 quote_expired`: request a new one.
- **It must match the beneficiary.** Its `method` and `destination_currency` must be the beneficiary's, or you get `422 quote_mismatch`.
- If the payout fails for insufficient funds, the quote is already used: request a new one to retry.
Pricing errors: `pricing_unavailable` (no price right now), `amount_too_small`, `same_currency`.
# Refunds (/en/docs/refunds)
A pay-in can be refunded when its method allows it: capabilities indicates this in `features` (`refund`, `partial_refund`). If it doesn't, `POST /v1/refunds` responds `422 refund_not_supported`.
```bash
curl "$CAIBO_API/v1/refunds" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: refund-order-8812" \
-H "Content-Type: application/json" \
-d '{ "payin_id": "pin_01m3sg9x...", "reason_code": "requested_by_customer", "amount": "10.000000" }'
```
| Field | Required | What it is |
| --- | --- | --- |
| `payin_id` | Yes | The pay-in to refund. |
| `reason_code` | Yes | `requested_by_customer`, `duplicate`, `fraud`, or `other`. |
| `amount` | No | In the pay-in's currency (the one that was credited). If you omit it, everything remaining is refunded. |
| `note` | No | Up to 500 characters, with no personal data. |
The refund comes out of your available balance and is sent asynchronously.
| `status` | What it means |
| --- | --- |
| `pending_review` | Under risk review. |
| `processing` | Sent. |
| `completed` | Returned to the payer. |
| `failed` | It couldn't be returned; `failure_code` tells you why. |
Events: `refund.created`, `refund.approved`, `refund.processing`, `refund.completed`, `refund.failed`.
Errors: `refund_not_supported`, `refund_exceeds_refundable` (you're requesting more than what's left), `payin_not_refundable`, `insufficient_funds`, `risk_blocked`. `GET /v1/payins/{id}` tells you how much is left in `refundable`.
# Remittances (/en/docs/remittances)
A remittance joins a pay-in and a payout: the payer deposits in their currency, it's converted, and the beneficiary receives in theirs. All with **one quote** and **exactly one payout**.
B[Your balance]
B --> C[Payout to the beneficiary]`} />
The available corridors are listed by `GET /v1/capabilities?product=remittance`.
| Field | Required | Description |
| --- | --- | --- |
| `quote_id` | Yes | The quote; its method and destination currency must be the beneficiary's. |
| `beneficiary_id` | Yes | Who receives. |
| `source` | Yes | Where the money comes from: `funding_account_id` (the next deposit into that funding account, before the quote expires) or `payin_id` (a pay-in already credited; each pay-in funds a single remittance). |
| `customer_id` | No | The sender. |
## Statuses [#statuses]
| `status` | Meaning |
| --- | --- |
| `awaiting_funds` | Waiting for the deposit. |
| `processing` | Funded and paying. |
| `review` | Under review; `review_reason` says why: `underfunded` (the deposit was less than the total), `screening`, or `payout_unknown`. |
| `verification_pending` | The payout went out and its outcome isn't certain yet. |
| `completed` | The beneficiary received the money. |
| `failed` | Not paid; what was deposited stays in your balance. |
| `returned` | It was paid and the bank returned it. |
Events: `remittance.created`, `remittance.processing`, `remittance.review`, `remittance.completed`, `remittance.failed`, `remittance.returned`.
A remittance's payout can't be cancelled on its own (`409` with `managed_by_remittance`).
# Reports (/en/docs/reports)
```bash
curl "$CAIBO_API/v1/reports/payouts?from=2026-10-01T00:00:00Z&to=2026-11-01T00:00:00Z&format=csv" \
-H "Authorization: Bearer $CAIBO_API_KEY" -o payouts-october.csv
```
| Report | Contains |
| --- | --- |
| `transactions` | All movements. |
| `payins` | Pay-ins. |
| `payouts` | Payouts, with principal, fee, markup, total, destination amount, and exchange rate. |
| `remittances` | Remittances. |
| `refunds` | Refunds. |
| `withdrawals` | Withdrawals. |
| `settlements` | Settlements. |
| `fees` | Fees charged and returned per operation. |
| `fx` | Conversions, with the market rate (`market_rate`) and the margin (`margin_bps`). |
| `balances` | Opening balance, credits, debits, and closing balance per currency. It reconciles: `opening + credits − debits = closing`. |
| Parameter | |
| --- | --- |
| `from`, `to` | Required, RFC 3339. The period includes `from` and excludes `to`; up to 366 days. |
| `currency` | Filters by currency. |
| `format` | `json` (default) or `csv`. |
| `after` | For the next page in JSON. |
The CSV follows RFC 4180 and comes with its file name (`payouts__.csv`).
# Sandbox and live (/en/docs/sandbox)
| | Sandbox | Live |
| --- | --- | --- |
| Host | `https://api-sandbox.caibopay.app` | `https://api.caibopay.app` |
| Key | `psp_test_…` | `psp_live_…` |
| Money | Test | Real |
| `livemode` in events | `false` | `true` |
| `environment` in `GET /v1/account` | `sandbox` | `live` |
They are separate deployments: each has its own data, customers, beneficiaries, webhooks, and keys. A key sent to the wrong environment is rejected with `401 invalid_api_key`, just like an invalid key.
## What exists only in sandbox [#what-exists-only-in-sandbox]
- **Simulated deposits.** deposits into a funding account at the test bank, the `bank_transfer` USD account. The deposit follows the real path (notification, verification, crediting) and you receive `payin.completed`. This route doesn't exist in live.
- **A test bank** that executes payouts, so you can run them end to end.
- In sandbox, PIX and soles pay-ins go to the real bank's test environment and **can't** be paid with `POST /v1/sandbox/deposits`.
- In sandbox, the test bank also accepts PIX payouts **without validating the details**, which is why `pix_key` and `name` appear as optional. In live both are required and validated. Always send complete details.
## Recommendations [#recommendations]
- Keep the host and the key in your configuration, not in code: going live means changing those two variables.
- Use each event's `livemode` so you never mix test data with real data.
- Before going live, work through the [checklist](/docs/go-live).
# SDKs (/en/docs/sdks)
The SDKs do for you what every integration must get right:
- **They pick the environment from your key**: `psp_test_…` goes to sandbox, `psp_live_…` to live.
- **They retry without duplicating**: on a network failure, a `429`, a `500` or a `503`, they retry with the **same** `Idempotency-Key`. If you pass none, they generate one per call.
- **They honor `Retry-After`** when the API asks to wait.
- **Typed errors**, with `type`, `code`, `param` and `request_id`.
- **Auto-pagination**: walk a whole list with a `for` loop.
- **Webhook verification**: signature, timestamp and event parsing in one function.
- **Complete types** for every resource, generated from the OpenAPI contract. Every endpoint of the [reference](/docs/api/payouts/create-payout) shows its example in all three languages.
## Install [#install]
```bash
npm install caibopay
```
Node.js 18 or later. No dependencies. ESM and CommonJS, with TypeScript types included.
```bash
pip install caibopay
```
Python 3.8 or later. Fully typed (`py.typed`).
```bash
go get go.caibopay.app/caibopay
```
Go 1.23 or later. No dependencies.
## Your first call [#your-first-call]
```ts
import { Caibo } from "caibopay";
const caibo = new Caibo(process.env.CAIBO_API_KEY!);
const account = await caibo.account.retrieve();
console.log(account.environment); // "sandbox"
```
```python
import os
import caibopay
client = caibopay.Client(os.environ["CAIBO_API_KEY"])
account = client.account.retrieve()
print(account["environment"]) # "sandbox"
```
```go
client, err := caibopay.NewClient(os.Getenv("CAIBO_API_KEY"))
if err != nil {
log.Fatal(err)
}
account, err := client.Account.Retrieve(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Println(account.Environment) // "sandbox"
```
## Collect an exact amount [#collect-an-exact-amount]
```ts
const fa = await caibo.fundingAccounts.create(
{ method: "pix", currency: "BRL", amount: "250.00", payer: { "payer.name": "Ana Souza" } },
{ idempotencyKey: "payin-order-8812" },
);
```
```python
fa = client.funding_accounts.create(
method="pix",
currency="BRL",
amount="250.00",
payer={"payer.name": "Ana Souza"},
idempotency_key="payin-order-8812",
)
```
```go
fa, err := client.FundingAccounts.Create(ctx, &caibopay.FundingAccountCreate{
Method: "pix",
Currency: "BRL",
Amount: "250.00",
Payer: map[string]string{"payer.name": "Ana Souza"},
}, caibopay.WithIdempotencyKey("payin-order-8812"))
```
## Pay out [#pay-out]
```ts
const quote = await caibo.quotes.create(
{ source_currency: "USDT", destination_currency: "PEN", method: "bank_transfer", amount: "350.00", amount_side: "destination" },
{ idempotencyKey: "quote-order-5531" },
);
const payout = await caibo.payouts.create(
{ beneficiary_id: "ben_01m3sgazybenxvqfw0h5bnszk4", quote_id: quote.id },
{ idempotencyKey: "payout-order-5531" },
);
```
```python
quote = client.quotes.create(
source_currency="USDT", destination_currency="PEN", method="bank_transfer",
amount="350.00", amount_side="destination", idempotency_key="quote-order-5531",
)
payout = client.payouts.create(
beneficiary_id="ben_01m3sgazybenxvqfw0h5bnszk4", quote_id=quote["id"], idempotency_key="payout-order-5531",
)
```
```go
quote, err := client.Quotes.Create(ctx, &caibopay.QuoteCreate{
SourceCurrency: "USDT", DestinationCurrency: "PEN", Method: "bank_transfer",
Amount: "350.00", AmountSide: caibopay.QuoteCreateAmountSideDestination,
}, caibopay.WithIdempotencyKey("quote-order-5531"))
if err != nil {
return err
}
payout, err := client.Payouts.Create(ctx, &caibopay.PayoutCreate{
BeneficiaryID: "ben_01m3sgazybenxvqfw0h5bnszk4", QuoteID: quote.ID,
}, caibopay.WithIdempotencyKey("payout-order-5531"))
```
## Walk a list [#walk-a-list]
```ts
for await (const payout of caibo.payouts.list({ status: "completed" })) {
console.log(payout.id, payout.destination.amount);
}
```
```python
for payout in client.payouts.list(status="completed"):
print(payout["id"], payout["destination"]["amount"])
```
```go
for payout, err := range client.Payouts.ListAll(ctx, &caibopay.ListPayoutsParams{Status: "completed"}) {
if err != nil {
return err
}
fmt.Println(payout.ID, payout.Destination.Amount)
}
```
## Errors [#errors]
```ts
import { CaiboError } from "caibopay";
try {
await caibo.payouts.create({ beneficiary_id: "ben_...", quote_id: "quo_..." });
} catch (err) {
if (err instanceof CaiboError && err.code === "quote_expired") {
// get a new quote
}
throw err;
}
```
```python
try:
client.payouts.create(beneficiary_id="ben_...", quote_id="quo_...")
except caibopay.InvalidRequestError as e:
if e.code == "quote_expired":
... # get a new quote
raise
```
```go
_, err := client.Payouts.Create(ctx, &caibopay.PayoutCreate{BeneficiaryID: "ben_...", QuoteID: "quo_..."})
if caibopay.IsCode(err, "quote_expired") {
// get a new quote
}
```
## Webhooks [#webhooks]
```ts
import express from "express";
import { constructEvent } from "caibopay";
app.post("/webhooks/caibo", express.raw({ type: "application/json" }), (req, res) => {
try {
const event = constructEvent(req.body, req.get("Psp-Signature"), process.env.CAIBO_WEBHOOK_SECRET!);
queue.push(event); // process later; dedupe on event.id
res.sendStatus(200);
} catch {
res.sendStatus(400);
}
});
```
```python
@app.post("/webhooks/caibo")
def webhook():
try:
event = caibopay.construct_event(request.get_data(), request.headers.get("Psp-Signature"), secret)
except caibopay.SignatureVerificationError:
return "", 400
enqueue(event) # process later; dedupe on event["id"]
return "", 200
```
```go
http.HandleFunc("/webhooks/caibo", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
event, err := caibopay.ConstructEvent(body, r.Header.Get(caibopay.SignatureHeader), secret)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
enqueue(event) // process later; dedupe on event.ID
w.WriteHeader(http.StatusOK)
})
```
## Options [#options]
| | Node.js | Python | Go |
| --- | --- | --- | --- |
| Retries (2 by default) | `{ maxRetries }` | `max_retries=` | `WithMaxRetries(n)` |
| Timeout per attempt (30 s) | `{ timeout }` | `timeout=` | `WithHTTPClient(...)` |
| Another host | `{ baseUrl }` | `base_url=` | `WithBaseURL(u)` |
| Your Idempotency-Key | `{ idempotencyKey }` | `idempotency_key=` | `WithIdempotencyKey(k)` |
| Your trace id | `{ correlationId }` | `request_options={"correlation_id": …}` | `WithCorrelationID(id)` |
Any language can use the API over HTTP and JSON, or generate its own client from [`/openapi.json`](/openapi.json). Write to us if you need an official SDK for another language.
# Settlements (/en/docs/settlements)
In addition to on-demand [withdrawals](/docs/withdrawals), Caibo can settle your balance periodically: daily, weekly, monthly, or when it reaches an amount. The schedule is part of your contract; Caibo sets it and you can view it.
| Endpoint | Returns |
| --- | --- |
| | Whether you have automatic settlement and for which currencies. `unconfigured`: nothing settles on its own and your balance stays available until you withdraw. |
| | Your schedules per currency: `frequency` (`manual`, `daily`, `weekly`, `monthly`, `threshold`), cutoff, minimum, and fee (`fee_bps`, `fee_fixed`). |
| | Your settlements. |
## A settlement [#a-settlement]
| Field | Description |
| --- | --- |
| `gross` | What came in during the period. |
| `fees` | The fees. |
| `adjustments` | Adjustments, signed. |
| `net` | `gross - fees + adjustments`: what gets sent. |
| `period_start`, `period_end` | The period. |
| `hold_reason` | Why it's on hold: `insufficient_available`, `no_route`, `no_destination`, `operator`. |
`GET /v1/settlements/{id}` adds `items`, the detail of each included movement.
| `status` | |
| --- | --- |
| `pending`, `ready` | Being prepared. |
| `processing` | Being sent. |
| `settled` | Arrived. |
| `on_hold` | On hold; see `hold_reason`. |
| `failed`, `disputed` | Failed or under dispute. |
Events: `settlement.created`, `settlement.processing`, `settlement.on_hold`, `settlement.completed`, `settlement.failed`, and `settlement_schedule.activated`, `settlement_schedule.blocked`.
# Verify the signature (/en/docs/webhook-signatures)
Every webhook includes `Psp-Signature`:
```
Psp-Signature: t=1790769600,v1=c0c9eaafdea23b0f8c992b380b286917c6459b0729b2496b8452fa695215e6b8
```
- `t` is the time of the signature, in Unix seconds.
- `v1` is a hex-encoded `HMAC-SHA256`, keyed with your secret, over `t` + `.` + the **exact** body you received.
- The key is the **full** secret, including the `whsec_` prefix.
- There can be more than one `v1` (during a rotation). It's enough for one to match.
To accept a webhook:
1. Compute the HMAC over the untouched body: don't parse or re-serialize it first.
2. Compare against each `v1` in **constant time**.
3. Reject it if `t` differs from your clock by more than **5 minutes**: that way nobody can replay an old notification to you.
```js
const crypto = require("crypto");
// rawBody: the exact bytes received (a Buffer).
function verifyCaiboSignature(secret, header, rawBody, toleranceSeconds = 300) {
let t = null;
const signatures = [];
for (const part of String(header || "").split(",")) {
const [key, value] = part.trim().split("=", 2);
if (key === "t") {
if (t !== null || !/^\d+$/.test(value)) return false;
t = value;
} else if (key === "v1" && /^[0-9a-f]{64}$/i.test(value)) {
signatures.push(Buffer.from(value, "hex"));
}
}
if (t === null || signatures.length === 0) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.`).update(rawBody).digest();
if (!signatures.some((s) => crypto.timingSafeEqual(s, expected))) return false;
return Math.abs(Date.now() / 1000 - Number(t)) <= toleranceSeconds;
}
// Express: read the body raw, verify, then parse.
app.post("/webhooks/caibo", express.raw({ type: "application/json" }), (req, res) => {
if (!verifyCaiboSignature(process.env.CAIBO_WEBHOOK_SECRET, req.get("Psp-Signature"), req.body)) {
return res.sendStatus(400);
}
const event = JSON.parse(req.body);
queue.push(event); // process later; dedupe on event.id
res.sendStatus(200);
});
```
```python
import hashlib
import hmac
import re
import time
_HEX64 = re.compile(r"^[0-9a-fA-F]{64}$")
def verify_caibo_signature(secret: str, header: str, raw_body: bytes, tolerance: int = 300) -> bool:
t, signatures = None, []
for part in (header or "").split(","):
key, _, value = part.strip().partition("=")
if key == "t":
if t is not None or not value.isdigit():
return False
t = value
elif key == "v1" and _HEX64.match(value):
signatures.append(bytes.fromhex(value))
if t is None or not signatures:
return False
expected = hmac.new(secret.encode(), t.encode() + b"." + raw_body, hashlib.sha256).digest()
if not any(hmac.compare_digest(s, expected) for s in signatures):
return False
return abs(time.time() - int(t)) <= tolerance
# Flask: request.get_data() is the raw body.
@app.post("/webhooks/caibo")
def caibo_webhook():
if not verify_caibo_signature(os.environ["CAIBO_WEBHOOK_SECRET"], request.headers.get("Psp-Signature"), request.get_data()):
return "", 400
event = request.get_json()
enqueue(event) # process later; dedupe on event["id"]
return "", 200
```
```go
package caibo
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"strconv"
"strings"
"time"
)
// VerifySignature reports whether header signs body with secret, within tolerance.
func VerifySignature(secret, header string, body []byte, tolerance time.Duration) bool {
var ts string
var signatures [][]byte
for _, part := range strings.Split(header, ",") {
key, value, _ := strings.Cut(strings.TrimSpace(part), "=")
switch key {
case "t":
if ts != "" {
return false
}
ts = value
case "v1":
if s, err := hex.DecodeString(value); err == nil && len(s) == sha256.Size {
signatures = append(signatures, s)
}
}
}
t, err := strconv.ParseInt(ts, 10, 64)
if err != nil || len(signatures) == 0 {
return false
}
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(ts + "."))
mac.Write(body)
expected := mac.Sum(nil)
ok := false
for _, s := range signatures {
ok = ok || hmac.Equal(s, expected)
}
age := time.Since(time.Unix(t, 0))
return ok && age <= tolerance && age >= -tolerance
}
```
## Test your code [#test-your-code]
With these values your function must accept the signature (ignoring the tolerance, because `t` is a past date):
| | |
| --- | --- |
| Secret | `whsec_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef` |
| Body (exact, no trailing newline) | `{"id":"evt_1","type":"payout.completed","data":{"amount":"10.00"}}` |
| `t` | `1790769600` |
| Expected signature | `t=1790769600,v1=c0c9eaafdea23b0f8c992b380b286917c6459b0729b2496b8452fa695215e6b8` |
To test against your real server, use .
Many frameworks parse the JSON before you see it. If you sign `JSON.stringify(req.body)` instead of the original body, the signature won't match. Read the **raw** body.
# Webhooks (/en/docs/webhooks)
```bash
curl "$CAIBO_API/v1/webhook-endpoints" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://tu-empresa.com/webhooks/caibo",
"description": "Production",
"event_types": ["payin.completed", "payout.completed", "payout.failed"]
}'
```
- `url`: `https`, public, on port 443.
- `event_types`: the types you want to receive. Empty or omitted: **all of them**.
- The response includes `secret` (`whsec_…`) **only once**. If you lose it, [rotate it](#rotate-the-secret).
- Up to 10 webhooks per account and per environment.
## What you receive [#what-you-receive]
```http
POST /webhooks/caibo HTTP/1.1
Content-Type: application/json
User-Agent: psp-webhooks/1 (live)
Psp-Signature: t=1790769600,v1=c0c9eaafdea23b0f8c992b380b286917c6459b0729b2496b8452fa695215e6b8
Psp-Event-Id: evt_01m3sgb02af7nb0jf73vwv2sd5
Psp-Delivery-Id: whd_01m3sgb03a...
Psp-Delivery-Attempt: 1
```
```json
{
"id": "evt_01m3sgb02af7nb0jf73vwv2sd5",
"type": "payout.completed",
"schema_version": 1,
"occurred_at": "2026-10-18T14:00:41.126938Z",
"livemode": true,
"data": { "id": "pout_01m3sgb02af7nb0jf73vwv2sd4", "status": "completed" }
}
```
`data` is the full resource, in the same shape the API returns. See [Events](/docs/events).
## How to respond [#how-to-respond]
### Verify the signature [#verify-the-signature]
Using the body **exactly as received**, before parsing it. See [Signatures](/docs/webhook-signatures).
### Respond 2xx right away [#respond-2xx-right-away]
You have **10 seconds**. Store the event and process it later, in a queue. The body of your response is ignored. A redirect (`3xx`) counts as a failure.
### Discard duplicates [#discard-duplicates]
Delivery is "at least once": the same event can arrive twice. Use `Psp-Event-Id` (the event's `id`) to avoid processing it twice.
## Retries [#retries]
If you don't respond `2xx` in time, we retry up to **10 times** over about 23 hours:
| Attempt | Wait before | | Attempt | Wait before |
| --- | --- | --- | --- | --- |
| 2 | 30 s | | 7 | 2 h |
| 3 | 2 min | | 8 | 4 h |
| 4 | 10 min | | 9 | 8 h |
| 5 | 30 min | | 10 | 8 h |
| 6 | 1 h | | | |
Each wait varies by ±20%. After 10 consecutive failures, the webhook moves to `failing` and we send it a test delivery every 15 minutes; the first one that succeeds returns it to `active`. No event is ever lost: it's always in `GET /v1/events`.
**Ordering:** one delivery at a time per webhook, and events for the same resource arrive in order.
## Tools [#tools]
| | |
| --- | --- |
| | Sends a test `webhook.ping` (up to 5 per minute). |
| | The delivery history, with status and error. |
| | Resends an event to all your webhooks, or only to `endpoint_id`. |
| | Changes `url`, `description`, `event_types`, or pauses with `active: false`. |
## Rotate the secret [#rotate-the-secret]
Returns a new `secret`. For **24 hours** we sign with both (the new one first), so you can update your server without missing notifications. `previous_secret_expires_at` tells you when the old one stops working.
# Withdrawals (/en/docs/withdrawals)
A withdrawal sends funds from your balance to a **destination account** of your own, over the same rails as a payout.
## 1. Register your destination account [#1-register-your-destination-account]
```json
{
"method": "bank_transfer",
"currency": "PEN",
"details": { "cci": "00219100123456780123", "document_number": "20123456789", "first_name": "Mi", "last_name": "Empresa SAC" }
}
```
`details` uses the same `beneficiary_fields` as a payout with that method and currency. Registering the same account twice returns the existing one.
## 2. Withdraw [#2-withdraw]
```bash
curl "$CAIBO_API/v1/withdrawals" \
-H "Authorization: Bearer $CAIBO_API_KEY" \
-H "Idempotency-Key: retiro-2026-10-18" \
-H "Content-Type: application/json" \
-d '{ "destination_id": "dest_01m3sgc0...", "amount": "5000.00" }'
```
- `amount` is what the account receives, in its currency.
- `fee` is set when the withdrawal is created, and `total = amount + fee` is what leaves your balance.
- If your balance isn't enough, the withdrawal is created with `status: failed` and `failure_code: insufficient_funds`.
| `status` | Meaning |
| --- | --- |
| `pending_approval` | Exceeds your threshold and awaits Caibo's approval. The funds are set aside. |
| `processing` | On its way. |
| `completed` | Arrived. |
| `failed` | It couldn't be completed; the funds return. |
| `cancelled` | Rejected while awaiting approval. |
Events: `withdrawal.created`, `withdrawal.pending_approval`, `withdrawal.approved`, `withdrawal.submitted`, `withdrawal.completed`, `withdrawal.failed`, `withdrawal.cancelled`.
# Retrieve the account of the credential (/en/docs/api/account/get-account)
Who the credential is: the account it belongs to, the environment that answered (sandbox or live) and the credential itself, without its secret. Use it to check a key and to show which account and environment a client is working in. The credential is an API key: there are no user identities (people, roles, single sign-on) yet, so nothing here describes a person.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/account",
"description": "Who the credential is: the account it belongs to, the environment that answered (sandbox or live) and the credential itself, without its secret. Use it to check a key and to show which account and environment a client is working in. The credential is an API key: there are no user identities (people, roles, single sign-on) yet, so nothing here describes a person.",
"operationId": "getAccount",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Account"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve the account of the credential",
"tags": [
"Account"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.account.retrieve();"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.account.retrieve()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Account.Retrieve(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Who is calling (/en/docs/api/account/get-me)
Who the credential of the request is: an API key (kind api_key) or a member of the account, a person signed in to the dashboard through its identity provider (kind member), with the account it acts for and its scopes. A member's role and scopes are the platform's: a client reads them here, never from the identity provider. For a member it also lists every account the person may act for; send the Caibo-Account header (acct_…) to act for another one. A person signed in to the dashboard who is no active member of an active account is answered 403 no_membership, one answer whatever the reason; this route binds the person's open invitations first. A dashboard session token is accepted only by this API, an operator console's never.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/me",
"description": "Who the credential of the request is: an API key (kind api_key) or a member of the account, a person signed in to the dashboard through its identity provider (kind member), with the account it acts for and its scopes. A member's role and scopes are the platform's: a client reads them here, never from the identity provider. For a member it also lists every account the person may act for; send the Caibo-Account header (acct_…) to act for another one. A person signed in to the dashboard who is no active member of an active account is answered 403 no_membership, one answer whatever the reason; this route binds the person's open invitations first. A dashboard session token is accepted only by this API, an operator console's never.",
"operationId": "getMe",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Me"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Who is calling",
"tags": [
"Account"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.account.me();"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.account.me()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Account.Me(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List balances (/en/docs/api/balances/list-balances)
The account's money per currency, by how usable it is. Every figure is read from the ledger; total = available + pending + reserved + in_settlement. Earnings are shown apart and not added.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/balances",
"description": "The account's money per currency, by how usable it is. Every figure is read from the ledger; total = available + pending + reserved + in_settlement. Earnings are shown apart and not added.",
"operationId": "listBalances",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Balance"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List balances",
"tags": [
"Balances"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.balances.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.balances.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Balances.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List the statement of a currency (/en/docs/api/balances/list-balance-entries)
Every movement on the account's balances in a currency, newest first: one entry per ledger posting on one of the account's own balances, with the operation it belongs to. Pass next_cursor as after to continue; the statement is walked without gaps or repeats.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/balances/{currency}/entries",
"description": "Every movement on the account's balances in a currency, newest first: one entry per ledger posting on one of the account's own balances, with the operation it belongs to. Pass next_cursor as after to continue; the statement is walked without gaps or repeats.",
"operationId": "listBalanceEntries",
"parameters": [
{
"in": "path",
"name": "currency",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "The id of the last entry received (the next_cursor of the previous page).",
"in": "query",
"name": "after",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/BalanceEntry"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List the statement of a currency",
"tags": [
"Balances"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.balances.listEntries(\"USDT\")) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.balances.list_entries(\"USDT\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Balances.ListEntriesAll(ctx, \"USDT\", nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# List beneficiaries (/en/docs/api/beneficiaries/list-beneficiaries)
Newest first.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/beneficiaries",
"description": "Newest first.",
"operationId": "listBeneficiaries",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"active",
"archived"
],
"type": "string"
}
},
{
"description": "Only the beneficiaries of this customer.",
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"pattern": "^cus_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Beneficiary"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List beneficiaries",
"tags": [
"Beneficiaries"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.beneficiaries.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.beneficiaries.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Beneficiaries.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a beneficiary (/en/docs/api/beneficiaries/create-beneficiary)
Registers who is paid. The same account registered twice for the same customer is the same beneficiary (200 with the existing one). Account details are write-only. The country is the method's when the method has one.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/beneficiaries",
"description": "Registers who is paid. The same account registered twice for the same customer is the same beneficiary (200 with the existing one). Account details are write-only. The country is the method's when the method has one.",
"operationId": "createBeneficiary",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/BeneficiaryCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Beneficiary"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Beneficiary"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a beneficiary",
"tags": [
"Beneficiaries"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.beneficiaries.create({\n currency: \"PEN\",\n details: {},\n method: \"bank_transfer\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.beneficiaries.create(currency=\"PEN\", details={}, method=\"bank_transfer\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Beneficiaries.Create(ctx, &caibopay.BeneficiaryCreate{\n\tCurrency: \"PEN\",\n\tMethod: \"bank_transfer\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a beneficiary (/en/docs/api/beneficiaries/get-beneficiary)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/beneficiaries/{id}",
"operationId": "getBeneficiary",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Beneficiary"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a beneficiary",
"tags": [
"Beneficiaries"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.beneficiaries.retrieve(\"ben_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.beneficiaries.retrieve(\"ben_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Beneficiaries.Retrieve(ctx, \"ben_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List what the account can do (/en/docs/api/capabilities/list-capabilities)
The products (payin, payout, remittance), methods, currencies and countries available to the account, with the fields each one requires and whether it can be used right now. Countries and rails are discovered here; they never have endpoints of their own.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/capabilities",
"description": "The products (payin, payout, remittance), methods, currencies and countries available to the account, with the fields each one requires and whether it can be used right now. Countries and rails are discovered here; they never have endpoints of their own.",
"operationId": "listCapabilities",
"parameters": [
{
"description": "Only this product: payin, payout or remittance.",
"in": "query",
"name": "product",
"required": false,
"schema": {
"enum": [
"payin",
"payout",
"remittance"
],
"type": "string"
}
},
{
"description": "Only this country (ISO 3166-1 alpha-2). For a remittance, the destination's.",
"in": "query",
"name": "country",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only this currency. For a remittance, the destination's.",
"in": "query",
"name": "currency",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only this method. For a remittance, the payout method.",
"in": "query",
"name": "method",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Capability"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List what the account can do",
"tags": [
"Capabilities"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.capabilities.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.capabilities.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Capabilities.List(ctx, nil)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List customers (/en/docs/api/customers/list-customers)
Newest first. The profile is not in a list; retrieve a customer for it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/customers",
"description": "Newest first. The profile is not in a list; retrieve a customer for it.",
"operationId": "listCustomers",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"active",
"blocked",
"closed"
],
"type": "string"
}
},
{
"description": "Only the customer with this external_id: your own id for it.",
"in": "query",
"name": "external_id",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Customer"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List customers",
"tags": [
"Customers"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.customers.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.customers.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Customers.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a customer (/en/docs/api/customers/create-customer)
Registers a person or business you act for, under your own external_id. The same external_id sent again with the same identity (type, country, display_name, profile) returns the existing customer (200); with a different identity it is a 409 conflict. metadata is yours and is not compared.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/customers",
"description": "Registers a person or business you act for, under your own external_id. The same external_id sent again with the same identity (type, country, display_name, profile) returns the existing customer (200); with a different identity it is a 409 conflict. metadata is yours and is not compared.",
"operationId": "createCustomer",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomerCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a customer",
"tags": [
"Customers"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.customers.create({\n country: \"...\",\n display_name: \"...\",\n external_id: \"id_...\",\n type: \"individual\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.customers.create(country=\"...\", display_name=\"...\", external_id=\"id_...\", type=\"individual\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Customers.Create(ctx, &caibopay.CustomerCreate{\n\tCountry: \"...\",\n\tDisplayName: \"...\",\n\tExternalID: \"id_...\",\n\tType: \"individual\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a customer (/en/docs/api/customers/get-customer)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/customers/{id}",
"operationId": "getCustomer",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a customer",
"tags": [
"Customers"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.customers.retrieve(\"cus_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.customers.retrieve(\"cus_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Customers.Retrieve(ctx, \"cus_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Update a customer's metadata or close it (/en/docs/api/customers/update-customer)
metadata replaces the whole object. status takes active or closed; closed is final. A blocked customer is blocked by the platform and cannot be reactivated here.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "PATCH",
"path": "/v1/customers/{id}",
"description": "metadata replaces the whole object. status takes active or closed; closed is final. A blocked customer is blocked by the platform and cannot be reactivated here.",
"operationId": "updateCustomer",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CustomerUpdate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Update a customer's metadata or close it",
"tags": [
"Customers"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.customers.update(\"cus_...\", {});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.customers.update(\"cus_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Customers.Update(ctx, \"cus_...\", &caibopay.CustomerUpdate{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List events (/en/docs/api/events/list-events)
Events in the order they became visible. Store next_cursor and pass it as after to poll; no event is ever skipped. With resource_id the list is the story of one resource, oldest first: every status it went through, from its creation to its outcome. Filters combine, and the cursor works the same with them.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/events",
"description": "Events in the order they became visible. Store next_cursor and pass it as after to poll; no event is ever skipped. With resource_id the list is the story of one resource, oldest first: every status it went through, from its creation to its outcome. Filters combine, and the cursor works the same with them.",
"operationId": "listEvents",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "The next_cursor of the previous page.",
"in": "query",
"name": "after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only events of this type (payout.completed), or of this family of types when it ends in a dot (payout.). A type the platform does not publish is a 400.",
"in": "query",
"name": "type",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only events about this resource, by its id: a payout, a pay-in, a funding account, a refund, a withdrawal, a remittance, a settlement, a customer, a beneficiary, a payout batch, a reconciliation exception, a risk decision or a webhook endpoint.",
"in": "query",
"name": "resource_id",
"required": false,
"schema": {
"pattern": "^[a-z]+_[0-9a-z]+$",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Event"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List events",
"tags": [
"Events"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.events.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.events.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Events.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Retrieve an event (/en/docs/api/events/get-event)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/events/{id}",
"operationId": "getEvent",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Event"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve an event",
"tags": [
"Events"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.events.retrieve(\"evt_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.events.retrieve(\"evt_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Events.Retrieve(ctx, \"evt_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Send an event to webhook endpoints again (/en/docs/api/webhooks/redeliver-event)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/events/{id}/redeliver",
"operationId": "redeliverEvent",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EventRedeliver"
}
}
},
"required": false
},
"responses": {
"202": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/WebhookDelivery"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "Accepted"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Send an event to webhook endpoints again",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.events.redeliver(\"evt_...\", {})) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.events.redeliver(\"evt_...\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Events.Redeliver(ctx, \"evt_...\", &caibopay.EventRedeliver{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List webhook endpoints (/en/docs/api/webhooks/list-webhook-endpoints)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/webhook-endpoints",
"operationId": "listWebhookEndpoints",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/WebhookEndpoint"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List webhook endpoints",
"tags": [
"Webhooks"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.webhookEndpoints.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.webhook_endpoints.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Create a webhook endpoint (/en/docs/api/webhooks/create-webhook-endpoint)
The response carries the signing secret. It is shown only here and after a rotation.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/webhook-endpoints",
"description": "The response carries the signing secret. It is shown only here and after a rotation.",
"operationId": "createWebhookEndpoint",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpointCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a webhook endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.create({\n url: \"https://example.com/webhooks/caibo\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.create(url=\"https://example.com/webhooks/caibo\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.Create(ctx, &caibopay.WebhookEndpointCreate{\n\tURL: \"https://example.com/webhooks/caibo\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a webhook endpoint (/en/docs/api/webhooks/get-webhook-endpoint)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/webhook-endpoints/{id}",
"operationId": "getWebhookEndpoint",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a webhook endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.retrieve(\"we_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.retrieve(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.Retrieve(ctx, \"we_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Update, pause or resume a webhook endpoint (/en/docs/api/webhooks/update-webhook-endpoint)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "PATCH",
"path": "/v1/webhook-endpoints/{id}",
"operationId": "updateWebhookEndpoint",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpointUpdate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Update, pause or resume a webhook endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.update(\"we_...\", {});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.update(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.Update(ctx, \"we_...\", &caibopay.WebhookEndpointUpdate{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Delete a webhook endpoint (/en/docs/api/webhooks/delete-webhook-endpoint)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "DELETE",
"path": "/v1/webhook-endpoints/{id}",
"operationId": "deleteWebhookEndpoint",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Delete a webhook endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nawait caibo.webhookEndpoints.delete(\"we_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nclient.webhook_endpoints.delete(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nif err := client.WebhookEndpoints.Delete(ctx, \"we_...\"); err != nil {\n\treturn err\n}"
}
]
}
```
# List recent deliveries to an endpoint (/en/docs/api/webhooks/list-webhook-deliveries)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/webhook-endpoints/{id}/deliveries",
"operationId": "listWebhookDeliveries",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/WebhookDelivery"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List recent deliveries to an endpoint",
"tags": [
"Webhooks"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.webhookEndpoints.listDeliveries(\"we_...\")) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.webhook_endpoints.list_deliveries(\"we_...\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.ListDeliveries(ctx, \"we_...\", nil)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Send a test event (/en/docs/api/webhooks/ping-webhook-endpoint)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/webhook-endpoints/{id}/ping",
"operationId": "pingWebhookEndpoint",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"202": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookDelivery"
}
}
},
"description": "Accepted"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Send a test event",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.ping(\"we_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.ping(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.Ping(ctx, \"we_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Rotate the signing secret (/en/docs/api/webhooks/rotate-webhook-secret)
Returns the new secret. For a grace period deliveries are signed with both the new and the previous secret.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/webhook-endpoints/{id}/rotate-secret",
"description": "Returns the new secret. For a grace period deliveries are signed with both the new and the previous secret.",
"operationId": "rotateWebhookSecret",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Rotate the signing secret",
"tags": [
"Webhooks"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.webhookEndpoints.rotateSecret(\"we_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.webhook_endpoints.rotate_secret(\"we_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.WebhookEndpoints.RotateSecret(ctx, \"we_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Create a funding account (/en/docs/api/funding/create-funding-account)
An account the balance is funded through. It is created pending; its payment instructions are available once it is active (event funding_account.active). With amount it is one payment of exactly that amount (collection payment in GET /v1/capabilities): the payer pays the amount and nothing more, and the account closes once it is paid; the pay-in that credits it is payin.completed.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/funding-accounts",
"description": "An account the balance is funded through. It is created pending; its payment instructions are available once it is active (event funding_account.active). With amount it is one payment of exactly that amount (collection payment in GET /v1/capabilities): the payer pays the amount and nothing more, and the account closes once it is paid; the pay-in that credits it is payin.completed.",
"operationId": "createFundingAccount",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FundingAccountCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FundingAccount"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FundingAccount"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a funding account",
"tags": [
"Funding"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.fundingAccounts.create({\n currency: \"PEN\",\n method: \"bank_transfer\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.funding_accounts.create(currency=\"PEN\", method=\"bank_transfer\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.FundingAccounts.Create(ctx, &caibopay.FundingAccountCreate{\n\tCurrency: \"PEN\",\n\tMethod: \"bank_transfer\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a funding account (/en/docs/api/funding/get-funding-account)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/funding-accounts/{id}",
"operationId": "getFundingAccount",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/FundingAccount"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a funding account",
"tags": [
"Funding"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.fundingAccounts.retrieve(\"fa_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.funding_accounts.retrieve(\"fa_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.FundingAccounts.Retrieve(ctx, \"fa_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List pay-ins (/en/docs/api/funding/list-pay-ins)
Newest first. refunded and refundable are not in a list; retrieve a pay-in for them.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payins",
"description": "Newest first. refunded and refundable are not in a list; retrieve a pay-in for them.",
"operationId": "listPayIns",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"processing",
"completed",
"failed"
],
"type": "string"
}
},
{
"description": "Only the pay-ins into this funding account.",
"in": "query",
"name": "funding_account_id",
"required": false,
"schema": {
"pattern": "^fa_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/PayIn"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List pay-ins",
"tags": [
"Funding"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.payins.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.payins.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Payins.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Retrieve a pay-in (/en/docs/api/funding/get-pay-in)
A credited pay-in also says what it has given back (refunded) and what can still be refunded (refundable).
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payins/{id}",
"description": "A credited pay-in also says what it has given back (refunded) and what can still be refunded (refundable).",
"operationId": "getPayIn",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayIn"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a pay-in",
"tags": [
"Funding"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payins.retrieve(\"pin_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payins.retrieve(\"pin_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Payins.Retrieve(ctx, \"pin_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List hosted domains (/en/docs/api/hosted-pages/list-hosted-domains)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-domains",
"operationId": "listHostedDomains",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/HostedDomain"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List hosted domains",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.hostedDomains.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.hosted_domains.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedDomains.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Claim a hostname for the hosted page (/en/docs/api/hosted-pages/create-hosted-domain)
Claims a hostname the page should be served at. The claim starts pending, with a verification_token to publish; the hostname serves the page only once the platform has verified it. A hostname with a live claim, yours or anybody's, is refused with hostname_taken.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/hosted-domains",
"description": "Claims a hostname the page should be served at. The claim starts pending, with a verification_token to publish; the hostname serves the page only once the platform has verified it. A hostname with a live claim, yours or anybody's, is refused with hostname_taken.",
"operationId": "createHostedDomain",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedDomainCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedDomain"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedDomain"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Claim a hostname for the hosted page",
"tags": [
"Hosted pages"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedDomains.create({\n hostname: \"...\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_domains.create(hostname=\"...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedDomains.Create(ctx, &caibopay.HostedDomainCreate{\n\tHostname: \"...\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a hosted domain (/en/docs/api/hosted-pages/get-hosted-domain)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-domains/{id}",
"operationId": "getHostedDomain",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedDomain"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a hosted domain",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedDomains.retrieve(\"hd_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_domains.retrieve(\"hd_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedDomains.Retrieve(ctx, \"hd_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Remove a hosted domain (/en/docs/api/hosted-pages/delete-hosted-domain)
The hostname stops serving the page at once and can be claimed again.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "DELETE",
"path": "/v1/hosted-domains/{id}",
"description": "The hostname stops serving the page at once and can be claimed again.",
"operationId": "deleteHostedDomain",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Remove a hosted domain",
"tags": [
"Hosted pages"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nawait caibo.hostedDomains.delete(\"hd_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nclient.hosted_domains.delete(\"hd_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nif err := client.HostedDomains.Delete(ctx, \"hd_...\"); err != nil {\n\treturn err\n}"
}
]
}
```
# Retrieve the hosted page configuration (/en/docs/api/hosted-pages/get-hosted-page)
How the account's hosted remittance page is configured. An account that never configured it gets the defaults, with no id.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-page",
"description": "How the account's hosted remittance page is configured. An account that never configured it gets the defaults, with no id.",
"operationId": "getHostedPage",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedPage"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve the hosted page configuration",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedPage.retrieve();"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_page.retrieve()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedPage.Retrieve(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Replace the hosted page configuration (/en/docs/api/hosted-pages/put-hosted-page)
Replaces the whole configuration; a field left out is reset to its default. The theme is data, validated here: colours are #rrggbb, the radius is one of a fixed scale, the font is the key of a font the page ships, and URLs are https. branding_mode white_label needs the entitlement (white_label_entitled), which the platform grants; it is refused with white_label_not_entitled otherwise.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "PUT",
"path": "/v1/hosted-page",
"description": "Replaces the whole configuration; a field left out is reset to its default. The theme is data, validated here: colours are #rrggbb, the radius is one of a fixed scale, the font is the key of a font the page ships, and URLs are https. branding_mode white_label needs the entitlement (white_label_entitled), which the platform grants; it is refused with white_label_not_entitled otherwise.",
"operationId": "putHostedPage",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedPageUpdate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedPage"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Replace the hosted page configuration",
"tags": [
"Hosted pages"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedPage.update({});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_page.update()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedPage.Update(ctx, &caibopay.HostedPageUpdate{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List hosted sessions (/en/docs/api/hosted-pages/list-hosted-sessions)
Newest first, those your customers started from the page included. Never with a token. A session's status is read off its remittance and its expiry when you ask, so the list is not filtered by it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-sessions",
"description": "Newest first, those your customers started from the page included. Never with a token. A session's status is read off its remittance and its expiry when you ask, so the list is not filtered by it.",
"operationId": "listHostedSessions",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only the sessions of this customer.",
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"pattern": "^cus_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the session this remittance was created from.",
"in": "query",
"name": "remittance_id",
"required": false,
"schema": {
"pattern": "^rem_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/HostedSession"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List hosted sessions",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.hostedSessions.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.hosted_sessions.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.HostedSessions.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a hosted session (/en/docs/api/hosted-pages/create-hosted-session)
Starts a session of the hosted remittance flow for one of your customers. The response carries the session token and the path the hosted page serves it at (/s/); they are shown only here. Send the customer to that path on your page's host: the same link is where they follow the remittance afterwards. A session creates at most one remittance, ever. Repeating the request with the same Idempotency-Key returns the same session, without the token. The hosted page must be enabled.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/hosted-sessions",
"description": "Starts a session of the hosted remittance flow for one of your customers. The response carries the session token and the path the hosted page serves it at (/s/); they are shown only here. Send the customer to that path on your page's host: the same link is where they follow the remittance afterwards. A session creates at most one remittance, ever. Repeating the request with the same Idempotency-Key returns the same session, without the token. The hosted page must be enabled.",
"operationId": "createHostedSession",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedSessionCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedSession"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedSession"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a hosted session",
"tags": [
"Hosted pages"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedSessions.create({}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_sessions.create(idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedSessions.Create(ctx, &caibopay.HostedSessionCreate{}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a hosted session (/en/docs/api/hosted-pages/get-hosted-session)
With the ids of what the session holds: its customer, beneficiary, quote, funding account and remittance. payment_reported_at is when the customer said they paid; it is a statement, not a confirmation: follow the remittance and its pay-in for that.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/hosted-sessions/{id}",
"description": "With the ids of what the session holds: its customer, beneficiary, quote, funding account and remittance. payment_reported_at is when the customer said they paid; it is a statement, not a confirmation: follow the remittance and its pay-in for that.",
"operationId": "getHostedSession",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HostedSession"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a hosted session",
"tags": [
"Hosted pages"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.hostedSessions.retrieve(\"hs_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.hosted_sessions.retrieve(\"hs_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.HostedSessions.Retrieve(ctx, \"hs_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List the account's members (/en/docs/api/members/list-members)
The people who act for the account through the dashboard, and the open invitations, newest first. A member's role maps to scopes: owner, admin and developer hold read and write, viewer read.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/members",
"description": "The people who act for the account through the dashboard, and the open invitations, newest first. A member's role maps to scopes: owner, admin and developer hold read and write, viewer read.",
"operationId": "listMembers",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Member"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List the account's members",
"tags": [
"Members"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.members.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.members.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Members.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Invite a person (/en/docs/api/members/create-member)
Invites an e-mail address with a role. The invitation expires after 7 days; it is bound at the person's first signed-in call to the person whose verified primary address it is, and the member becomes active. Inviting an address that was invited and never signed in renews its invitation (200). Only a signed-in owner or admin invites, and only an owner invites an owner: an API key does not manage people (403 insufficient_role). An address that is already a member is 409 member_exists.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/members",
"description": "Invites an e-mail address with a role. The invitation expires after 7 days; it is bound at the person's first signed-in call to the person whose verified primary address it is, and the member becomes active. Inviting an address that was invited and never signed in renews its invitation (200). Only a signed-in owner or admin invites, and only an owner invites an owner: an API key does not manage people (403 insufficient_role). An address that is already a member is 409 member_exists.",
"operationId": "createMember",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MemberCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Member"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Member"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Invite a person",
"tags": [
"Members"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.members.create({\n email: \"...\",\n role: \"owner\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.members.create(email=\"...\", role=\"owner\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Members.Create(ctx, &caibopay.MemberCreate{\n\tEmail: \"...\",\n\tRole: \"owner\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Change a member's role or disable it (/en/docs/api/members/update-member)
status disabled refuses the member's next request at once, whatever its session; active enables it again (only a member that signed in once). Only a signed-in owner or admin changes members, not their own; only an owner touches an owner; the account keeps at least one active owner (409 last_owner). Withdraw an invitation by disabling it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "PATCH",
"path": "/v1/members/{id}",
"description": "status disabled refuses the member's next request at once, whatever its session; active enables it again (only a member that signed in once). Only a signed-in owner or admin changes members, not their own; only an owner touches an owner; the account keeps at least one active owner (409 last_owner). Withdraw an invitation by disabling it.",
"operationId": "updateMember",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MemberUpdate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Member"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Change a member's role or disable it",
"tags": [
"Members"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.members.update(\"mem_...\", {});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.members.update(\"mem_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Members.Update(ctx, \"mem_...\", &caibopay.MemberUpdate{})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List payout batches (/en/docs/api/payouts/list-payout-batches)
Newest first, each with its summary, totals and cancellation as they are now. A batch accepted while you page never shifts or repeats the pages that follow.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payout-batches",
"description": "Newest first, each with its summary, totals and cancellation as they are now. A batch accepted while you page never shifts or repeats the pages that follow.",
"operationId": "listPayoutBatches",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"accepted",
"processing",
"completed",
"completed_with_failures",
"cancelled",
"partially_cancelled"
],
"type": "string"
}
},
{
"description": "Only batches with exactly this label.",
"in": "query",
"name": "label",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/PayoutBatch"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List payout batches",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.payoutBatches.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.payout_batches.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.PayoutBatches.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a payout batch (/en/docs/api/payouts/create-payout-batch)
Accepts up to 1000 payouts in one request. Every item is checked for form first: one malformed item refuses the whole batch (400, param items[i].field) and nothing is created. The batch is then accepted and each item becomes, asynchronously and at most once, an ordinary payout with its own status and events, in index order. An item that cannot be paid does not stop the others: it is refused (status refused, error_code) when it never became a payout, or its payout fails (insufficient_funds) as a single payout would. A quote named by an item is used by that item from the moment the batch is accepted. A payout kill switch for the account refuses the whole batch (503). Repeating the request with the same Idempotency-Key returns the same batch and creates nothing.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/payout-batches",
"description": "Accepts up to 1000 payouts in one request. Every item is checked for form first: one malformed item refuses the whole batch (400, param items[i].field) and nothing is created. The batch is then accepted and each item becomes, asynchronously and at most once, an ordinary payout with its own status and events, in index order. An item that cannot be paid does not stop the others: it is refused (status refused, error_code) when it never became a payout, or its payout fails (insufficient_funds) as a single payout would. A quote named by an item is used by that item from the moment the batch is accepted. A payout kill switch for the account refuses the whole batch (503). Repeating the request with the same Idempotency-Key returns the same batch and creates nothing.",
"operationId": "createPayoutBatch",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatchCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatch"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatch"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a payout batch",
"tags": [
"Payouts"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payoutBatches.create({\n items: [],\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payout_batches.create(items=[], idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.PayoutBatches.Create(ctx, &caibopay.PayoutBatchCreate{}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a payout batch (/en/docs/api/payouts/get-payout-batch)
With its summary and totals, computed from its payouts as they are now. A payout whose outcome is not yet certain is counted as uncertain (its item is verification_pending) and keeps the batch processing; it is never sent again.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payout-batches/{id}",
"description": "With its summary and totals, computed from its payouts as they are now. A payout whose outcome is not yet certain is counted as uncertain (its item is verification_pending) and keeps the batch processing; it is never sent again.",
"operationId": "getPayoutBatch",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatch"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a payout batch",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payoutBatches.retrieve(\"pbat_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payout_batches.retrieve(\"pbat_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.PayoutBatches.Retrieve(ctx, \"pbat_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Cancel a payout batch (/en/docs/api/payouts/cancel-payout-batch)
Asks for the batch to be cancelled. Nothing that was sent is reversed. The request is recorded at once and carried out asynchronously, item by item: an item not yet issued is cancelled; an item whose payout has provably not reached a provider is cancelled with its payout (the payout fails with failure_code cancelled_before_submission and its funds are available again); every other item keeps its state, with not_cancelled_reason saying why (in_review, submitted, outcome_uncertain, already_completed, already_failed, already_returned, already_refused). A payout whose outcome is uncertain is never cancelled and never sent again. The answer is the batch as it is now: cancellation.status is in_progress until every item has its decision (event payout_batch.cancellation_finished); the batch then ends cancelled (no payout was executed), partially_cancelled (some were) or, when nothing could be cancelled, completed or completed_with_failures. Asking again, or for a batch that is already finished, changes nothing and returns the batch as it is.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/payout-batches/{id}/cancel",
"description": "Asks for the batch to be cancelled. Nothing that was sent is reversed. The request is recorded at once and carried out asynchronously, item by item: an item not yet issued is cancelled; an item whose payout has provably not reached a provider is cancelled with its payout (the payout fails with failure_code cancelled_before_submission and its funds are available again); every other item keeps its state, with not_cancelled_reason saying why (in_review, submitted, outcome_uncertain, already_completed, already_failed, already_returned, already_refused). A payout whose outcome is uncertain is never cancelled and never sent again. The answer is the batch as it is now: cancellation.status is in_progress until every item has its decision (event payout_batch.cancellation_finished); the batch then ends cancelled (no payout was executed), partially_cancelled (some were) or, when nothing could be cancelled, completed or completed_with_failures. Asking again, or for a batch that is already finished, changes nothing and returns the batch as it is.",
"operationId": "cancelPayoutBatch",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutBatch"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Cancel a payout batch",
"tags": [
"Payouts"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payoutBatches.cancel(\"pbat_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payout_batches.cancel(\"pbat_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.PayoutBatches.Cancel(ctx, \"pbat_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List the items of a payout batch (/en/docs/api/payouts/list-payout-batch-items)
In index order, each with its payout's status now, why it was refused, or what the batch's cancellation decided about it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payout-batches/{id}/items",
"description": "In index order, each with its payout's status now, why it was refused, or what the batch's cancellation decided about it.",
"operationId": "listPayoutBatchItems",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "The index of the last item received (the next_cursor of the previous page).",
"in": "query",
"name": "after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status: queued, refused, cancelled, processing, verification_pending, completed, failed or returned.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"queued",
"refused",
"cancelled",
"processing",
"verification_pending",
"completed",
"failed",
"returned"
],
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/PayoutBatchItem"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List the items of a payout batch",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.payoutBatches.listItems(\"pbat_...\")) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.payout_batches.list_items(\"pbat_...\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.PayoutBatches.ListItemsAll(ctx, \"pbat_...\", nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# List payouts (/en/docs/api/payouts/list-payouts)
Newest first. A list carries the payout without its detail (description, country, completed_at, failed_at, returned_at); retrieve a payout for it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payouts",
"description": "Newest first. A list carries the payout without its detail (description, country, completed_at, failed_at, returned_at); retrieve a payout for it.",
"operationId": "listPayouts",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"processing",
"verification_pending",
"completed",
"failed",
"returned",
"cancelled"
],
"type": "string"
}
},
{
"description": "Only the payouts to this beneficiary.",
"in": "query",
"name": "beneficiary_id",
"required": false,
"schema": {
"pattern": "^ben_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the payouts whose risk_status is this: allowed, in_review (funds held, waiting for a person), approved or rejected. A payout without a risk decision has no risk_status and matches none.",
"in": "query",
"name": "risk_status",
"required": false,
"schema": {
"enum": [
"allowed",
"in_review",
"approved",
"rejected"
],
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Payout"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List payouts",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.payouts.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.payouts.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Payouts.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a payout (/en/docs/api/payouts/create-payout)
Reserves the funds and accepts the payout; it is executed asynchronously. A payout the balance cannot fund is created with status failed and failure_code insufficient_funds. Repeating the request with the same Idempotency-Key returns the same payout and never pays twice.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/payouts",
"description": "Reserves the funds and accepts the payout; it is executed asynchronously. A payout the balance cannot fund is created with status failed and failure_code insufficient_funds. Repeating the request with the same Idempotency-Key returns the same payout and never pays twice.",
"operationId": "createPayout",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PayoutCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a payout",
"tags": [
"Payouts"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payouts.create({\n beneficiary_id: \"ben_...\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payouts.create(beneficiary_id=\"ben_...\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Payouts.Create(ctx, &caibopay.PayoutCreate{\n\tBeneficiaryID: \"ben_...\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a payout (/en/docs/api/payouts/get-payout)
With its detail: your own description, the country of the beneficiary's account, when it completed, failed, was returned or was cancelled, and its latest cancellation if one was asked for. Its story, step by step, is GET /v1/events?resource_id={id}. A payout whose submission's outcome is uncertain is verification_pending: its funds stay reserved, it is being verified with the provider, and nothing sends it again or in its place; it ends completed or failed on the provider's evidence. No request retries or cancels it.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/payouts/{id}",
"description": "With its detail: your own description, the country of the beneficiary's account, when it completed, failed, was returned or was cancelled, and its latest cancellation if one was asked for. Its story, step by step, is GET /v1/events?resource_id={id}. A payout whose submission's outcome is uncertain is verification_pending: its funds stay reserved, it is being verified with the provider, and nothing sends it again or in its place; it ends completed or failed on the provider's evidence. No request retries or cancels it.",
"operationId": "getPayout",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a payout",
"tags": [
"Payouts"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payouts.retrieve(\"pout_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payouts.retrieve(\"pout_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Payouts.Retrieve(ctx, \"pout_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Cancel a payout that was never sent (/en/docs/api/payouts/cancel-payout)
Asks for a payout to be cancelled. Only a payout nothing of which can have reached a provider is cancelled: it is processing, it was never sent (or every send is proven never to have left) and it is not waiting for a risk review. A payout that was sent, may have been sent (verification_pending), is final, waits for a risk review, or belongs to a payout batch or a remittance is refused with 409 payout_not_cancellable, reasons saying why (submitted, outcome_uncertain, already_completed, already_failed, already_returned, in_review, managed_by_batch, managed_by_remittance); nothing changes. The request is recorded at once and decided by the platform, under the payout's lock, before the payout would be sent: the answer is 202 with cancellation.status requested. Once cancelled, the payout's status is cancelled (failure_code cancelled_before_submission), its funds are available again and payout.cancelled is published; asking again, with any key, answers 200 with the cancelled payout. If the payout was sent in the meantime, cancellation.status becomes refused with not_cancelled_reason, and the payout goes on. Repeating the request with the same Idempotency-Key never cancels twice; the same key for another payout is 409 idempotency_key_reused.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/payouts/{id}/cancel",
"description": "Asks for a payout to be cancelled. Only a payout nothing of which can have reached a provider is cancelled: it is processing, it was never sent (or every send is proven never to have left) and it is not waiting for a risk review. A payout that was sent, may have been sent (verification_pending), is final, waits for a risk review, or belongs to a payout batch or a remittance is refused with 409 payout_not_cancellable, reasons saying why (submitted, outcome_uncertain, already_completed, already_failed, already_returned, in_review, managed_by_batch, managed_by_remittance); nothing changes. The request is recorded at once and decided by the platform, under the payout's lock, before the payout would be sent: the answer is 202 with cancellation.status requested. Once cancelled, the payout's status is cancelled (failure_code cancelled_before_submission), its funds are available again and payout.cancelled is published; asking again, with any key, answers 200 with the cancelled payout. If the payout was sent in the meantime, cancellation.status becomes refused with not_cancelled_reason, and the payout goes on. Repeating the request with the same Idempotency-Key never cancels twice; the same key for another payout is 409 idempotency_key_reused.",
"operationId": "cancelPayout",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "The payout is cancelled: by this request's decision or an earlier one."
},
"202": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Payout"
}
}
},
"description": "Accepted"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Cancel a payout that was never sent",
"tags": [
"Payouts"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.payouts.cancel(\"pout_...\", { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.payouts.cancel(\"pout_...\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Payouts.Cancel(ctx, \"pout_...\", caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Create a quote (/en/docs/api/quotes/create-quote)
Freezes a price for a short time. A quote is used by at most one payout.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/quotes",
"description": "Freezes a price for a short time. A quote is used by at most one payout.",
"operationId": "createQuote",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QuoteCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Quote"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Quote"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a quote",
"tags": [
"Quotes"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.quotes.create({\n amount: \"100.00\",\n amount_side: \"source\",\n destination_currency: \"PEN\",\n source_currency: \"USDT\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.quotes.create(amount=\"100.00\", amount_side=\"source\", destination_currency=\"PEN\", source_currency=\"USDT\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Quotes.Create(ctx, &caibopay.QuoteCreate{\n\tAmount: \"100.00\",\n\tAmountSide: \"source\",\n\tDestinationCurrency: \"PEN\",\n\tSourceCurrency: \"USDT\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a quote (/en/docs/api/quotes/get-quote)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/quotes/{id}",
"operationId": "getQuote",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Quote"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a quote",
"tags": [
"Quotes"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.quotes.retrieve(\"quo_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.quotes.retrieve(\"quo_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Quotes.Retrieve(ctx, \"quo_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List reconciliation exceptions (/en/docs/api/reconciliation/list-reconciliation-exceptions)
Inconsistencies the platform found about your own operations (a pay-in, a payout, a withdrawal, a refund, a settlement or a remittance) and is working on, newest first. Read-only: the platform's operators investigate and close them.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/reconciliation-exceptions",
"description": "Inconsistencies the platform found about your own operations (a pay-in, a payout, a withdrawal, a refund, a settlement or a remittance) and is working on, newest first. Read-only: the platform's operators investigate and close them.",
"operationId": "listReconciliationExceptions",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/ReconciliationException"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List reconciliation exceptions",
"tags": [
"Reconciliation"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.reconciliationExceptions.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.reconciliation_exceptions.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.ReconciliationExceptions.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Retrieve a reconciliation exception (/en/docs/api/reconciliation/get-reconciliation-exception)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/reconciliation-exceptions/{id}",
"operationId": "getReconciliationException",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReconciliationException"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a reconciliation exception",
"tags": [
"Reconciliation"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.reconciliationExceptions.retrieve(\"rex_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.reconciliation_exceptions.retrieve(\"rex_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.ReconciliationExceptions.Retrieve(ctx, \"rex_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List refunds (/en/docs/api/refunds/list-refunds)
Newest first.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/refunds",
"description": "Newest first.",
"operationId": "listRefunds",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"pending_review",
"processing",
"completed",
"failed"
],
"type": "string"
}
},
{
"description": "Only the refunds of this pay-in.",
"in": "query",
"name": "payin_id",
"required": false,
"schema": {
"pattern": "^pin_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Refund"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List refunds",
"tags": [
"Refunds"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.refunds.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.refunds.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Refunds.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Refund a pay-in (/en/docs/api/refunds/create-refund)
Sends part or all of a credited pay-in back to its payer, from the available balance, through the provider that received it. Reserves the funds and accepts the refund; it is executed asynchronously. A refund the platform's risk controls hold for a review is created with status pending_review: its funds are reserved and it counts against what is left to refund, but nothing is sent until it is approved; a refund they refuse is a 422 risk_blocked. Omit amount to refund everything that is left. Repeating the request with the same Idempotency-Key returns the same refund and never refunds twice.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/refunds",
"description": "Sends part or all of a credited pay-in back to its payer, from the available balance, through the provider that received it. Reserves the funds and accepts the refund; it is executed asynchronously. A refund the platform's risk controls hold for a review is created with status pending_review: its funds are reserved and it counts against what is left to refund, but nothing is sent until it is approved; a refund they refuse is a 422 risk_blocked. Omit amount to refund everything that is left. Repeating the request with the same Idempotency-Key returns the same refund and never refunds twice.",
"operationId": "createRefund",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RefundCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Refund"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Refund"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Refund a pay-in",
"tags": [
"Refunds"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.refunds.create({\n payin_id: \"pin_...\",\n reason_code: \"requested_by_customer\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.refunds.create(payin_id=\"pin_...\", reason_code=\"requested_by_customer\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Refunds.Create(ctx, &caibopay.RefundCreate{\n\tPayinID: \"pin_...\",\n\tReasonCode: \"requested_by_customer\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a refund (/en/docs/api/refunds/get-refund)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/refunds/{id}",
"operationId": "getRefund",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Refund"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a refund",
"tags": [
"Refunds"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.refunds.retrieve(\"rfd_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.refunds.retrieve(\"rfd_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Refunds.Retrieve(ctx, \"rfd_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List remittances (/en/docs/api/remittances/list-remittances)
Newest first. payin_id and payout_id find the remittance a pay-in funded or a payout pays: at most one.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/remittances",
"description": "Newest first. payin_id and payout_id find the remittance a pay-in funded or a payout pays: at most one.",
"operationId": "listRemittances",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"awaiting_funds",
"processing",
"verification_pending",
"review",
"completed",
"failed",
"returned"
],
"type": "string"
}
},
{
"description": "Only the remittances sent by this customer.",
"in": "query",
"name": "customer_id",
"required": false,
"schema": {
"pattern": "^cus_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the remittances to this beneficiary.",
"in": "query",
"name": "beneficiary_id",
"required": false,
"schema": {
"pattern": "^ben_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the remittance this pay-in funded.",
"in": "query",
"name": "payin_id",
"required": false,
"schema": {
"pattern": "^pin_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only the remittance this payout pays.",
"in": "query",
"name": "payout_id",
"required": false,
"schema": {
"pattern": "^pout_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Remittance"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List remittances",
"tags": [
"Remittances"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.remittances.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.remittances.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Remittances.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a remittance (/en/docs/api/remittances/create-remittance)
Sends a quote's destination amount to a beneficiary, funded by a deposit: either the next deposit into a funding account (source.funding_account_id; the remittance awaits it and the deposit must be credited before the quote expires) or a pay-in that already credited the balance (source.payin_id; a pay-in funds at most one remittance). The quote is used by the remittance from the moment it is created. The remittance never spends more than its pay-in credited. It is executed asynchronously and makes exactly one payout; while that payout's outcome is uncertain the remittance stays processing or review, and no second payout is ever made.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/remittances",
"description": "Sends a quote's destination amount to a beneficiary, funded by a deposit: either the next deposit into a funding account (source.funding_account_id; the remittance awaits it and the deposit must be credited before the quote expires) or a pay-in that already credited the balance (source.payin_id; a pay-in funds at most one remittance). The quote is used by the remittance from the moment it is created. The remittance never spends more than its pay-in credited. It is executed asynchronously and makes exactly one payout; while that payout's outcome is uncertain the remittance stays processing or review, and no second payout is ever made.",
"operationId": "createRemittance",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RemittanceCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Remittance"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Remittance"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a remittance",
"tags": [
"Remittances"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.remittances.create({\n beneficiary_id: \"ben_...\",\n quote_id: \"quo_...\",\n source: {},\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.remittances.create(beneficiary_id=\"ben_...\", quote_id=\"quo_...\", source={}, idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Remittances.Create(ctx, &caibopay.RemittanceCreate{\n\tBeneficiaryID: \"ben_...\",\n\tQuoteID: \"quo_...\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a remittance (/en/docs/api/remittances/get-remittance)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/remittances/{id}",
"operationId": "getRemittance",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Remittance"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a remittance",
"tags": [
"Remittances"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.remittances.retrieve(\"rem_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.remittances.retrieve(\"rem_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Remittances.Retrieve(ctx, \"rem_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Run a report (/en/docs/api/reports/get-report)
A read-only view of a period, never the authority for money (the ledger is). The answer says what it was computed from (source) and the instant it is complete up to (as_of). name is one of transactions, payins, payouts, remittances, refunds, withdrawals, settlements, fees, fx, balances. Row reports list what was created in [from, to), oldest first, in pages (pass next_cursor as after); balances is returned whole: per currency and balance, the opening at from, the credits and debits of the period and the closing at to, with opening + credits - debits = closing exactly. Every value is a string (amounts as decimal strings in the currency's precision, timestamps in UTC) or null. With format=csv the whole report is streamed as RFC 4180 CSV with a header row, as an attachment.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/reports/{name}",
"description": "A read-only view of a period, never the authority for money (the ledger is). The answer says what it was computed from (source) and the instant it is complete up to (as_of). name is one of transactions, payins, payouts, remittances, refunds, withdrawals, settlements, fees, fx, balances. Row reports list what was created in [from, to), oldest first, in pages (pass next_cursor as after); balances is returned whole: per currency and balance, the opening at from, the credits and debits of the period and the closing at to, with opening + credits - debits = closing exactly. Every value is a string (amounts as decimal strings in the currency's precision, timestamps in UTC) or null. With format=csv the whole report is streamed as RFC 4180 CSV with a header row, as an attachment.",
"operationId": "getReport",
"parameters": [
{
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
},
{
"description": "Required. The start of the period, inclusive (RFC 3339).",
"in": "query",
"name": "from",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Required. The end of the period, exclusive (RFC 3339). At most 366 days after from.",
"in": "query",
"name": "to",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only this currency.",
"in": "query",
"name": "currency",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "json (the default) or csv.",
"in": "query",
"name": "format",
"required": false,
"schema": {
"enum": [
"json",
"csv"
],
"type": "string"
}
},
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "The next_cursor of the previous page (JSON only; not for balances).",
"in": "query",
"name": "after",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"as_of": {
"description": "The instant the rows are complete up to: everything recorded before it is in them. Each page is computed on its own and has its own as_of; a CSV export is one snapshot.",
"format": "date-time",
"type": "string"
},
"data": {
"items": {
"$ref": "#/components/schemas/ReportRow"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
},
"source": {
"description": "What the rows were read from. live: the operations and the ledger themselves, in the snapshot of this request. view: a view over them, in the snapshot of this request. materialized: a stored copy, as fresh as as_of.",
"enum": [
"live",
"view",
"materialized"
],
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
},
"text/csv": {
"schema": {
"description": "RFC 4180 CSV: a header row with the column names, then one record per row; CRLF line endings.",
"type": "string"
}
}
},
"description": "OK",
"headers": {
"Content-Disposition": {
"description": "With format=csv: attachment; filename=\"__.csv\".",
"schema": {
"type": "string"
}
},
"Report-As-Of": {
"description": "With format=csv: the instant the export is complete up to (the as_of of a JSON page).",
"schema": {
"format": "date-time",
"type": "string"
}
},
"Report-Source": {
"description": "With format=csv: what the export was read from (the source of a JSON page).",
"schema": {
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Run a report",
"tags": [
"Reports"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.reports.retrieve(\"payouts\")) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.reports.retrieve(\"payouts\"):\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Reports.RetrieveAll(ctx, \"payouts\", nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Simulate a deposit into a funding account (/en/docs/api/sandbox/simulate-deposit)
Sandbox only. The simulated provider reports a deposit; it is verified and credited through the same path as a real one. Not served in live.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/sandbox/deposits",
"description": "Sandbox only. The simulated provider reports a deposit; it is verified and credited through the same path as a real one. Not served in live.",
"operationId": "simulateDeposit",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SandboxDeposit"
}
}
},
"required": true
},
"responses": {
"202": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SandboxDepositAccepted"
}
}
},
"description": "Accepted"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Simulate a deposit into a funding account",
"tags": [
"Sandbox"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.sandbox.simulateDeposit({\n amount: \"100.00\",\n funding_account_id: \"fa_...\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.sandbox.simulate_deposit(amount=\"100.00\", funding_account_id=\"fa_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Sandbox.SimulateDeposit(ctx, &caibopay.SandboxDeposit{\n\tAmount: \"100.00\",\n\tFundingAccountID: \"fa_...\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Read how the account is settled (/en/docs/api/settlements/get-settlement-configuration)
Whether and how settlements are generated, for the account and per currency. The account's state is unconfigured when no schedule is in force in any currency: nothing is settled automatically and the balance stays available until you withdraw it or the platform puts a schedule in force. Per currency, state is unconfigured (no schedule in force), active (the schedule in force generates settlements as its frequency says; automatic is false for a manual schedule, whose settlements are generated only on request to the platform) or unexecutable (a schedule is in force but cannot be executed now; reason says why, e.g. no_destination; settlements that fall due wait and are generated once it can). currencies lists every currency the account holds a balance in or has a schedule for; with the currency parameter, that currency alone, whatever the account holds.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlement-configuration",
"description": "Whether and how settlements are generated, for the account and per currency. The account's state is unconfigured when no schedule is in force in any currency: nothing is settled automatically and the balance stays available until you withdraw it or the platform puts a schedule in force. Per currency, state is unconfigured (no schedule in force), active (the schedule in force generates settlements as its frequency says; automatic is false for a manual schedule, whose settlements are generated only on request to the platform) or unexecutable (a schedule is in force but cannot be executed now; reason says why, e.g. no_destination; settlements that fall due wait and are generated once it can). currencies lists every currency the account holds a balance in or has a schedule for; with the currency parameter, that currency alone, whatever the account holds.",
"operationId": "getSettlementConfiguration",
"parameters": [
{
"description": "Only this currency. A currency without a schedule is answered as unconfigured.",
"in": "query",
"name": "currency",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementConfiguration"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Read how the account is settled",
"tags": [
"Settlements"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.settlements.configuration();"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.settlements.configuration()"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Settlements.Configuration(ctx, nil)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List settlement schedules (/en/docs/api/settlements/list-settlement-schedules)
The account's settlement terms per currency, as agreed in its contract: the one in force (status active) and those it replaced (closed), newest first. Read-only: a schedule carries the fee and the destination and is set by the platform; a change is a new schedule and applies from the period that is open: settlements that exist do not change. An empty list means no schedule was ever in force; GET /v1/settlement-configuration says so explicitly (unconfigured).
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlement-schedules",
"description": "The account's settlement terms per currency, as agreed in its contract: the one in force (status active) and those it replaced (closed), newest first. Read-only: a schedule carries the fee and the destination and is set by the platform; a change is a new schedule and applies from the period that is open: settlements that exist do not change. An empty list means no schedule was ever in force; GET /v1/settlement-configuration says so explicitly (unconfigured).",
"operationId": "listSettlementSchedules",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/SettlementSchedule"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List settlement schedules",
"tags": [
"Settlements"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.settlements.listSchedules()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.settlements.list_schedules():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Settlements.ListSchedules(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List settlements (/en/docs/api/settlements/list-settlements)
The periodic statements of what the account is owed, newest first. Each one is a closed (or still open) period of one currency: what accrued to the balance, the fee, the adjustments, and the net that is or was transferred to the account's settlement destination.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlements",
"description": "The periodic statements of what the account is owed, newest first. Each one is a closed (or still open) period of one currency: what accrued to the balance, the fee, the adjustments, and the net that is or was transferred to the account's settlement destination.",
"operationId": "listSettlements",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only settlements in this currency.",
"in": "query",
"name": "currency",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only periods ending after this RFC 3339 timestamp.",
"in": "query",
"name": "period_from",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only periods starting before this RFC 3339 timestamp.",
"in": "query",
"name": "period_to",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"pending",
"ready",
"processing",
"settled",
"on_hold",
"failed",
"disputed"
],
"type": "string"
}
},
{
"description": "Only settlements generated under this schedule.",
"in": "query",
"name": "schedule_id",
"required": false,
"schema": {
"pattern": "^stls_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Settlement"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List settlements",
"tags": [
"Settlements"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.settlements.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.settlements.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Settlements.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Retrieve a settlement (/en/docs/api/settlements/get-settlement)
With its items: the ledger journals its figures are made of.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlements/{id}",
"description": "With its items: the ledger journals its figures are made of.",
"operationId": "getSettlement",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Settlement"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a settlement",
"tags": [
"Settlements"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.settlements.retrieve(\"stl_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.settlements.retrieve(\"stl_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Settlements.Retrieve(ctx, \"stl_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List settlement destinations (/en/docs/api/withdrawals/list-settlement-destinations)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlement-destinations",
"operationId": "listSettlementDestinations",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/SettlementDestination"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List settlement destinations",
"tags": [
"Withdrawals"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.settlementDestinations.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.settlement_destinations.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.SettlementDestinations.List(ctx)\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Create a settlement destination (/en/docs/api/withdrawals/create-settlement-destination)
Registers an account of your own that withdrawals go to. The same account registered twice is the same destination (200 with the existing one). Account details are write-only.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/settlement-destinations",
"description": "Registers an account of your own that withdrawals go to. The same account registered twice is the same destination (200 with the existing one). Account details are write-only.",
"operationId": "createSettlementDestination",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementDestinationCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementDestination"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementDestination"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a settlement destination",
"tags": [
"Withdrawals"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.settlementDestinations.create({\n currency: \"PEN\",\n details: {},\n method: \"bank_transfer\",\n});"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.settlement_destinations.create(currency=\"PEN\", details={}, method=\"bank_transfer\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.SettlementDestinations.Create(ctx, &caibopay.SettlementDestinationCreate{\n\tCurrency: \"PEN\",\n\tMethod: \"bank_transfer\",\n})\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a settlement destination (/en/docs/api/withdrawals/get-settlement-destination)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/settlement-destinations/{id}",
"operationId": "getSettlementDestination",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SettlementDestination"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a settlement destination",
"tags": [
"Withdrawals"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.settlementDestinations.retrieve(\"dest_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.settlement_destinations.retrieve(\"dest_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.SettlementDestinations.Retrieve(ctx, \"dest_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# List withdrawals (/en/docs/api/withdrawals/list-withdrawals)
Newest first.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/withdrawals",
"description": "Newest first.",
"operationId": "listWithdrawals",
"parameters": [
{
"description": "Maximum number of items to return.",
"in": "query",
"name": "limit",
"required": false,
"schema": {
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
{
"description": "Return items after this id (the next_cursor of the previous page).",
"in": "query",
"name": "starting_after",
"required": false,
"schema": {
"type": "string"
}
},
{
"description": "Only items with this status.",
"in": "query",
"name": "status",
"required": false,
"schema": {
"enum": [
"pending_approval",
"processing",
"completed",
"failed",
"cancelled"
],
"type": "string"
}
},
{
"description": "Only the withdrawals to this settlement destination.",
"in": "query",
"name": "destination_id",
"required": false,
"schema": {
"pattern": "^dest_[0-9a-z]+$",
"type": "string"
}
},
{
"description": "Only items created at or after this RFC 3339 timestamp.",
"in": "query",
"name": "created_after",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
},
{
"description": "Only items created before this RFC 3339 timestamp.",
"in": "query",
"name": "created_before",
"required": false,
"schema": {
"format": "date-time",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"properties": {
"data": {
"items": {
"$ref": "#/components/schemas/Withdrawal"
},
"type": "array"
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": "string"
}
},
"required": [
"data",
"has_more"
],
"type": "object"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "List withdrawals",
"tags": [
"Withdrawals"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nfor await (const item of caibo.withdrawals.list()) {\n console.log(item);\n}"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nfor item in client.withdrawals.list():\n print(item)"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nfor item, err := range client.Withdrawals.ListAll(ctx, nil) {\n\tif err != nil {\n\t\treturn err\n\t}\n\tfmt.Println(item)\n}"
}
]
}
```
# Create a withdrawal (/en/docs/api/withdrawals/create-withdrawal)
Holds the amount plus the fee from the available balance and sends it to one of your settlement destinations, in the destination's currency, asynchronously. The fee is fixed when the withdrawal is created and stated in the response (fee, total); the balance must cover both. A withdrawal the balance cannot fund is created with status failed and failure_code insufficient_funds. Above the account's approval threshold it is created pending_approval and waits for the platform's operators. Repeating the request with the same Idempotency-Key returns the same withdrawal and never sends twice.
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "POST",
"path": "/v1/withdrawals",
"description": "Holds the amount plus the fee from the available balance and sends it to one of your settlement destinations, in the destination's currency, asynchronously. The fee is fixed when the withdrawal is created and stated in the response (fee, total); the balance must cover both. A withdrawal the balance cannot fund is created with status failed and failure_code insufficient_funds. Above the account's approval threshold it is created pending_approval and waits for the platform's operators. Repeating the request with the same Idempotency-Key returns the same withdrawal and never sends twice.",
"operationId": "createWithdrawal",
"parameters": [
{
"$ref": "#/components/parameters/IdempotencyKey"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WithdrawalCreate"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Withdrawal"
}
}
},
"description": "The request was already made: the existing resource is returned.",
"headers": {
"Idempotent-Replayed": {
"schema": {
"enum": [
"true"
],
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Withdrawal"
}
}
},
"description": "Created"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The Idempotency-Key was used with a different request, or the resource is in conflict."
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is well formed but cannot be carried out."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Create a withdrawal",
"tags": [
"Withdrawals"
],
"x-required-scope": "write",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.withdrawals.create({\n amount: \"100.00\",\n destination_id: \"dest_...\",\n}, { idempotencyKey: \"your-operation-id\" });"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.withdrawals.create(amount=\"100.00\", destination_id=\"dest_...\", idempotency_key=\"your-operation-id\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Withdrawals.Create(ctx, &caibopay.WithdrawalCreate{\n\tAmount: \"100.00\",\n\tDestinationID: \"dest_...\",\n}, caibopay.WithIdempotencyKey(\"your-operation-id\"))\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```
# Retrieve a withdrawal (/en/docs/api/withdrawals/get-withdrawal)
The operation, from the OpenAPI contract (https://docs.caibopay.app/openapi.json):
```json
{
"method": "GET",
"path": "/v1/withdrawals/{id}",
"operationId": "getWithdrawal",
"parameters": [
{
"in": "path",
"name": "id",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Withdrawal"
}
}
},
"description": "OK"
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The request is not valid."
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key is missing or not valid."
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "The API key lacks the required scope."
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "No such resource."
},
"429": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Too many requests."
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "An error on our side. Safe to retry with the same Idempotency-Key."
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ErrorResponse"
}
}
},
"description": "Temporarily unavailable or suspended. Safe to retry with the same Idempotency-Key."
}
},
"summary": "Retrieve a withdrawal",
"tags": [
"Withdrawals"
],
"x-required-scope": "read",
"x-codeSamples": [
{
"lang": "js",
"label": "Node.js",
"source": "import { Caibo } from \"caibopay\";\n\nconst caibo = new Caibo(process.env.CAIBO_API_KEY);\n\nconst result = await caibo.withdrawals.retrieve(\"wdr_...\");"
},
{
"lang": "python",
"label": "Python",
"source": "import os\n\nimport caibopay\n\nclient = caibopay.Client(os.environ[\"CAIBO_API_KEY\"])\n\nresult = client.withdrawals.retrieve(\"wdr_...\")"
},
{
"lang": "go",
"label": "Go",
"source": "client, err := caibopay.NewClient(os.Getenv(\"CAIBO_API_KEY\"))\nif err != nil {\n\treturn err\n}\nctx := context.Background()\n\nresult, err := client.Withdrawals.Retrieve(ctx, \"wdr_...\")\nif err != nil {\n\treturn err\n}\nfmt.Println(result)"
}
]
}
```