Crea o actualiza un cliente
POST /v1/clientes
Devuelve el id del cliente, que es lo que piden las tarjetas, los cobros y las suscripciones.
Es un upsert: reintentar es seguro
El cliente se busca primero por referenciaIntegrador (tu id del cliente) y, si no, por su documento. Si existe, se actualiza con lo que mandes (lo que omitís se conserva) y responde 200; si no, se crea y responde 201. meta.creado dice cuál de los dos pasó. Tenés que mandar al menos una de las dos identidades: sin ninguna, un reintento crearía un duplicado.
El documento es opcional
Para guardarle una tarjeta o cobrarle no hace falta su documento. Sólo se necesita para identificarlo en un comprobante: sin documento, un e-Ticket le sale como consumidor final y una e-Factura lo rechaza (exige RUC). Se lo podés agregar después con otra llamada.
| Campo | Obligatorio | Descripción |
|---|---|---|
nombre | sí | Nombre o razón social (hasta 150). |
referenciaIntegrador | uno de los dos | Tu id del cliente. Único por empresa. Letras, dígitos y . _ : / -, hasta 128. |
tipoDocumento + documento | uno de los dos | Van juntos. RUC, CI, Pasaporte, DNI, NIFE, NIE u Otros. Se valida el dígito verificador. |
email, telefono | no | Contacto. |
direccion, ciudad, departamento | no | Salen en el comprobante. |
pais | no | ISO de 2 letras. Por defecto UY. |
Cualquier otro campo es un 422: la lista es cerrada.
Alcance requerido:
clientes:escribir. Si la credencial no lo tiene, la respuesta es403 API_ALCANCE_INSUFICIENTEcon la lista enerror.requerido. Las credenciales creadas antes del modelo de alcances (alcances: null) conservan acceso total.
Autorizaciones
Sección titulada «Autorizaciones »Parámetros
Sección titulada « Parámetros »Parámetros de header
Sección titulada «Parámetros de header »Ejemplo
0199d1b0-0000-7000-8000-000000000000Sólo para credenciales de cuenta proveedora (revendedor). UUID de la subcuenta de la cartera sobre la que se quiere operar: la cuenta efectiva del request pasa a ser esa.
Una credencial que no es de proveedor, o una subcuenta que no está en su cartera, recibe 403 API_CUENTA_FUERA_DE_CARTERA. Sin la cabecera, la cuenta es siempre la de la credencial.
Cuerpo de la solicitud
Sección titulada «Cuerpo de la solicitud »Cliente. Mínimo: nombre y referenciaIntegrador (o el documento).
object
Ejemplos
Sólo para cobrarle (sin documento)
{ "nombre": "Ana Pérez", "referenciaIntegrador": "usuario-4821", "email": "ana@ejemplo.com"}Empresa, para emitirle e-Factura
{ "nombre": "Ejemplo SA", "referenciaIntegrador": "empresa-77", "tipoDocumento": "RUC", "documento": "211234560019", "direccion": "Av. 18 de Julio 1234", "ciudad": "Montevideo", "departamento": "Montevideo"}Respuestas
Sección titulada « Respuestas »Ya existía: se actualizó
object
Ejemplos
{ "data": { "id": "7e6d5c4b-3a2f-4e1d-9c8b-7a6f5e4d3c2b", "nombre": "Ana Pérez", "referenciaIntegrador": "usuario-4821", "tipoDocumento": null, "documento": null, "email": "ana@ejemplo.com", "telefono": "099123456", "direccion": null, "ciudad": null, "departamento": null, "pais": "UY", "fechaCreacion": "2026-09-28T13:05:00.000Z", "fechaActualizacion": "2026-09-28T13:05:00.000Z" }, "meta": { "creado": false }}Creado
object
Ejemplos
{ "data": { "id": "7e6d5c4b-3a2f-4e1d-9c8b-7a6f5e4d3c2b", "nombre": "Ana Pérez", "referenciaIntegrador": "usuario-4821", "tipoDocumento": null, "documento": null, "email": "ana@ejemplo.com", "telefono": "099123456", "direccion": null, "ciudad": null, "departamento": null, "pais": "UY", "fechaCreacion": "2026-09-28T13:05:00.000Z", "fechaActualizacion": "2026-09-28T13:05:00.000Z" }, "meta": { "creado": true }}No autenticado. La API_KEY no fue enviada, no es válida o la credencial está desactivada.
Códigos posibles: API_AUTH_HEADER_MISSING, API_AUTH_HEADER_INVALID, API_ACCESS_INVALID.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Falta header Authorization
{ "error": { "code": "API_AUTH_HEADER_MISSING", "message": "Se esperaba la cabecera Authorization con esquema Bearer" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}Secret key inválida o revocada
{ "error": { "code": "API_ACCESS_INVALID", "message": "Acceso no autorizado" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}Acceso prohibido. La credencial es válida pero algo del contexto lo impide. Las cinco causas se corrigen de forma distinta y ninguna se arregla reintentando:
| Code | Qué pasó | Cómo se corrige |
|---|---|---|
API_FEATURE_DISABLED | La cuenta no tiene la API habilitada en su plan | Pedir la habilitación a soporte o al proveedor |
API_ALCANCE_INSUFICIENTE | La credencial no tiene el alcance de la operación (va en error.requerido) | Editar la credencial en Integraciones → API |
API_ALCANCE_NO_DISPONIBLE | La credencial tiene el alcance pero la cuenta no lo admite: sin cobros habilitados (pagos:*), sin facturación (cfe:*) o no es cuenta proveedora (webhooks:gestionar). Va en error.details | Pedir la habilitación a soporte o al proveedor |
API_ACCESS_BRANCH_MISMATCH | x-branch-id distinto de la sucursal fijada en la credencial | Quitar la cabecera o usar otra credencial |
API_CUENTA_FUERA_DE_CARTERA | x-cuenta-id apunta a una cuenta que no es de la cartera | Revisar el UUID de la subcuenta |
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Falta el alcance
{ "error": { "code": "API_ALCANCE_INSUFICIENTE", "message": "La credencial de API no tiene ninguno de los alcances necesarios para esta operación (pagos:cobrar)", "requerido": [ "pagos:cobrar" ] }, "requestId": "3f6b1c2e-9a4d-4f80-bc11-7e2d5a8f0c31"}La cuenta no admite el alcance
{ "error": { "code": "API_ALCANCE_NO_DISPONIBLE", "message": "Disponible sólo para cuentas proveedoras. La credencial tiene el permiso, pero la cuenta no puede usarlo.", "details": { "alcances": [ "webhooks:gestionar" ], "motivo": "SOLO_REVENDEDOR" } }, "requestId": "3f6b1c2e-9a4d-4f80-bc11-7e2d5a8f0c31"}La cuenta no tiene la API habilitada
{ "error": { "code": "API_FEATURE_DISABLED", "message": "El plan de esta cuenta no tiene habilitado el acceso a la API" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}Header x-branch-id distinto al fijo del ApiAccess
{ "error": { "code": "API_ACCESS_BRANCH_MISMATCH", "message": "El ApiAccess está fijado a otra sucursal y no coincide con x-branch-id" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}x-cuenta-id fuera de la cartera
{ "error": { "code": "API_CUENTA_FUERA_DE_CARTERA", "message": "La cuenta indicada en 'x-cuenta-id' no pertenece a la cartera de esta credencial" }, "requestId": "3f6b1c2e-9a4d-4f80-bc11-7e2d5a8f0c31"}Las dos identidades se contradicen: la referencia ya es de un cliente con otro documento (CLIENTE_DOCUMENTO_DISTINTO), el documento ya es de otro cliente (CLIENTE_DOCUMENTO_EN_USO) o el cliente de ese documento ya tiene otra referencia (CLIENTE_REFERENCIA_EN_CONFLICTO). error.details.clienteId es el cliente existente.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Documento de otro cliente
{ "error": { "code": "CLIENTE_DOCUMENTO_EN_USO", "message": "El documento RUC 211234560019 ya es de otro cliente de la cuenta", "details": { "clienteId": "3a2f1e0d-9c8b-4a7f-8e6d-5c4b3a2f1e0d" } }, "requestId": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"}Cuerpo inválido (VALIDATION_ERROR) o documento con dígito verificador incorrecto (CLIENTE_DOCUMENTO_INVALIDO).
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Documento inválido
{ "error": { "code": "CLIENTE_DOCUMENTO_INVALIDO", "message": "Documento no válido para el tipo RUC" }, "requestId": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d"}Rate limit excedido. Esperá los segundos del header Retry-After. La cuota va por credencial: 60 req/min en cuentas estándar, 600 en cuentas proveedor.
object
object
Identificador estable del error en SCREAMING_SNAKE_CASE
Mensaje legible en español. No parsearlo: puede cambiar
object
object
Sólo en 403 API_ALCANCE_INSUFICIENTE: alcances que habilitan la operación
UUID de correlación; mismo valor que el header X-Request-ID
Ejemplos
Excediste el rate limit
{ "error": { "code": "API_RATE_LIMITED", "message": "Se superó el límite de requests para esta API key" }, "requestId": "5b2c7c8a-1f6e-4d29-9a0b-7c3a8d1e2f4c"}Headers
Sección titulada «Headers »Ejemplo
42Segundos hasta que se libera la ventana de rate limit