Skip to main content

Excluded Subject — SUEX (14)

The Excluded Subject DTE (type 14) is a document issued by the buyer, not the seller. It's used when your company buys from a natural person who is not a VAT contributor (no NRC) — typically professional services, rentals, purchases from small producers, etc.

Unlike Invoice 01 and CCF 03 where the flow is "I sell and I issue", in SUEX the flow is "I buy and I document the purchase" — hence it uses the PurchaseHeader model internally, not SalesHeader.

SUEX stands for "Sujeto Excluido", the Spanish term used in Salvadoran fiscal terminology.

When to use SUEX

  • Payments to independent professionals without NRC.
  • Purchases from individual suppliers not registered for VAT.
  • Rentals to individuals.
  • Any purchase from a "Sujeto Excluido" in MH fiscal terms.

Automatic 10% income-tax withholding

When a line is flagged is_service: true, the API automatically applies a 10% withholding on the service value as income-tax advance. Your company pays this withholding to MH monthly; the excluded subject receives the net amount (total − withholding).

If the line is is_service: false (purchase of goods), no income-tax withholding applies.

Technical details

MethodPOST
URLhttps://ocote.io/api/connect/suex
Content-Typeapplication/json
AuthenticationHeader Authorization: Bearer odt_...

Request

Main fields

FieldTypeRequiredDescription
linesarrayYesDocument lines. At least one.
subjectobjectYesData of the excluded subject (seller).
external_refstringNoYour idempotent identifier.

Lines (lines)

FieldTypeRequiredDescription
descriptionstringYesGood/service description. Max 1,000 characters.
quantityfloatYesQuantity. Must be greater than zero.
unit_pricefloatYesUnit price. Must be greater than zero.
is_serviceboolNo (default false)true → applies 10% income-tax withholding.

Subject (subject)

All fields describe the excluded subject (the seller you're buying from).

FieldTypeRequiredDescription
namestringYesFull name of the subject.
document_typestringNo (default "13")Identifier document type. Valid values: "02" (Resident Card), "03" (Passport), "13" (DUI), "36" (NIT), "37" (Other).
document_nostringYesIdentifier document number.
addressstringYesSubject's address.
districtstringNoDistrict UUID — look it up in /catalogs/districts/search. If sent, department and municipality are ignored. Recommended flow.
departmentstringNoMH department code. If you send it, municipality is also required. Ignored if district is provided.
municipalitystringNoMH municipality code. Accepts short format ("24") or long format ("1124"). Ignored if district is provided.
phone_numberstringNoSubject's phone.
emailstringNoEmail address.
Recurring subjects

If you issue a SUEX with a document_no that already exists in your company, Ocote updates the subject's data (address, email, etc.) and reuses the record. This avoids duplicates in your subjects database.

Response

Structure identical to /invoice with the same state flags (success, dte_success, contingency, rejected, etc.). See Responses and states.

Amounts are queried separately

Unlike /invoice, the direct response of POST /suex does not include the computed amount fields. To get amount, amount_irs (income-tax withholding), and total_pay (net amount to pay), query the document state with GET /suex/status/{id_or_ref} after issuing. See Query status.

Example: payment for professional services

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",
"phone_number": "7888-9999",
"email": "ana.gonzalez@example.com"
},
"lines": [
{
"description": "Corporate legal consulting - March 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',
phone_number: '7888-9999',
email: 'ana.gonzalez@example.com',
},
lines: [
{ description: 'Corporate legal consulting - March 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",
"phone_number": "7888-9999",
"email": "ana.gonzalez@example.com",
},
"lines": [
{
"description": "Corporate legal consulting - March 2026",
"quantity": 1,
"unit_price": 1500.00,
"is_service": True,
},
],
},
)

Querying the computed amounts

After issuing, query the status to see the applied withholding:

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

Response:

{
"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/connect/file/b2c3d4e5-...?type=invoice",
"json_url": "https://ocote.io/api/connect/file/b2c3d4e5-...?type=json",

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

Breakdown:

  • amount: 1500.00 — declared service value.
  • amount_irs: 150.00 — 10% income-tax withholding (1500 × 0.10). Paid by your company to MH.
  • total_pay: 1350.00 — the amount you actually transfer to Ana María.

Example without withholding: purchase of goods

If you buy goods (not services), flag is_service: false:

{
"external_ref": "SUEX-2026-0016",
"subject": {
"name": "José Pérez",
"document_type": "13",
"document_no": "98765432-1",
"address": "Ilobasco, Cabañas",
"phone_number": "6555-0011"
},
"lines": [
{
"description": "White corn - 10 quintals",
"quantity": 10,
"unit_price": 45.00,
"is_service": false
}
]
}

In the status response we'll see amount_irs: 0.00 and total_pay: 450.00.

Specific validation errors

HTTP 400 with detail populated:

MessageCause
Debe incluir al menos una línealines empty or absent.
Línea N: cantidad debe ser mayor a ceroSome item has quantity <= 0.
Línea N: precio unitario debe ser mayor a ceroSome item has unit_price <= 0.
Línea N: descripción es requeridaEmpty description.
Nombre del sujeto excluido es requeridosubject.name empty.
Número de documento del sujeto es requeridosubject.document_no empty.
Dirección del sujeto es requeridasubject.address empty.
Tipo de documento inválido (02, 03, 13, 36, 37)subject.document_type out of allowed range.
Departamento/municipio no encontrado: X/YInvalid combination in MH catalog.

Messages are in Spanish — the language MH operates in.

Invalidation

Invalidation uses a dedicated endpoint that does NOT share the route with invoices:

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

See Invalidate DTE.

See also