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.
departmentstringNoMH department code. If you send it, municipality is also required.
municipalitystringNoMH municipality code.
phone_numberstringNoPhone. Unlike customer.phone in Invoice/CCF, this field works correctly.
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",
"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',
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",
"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/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": ""
}

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"
},
"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