Crear una factura
Qué significa cada campo de una factura, con un ejemplo completo de petición y respuesta.
Página de muestra
Esta página es una muestra del nuevo estilo de la documentación. La referencia técnica completa está en POST /v1/invoices.
Para crear una factura envías sus datos con POST /v1/invoices. Trifaco le asigna el número, calcula el CUFE, la firma, la envía a la DIAN y genera el PDF.
Tú no envías el emisor, el número, el CUFE ni la firma: los pone Trifaco.
Antes de empezar
- Tu API key (ver Empieza aquí).
- El
idde tu rango de numeración, que obtienes conGET /v1/numbering-ranges.
Los valores van entre comillas
Cantidades, precios e impuestos se envían como texto ("10000.00"), no como números (10000.00). Así no se pierden decimales. Admiten hasta seis decimales.
Encabezados
| Encabezado | Obligatorio | Qué es |
|---|---|---|
X-API-Key | Sí | Tu API key. |
Content-Type | Sí | Siempre application/json. |
Idempotency-Key | Sí | Un texto único por factura (de 8 a 128 letras, números, ., _, : o -). Si repites la petición con la misma clave, recibes la misma factura en lugar de una nueva. |
Datos generales
| Campo | Obligatorio | Qué es | Ejemplo |
|---|---|---|---|
document_type | Sí | El tipo de documento. Para facturas, siempre invoice. | "invoice" |
external_reference | Sí | El identificador de la factura en tu sistema, por ejemplo el número de pedido. Hasta 100 caracteres: letras, números y . _ : / -. | "PEDIDO-001" |
profile_id | Sí | Las reglas con las que se valida la factura. Usa co-sale-cop-v1 (venta nacional en pesos). | "co-sale-cop-v1" |
numbering_range_id | Sí | El id del rango de numeración con el que se numera. | "3f6c…" |
issued_at | Sí | Fecha y hora de expedición, con zona horaria. En Colombia, -05:00. | "2026-09-16T10:00:00-05:00" |
currency | Sí | La moneda. Hoy solo COP. | "COP" |
notes | No | Un texto libre que aparece en la factura. Hasta 2000 caracteres. | "Gracias por su compra" |
Comprador (buyer)
| Campo | Obligatorio | Qué es | Ejemplo |
|---|---|---|---|
party_type | Sí | person si es una persona, company si es una empresa. | "person" |
identification.type_code | Sí | Tipo de documento: 13 cédula de ciudadanía, 31 NIT. | "13" |
identification.number | Sí | El número, sin puntos, sin ceros al inicio y, si es NIT, sin el dígito de verificación. | "1000000000" |
identification.check_digit | Si es NIT | El dígito de verificación del NIT. | "7" |
name | Sí | Nombre completo o razón social. Hasta 200 caracteres. | "Cliente de prueba" |
email | No | Correo del comprador. | "cliente@example.com" |
address | Si es empresa | Dirección en Colombia (ver la tabla siguiente). | |
tax_registration.responsibility_codes | Sí | Responsabilidades fiscales del comprador según el RUT. Para personas sin responsabilidades, R-99-PN. | ["R-99-PN"] |
tax_registration.tax_scheme_codes | Sí | Tributos a los que está sujeto el comprador. 01 es IVA. | ["01"] |
Dirección (buyer.address)
| Campo | Qué es | Ejemplo |
|---|---|---|
country_code | País. Siempre CO. | "CO" |
department_code | Código DANE del departamento (2 dígitos). | "11" |
municipality_code | Código DANE del municipio (5 dígitos). | "11001" |
city_name | Nombre de la ciudad. | "Bogotá" |
line | Dirección. | "Calle 1 # 2-3" |
postal_code | Código postal (opcional). | "110111" |
Productos o servicios (lines)
Cada elemento de lines es un renglón de la factura.
| Campo | Obligatorio | Qué es | Ejemplo |
|---|---|---|---|
id | Sí | Número del renglón, único dentro de la factura. | "1" |
description | Sí | Qué se vende. Hasta 300 caracteres. | "Servicio de prueba" |
product_identification.scheme_code | Sí | Tipo de código del producto. Usa 999 (código propio). | "999" |
product_identification.value | Sí | Tu código del producto. | "SERV-001" |
quantity | Sí | Cantidad. Mayor que cero. | "1" |
unit_code | Sí | Unidad de medida. Hoy 94 (unidad). | "94" |
unit_price | Sí | Precio de una unidad, sin impuestos. | "10000.00" |
price_base_quantity | Sí | A cuántas unidades corresponde unit_price. Normalmente 1. | "1" |
net_amount | Sí | Total del renglón sin impuestos: cantidad × precio, menos descuentos. | "10000.00" |
taxes | Sí | Los impuestos del renglón (ver la tabla siguiente). Puede ir vacío. | |
adjustments | Sí | Descuentos o cargos del renglón. Envía [] si no hay. | [] |
withholdings | Sí | Retenciones del renglón. Envía [] si no hay. | [] |
Impuestos (taxes y tax_totals)
| Campo | Qué es | Ejemplo |
|---|---|---|
code | El impuesto. 01 es IVA. | "01" |
rate | La tarifa en porcentaje: 0, 5 o 19. | "19" |
taxable_amount | La base sobre la que se calcula el impuesto. | "10000.00" |
amount | El valor del impuesto: base × tarifa ÷ 100. | "1900.00" |
En tax_totals va la suma de los impuestos de todos los renglones, agrupada por impuesto y tarifa.
Totales (totals)
Trifaco revisa que los totales cuadren con los renglones. Si no cuadran, la factura se rechaza antes de enviarla a la DIAN.
| Campo | Qué es | En el ejemplo |
|---|---|---|
line_extension_amount | Suma de net_amount de todos los renglones. | "10000.00" |
tax_exclusive_amount | Base gravable total (suma de las bases de impuestos). | "10000.00" |
tax_inclusive_amount | Total con impuestos. | "11900.00" |
allowance_total_amount | Descuentos generales de la factura. | "0.00" |
charge_total_amount | Cargos generales de la factura. | "0.00" |
prepaid_amount | Anticipos ya recibidos. | "0.00" |
payable_rounding_amount | Ajuste por redondeo. | "0.00" |
payable_amount | Lo que debe pagar el comprador. | "11900.00" |
Pago (payment)
| Campo | Obligatorio | Qué es | Ejemplo |
|---|---|---|---|
terms | Sí | cash de contado o credit a crédito. | "cash" |
means_code | Sí | Medio de pago. Hoy 10 (efectivo). | "10" |
due_date | Si es a crédito | Fecha de vencimiento (AAAA-MM-DD). | "2026-10-16" |
Otros campos opcionales
| Campo | Qué es |
|---|---|
adjustments | Descuentos o cargos generales de la factura. Obligatorio: envía [] si no hay. |
withholding_totals | Suma de las retenciones. Obligatorio: envía [] si no hay. |
delivery | Para que Trifaco envíe la factura por correo: { "mode": "trifaco_email", "recipients": ["cliente@example.com"] } (hasta 5 correos). |
references | Documentos relacionados, como una orden de compra: { "type": "order", "number": "OC-55" }. |
prepaid_payments | Detalle de los anticipos recibidos. |
Los códigos válidos de cada campo se pueden consultar con GET /v1/catalogs/{catalog}, por ejemplo identification_types o unit_codes.
Ejemplo completo
Petición
curl -s -X POST https://api-sandbox.trinity-soft.com/v1/invoices \
-H "X-API-Key: $TRIFACO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-001-v1" \
-d @factura.jsonContenido de factura.json: una venta de un servicio de $10.000 más IVA del 19 %, pagada de contado y enviada por correo al comprador.
{
"document_type": "invoice",
"external_reference": "PEDIDO-001",
"profile_id": "co-sale-cop-v1",
"numbering_range_id": "RANGO_ID",
"issued_at": "2026-09-16T10:00:00-05:00",
"currency": "COP",
"buyer": {
"party_type": "person",
"identification": { "type_code": "13", "number": "1000000000" },
"name": "Cliente de prueba",
"email": "cliente@example.com",
"tax_registration": {
"responsibility_codes": ["R-99-PN"],
"tax_scheme_codes": ["01"]
}
},
"lines": [
{
"id": "1",
"description": "Servicio de prueba",
"product_identification": { "scheme_code": "999", "value": "SERV-001" },
"quantity": "1",
"unit_code": "94",
"unit_price": "10000.00",
"price_base_quantity": "1",
"net_amount": "10000.00",
"adjustments": [],
"taxes": [
{ "code": "01", "rate": "19", "taxable_amount": "10000.00", "amount": "1900.00" }
],
"withholdings": []
}
],
"adjustments": [],
"tax_totals": [
{ "code": "01", "rate": "19", "taxable_amount": "10000.00", "amount": "1900.00" }
],
"withholding_totals": [],
"totals": {
"line_extension_amount": "10000.00",
"tax_exclusive_amount": "10000.00",
"tax_inclusive_amount": "11900.00",
"allowance_total_amount": "0.00",
"charge_total_amount": "0.00",
"prepaid_amount": "0.00",
"payable_rounding_amount": "0.00",
"payable_amount": "11900.00"
},
"payment": { "terms": "cash", "means_code": "10" },
"delivery": { "mode": "trifaco_email", "recipients": ["cliente@example.com"] }
}Respuesta: 202 Accepted
{
"operation_id": "8a1d2c3e-0000-4000-8000-000000000030",
"document_id": "8a1d2c3e-0000-4000-8000-000000000020",
"revision": 1,
"version": 1,
"environment": "qualification",
"external_reference": "PEDIDO-001",
"processing_status": "queued",
"dian_status": "not_sent",
"billing_status": "not_billable",
"created_at": "2026-09-16T15:00:00Z",
"status_url": "/v1/documents/8a1d2c3e-0000-4000-8000-000000000020"
}| Campo | Qué significa |
|---|---|
document_id | El ID de tu factura en Trifaco. Guárdalo para consultarla. |
environment | qualification = habilitación (pruebas) de la DIAN. |
processing_status | queued: la recibimos y está en fila para firmarse y enviarse. |
dian_status | not_sent: todavía no se ha enviado a la DIAN. |
status_url | La dirección para consultar el resultado. |
202 significa que recibimos la factura, no que la DIAN la aprobó. Para saber el resultado, consulta status_url o espera un webhook. Cómo leer el resultado y obtener el CUFE: Empieza aquí, paso 4.
Si algo sale mal
| Respuesta | Qué pasó | Qué hacer |
|---|---|---|
400 | La petición está mal formada: el JSON no es válido o falta el encabezado Idempotency-Key. | Revisa code y message en la respuesta. |
401 | La API key falta o no es válida. | Revisa el encabezado X-API-Key. |
409 | Ya habías usado esa Idempotency-Key o esa external_reference con otros datos. | Si es una factura nueva, usa una clave y una referencia nuevas. Si es la misma factura, envía exactamente los mismos datos. |
422 | Los datos no cumplen una regla: falta un campo, un código no existe o los totales no cuadran. | Revisa errors en la respuesta: dice qué campo falla y por qué. |
429, 503 o se cortó la conexión | Demasiadas peticiones, el servicio está ocupado, o no sabes si la factura llegó. | Espera y repite exactamente la misma petición con la misma Idempotency-Key. Así no se duplica. |
Para revisar una factura sin crearla, envía el mismo cuerpo a POST /v1/invoice-validations. Más detalles en Errores.