Skip to Content
v1.5Official documentation for the LX CloudPos API · stable in production

Catalog DTOs

Full schemas of the DTOs used by the catalog endpoints: products, customers, code catalogs, and brands.

ProductoApiRequestDto

Body of POST /api/v1/productos.

interface ProductoApiRequestDto { /** REQUIRED. Integrator's own SKU/code. Upsert key. */ codigo: string; /** REQUIRED. */ nombre: string; descripcion?: string | null; /** REQUIRED. Hacienda CABYS code, minimum 13 digits. Tax data — goes into the XML. */ codigoCabys: string; /** REQUIRED. Unit-of-measure code from Hacienda's catalog (GET /catalogos/unidades-medida). Tax data — goes into the XML. */ unidadMedida: string; /** REQUIRED. > 0. */ precioVenta: number; /** REQUIRED. > 0. */ precioCosto: number; /** Default 0. Informational only — not recalculated against precioVenta/precioCosto. */ porcentajeGanancia?: number; idCategoria?: number | null; idSubcategoria?: number | null; /** Optional. If omitted on a CREATE, the product is left WITHOUT a brand (shown as 0 in the response). On an UPDATE, if omitted, the product keeps the brand it already had — this is one of the two exceptions to the update not being partial. */ idMarca?: number | null; /** Optional. Same rule as idMarca, applied to the supplier. */ idProveedor?: number | null; /** Hacienda code-type code ("01" from the seller, "02" from the buyer, …). Defaults to "01" if omitted. */ tipoCodigo?: string | null; /** Only applies when creating (default true). On an update the product keeps its current status, and sending a value different from the current one returns a 400. */ estado?: boolean; /** REQUIRED. At least 1 line. On an update it replaces the product's entire tax list — it is not merged with the one it already had. */ impuestos: ProductoApiImpuestoDto[]; }

Field validations

FieldRuleError if it fails
codigoNot empty after trimming whitespace.400 — Debe indicar 'codigo'.
nombreNot empty after trimming whitespace.400 — Debe indicar 'nombre'.
codigoCabysMinimum 13 digits.400 — El código CABYS debe tener 13 dígitos.
unidadMedidaNot empty.400 — Debe indicar 'unidadMedida'.
precioVenta> 0.400 — Debe indicar 'precioVenta'.
precioCosto> 0.400 — Debe indicar 'precioCosto'.
impuestosNon-empty array, each line with codigo.400 — Debe indicar al menos un impuesto en 'impuestos'. / 400 — Cada línea de 'impuestos' debe indicar 'codigo'.

ProductoApiImpuestoDto

A product’s tax line.

interface ProductoApiImpuestoDto { /** REQUIRED. Tax code from Hacienda's catalog (e.g. "01" = VAT). */ codigo: string; porcentaje: number; /** Rate code within the tax (e.g. "08" = general 13% rate). */ codigoTarifa?: string | null; }

ProductoApiResponseDto

Returned by POST /api/v1/productos and GET /api/v1/productos/{codigo}.

interface ProductoApiResponseDto { idProducto: number; codigo: string; nombre: string; descripcion?: string | null; codigoCabys: string; unidadMedida: string; precioVenta: number; precioCosto: number; idCategoria?: number | null; idSubcategoria?: number | null; /** 0 = no brand assigned. Not "brand number 0". */ idMarca: number; /** 0 = no supplier assigned. Not "supplier number 0". */ idProveedor: number; estado: boolean; impuestos: ProductoApiImpuestoDto[]; /** Non-blocking. Only populated when saving auto-corrected the unit of measure (a service CABYS with an incompatible unit). It travels only in the response of the POST that generated it — GET /productos/{codigo} always returns it as null. */ advertencia?: string | null; }

ClienteApiRequestDto

Body of POST /api/v1/clientes. Upsert by identificacion: created if it doesn’t exist, partially updated if it does.

