> ## Documentation Index
> Fetch the complete documentation index at: https://docs.onepay.la/llms.txt
> Use this file to discover all available pages before exploring further.

# Empresas y métodos de pago

> Errores de empresas, clientes, cuentas bancarias y tarjetas.

Esta página cubre [Empresas](/client/companies/create) y Métodos de pago: [clientes](/client/customers/index), [cuentas bancarias](/client/accounts/index) y [tarjetas](/client/cards/index). Además de lo que se lista acá, cualquiera de estos endpoints puede devolver los [errores comunes](/client/base/errors/common). Los que tienen un ID en la ruta también responden `404 record_not_found` si el ID no es un UUID, y `404 environment_key_mismatch` si el recurso es del otro ambiente.

**Endpoints:** [Empresas](#empresas) · [Clientes](#clientes) · [Cuentas bancarias](#cuentas-bancarias) · [Tarjetas](#tarjetas)

## Empresas

### Crear una empresa

`POST /companies` · [Referencia](/client/companies/create)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10001`<br />`validation_error` | 422 | El campo nombre es obligatorio. | Falta un campo obligatorio o tiene un formato inválido (`type`, `name`, `legal_name`, documento, `phone` en E.164, `email`, `website`, `economic_activity` de 4 dígitos, `sales`, responsabilidades fiscales, `city_id`, dirección, documentos o datos del representante). | Revisa `errors` y corrige el cuerpo. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | El tipo de documento no es válido para el tipo de compañía seleccionado. | `organization` exige NIT o RUT; `individual` exige CC, CE, PPT, PEP o PASSPORT. | Ajusta `document_type` al `type`. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | El banco seleccionado no soporta el tipo de cuenta. | `account.type` no es un tipo que ese banco soporte. | Cambia el tipo de cuenta o el banco. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | El nombre no puede contener los caracteres \< o >. | `name` o `legal_name` trae `<`, `>` o caracteres de control. | Envía el nombre en texto plano. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | No se pudo descargar el documento proporcionado. | La URL de un documento respondió con error. El detalle llega en `errors.documents.*`. | Envía una URL pública que se pueda descargar. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | No se pudo guardar el documento. | Falló el guardado del documento en OnePay. | Reintenta. | Sí, con espera |
| Sin código | 500 | Server Error | La URL de un documento no respondió a tiempo. La empresa no se crea. | Usa URLs que respondan en menos de 10 segundos y reintenta. | Sí, tras corregir |

### Listar departamentos

`GET /states` · [Referencia](/client/companies/list-states)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| Sin código | 400 | Requested filter(s) \`...\` are not allowed. Allowed filter(s) are \`name\`. | Enviaste un filtro que no existe. | Usa solo `filter[name]`. | Sí, tras corregir |
| Sin código | 400 | Requested sort(s) \`...\` is not allowed. Allowed sort(s) are \`name\`. | Enviaste un orden que no existe. | Usa `sort=name` o `sort=-name`. | Sí, tras corregir |

### Listar ciudades

`GET /cities` · [Referencia](/client/companies/list-cities)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| Sin código | 400 | Requested filter(s) \`...\` are not allowed. Allowed filter(s) are \`name, state\_id\`. | Enviaste un filtro que no existe. | Usa solo `filter[name]` o `filter[state_id]`. | Sí, tras corregir |
| Sin código | 400 | Requested sort(s) \`...\` is not allowed. Allowed sort(s) are \`name\`. | Enviaste un orden que no existe. | Usa `sort=name` o `sort=-name`. | Sí, tras corregir |
| Sin código | 500 | Server Error | `filter[state_id]` no es numérico. | Envía el `id` numérico de [listar departamentos](/client/companies/list-states). | Sí, tras corregir |

## Clientes

### Listar clientes

`GET /customers` · [Referencia](/client/customers/list)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| Sin código | 400 | El método QUERY requiere Content-Type: application/json. | Usaste el método `QUERY` sin `Content-Type: application/json`. | Agrega el header o usa `GET` con parámetros en la URL. | Sí, tras corregir |
| Sin código | 400 | El cuerpo del método QUERY no es JSON válido. | El cuerpo de la petición `QUERY` no es un JSON válido. | Envía un objeto JSON bien formado. | Sí, tras corregir |

### Detalle, eliminar, cuentas, tarjetas y tarjetas emitidas de un cliente

`GET /customers/{customer_id}` · [Referencia](/client/customers/detail)<br />
`DELETE /customers/{customer_id}` · [Referencia](/client/customers/delete)<br />
`GET /customers/{customer_id}/accounts` · [Referencia](/client/customers/accounts)<br />
`GET /customers/{customer_id}/cards` · [Referencia](/client/customers/cards)<br />
`GET /customers/{customer_id}/issuing-cards` · [Referencia](/client/customers/issuing-cards)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10002`<br />`record_not_found` | 404 | Registro no encontrado, Cliente no existe | El cliente no existe, se eliminó o es de otra empresa. Un segundo `DELETE` sobre el mismo cliente también responde esto. | Revisa el `customer_id`. | No |

### Crear un cliente

`POST /customers` · [Referencia](/client/customers/create)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10001`<br />`validation_error` | 422 | El campo nombre es obligatorio. | Falta un campo obligatorio o tiene un formato inválido: `first_name`, `last_name`, `user_type`, `document_type`, `document_number`, y `phone` y `email` si no envías `related_to`. | Revisa `errors` y corrige el cuerpo. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | The document type must be NIT or RUT when user\_type is company. | `user_type` es `company` y `document_type` no es NIT ni RUT. | Usa NIT o RUT, o cambia `user_type` a `natural`. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | El teléfono debe estar en formato E.164 (ej: +573001234567). | `phone` no tiene la forma `+<indicativo><número>` o no es un número válido para su país. | Envía el teléfono en E.164. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | El related to seleccionado es inválido. | `related_to` no es un cliente tuyo, se eliminó, o es de prueba y usas la llave de producción. | Envía el `id` de un cliente tuyo del mismo ambiente. | Sí, tras corregir |
| Sin código | 500 | Server Error | Enviaste el objeto `account` incompleto. El cliente sí queda creado o actualizado. | Envía `account` con `bank_id`, `subtype` y `account_number` juntos, o no lo envíes. | Sí, tras corregir |

Si ya existe un cliente con el mismo documento (o el mismo correo), la respuesta es `200` con el cliente existente: no es un error. Mira [Crear clientes](/client/customers/create).

## Cuentas bancarias

### Listar cuentas

`GET /accounts` · [Referencia](/client/accounts/list)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| Sin código | 400 | Requested filter(s) \`...\` are not allowed. Allowed filter(s) are \`id, bank\_id, subtype, status, label\`. | Enviaste un filtro que no existe. | Usa solo los filtros de la lista. | Sí, tras corregir |
| Sin código | 400 | Requested sort(s) \`...\` is not allowed. Allowed sort(s) are \`created\_at, id\`. | Enviaste un orden que no existe. | Ordena por `created_at` o `id`. | Sí, tras corregir |
| Sin código | 500 | Server Error | Usaste `filter[id]` o `filter[bank_id]`. Hoy esos dos filtros fallan. | Filtra por `subtype`, `status` o `label`; para una cuenta puntual usa el detalle. | No |

### Detalle y eliminar una cuenta

`GET /accounts/{account_id}` · [Referencia](/client/accounts/detail)<br />
`DELETE /accounts/{account_id}` · [Referencia](/client/accounts/delete)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10002`<br />`record_not_found` | 404 | Registro no encontrado, Cuenta no existe | La cuenta no existe, se eliminó o es de otra empresa. | Revisa el `account_id`. | No |

### Crear una cuenta

`POST /accounts` · [Referencia](/client/accounts/create) · [Crear llave Bre-B](/client/accounts/create-breb)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10001`<br />`validation_error` | 422 | El customer id seleccionado es inválido. | Un campo falta o no es válido: `customer_id` (un cliente tuyo del mismo ambiente), `bank_id` (obligatorio salvo para llaves), `subtype` o `account_number`. | Revisa `errors` y corrige el cuerpo. | Sí, tras corregir |
| `10001`<br />`validation_error` | 422 | La llave BreB no existe o no está disponible en este momento. | La llave no existe en el directorio Bre-B, o el directorio no respondió. También: «La llave BreB no está activa.» y «La llave BreB no corresponde al documento del cliente.». | Revisa la llave con el beneficiario. Si estás seguro de que existe, reintenta en unos minutos. | Sí, tras revisar |
| `10002`<br />`record_not_found` | 404 | Registro no encontrado, Bank no existe | `bank_id` tiene formato de UUID pero no es un banco de OnePay. | Toma el `bank_id` de [listar bancos](/client/accounts/list-banks). | Sí, tras corregir |
| `10003`<br />`account_validation_error` | 400 | Error al validar la cuenta | Cuenta Nequi cuyo número no es un celular colombiano de 10 dígitos. | Envía el celular de 10 dígitos de la cuenta Nequi. | Sí, tras corregir |
| Sin código | 500 | Server Error | Otra petición idéntica estaba creando la misma cuenta al mismo tiempo. | Reintenta en unos segundos: si la cuenta ya se creó, la recibes. | Sí, con espera |

Esta ruta acepta la llave pública (`pk_`).

### Validar una cuenta

`POST /accounts/{account_id}/validate` · [Referencia](/client/accounts/validate)

Este endpoint solo valida cuentas Daviplata. Algunos de sus errores usan un cuerpo distinto: `{"error": "...", "message": "..."}`.

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10002`<br />`record_not_found` | 404 | Registro no encontrado, Cuenta no existe | La cuenta no existe o se eliminó. | Revisa el `account_id`. | No |
| `10001`<br />`validation_error` | 422 | La cuenta ya ha sido validada previamente. | La cuenta ya no está pendiente de validación. | Nada: la cuenta ya está validada. | No |
| `10001`<br />`validation_error` | 422 | El OTP es requerido para validar cuentas de Daviplata. | Falta `otp` o no tiene 6 dígitos. | Envía el OTP de 6 dígitos que recibió el titular. | Sí, tras corregir |
| Sin código | 400 | `{"error": "Banco no soportado para validación"}` | La cuenta no es Daviplata. | No uses este endpoint para otros bancos. | No |
| Sin código | 500 | `{"error": "Error al validar la cuenta de Daviplata", "message": "Autenticación Denegada - OTP invalido"}` | El OTP no es correcto. | Pide al titular un OTP nuevo y reintenta. | Sí, con otro OTP |
| Sin código | 500 | `{"error": "Error al validar la cuenta de Daviplata", "message": "El OTP de la transacción ha expirado, por favor inicie nuevamente el proceso."}` | El OTP venció. | Reinicia la inscripción de la cuenta para generar un OTP nuevo. | Sí, tras reiniciar |
| Sin código | 500 | `{"error": "Error al validar la cuenta de Daviplata", "message": "..."}` | Daviplata falló por otra razón. | Reintenta más tarde. Si persiste, escribe a soporte. | Sí, con espera |

### Actualizar una cuenta

`PUT /accounts/{account_id}` · [Referencia](/client/accounts/update)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| Sin código | 405 | The PUT method is not supported for route v1/accounts/... | La API no permite actualizar cuentas. | Elimina la cuenta y créala de nuevo con los datos corregidos. | No |

### Listar bancos

`GET /banks` · [Referencia](/client/accounts/list-banks)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| Sin código | 400 | Requested filter(s) \`...\` are not allowed. Allowed filter(s) are \`name, available, connection\_type, pse\`. | Enviaste un filtro que no existe. | Usa solo los filtros de la lista. | Sí, tras corregir |
| Sin código | 400 | Requested sort(s) \`...\` is not allowed. Allowed sort(s) are \`priority, name\`. | Enviaste un orden que no existe. | Ordena por `priority` o `name`. | Sí, tras corregir |
| Sin código | 500 | Server Error | Usaste `filter[available]`. Hoy ese filtro falla. | Filtra por el campo `available` de la respuesta. | No |

### Consultar una llave Bre-B

`GET /accounts/bre-b/{key}` · [Referencia](/client/accounts/bre-b-keys)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10002`<br />`record_not_found` | 404 | Registro no encontrado, llave no existe | La llave no existe en el directorio Bre-B. | Revisa la llave con el beneficiario. | No |
| `90006`<br />`breb_directory_unavailable` | 503 | No fue posible consultar el directorio Bre-B. Intenta de nuevo en unos segundos. | El directorio Bre-B no respondió. | Reintenta en unos segundos. | Sí, con espera |
| Sin código | 500 | Server Error | El titular de la llave tiene un tipo de documento que OnePay no reconoce. | Escribe a soporte con la llave. | No |

## Tarjetas

Los errores de tarjeta (`101xx`) solo salen en producción: con la llave de pruebas la tarjeta se crea sin pasar por la bóveda.

### Crear una tarjeta

`POST https://cards.onepay.la/v1/cards` · [Referencia](/client/cards/create)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10001`<br />`validation_error` | 422 | El número de la tarjeta es inválido. | Un campo no es válido: número de tarjeta, CVV, vencimiento («El año de expiración de la tarjeta es inválido.»), `holder_name` (5 a 40), `customer_id` (un cliente tuyo del mismo ambiente) o `authorization`. | Revisa `errors` y corrige el cuerpo. | Sí, tras corregir |
| `10100`<br />`card_generic` | 422 | Los datos de la tarjeta son inválidos. | La bóveda de tarjetas rechazó los datos. | Revisa los datos de la tarjeta y reintenta. | Sí, tras corregir |
| `10104`<br />`card_number` | 422 | Número de tarjeta inválido. | La tarjeta fue rechazada al tokenizarla. | Pide otra tarjeta o que revise el número. | Sí, tras corregir |
| `10122`<br />`card_expired` | 422 | Tarjeta expirada, Pídele al usuario que actualice su tarjeta. | La fecha de vencimiento no es válida. | Pide la fecha correcta o una tarjeta vigente. | Sí, tras corregir |
| `10102`<br />`card_cvv` | 422 | CVV inválido. | El código de seguridad no es válido. | Pide que vuelva a ingresar el CVV. | Sí, tras corregir |
| `10002`<br />`record_not_found` | 404 | Registro no encontrado | No se pudo leer la tarjeta en la bóveda (falló la conexión o el token venció). | Reintenta con espera. | Sí, con espera |
| Sin código | 500 | Server Error | Falló la tokenización de la tarjeta. | Reintenta con espera. Revisa [listar tarjetas](/client/cards/list) antes: la tarjeta puede haber quedado creada. | Sí, tras verificar |

Esta ruta acepta la llave pública (`pk_`).

### Crear una tarjeta tokenizada

`POST /cards/tokenized` · [Referencia](/client/cards/create-tokenized)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10001`<br />`validation_error` | 422 | El campo card token es obligatorio. | Falta `card_token` o no es un UUID, o `customer_id` no es un cliente tuyo del mismo ambiente. | Revisa `errors` y corrige el cuerpo. | Sí, tras corregir |
| `10104`<br />`card_number` | 422 | Número de tarjeta inválido. | La tarjeta fue rechazada al tokenizarla. | Pide otra tarjeta y genera un token nuevo. | Sí, con otro token |
| `10122`<br />`card_expired` | 422 | Tarjeta expirada, Pídele al usuario que actualice su tarjeta. | La fecha de vencimiento no es válida. | Pide la fecha correcta o una tarjeta vigente. | Sí, tras corregir |
| `10102`<br />`card_cvv` | 422 | CVV inválido. | El código de seguridad no es válido. | Pide que vuelva a ingresar el CVV. | Sí, tras corregir |
| `10002`<br />`record_not_found` | 404 | Registro no encontrado | No se pudo leer el token temporal (venció o falló la conexión con la bóveda). | Genera un token nuevo y reintenta. | Sí, con otro token |
| Sin código | 500 | Server Error | Falló la tokenización de la tarjeta. | Reintenta con espera. Revisa [listar tarjetas](/client/cards/list) antes. | Sí, tras verificar |

Esta ruta acepta la llave pública (`pk_`).

### Listar tarjetas

`GET /cards` · [Referencia](/client/cards/list)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| Sin código | 400 | Requested filter(s) \`...\` are not allowed. Allowed filter(s) are \`customer\_id\`. | Enviaste un filtro que no existe. | Usa solo `filter[customer_id]`. | Sí, tras corregir |
| Sin código | 400 | Requested sort(s) \`...\` is not allowed. Allowed sort(s) are \`created\_at\`. | Enviaste un orden que no existe. | Ordena por `created_at`. | Sí, tras corregir |

### Detalle y eliminar una tarjeta

`GET /cards/{card_id}` · [Referencia](/client/cards/detail)<br />
`DELETE /cards/{card_id}` · [Referencia](/client/cards/delete)

| Código | HTTP | Mensaje | Causa probable | Qué hacer | ¿Reintentar? |
| - | - | - | - | - | - |
| `10002`<br />`record_not_found` | 404 | Registro no encontrado, CreditCard no existe | La tarjeta no existe, se eliminó o es de otra empresa. Un segundo `DELETE` también responde esto. | Revisa el `card_id` con [listar tarjetas](/client/cards/list). | No |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.