Facturiadocs
Empieza aquí

El sandbox

Modo test — qué garantiza, cómo forzar un rechazo o un reparo, y los test helpers que mueven el mundo exterior.

Qué es, y qué no es

Modo test (sk_test_)Certificación SII (sk_live_, empresa ambiente: certificacion)Producción (sk_live_, empresa ambiente: produccion)
Tráfico al SIIningunomaullin / apicert (servidores de prueba del SII)palena / api.sii.cl
Certificado requeridonosí (el .pfx real de la empresa)
CAF real requeridono (folios virtuales)sí (CAF de maullin)
Latencia a estado terminal~1 s, deterministaminutos a horasminutos a horas
Resultadoforzablelo que diga el SIIlo que diga el SII
Efecto legalningunoningunocompleto
Preciogratis para siempremedidomedido

El modo test es una simulación completa en proceso. Nunca abre un socket al SII, así que es instantáneo, determinista e inmune a las ventanas de mantención del SII. La certificación SII es el SII real en sus servidores de prueba, usada durante la puesta en marcha para certificar una empresa específica — rara vez la manejarás directamente.

Garantías de determinismo

En modo test:

  • Los folios parten en 1 por cada (empresa, tipo_dte) e incrementan de a uno. No se necesita CAF; GET /v1/folios reporta un rango virtual de 1 a 1.000.000.
  • El track_id es un entero sintético creciente de 10 dígitos que empieza en 9000000001.
  • Los documentos se asientan queued → sent → accepted en aproximadamente un segundo, disparando cada webhook que dispararía un documento real.
  • El XML es válido contra el esquema, firmado con el certificado de sandbox de Facturia, y lleva un TED construido desde un CAF de sandbox. No va a validar contra el SII — ese es el punto.
  • Los PDF traen el layout real con una marca de agua SIN VALOR TRIBUTARIO.
  • Todo objeto lleva estampado "mode": "test".

Los límites de tasa del modo test son los mismos que los de live, así que una prueba de carga es representativa.

Forzar resultados

Agrega un objeto test a cualquier emisión.

curl -sS https://api.facturia.cl/v1/documents \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Content-Type: application/json" \
  -d '{
    "tipo_dte": 33,
    "receptor": { "rut": "76543212-K" },
    "items": [{ "description": "Consultoría", "quantity": 1, "unit_price": 1200000 }],
    "test": { "outcome": "rejected", "reason_code": "TED-2-510", "settle_after_ms": 3000 }
  }'
test.outcomeResultado
accepted (por defecto)status: accepted, estado SII DOK
reparostatus: reparo, estado SII DNK, un rejection_reason
rejectedstatus: rejected, estado de sobre RCT, reason_code devuelto tal cual
failedstatus: failed antes de transmitir (simula una falla al armar o firmar)
stuckse queda en sent para siempre (para probar tus timeouts de polling)

Trampa

El campo test es una alarma, no una opción

Enviar el objeto test con una llave live se rechaza con 400 test_field_in_live_mode. Es un cable trampa deliberado: el código de simulación no puede correr en silencio contra el SII.

Si tu cliente no puede agregar campos, los RUT de receptor mágicos hacen lo mismo:

RUT del receptorFuerza
44444440-1accepted
44444441-Kreparo
44444442-8rejected
44444443-6failed
44444444-4stuck
66666666-6consumidor final anónimo (válido también en live, solo boletas)

Test helpers

Los endpoints bajo /v1/test_helpers existen solo para llaves de test (403 test_mode_only en otro caso). Te dejan manejar las mitades del sistema que normalmente maneja el mundo exterior.

# Inyectar un DTE de proveedor como si hubiera llegado a 77928532-4@dte.facturia.cl
curl -sS https://api.facturia.cl/v1/test_helpers/received_documents \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Facturia-Empresa: $EMPRESA" \
  -H "Content-Type: application/json" \
  -d '{
    "tipo_dte": 33,
    "folio": 8812,
    "emisor": { "rut": "96790240-3", "legal_name": "Proveedor Austral SpA" },
    "issue_date": "2026-08-12",
    "totals": { "net": 450000, "iva": 85500, "total": 535500 }
  }'
# Sembrar filas de RCV en un período para que la propuesta de F29 tenga sobre qué calcular
curl -sS https://api.facturia.cl/v1/test_helpers/rcv/seed \
  -H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
  -H "Content-Type: application/json" \
  -d '{"period":"2026-07","purchases":12,"sales":40}'

# Adelantar el reloj simulado de esta empresa
# (prueba la ventana de acuse de 8 días, el vencimiento de folios, los plazos del F29)
curl -sS https://api.facturia.cl/v1/test_helpers/clock \
  -H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
  -H "Content-Type: application/json" \
  -d '{"advance_days":9}'

# Llevar una máquina de estados de puesta en marcha a cualquier estado sin esperar al SII
curl -sS https://api.facturia.cl/v1/test_helpers/empresas/emp_01K2R.../onboarding \
  -H "Authorization: Bearer $FACTURIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"action_required","step":"sii_postulacion"}'

El helper del reloj es cómo se prueba la ventana de 8 días

Inyecta un documento recibido, avanza el reloj nueve días y observa cómo la respuesta comercial deja de aceptar acciones con 422 commercial_response_window_closed. Es la única forma de ejercitar ese plazo sin esperar más de una semana. La ventana está explicada en La ventana de 8 días.

Realidades de arriba que igual conviene diseñar

Por encima de nuestros límites hay dos realidades del SII que existen aunque el sandbox no las simule: el SII limita tasa sin publicar sus cifras, y tiene ventanas de mantención programadas. La emisión está encolada de nuestro lado, así que una ráfaga sobre 10 req/s es un 429 del lado del cliente, nunca un documento perdido — pero un documento que ya aceptamos va a quedarse en queued más tiempo durante una caída del SII. Construye sobre webhooks, no sobre polling apretado.

En esta página