interface ClienteApiRequestDto { /** REQUIRED. Upsert key. Cannot be changed once the customer is created. */ identificacion?: string | null; /** Hacienda identification-type code (01 individual, 02 corporate, …). REQUIRED when creating. On an update, "" is ignored. */ tipoIdentificacion?: string | null; /** REQUIRED when creating. On an update, "" is ignored. */ nombre?: string | null; /** On an update, "" DOES apply (ends up empty). */ apellidos?: string | null; /** Internal/trade name. Only applies to corporate ID ("02"). */ nombreInterno?: string | null; /** REQUIRED when creating — an empty string does not pass validation. On an update, if sent, it must be a valid email: it cannot be cleared. */ correo?: string | null; /** REQUIRED when creating. Normalized. On an update, if sent, it must be a valid phone number: it cannot be cleared. */ telefono?: string | null; /** On an update, "" DOES apply (ends up null). */ direccion?: string | null; /** On an update, "" DOES apply (ends up null). */ comentario?: string | null; /** Defaults to false when creating. On an update it is only overwritten if the field is present in the JSON — including an explicit false. */ pagaTimbre?: boolean | null; /** Marker; tax exemptions themselves are not managed through this endpoint. */ exonerado?: boolean | null; limiteCredito?: number | null; }

The field-by-field semantics of the partial update are in Create or update customer.

ClienteApiResponseDto

Returned by POST /api/v1/clientes and GET /api/v1/clientes/{identificacion}.

interface ClienteApiResponseDto { idCliente: number; identificacion: string; tipoIdentificacion: string; nombre: string; apellidos: string; nombreInterno?: string | null; correo: string; telefono: string; direccion?: string | null; comentario?: string | null; estado: boolean; exonerado: boolean; pagaTimbre: boolean; limiteCredito?: number | null; /** Added in the 2026-08-31 release. The customer's exemption documents: this is where the idExoneracion sent per line at issuance comes from (see Tax exemptions). All are returned, current or not, with `vigente` already resolved by the server. */ exoneraciones: ExoneracionClienteApiDto[]; } interface ExoneracionClienteApiDto { /** The id sent as idExoneracion on the document's line. */ idExoneracion: number; /** Exemption document type code (Hacienda catalog). */ tipoDocumento: string; /** Document type description, for display. */ tipoDocumentoNombre: string; numeroDocumento: string; nombreInstitucion: string; fechaEmision?: string | null; fechaExpiracion?: string | null; /** Authorized percentage. At issuance it's capped at the product's real rate: a line can't be exempted from more tax than it actually carries. */ porcentajeExoneracion?: number | null; /** Whether the document is active in the tenant's catalog. */ estado: boolean; /** Whether it can be used TODAY: active and not expired. Same condition the server validates at issuance — an exemption with vigente:false returns 400 if its idExoneracion is used. */ vigente: boolean; }

Read-only DTOs

DTOs returned by the code catalogs.

interface MedioPagoApiDto { /** Use as medioPago when issuing. */ codigo: string; nombre: string; permiteDescuento: boolean; } interface CondicionVentaApiDto { /** Use as condicionVenta when issuing. */ codigo: string; nombre: string; } interface UnidadMedidaApiDto { /** Unit-of-measure code from Hacienda's catalog. */ codigo: string; nombre: string; reduceInventario: boolean; } interface ActividadEconomicaApiDto { codigo: string; descripcion: string; /** true = the tenant's default activity when codigoActividad is not given when issuing. */ principal: boolean; } interface PuntoVentaApiDto { /** Use as idPuntoVenta when issuing. */ id: number; nombre: string; activo: boolean; } interface TipoCodigoApiDto { /** Use as tipoCodigo when creating a product. */ codigo: string; descripcion: string; } interface MarcaApiDto { /** Use as idMarca when creating a product. */ id: number; nombre: string; /* No 'activo' field: the listing already returns only active brands. */ }