Cesibilidad (Ley 19.983)
Whether a factura can be ceded to a factoring company, and why only the SII knows.
An electronic factura (Chile's electronic invoice) can be ceded — its credit handed to a factoring company, with mérito ejecutivo, meaning it is directly enforceable in court. Ley 19.983 says when:
- when the receptor gives an acuse de recibo, a formal acknowledgement of receipt (art. 3), or
- when eight calendar days pass without them disputing it (art. 4 inc. 4).
It also says when never: if the emisor declared the payment as al contado — cash, with no outstanding balance — the document is not cedible. Circular N°35 of 23.06.2017 leaves no room: "these documents may not be ceded".
None of those three things can be computed from the document you are holding. They depend on what
the counterparty did — or did not do — and on what the SII has on record. That is why Facturia does
not compute cesibilidad: it asks the SII's registry and hands you the answer exactly as it came. The
eight calendar days run from receipt at the SII, not from your issue_date.
Ask
curl -X POST https://api.facturia.cl/v1/documents/doc_01K2R7.../cesion \
-H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA"202 if this call queued the question, 200 if an identical one is already in flight. The answer
lands on the document; there is no webhook, so you read it with GET /v1/documents/doc_01K2R7...:
{
"id": "doc_01K2R7...",
"tipo_dte": 33,
"status": "accepted",
"cesion": {
"cedible": true,
"sii_status_code": 25,
"checked_at": "2026-08-23T09:12:40Z"
}
}| Field | What it is |
|---|---|
cedible | true for SII codes 23 and 25, false for 21 and 24, null if nobody has asked yet or if the SII answered with a code we do not read as a verdict |
sii_status_code | The raw codResp, exactly as it came. 23 = express acuse; 25 = the eight days elapsed; 24 = not cedible; 21 = not cedible because an annulling credit note references it |
checked_at | When the SII answered — not when we tried. A transient network failure does not move it: the queue retries, not you |
cedible and sii_status_code travel together on purpose. If the SII answers with a code we have not
mapped, cedible stays null and the code is stored whole: we would rather tell you "the SII
answered 9" than invent a boolean. An invented false would tell a factoring company that a
perfectly cedible factura is not.
The two rejections
| Code | HTTP | When |
|---|---|---|
cesion_not_applicable | 422 | The SII registry answers for types 33, 34 and 43 and for no others. Boletas and notes have no cesibilidad status |
cesion_status_not_available | 409 | The SII does not have the document on record yet (queued, sent) or never will (failed, rejected). Ask again once it is accepted |
Type 46 is not on that list, even though it looks like it should be. The factura de compra
(purchase invoice) does appear in Ley 19.983's enumeration of receipts (33, 34, 43, 46 and 52), but
it appears on no tipoDoc list of the SII registry, which answers code 3 ("document type does not
apply"). They are two different lists, and here the registry's list is the one that applies.
This is read-only
POST .../cesion cedes nothing. It builds no AEC, signs nothing, writes nothing to the SII's
Registro de Cesión de Créditos, the credit assignment registry. The operation it calls
(consultarDocDteCedible) is the only one in that service that carries no action code, and it cannot
change any state over there.
That is exactly why it accepts a key with the documents:read scope: whoever needs this is usually a
factoring system, and it has no business carrying a key that can issue facturas.
Do not confuse it with the cedible copy
Two different things whose names look very much alike:
GET /v1/documents/doc_01K2R7.../pdf?copy=cediblegives you the third printed copy, the one carrying theCEDIBLElegend and the acuse de recibo box. It exists per type: every 33 and every 34 has one, even an al contado factura whose copy cedes nothing to anyone. See Artifacts.cesiontells you whether the credit can move now.
Holding the copy does not mean you can cede.
In test mode
In sandbox none of this touches the network: the answer is simulated in process, applying the same
legal rule against the empresa's simulated clock. It returns 24 until eight days have passed since
acceptance and 25 from then on, so both branches are testable:
# Recién emitida: todavía no
curl -X POST https://api.facturia.cl/v1/documents/doc_01K2R7.../cesion \
-H "Authorization: Bearer $FACTURIA_TEST_KEY" -H "Facturia-Empresa: $EMPRESA"
# → "cesion": { "cedible": false, "sii_status_code": 24, ... }
# Adelanta el reloj de la empresa nueve días
curl -X POST https://api.facturia.cl/v1/test_helpers/clock \
-H "Authorization: Bearer $FACTURIA_TEST_KEY" -H "Facturia-Empresa: $EMPRESA" \
-H "Content-Type: application/json" -d '{"advance_days":9}'
curl -X POST https://api.facturia.cl/v1/documents/doc_01K2R7.../cesion \
-H "Authorization: Bearer $FACTURIA_TEST_KEY" -H "Facturia-Empresa: $EMPRESA"
# → "cesion": { "cedible": true, "sii_status_code": 25, ... }The simulated code for the cedible case is 25 and not 23 on purpose: in sandbox there is no
receptor to acknowledge anything, so silence is the only way a simulated factura ever becomes
cedible.
Ceding for real — POST .../cede (ticket #60)
Everything above is a read: POST .../cesion only asks. POST .../cede actually cedes — it
assembles an Archivo Electrónico de Cesión (AEC) — the emisor's original signed DTE plus the terms of
the transfer, signed by the cedente — and uploads it to the SII's Registro Electrónico de
Transferencia de Crédito. It is a real and irreversible act, and it works the same regardless of
which channel emitted the document — the AEC carries the original signed envelope verbatim, so it
no longer distinguishes emission_channel=sfg from emission_channel=mercado (ticket #60, ruled
2026-09-06).
curl -X POST https://api.facturia.cl/v1/documents/doc_01K2R7.../cede \
-H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
-H "Idempotency-Key: $(uuidgen)" -H "Content-Type: application/json" \
-d '{
"cesionario": {
"rut": "76000000-0",
"razon_social": "Factoring Ejemplo SpA",
"direccion": "Av. Ejemplo 1234, Santiago",
"email": "[email protected]"
},
"ultimo_vencimiento": "2026-10-15"
}'| Field | Required | Note |
|---|---|---|
cesionario.rut | Yes | Módulo 11 check digit |
cesionario.razon_social | Yes | |
cesionario.direccion | Yes | Between 5 and 80 characters — the AEC schema's own minimum and maximum |
cesionario.email | Yes | |
monto | No | CLP, between 1 and the document total. Defaults to the full total |
ultimo_vencimiento | Yes | AAAA-MM-DD |
otras_condiciones, contacto {nombre, fono, email}, email_deudor | No |
202 with a job if this call queued a NEW attempt; 200 with the SAME job if there is already one
in queued/submitted/aec_generated for this document — one attempt at a time. The result lands on
the document, under cesion.status:
"cesion": {
"cedible": true,
"sii_status_code": 25,
"checked_at": "2026-08-23T09:12:40Z",
"status": "confirmed"
}status runs queued → one of:
status | What it means |
|---|---|
submitted | The AEC was assembled, signed and uploaded to the Registro Electrónico de Transferencia de Crédito, which answered "Envío recibido OK" and issued a TrackID. A receipt is not a registration (ticket #69): the registry validates afterwards and notifies a rejection by e-mail to the cedente, hours later. Do not pay against this value. |
confirmed | The registry's own consulta, wsRPETCConsulta.getEstEnvio, answered EOK ("Envío Aceptado") for that TrackID. That is the SII saying the cesión is anotada, and it is the only thing that writes confirmed. |
refused | The SII said no: it refused the upload (the authenticated user has no "Envío de Documentos" permission for the cedente empresa, or the empresa is not a DTE issuer), or the registry rejected the envelope at one of its validation stages |
failed | A fenced attempt, a malformed upload, an SII-side internal error, a transport failure, or an answer nobody recognises and saved for review instead of acted on |
aec_generated | LEGACY. The retired Portal MIPYME walk reached its "AEC ha sido generado exitosamente" page, which produced a FILE and registered nothing. Nothing writes it any more |
An attempt whose envelope never settles within the poll budget keeps submitted (the AEC really
was received) and its job ends failed with cesion_registration_unconfirmed: someone has to open
the Registro de Cesión de Créditos and look.
document.cesion_submitted means "AEC received, anotación pending", not "cesión registered".
The event a factoring integration should pay against is document.cesion_confirmed.
document.cesion_failed covers refused, failed and the registration that could never be
confirmed.
Rejections before anything gets written, on top of the usual 404/permission ones:
| Code | HTTP | When |
|---|---|---|
cesion_tipo_not_cedible | 422 | The type is not 33, 34 or 43 |
cesion_attempt_may_have_registered | 409 | This document's most recent attempt had already put the signed AEC on the wire when it stopped (ticket #76). From here there is no way to know whether it registered in time, so a second cesión on the same factura is refused. Waiting does not resolve it |
In test mode this resolves within the same request, just like the sandbox branch of
POST .../cesion: no socket is opened, the attempt ends simulated, and both webhooks fire —
document.cesion_submitted and then document.cesion_confirmed — so the event you get paid against
in production is exercisable in tests too.
Live submission stays blocked by the owner, and since 2026-09-06 also requires the empresa to be
enabled. The AEC assembly and the upload to the registry are built and checked against the SII's
own schema — the first live upload (2026-09-03) was accepted by the registry with a real TrackID and
then rejected at validation for a signature defect, since fixed. Opening live submission now needs
BOTH of two independent things, neither of which a deploy flips on its own: an environment variable
only the owner exports in their own shell, and the ceding empresa's own connection having reached
onboarding_status=emitting, active, ambiente=palena and not a sandbox connection. A live attempt
missing either one is accepted and queued like any other, and ends failed non-retryably, naming
whichever condition is missing.