Folios y CAF
Listar los CAF de una empresa, contar los folios de un rango y volver a bajar un CAF puntual con folioInicial.
Esta guía cubre tres operaciones de CAF que se usan juntas, en este orden:
caf_v1_listar: qué CAF autorizó el SII para la empresa y el tipo de documento.caf_v1_estado_folios, opcional: cuántos folios de uno de esos CAF el SII todavía no recibió, cuántos ya no permite anular y cuántos se anularon.caf_v1_reobtenerconfolioInicial: volver a bajar uno de esos CAF, ya timbrado.
Ninguna de las tres pide folios nuevos: para eso está caf_v1_descargar. Las tres están vigentes desde el despliegue de la API del 2026-10-17 (versión 1.5.0 del contrato).
Antes de empezar
- El certificado va en el cuerpo del POST, con
DatayContrasenna, como en las demás operaciones de CAF. Mande siempre el cuerpo: sin él,caf_v1_listarycaf_v1_estado_foliosrespondenCERT_REQUERIDO.caf_v1_reobtenertambién, desde el despliegue de la versión 1.5.3; hasta entonces responde un error del framework en JSON. - Pase
ambienteexplícito, 0 o 1, y el mismo en las tres. Si lo omite, las tres corren en producción. Con un número distinto de 0 y 1,caf_v1_listarycaf_v1_estado_folioscorren en homologación ycaf_v1_reobteneren producción: no corren en el mismo ambiente. Más en Ambientes. - El certificado no se valida en el mismo ambiente en las tres.
caf_v1_listarycaf_v1_estado_folioslo validan en el ambiente pedido.caf_v1_reobtener, también confolioInicial, lo valida siempre en producción, aunque pidaambiente=0. Un certificado habilitado solo en el ambiente de certificación del SII sirve para listar conambiente=0, pero no para reobtener: el error habla del certificado, no del ambiente. - El titular del certificado tiene que estar autorizado por la empresa para operar con folios (CAF) en el SII. No hace falta que administre usuarios. Además,
caf_v1_listarycaf_v1_estado_foliosconsultan la opción de anulación masiva del SII: una empresa que no está habilitada ahí recibeCONTRIBUYENTE_SIN_PERMISO, y eso lo tiene que resolver la empresa con el SII. - Las tres hablan con el SII en serie y pueden tardar decenas de segundos. Configure un timeout de cliente de al menos 70 segundos. Pasados 60 segundos, la capa de entrada de la API responde 504 con una página HTML, sin código: está en Tiempos de respuesta y 504.
Paso 1: listar los CAF
caf_v1_listar es POST /v1/caf/{rut}/listar/{tipoDocumento}:
curl -u '<usuario>:<apikey>' -X POST \
-H 'Accept: application/json' -H 'Content-Type: application/json' \
-d '{"Data": "<pfx en base64>", "Contrasenna": "********"}' \
'https://api.enrolamiento.cl/v1/caf/11111111-1/listar/33?ambiente=0'La respuesta trae Cafs, un elemento por CAF, ordenados por FolioInicial de mayor a menor:
{
"Cafs": [
{ "FolioInicial": 1101, "FolioFinal": 1200, "Cantidad": 100, "Fecha": "12-03-2026", "Dueno": "Usuario Ejemplo", "RUTDueno": "12345678-5" },
{ "FolioInicial": 1001, "FolioFinal": 1100, "Cantidad": 100, "Fecha": "05-01-2026", "Dueno": "Usuario Ejemplo", "RUTDueno": "12345678-5" }
]
}- Vienen todos los CAF que el SII lista, también los ya usados o anulados enteros. Que un CAF esté en la lista no dice que le queden folios: para eso está el paso 2.
Cafsvacía quiere decir que el SII no lista CAF de ese tipo para la empresa. Nunca es nula.- Es una lectura: no timbra ni anula nada, y repetirla no cambia nada en el SII.
- Reemplaza a
caf_v1_anulacion_masiva_listarpara listar CAF: el mismo modelo de respuesta, pero en el ambiente pedido y verificando el permiso del certificado.
Errores de este paso. Los del certificado (CERT_REQUERIDO, CERT_EXPIRADO, CERT_NO_VALIDO y los demás de la tabla de la operación), CERT_SIN_PERMISO si el titular no está autorizado por la empresa, SEC_EMP_NOT_AUTHORIZED si la empresa opera en la modalidad MiPyme, CONTRIBUYENTE_SIN_PERMISO, SII_ERROR_CXN (reintentable; desde el despliegue de la versión 1.5.3, también cuando el SII pide volver a iniciar sesión) y SII_RESPUESTA_INESPERADA (no reintentable). Esta operación nunca responde 429.
Paso 2: contar los folios de un CAF
caf_v1_estado_folios es POST /v1/caf/{rut}/estado-folios/{tipoDocumento}/{folioInicial}/{folioFinal}. Tome FolioInicial y FolioFinal de un CAF del paso 1, o un subrango: el rango tiene que caber entero en un solo CAF.
curl -u '<usuario>:<apikey>' -X POST \
-H 'Accept: application/json' -H 'Content-Type: application/json' \
-d '{"Data": "<pfx en base64>", "Contrasenna": "********"}' \
'https://api.enrolamiento.cl/v1/caf/11111111-1/estado-folios/33/1001/1100?ambiente=0'{ "Rut": "11111111-1", "TipoDocumento": 33, "FolioInicial": 1001, "FolioFinal": 1100,
"Cantidad": 100, "Disponibles": 60, "Utilizados": 38, "Anulados": 2 }Qué dice cada número:
| Campo | Qué es |
|---|---|
Cantidad | Los folios del rango: FolioFinal - FolioInicial + 1. Siempre es Disponibles + Utilizados + Anulados. |
Disponibles | Los que el SII todavía no recibió ni anuló. Lo informa el SII. |
Utilizados | Los que el SII ya no permite anular: en la práctica, los de documentos que el SII recibió. No lo informa el SII: se calcula como Cantidad - Disponibles - Anulados. |
Anulados | Los anulados en el SII. Lo informa el SII. |
Disponibles no es la cantidad de folios libres para emitir. Puede incluir folios que usted ya usó en documentos que aún no envió al SII. Para decidir qué folio emitir, use su propio foliado. Para saber el último folio emitido, use caf_v1_consulta: esta operación cuenta un rango.
Consulte bajo demanda, un CAF a la vez. Cada llamada es una consulta completa al SII, y no hay una consulta de varios CAF juntos. Recorrer todos los CAF del paso 1 cuesta una llamada por CAF, y cada una cuenta para el límite de requests. Si necesita varios CAF, haga una llamada por CAF y en secuencia. La suma de los subrangos de un CAF no tiene por qué coincidir con una sola consulta del CAF entero si entre una y otra se emitieron o anularon folios.
Errores de este paso. Antes de validar el certificado o consultar al SII, también con el RUT de prueba: PARAMETRO_FUERA_DE_RANGO si un folio es menor que 1 o folioInicial es mayor que folioFinal, y NO_SOPORTADO_BOLETAS si pide boletas (39 o 41) en producción; las boletas solo se consultan con ambiente=0. Después, los mismos del paso 1, más CAF_NO_ENCONTRADO si el rango no cabe entero en un solo CAF del listado del SII, y SII_RESPUESTA_INESPERADA si los conteos del SII no cuadran con el rango: nunca un 200 con ceros. Esta operación nunca responde 429.
Paso 3: volver a bajar un CAF con folioInicial
caf_v1_reobtener es POST /v1/caf/{rut}/reobtener/{tipoDocumento}. Sin folioInicial devuelve el último CAF, como siempre. Con folioInicial, el FolioInicial de un CAF del paso 1, devuelve el CAF que empieza en ese folio:
curl -u '<usuario>:<apikey>' -X POST \
-H 'Accept: application/json' -H 'Content-Type: application/json' \
-d '{"Data": "<pfx en base64>", "Contrasenna": "********"}' \
'https://api.enrolamiento.cl/v1/caf/11111111-1/reobtener/33?folioInicial=1101&ambiente=0'- No pide folios nuevos. El CAF ya está timbrado: repetir la llamada vuelve a bajar el mismo CAF. No se aplica el filtro de 3 meses de
descargarCafAntiguos, que confolioInicialno se usa. - El certificado se valida en producción, aunque pida
ambiente=0. Vea Antes de empezar. - El CAF se busca solo en la primera página del listado de reobtención del SII, que no es la fuente de
caf_v1_listar. Un CAF que el paso 1 muestra, de los más antiguos, puede no estar en esa primera página: la respuesta esCAF_NO_ENCONTRADOaunque el CAF exista. Hoy la API no tiene cómo reobtener ese CAF, ycaf_v1_descargarconultimoFoliotampoco: mira la misma primera página y, si no encuentra el CAF, pide folios nuevos. En ese caso, contacte a soporte con el RUT, el tipo de documento y el folio inicial. - Pídalos en secuencia. Si su cuenta tiene el control de solicitudes concurrentes de CAF, las solicitudes del mismo RUT, tipo de documento y ambiente se atienden de a una, entre
caf_v1_descargar,caf_v1_reobtenerycaf_v1_anular. Si va a bajar varios CAF del mismo RUT y tipo, no los pida en paralelo. El detalle está en 409 y 429.
Verifique el CAF que recibe
La respuesta es un string JSON con el XML del CAF en base64 (ver Formatos). Antes de usarlo, verifique que el CAF empiece en el folio que pidió: el <D> de <RNG> del XML tiene que ser folioInicial. Una API sin la versión 1.5.0 ignora el parámetro en silencio y devuelve el último CAF con un 200. Si no empieza ahí, no use ese CAF: vuelva a pedirlo o contacte a soporte.
// Node.js: decodifica la respuesta de caf_v1_reobtener y verifica que el CAF empiece en folioInicial.
async function cafQueEmpiezaEn(respuesta, folioInicial) {
const base64 = await respuesta.json(); // un string JSON
const xml = Buffer.from(base64, 'base64').toString('latin1');
const desde = /<RNG>\s*<D>\s*(\d+)\s*<\/D>/.exec(xml)?.[1];
if (Number(desde) !== Number(folioInicial)) {
throw new Error(`El CAF devuelto empieza en ${desde ?? '(sin RNG)'}, no en ${folioInicial}: no lo use.`);
}
return xml;
}Errores de este paso. PARAMETRO_FUERA_DE_RANGO antes que todo, también con el RUT de prueba, si folioInicial no es un entero mayor o igual a 1 o viene repetido. Después, CERT_REQUERIDO si falta el cuerpo o le falta Data o Contrasenna (desde el despliegue de la versión 1.5.3, antes de esperar por otra solicitud en curso), los del certificado validado en producción; CAF_NO_ENCONTRADO si ningún CAF de la primera página empieza en folioInicial; y, si el listado o la descarga trajo una página del SII, NO_CAF, CERT_SIN_PERMISO, SEC_EMP_NOT_AUTHORIZED o SII_ERROR_CXN según la página, o UNKNOWN_ERROR_CAF con el motivo en el mensaje. Con folioInicial, UNKNOWN_ERROR_CAF no pide folios nuevos: el CAF ya está timbrado; lea el mensaje y reintente más tarde. Con el control de solicitudes concurrentes, también el 429 de CAF_REQUEST_IN_PROGRESS.
Qué hacer con cada código
| Código | Paso | Qué hacer |
|---|---|---|
SII_ERROR_CXN | 1, 2 y 3 | Reintente respetando Retry-After (30 segundos), con espera exponencial (30, 60 y 120 segundos) y un tope de 3 intentos. En el SII de producción es frecuente e intermitente. Desde el despliegue de la versión 1.5.3, en los pasos 1 y 2 también llega cuando el SII pide volver a iniciar sesión: si persiste, espere 15 minutos y repita (ver Ambientes). |
| 504 con una página HTML | 1, 2 y 3 | Es la capa de entrada de la API, que cortó a los 60 segundos. En los pasos 1 y 2, repita: son lecturas. En el paso 3, repita pasados 30 segundos: el pedido puede seguir en curso. |
CAF_REQUEST_IN_PROGRESS | 3 | Espere los segundos de Retry-After y repita el mismo request. |
CAF_NO_ENCONTRADO | 2 | Pida un rango que quepa entero en un CAF del paso 1. |
CAF_NO_ENCONTRADO | 3 | Revise que folioInicial sea el FolioInicial de un CAF del paso 1. Si lo es, el CAF no está en la primera página: contacte a soporte. No lo reintente. |
UNKNOWN_ERROR_CAF | 3 | Lea el mensaje y reintente más tarde. No pida folios nuevos por esto. |
NO_CAF | 3 | El SII no registra CAF de ese tipo para la empresa: no hay nada que reobtener. |
PARAMETRO_FUERA_DE_RANGO | 2 y 3 | Corrija el folio. Repetir da el mismo error. |
NO_SOPORTADO_BOLETAS | 2 | Las boletas (39 y 41) solo se consultan con ambiente=0. |
CERT_SIN_PERMISO | 1, 2 y 3 | Use el certificado de un usuario autorizado por la empresa para operar con folios. |
CONTRIBUYENTE_SIN_PERMISO | 1 y 2 | La empresa tiene que habilitarse en la anulación masiva del SII. |
SII_RESPUESTA_INESPERADA | 1 y 2 | No reintente; contacte a soporte con el RUT. Hasta el despliegue de la versión 1.5.3 también llega si el SII rechazó la sesión, por ejemplo al alternar de ambiente con el mismo certificado: vea Ambientes. |
Un código que no está en esta tabla se resuelve con la tabla «Reintentos e idempotencia» de la operación y, si tampoco está ahí, con la regla de respaldo.
Probar sin el SII
Con el RUT 1-9 o un RUT de prueba de su perfil de cliente, las tres responden sin consultar al SII ni validar el certificado:
caf_v1_listardevuelve siempre un único CAF de ejemplo, del folio 1 al 10.caf_v1_estado_foliosresponde cualquier rango válido con todos sus folios disponibles, sin contrastarlo con ese CAF de ejemplo.caf_v1_reobtenerresponde una cadena vacía (""en JSON), con o sinfolioInicial. La verificación del<D>de<RNG>no aplica a esa respuesta.
PARAMETRO_FUERA_DE_RANGO y NO_SOPORTADO_BOLETAS sí llegan con el RUT de prueba, porque se revisan antes. Los errores del SII no se simulan: CAF_NO_ENCONTRADO, SII_ERROR_CXN y los rechazos solo se ven contra el SII, en certificación con una empresa real.