Skip to content

Clientes ​

Con estos endpoints tu tienda busca a sus compradores entre los clientes del comercio, los registra y corrige sus datos. El cliente de una venta es a quien se le emite la factura electrónica, así que sus datos fiscales tienen que estar completos.

EndpointPermiso
GET /customerscustomers:read
GET /customers/{id}customers:read
POST /customerscustomers:write
PATCH /customers/{id}customers:write
POST /customers/{id}/companiescustomers:write
DELETE /customers/{id}/companies/{companyId}customers:write

Los clientes son los mismos que ve el comercio en Clientes: uno creado por la API aparece ahí, y uno creado en el POS se encuentra por la API. Por la API no se eliminan clientes.

El cliente y sus compañías ​

  • fiscalCategory dice qué clase de comprador es: no_contribuyente (consumidor final), contribuyente_natural, contribuyente_juridico o extranjero.
  • company es la compañía principal a la que se le factura: su tipo, nombre, RUC y DV. Un no_contribuyente no tiene; los demás la necesitan.
  • additionalCompanies son otras compañías a las que también se le puede facturar al mismo cliente, por ejemplo una persona que a veces compra para su empresa. Para facturarle a una de ellas, envía su id como companyId en .
company.typePara
naturalPersona natural con RUC (cédula)
juridicaEmpresa
gobiernoEntidad del Estado
extranjero_natural, extranjero_juridicoExtranjero: en ruc va el pasaporte o el ID fiscal de su país, y lleva country (código ISO de dos letras, como US)

Buscar clientes ​

http
GET /customers
ParámetroTipoDescripción
searchtexto, hasta 120 caracteresBusca por nombre, correo, teléfono, identificación o el RUC de cualquiera de sus compañías
emailtextoSolo el cliente con ese correo exacto, sin importar mayúsculas
ructextoSolo los clientes que tienen una compañía con ese RUC exacto. Da igual si lo escribes con o sin guiones: 8-123-456 encuentra 8123456
pageenteroPágina, desde 1. Por defecto 1
limitenteroDe 1 a 100. Por defecto 50

Antes de crear un cliente, búscalo por email o ruc para no duplicarlo.

bash
curl "https://api.zenci.app/public/v1/customers?ruc=155612345-2-2015" \
  -H "Authorization: Bearer $ZENCI_API_KEY"
json
{
  "data": [
    {
      "id": "u3i7o1p5a9s2d6f0g4h8j2k6",
      "fullName": "Ana Pérez",
      "fiscalCategory": "contribuyente_juridico",
      "email": "ana@ejemplo.com",
      "phone": "+507 6000-0000",
      "identification": null,
      "address": "Calle 50",
      "province": "Panamá",
      "city": "Panamá",
      "district": "San Francisco",
      "company": {
        "id": "t5y9u3i7o1p4a8s2d6f0g4h8",
        "type": "juridica",
        "name": "Distribuidora ABC, S.A.",
        "ruc": "155612345-2-2015",
        "dv": "45",
        "country": null
      },
      "additionalCompanies": [],
      "createdAt": "2026-09-14T15:02:11.000Z",
      "updatedAt": "2026-10-02T21:15:40.000Z"
    }
  ],
  "pagination": { "page": 1, "limit": 50, "total": 1, "totalPages": 1 }
}

GET /customers/{id} devuelve un cliente con la misma forma. Uno que no existe, o de otro comercio, responde 404.

Crear un cliente ​

http
POST /customers
CampoTipoObligatorioDescripción
fullNametextoSíNombre del cliente
fiscalCategorytextoSíVer
companyobjetoSegún fiscalCategoryObligatoria para contribuyentes y extranjeros; se omite para no_contribuyente
company.typetextoSíVer la tabla de arriba
company.nametextoSíRazón social o nombre con el que se factura
company.ructextoSíRUC, cédula o, para extranjeros, pasaporte o ID fiscal
company.dvtextoNoDígito verificador. Si no lo envías, Zenci lo toma de la DGI
company.countrytextoPara extranjerosCódigo ISO de dos letras
emailtextoPara extranjerosCorreo del cliente. Si lo tiene, la DGI le envía las facturas
phone, identificationtextoNoTeléfono e identificación
address, province, city, districttextoNoDirección
bash
curl -X POST https://api.zenci.app/public/v1/customers \
  -H "Authorization: Bearer $ZENCI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fullName": "Ana Pérez",
    "fiscalCategory": "contribuyente_juridico",
    "email": "ana@ejemplo.com",
    "company": {
      "type": "juridica",
      "name": "Distribuidora ABC, S.A.",
      "ruc": "155612345-2-2015"
    }
  }'

Responde 201 con el cliente, ya con el dv que puso la DGI.

El RUC y el DV ​

La DGI rechaza una factura sin DV, y la factura de una venta por API se emite sola, lejos de quien puede corregir el dato. Por eso Zenci revisa la compañía al guardarla:

  • Consulta el RUC en el registro de la DGI. Si no está registrado, responde 400 (RUC "…" is not registered with the DGI).
  • Si no enviaste dv, guarda el que tiene la DGI.
  • Si enviaste un dv distinto del de la DGI, responde 400 y dice cuál es el correcto.
  • Si la DGI no responde en ese momento, el cliente se guarda solo si enviaste el dv; si no, responde 400 y puedes reintentar.

Las compañías extranjeras no pasan por la DGI.

Corregir un cliente ​

http
PATCH /customers/{id}

Envía solo los campos que cambian; los que no envías quedan como estaban. address, province, city y district aceptan null para borrarlos.

  • company corrige la compañía principal, con la misma revisión de RUC y DV que al crear.
  • Para pasar a contribuyente a un no_contribuyente, envía fiscalCategory y company juntos.
  • Para pasar a no_contribuyente, envía solo fiscalCategory: la compañía principal se quita.

No pisar un cambio del comercio ​

Alguien del comercio puede estar editando el mismo cliente en el POS. Para no pisar su cambio, envía expectedUpdatedAt con el updatedAt que leíste:

json
{
  "expectedUpdatedAt": "2026-10-02T21:15:40.000Z",
  "phone": "+507 6111-1111"
}

Si el cliente cambió desde entonces, la respuesta es 409 conflict y no se guarda nada: vuelve a leerlo y decide. Sin expectedUpdatedAt, tu cambio se aplica sobre lo que haya.

Compañías adicionales ​

http
POST /customers/{id}/companies
DELETE /customers/{id}/companies/{companyId}

El cuerpo de POST es el mismo objeto que company y pasa por la misma revisión de RUC y DV. Responde 201 con la compañía. Un RUC que el cliente ya tiene responde 409.

DELETE quita una compañía adicional y responde 204. La compañía principal no se quita por aquí: se cambia con PATCH o pasando el cliente a no_contribuyente.

Errores frecuentes ​

HTTPMensajeCausa
400"company" is required for fiscalCategory "…"Un contribuyente o extranjero sin compañía
400"ruc" is required for a company of type "…"Una compañía nacional sin RUC
400RUC "…" is not registered with the DGIEl RUC no existe en la DGI
400"dv" does not match the DGI registry…El DV enviado no es el de la DGI
400email is required for extranjero customersUn extranjero sin correo
409Customer with this email already existsYa hay un cliente con ese correo: búscalo con ?email=
409This customer already has a company with this RUCLa compañía adicional repite un RUC del cliente
409The record changed since you read it…El cliente cambió desde tu expectedUpdatedAt

Siguientes pasos ​

  • — Vende a nombre del cliente y de su compañía.
  • — Entérate si una factura no se pudo emitir por datos del cliente.

Documentación oficial de Zelta