Saltar al contenido principal

Factura (01)

La Factura (tipo 01) se emite a consumidor final — personas naturales sin NRC, o clientes que no requieren crédito fiscal. Es el tipo de DTE más común en retail, restaurantes y servicios al público.

Detalles técnicos

MétodoPOST
URLhttps://ocote.io/api/connect/invoice
Content-Typeapplication/json
AutenticaciónHeader Authorization: Bearer odt_...

Request

Campos principales

CampoTipoRequeridoDescripción
doc_typestringNo (default "01")Tipo de DTE. Para Factura: "01".
linesarrayLíneas del documento. Al menos una. Ver LineIn.
customerobjectNoDatos del cliente. Opcional en Factura 01. Ver CustomerIn.
customer_namestringNoNombre del consumidor para facturas sin objeto customer. Default: "Consumidor Final".
payment_methodstringNo (default "01")Forma de pago. Ver Catálogos MH.
transaction_conditionintNo (default 1)1 = Contado, 2 = Crédito, 3 = Otro.
deadlineintNo (default 1)Plazo de pago en días (solo aplica a transaction_condition: 2).
periodintNo (default 1)Periodo del plazo.
activity_codestringNoCódigo de actividad económica del emisor para este documento. Override del default de la empresa.
redirect_emailstringNoCorreo adicional al que se envía copia del DTE (además del del customer).
external_refstringNoTu identificador idempotente. Ver Retry e idempotencia.

Líneas (lines)

CampoTipoRequeridoDescripción
descriptionstringDescripción del producto/servicio. Máx 1 000 caracteres.
quantityfloatCantidad. Debe ser mayor a cero.
unit_pricefloatPrecio unitario con IVA incluido. Debe ser mayor a cero.
discount_percentagefloatNo (default 0)Descuento en porcentaje (0-99).

Cliente (customer)

Totalmente opcional en Factura 01. Si no lo envías o lo envías incompleto, Ocote aplica defaults razonables:

CampoTipoRequeridoDefault (al crear)Descripción
namestring (si envías customer)Nombre o razón social.
nitstringNoNIT del cliente (si aplica).
nrcstringNoNRC del cliente (solo si es contribuyente IVA).
duistringNoDUI para personas naturales.
document_typestringNo"36"Tipo de documento identificador MH.
type_contributorintNo1 (Pequeño)Tipo de contribuyente. Ver Convenciones.
favorite_docstringNo"01"Tipo de DTE preferido del cliente.
addressstringNo"San Salvador"Dirección.
activity_codestringNoCódigo actividad económica del cliente.
departmentstringNoCódigo de departamento MH. Ver Catálogos MH. Si lo envías, municipality también es obligatorio.
municipalitystringNoCódigo de municipio MH.
emailstringNoCorreo electrónico para envío del DTE.
phonestringNoTeléfono. Bug conocido: omite este campo temporalmente, ver Convenciones.
Clientes nuevos vs existentes

Si el customer.nit (o customer.dui) ya existe en tu empresa en Ocote, el API actualiza únicamente los campos que enviaste explícitamente. Si no existe, crea el cliente con los defaults de la tabla anterior. Los campos fiscales sensibles (type_contributor, favorite_doc, document_type, nit, nrc, dui) se auditan en el log interno de Ocote cuando cambian.

Response

Ver Respuestas y estados para la semántica completa de flags. Campos específicos de /invoice:

CampoTipoDescripción
document_idstring (UUID)Identificador interno Ocote.
external_refstringEl que enviaste (o el autogenerado).
control_numberstringCorrelativo DTE MH. Nunca se regenera.
generation_codestringCódigo de generación MH (igual al UUID en mayúsculas).
reception_stampstringSello de recepción MH. Vacío si contingency: true o rejected: true.
amount_taxablefloatBase gravable (precio sin IVA).
amount_vatfloatIVA 13%.
amount_grossfloatTotal con IVA, antes de retención.
amount_retentionfloatRetención IVA 1% (aplica solo si receptor es type_contributor 3 o 4 y amount_taxable >= 100).
amount_totalfloatTotal neto = amount_gross − amount_retention.
ticket_urlstringURL al ticket PDF. Disponible si el documento se procesó.
json_urlstringURL al JSON firmado. Solo si dte_success: true.
dteobjectSchema completo del DTE firmado (solo si dte_success: true).

