Wildcard items
El API Connect está diseñado para no exigirte mantener un catálogo de productos sincronizado con Ocote. Tu sistema tiene su propia base de datos de productos/servicios; el API acepta cualquier descripción de línea que le envíes sin validar que exista en un inventario de Ocote.
Esto simplifica la integración a casi cero: envías description, quantity, unit_price, y el API se encarga del resto.
Cómo funciona internamente
Cuando emites un documento vía API Connect, Ocote internamente asocia cada línea a uno de dos items comodín (wildcard items) registrados en tu empresa:
| Wildcard | Código interno | Tipo MH | Cuándo se usa |
|---|---|---|---|
| Bien/producto | __API_WILDCARD__ | 1 (Bienes) | Líneas en Factura, CCF, Exportación. También en SUEX si is_service: false. |
| Servicio | __API_WILDCARD_SVC__ | 2 (Servicios) | Líneas en SUEX cuando is_service: true (dispara retención renta 10%). |
Estos wildcards se crean automáticamente en tu empresa la primera vez que se emite un API key. No tienes que hacer nada para activarlos. Tampoco aparecen en tus reportes de inventario — son solo un mecanismo para satisfacer la referencia interna que Ocote mantiene por diseño.
Qué envías tú
Simplemente los campos descriptivos de la línea:
{
"lines": [
{
"description": "Servicio de consultoría estratégica - Abril 2026",
"quantity": 1,
"unit_price": 2500.00,
"discount_percentage": 10
}
]
}
La description es texto libre de hasta 1 000 caracteres. Aparece textual en el JSON firmado del DTE, en el ticket y en el PDF. No hay un catálogo contra el cual validar — el MH no requiere códigos de producto en los documentos.
Retención IVA 1% — automática
Para Factura (01) y CCF (03), cuando el receptor es Gran Contribuyente (type_contributor: 3) o Gobierno (type_contributor: 4), la normativa salvadoreña exige una retención del 1% del monto gravable si este excede $100.00.
El API calcula y aplica esta retención automáticamente. No tienes que:
- Conocer el tipo de contribuyente antes de emitir.
- Calcular el 1 %.
- Enviar campos de retención en el payload.
En el response verás:
{
"amount_taxable": 1000.00,
"amount_vat": 130.00,
"amount_gross": 1130.00,
"amount_retention": 10.00,
"amount_total": 1120.00
}
amount_retention se calcula como 1% × amount_taxable cuando aplica, 0.00 cuando no.
Si amount_taxable < 100.00, no aplica retención aunque el cliente sea Gran Contribuyente o Gobierno. Es parte de la normativa, no un comportamiento del API.
Retención Renta 10% en SUEX — automática
Para Sujeto Excluido (14) con líneas de servicios (is_service: true), la normativa exige retención de renta del 10% del monto.
El API también la calcula automáticamente. En el response de SUEX con servicios:
{
"amount_total": 1000.00,
"amount_retention": 100.00,
"amount_to_pay": 900.00
}
amount_to_pay es lo que efectivamente transfieres al sujeto excluido (monto bruto menos retención). La retención la reporta tu empresa al MH mensualmente como de costumbre.
Si la línea SUEX es is_service: false (venta de bienes), no hay retención de renta.
Qué NO obtienes con wildcards
Por ser items comodín, hay dos cosas que no puedes hacer dentro del API Connect:
- Tracking de inventario. El API no descuenta stock al emitir. Eso lo maneja tu ERP.
- Reportes de productos más vendidos desde Ocote. Los reportes de Ocote agrupan por el wildcard, no por tu
description. Si necesitas ese análisis, hazlo desde tu sistema (que sí tiene el catálogo real).
Estas dos limitaciones son exactamente las que hacen viable la integración sin sincronización. Si las necesitaras cubrir, la plataforma Ocote DTE completa (no el API Connect) sí maneja inventario.
Campos relevantes en el payload
Cuando envías una línea, los únicos campos obligatorios son:
| Campo | Tipo | Descripción |
|---|---|---|
description | string | Descripción textual de la línea. Aparece en el DTE. |
quantity | number | Cantidad. Admite decimales. |
unit_price | number | Precio unitario con IVA incluido para ventas locales. |
Opcionales:
| Campo | Tipo | Descripción |
|---|---|---|
discount_percentage | number | Porcentaje de descuento (0-99). |
is_service | boolean | Solo SUEX: marca la línea como servicio (dispara retención renta 10%). |
El resto de campos que aparecen en el JSON firmado del DTE (código interno, unidad de medida, tipo MH, etc.) los asigna Ocote con valores estándar apropiados al tipo de documento.
Ejemplo: CCF a Gran Contribuyente
curl -X POST https://ocote.io/api/connect/invoice \
-H "Authorization: Bearer odt_xxx" \
-H "Content-Type: application/json" \
-d '{
"doc_type": "03",
"external_ref": "CCF-2026-0042",
"customer": {
"name": "EMPRESA GRANDE, S.A. DE C.V.",
"nit": "06140710141035",
"nrc": "2360090",
"type_contributor": 3,
"activity_code": "86902",
"municipality_code": "0614"
},
"lines": [
{ "description": "Desarrollo de software", "quantity": 1, "unit_price": 5000.00 }
]
}'
Response (excerpted):
{
"success": true,
"dte_success": true,
"control_number": "DTE-03-M001P001-000000000000042",
"amount_taxable": 4424.78,
"amount_vat": 575.22,
"amount_gross": 5000.00,
"amount_retention": 44.25,
"amount_total": 4955.75
}
Nota que el unit_price: 5000.00 se envió con IVA incluido; el API extrae el IVA (desglosa a amount_taxable: 4424.78) y aplica retención del 1 % sobre la base gravable. Nada de eso lo calculaste tú.
Ver también
- Convenciones > Montos — reglas de precio con IVA incluido.
- Factura (01) — schema completo.
- CCF (03) — incluye detalle de retenciones.
- Sujeto Excluido (14) — incluye retención renta 10%.