Saltar al contenido principal

Sujeto Excluido (14)

El DTE de Sujeto Excluido (tipo 14) es un documento que emite el comprador, no el vendedor. Se usa cuando tu empresa compra a una persona natural no contribuyente IVA (sin NRC) — típicamente servicios profesionales, arrendamientos, compra de bienes de pequeños productores, etc.

A diferencia de Factura 01 y CCF 03 donde el flujo es "yo vendo y emito", en SUEX el flujo es "yo compro y documento la compra" — de ahí que use el modelo PurchaseHeader internamente y no SalesHeader.

Cuándo usar SUEX

  • Pago a profesionales independientes sin NRC.
  • Compra a proveedores personas naturales no inscritos en IVA.
  • Arrendamientos a personas naturales.
  • Cualquier compra a un "Sujeto Excluido" en términos fiscales MH.

Retención renta 10% automática

Cuando una línea está marcada con is_service: true, el API aplica automáticamente una retención del 10% del valor del servicio como anticipo de renta. Esta retención la paga tu empresa al MH mensualmente; el sujeto excluido recibe el monto neto (total − retención).

Si la línea es is_service: false (compra de bienes), no hay retención de renta.

Detalles técnicos

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

Request

Campos principales

CampoTipoRequeridoDescripción
linesarrayLíneas del documento. Al menos una.
subjectobjectDatos del sujeto excluido (vendedor).
external_refstringNoTu identificador idempotente.

Líneas (lines)

CampoTipoRequeridoDescripción
descriptionstringDescripción del bien/servicio. Máx 1 000 caracteres.
quantityfloatCantidad. Debe ser mayor a cero.
unit_pricefloatPrecio unitario. Debe ser mayor a cero.
is_serviceboolNo (default false)true → aplica retención renta 10%.

Sujeto (subject)

Todos los campos son del sujeto excluido (el vendedor a quien le compras).

CampoTipoRequeridoDescripción
namestringNombre completo del sujeto.
document_typestringNo (default "13")Tipo de documento identificador. Valores válidos: "02" (Carnet de Residente), "03" (Pasaporte), "13" (DUI), "36" (NIT), "37" (Otro).
document_nostringNúmero del documento identificador.
addressstringDirección del sujeto.
departmentstringNoCódigo de departamento MH. Si lo envías, municipality también es obligatorio.
municipalitystringNoCódigo de municipio MH.
phone_numberstringNoTeléfono. A diferencia del customer.phone en Factura/CCF, este campo sí funciona correctamente.
emailstringNoCorreo electrónico.
Sujetos recurrentes

Si emites un SUEX con un document_no que ya existe en tu empresa, Ocote actualiza los datos del sujeto (dirección, email, etc.) y reutiliza el registro. Esto evita duplicados en tu base de sujetos.

Response

Estructura idéntica a la de /invoice con los mismos flags de estado (success, dte_success, contingency, rejected, etc.). Ver Respuestas y estados.

Los montos se consultan por separado

A diferencia de /invoice, el response directo de POST /suex no incluye los campos de montos calculados. Para obtener amount, amount_irs (retención renta) y total_pay (monto neto a pagar), consulta el estado del documento con GET /suex/status/{id_or_ref} después de emitir. Ver Consultar estado.

Ejemplo: pago de servicios profesionales