Ejemplo mínimo: venta simple

curl
curl -X POST https://ocote.io/api/connect/invoice \
-H "Authorization: Bearer odt_xxx" \
-H "Content-Type: application/json" \
-d '{
"external_ref": "VENTA-2026-0042",
"lines": [
{ "description": "Café americano", "quantity": 2, "unit_price": 2.50 },
{ "description": "Empanada de pollo", "quantity": 1, "unit_price": 3.00 }
]
}'
Node.js (axios)
const { data } = await axios.post(
'https://ocote.io/api/connect/invoice',
{
external_ref: 'VENTA-2026-0042',
lines: [
{ description: 'Café americano', quantity: 2, unit_price: 2.50 },
{ description: 'Empanada de pollo', quantity: 1, unit_price: 3.00 },
],
},
{ headers: { Authorization: `Bearer ${process.env.OCOTE_API_KEY}` } }
);
Python (requests)
r = requests.post(
"https://ocote.io/api/connect/invoice",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"external_ref": "VENTA-2026-0042",
"lines": [
{"description": "Café americano", "quantity": 2, "unit_price": 2.50},
{"description": "Empanada de pollo", "quantity": 1, "unit_price": 3.00},
],
},
)

Ejemplo completo: con cliente y crédito

curl
curl -X POST https://ocote.io/api/connect/invoice \
-H "Authorization: Bearer odt_xxx" \
-H "Content-Type: application/json" \
-d '{
"external_ref": "VENTA-2026-0043",
"customer": {
"name": "Juan Pérez",
"dui": "01234567-8",
"email": "juan@example.com",
"address": "Colonia Escalón, San Salvador"
},
"lines": [
{
"description": "Consultoría de marketing - 8 horas",
"quantity": 8,
"unit_price": 50.00,
"discount_percentage": 10
}
],
"payment_method": "05",
"transaction_condition": 2,
"deadline": 30,
"redirect_email": "contabilidad@miempresa.com"
}'

payment_method: "05" = Transferencia. transaction_condition: 2 = Crédito. deadline: 30 = 30 días. Ver Catálogos MH para el listado completo de códigos.

Respuesta exitosa

{
"success": true,
"dte_success": true,
"contingency": false,
"rejected": false,
"posted": true,
"is_duplicate": false,

"document_id": "a1b2c3d4-1234-5678-9abc-def012345678",
"external_ref": "VENTA-2026-0042",
"control_number": "DTE-01-M001P001-000000000000123",
"generation_code": "A1B2C3D4-1234-5678-9ABC-DEF012345678",
"reception_stamp": "20260421154532...",

"amount_taxable": 7.96,
"amount_vat": 1.04,
"amount_gross": 9.00,
"amount_retention": 0.00,
"amount_total": 9.00,

"ticket_url": "https://ocote.io/api/connect/file/a1b2c3d4-1234-5678-9abc-def012345678?type=ticket&key=odt_xxx",
"json_url": "https://ocote.io/api/connect/file/a1b2c3d4-1234-5678-9abc-def012345678?type=json&key=odt_xxx"
}

Errores de validación específicos

HTTP 400 con detalle en detail:

MensajeCausa
doc_type debe ser uno de: 01, 03, 11Valor de doc_type inválido.
Debe incluir al menos una línealines vacío o ausente.
Línea N: cantidad debe ser mayor a ceroAlgún item con quantity <= 0.
Línea N: precio unitario debe ser mayor a ceroAlgún item con unit_price <= 0.
Línea N: descripción es requeridaDescripción vacía.
Departamento/municipio no encontrado: X/YCombinación department/municipality no existe en el catálogo MH.

Ver también

  • Convenciones — montos con IVA incluido, timezone, valores enumerados.
  • CCF (03) — emisión a contribuyentes IVA con NIT y NRC.
  • Wildcard items — cómo funciona el catálogo interno y retenciones automáticas.
  • Catálogos MH — códigos de actividad, departamento, municipio, forma de pago.
  • Respuestas y estados — semántica completa del response.