curl
curl -X POST https://ocote.io/api/connect/suex \
-H "Authorization: Bearer odt_xxx" \
-H "Content-Type: application/json" \
-d '{
"external_ref": "SUEX-2026-0015",
"subject": {
"name": "Ana María González Rodríguez",
"document_type": "13",
"document_no": "01234567-8",
"address": "Colonia San Benito, San Salvador",
"department": "06",
"municipality": "14",
"email": "ana.gonzalez@example.com"
},
"lines": [
{
"description": "Asesoría legal corporativa - Marzo 2026",
"quantity": 1,
"unit_price": 1500.00,
"is_service": true
}
]
}'
Node.js (axios)
const { data } = await axios.post(
'https://ocote.io/api/connect/suex',
{
external_ref: 'SUEX-2026-0015',
subject: {
name: 'Ana María González Rodríguez',
document_type: '13',
document_no: '01234567-8',
address: 'Colonia San Benito, San Salvador',
department: '06',
municipality: '14',
email: 'ana.gonzalez@example.com',
},
lines: [
{ description: 'Asesoría legal corporativa - Marzo 2026',
quantity: 1, unit_price: 1500.00, is_service: true },
],
},
{ headers: { Authorization: `Bearer ${process.env.OCOTE_API_KEY}` } }
);
Python (requests)
r = requests.post(
"https://ocote.io/api/connect/suex",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"external_ref": "SUEX-2026-0015",
"subject": {
"name": "Ana María González Rodríguez",
"document_type": "13",
"document_no": "01234567-8",
"address": "Colonia San Benito, San Salvador",
"department": "06",
"municipality": "14",
"email": "ana.gonzalez@example.com",
},
"lines": [
{
"description": "Asesoría legal corporativa - Marzo 2026",
"quantity": 1,
"unit_price": 1500.00,
"is_service": True,
},
],
},
)

Consultar los montos calculados

Tras emitir, consulta el estado para ver la retención aplicada:

curl https://ocote.io/api/connect/suex/status/SUEX-2026-0015 \
-H "Authorization: Bearer odt_xxx"

Respuesta:

{
"document_id": "b2c3d4e5-...",
"external_ref": "SUEX-2026-0015",
"doc_type": "14",
"control_number": "DTE-14-M001P001-000000000000015",
"reception_stamp": "20260421...",
"success": true,
"posted": true,
"invalidated": false,

"amount": 1500.00,
"amount_irs": 150.00,
"total_pay": 1350.00,

"suex_name": "Ana María González Rodríguez",
"created": "2026-04-21T10:42:15-06:00",
"posted_date": "2026-04-21T10:42:18-06:00",

"invoice_url": "https://ocote.io/api/v2/suex-history/b2c3d4e5-.../file?type=invoice",
"json_url": "https://ocote.io/api/v2/suex-history/b2c3d4e5-.../file?type=json",

"dte_success": true,
"contingency": false,
"rejected": false,
"dte_state": "",
"dte_message": "",
"observaciones": [],
"codigo_msg": ""
}

Desglose:

  • amount: 1500.00 — valor del servicio declarado.
  • amount_irs: 150.00 — 10% de retención renta (1500 × 0.10). Lo paga tu empresa al MH.
  • total_pay: 1350.00 — lo que efectivamente transfieres a Ana María.

Ejemplo sin retención: compra de bienes

Si compras bienes (no servicios), marca is_service: false:

{
"external_ref": "SUEX-2026-0016",
"subject": {
"name": "José Pérez",
"document_type": "13",
"document_no": "98765432-1",
"address": "Ilobasco, Cabañas"
},
"lines": [
{
"description": "Maíz blanco - 10 quintales",
"quantity": 10,
"unit_price": 45.00,
"is_service": false
}
]
}

En el status veremos amount_irs: 0.00 y total_pay: 450.00.

Errores de validación específicos

HTTP 400 con detalle en detail:

MensajeCausa
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.
Nombre del sujeto excluido es requeridosubject.name vacío.
Número de documento del sujeto es requeridosubject.document_no vacío.
Dirección del sujeto es requeridasubject.address vacío.
Tipo de documento inválido (02, 03, 13, 36, 37)subject.document_type fuera del rango permitido.
Departamento/municipio no encontrado: X/YCombinación inválida en catálogo MH.

Anulación

Se anula con un endpoint dedicado que NO comparte ruta con facturas:

curl -X POST https://ocote.io/api/connect/invalidate/suex/SUEX-2026-0015 \
-H "Authorization: Bearer odt_xxx"

Ver Anular DTE.

Ver también