Servicios digitales extranjeros y el tipo 46
El ciclo de tres pasos — ingresar cargos, leer sugerencias, confirmar — y de dónde salen los cargos si no los tienes.
Desde la Ley 21.210, cuando un contribuyente chileno de IVA compra servicios digitales a un proveedor extranjero, el comprador pasa a ser el sujeto del impuesto: el proveedor no cobra IVA, el comprador se autoemite una factura de compra (tipo 46) con IVA totalmente retenido, y toma ese IVA como crédito fiscal.
Sobre un millón de pesos mensuales de gasto en publicidad, son CLP 190.000 al mes recuperados. Casi nadie lo hace, porque exige notar cada cargo extranjero y emitir un documento por él.
La API lo modela como un ciclo de tres pasos.
1. Ingresar el cargo
curl -sS https://api.facturia.cl/v1/tax/expenses \
-H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
-H "Idempotency-Key: $(uuidgen)" -H "Content-Type: application/json" \
-d '{
"provider": { "name": "Google Ads", "country": "IE" },
"description": "Google Ads — julio 2026",
"amount_original": 1050.00,
"currency": "USD",
"date": "2026-07-31",
"fx_rate": 952.4,
"fx_source": "card_rate",
"external_id": "card-txn-99381"
}'Trampa
El tipo de cambio lo pones tú
fx_rate es obligatorio cada vez que currency no es CLP. Omítelo y la llamada falla con
400 fx_rate_required.
No inventamos un tipo de cambio, porque esa cifra determina la base en pesos de un documento tributario y adivinarla nos convertiría en los autores de tu posición fiscal.
Qué fx_source usar
- Recomendado:
card_rate— el tipo de cambio de liquidación que aplicó efectivamente tu emisor de tarjeta, es decir los pesos que realmente salieron de la cuenta. Es la cifra que puedes defender con una cartola, y es la que esta documentación recomienda. sii_observado(el dólar observado publicado para la fecha) ycustomtambién se aceptan, y se guardan textualmente en el gasto y en el documento resultante.
Salvedad documentada
Cuál tipo de cambio es definitivamente correcto para el tipo 46 sobre servicios digitales extranjeros no está zanjado por un pronunciamiento que estemos dispuestos a citar. Nuestra recomendación es la de un practicante, no asesoría tributaria, y está en revisión con un contador. Si esa revisión cambia la guía, lo diremos en el changelog en vez de cambiar el default en silencio.
Lo que envíes es lo que usamos, y queda visible en el documento para siempre — que es la propiedad que importa si alguna vez se cuestiona el criterio.
2. Leer la sugerencia
curl -G https://api.facturia.cl/v1/tax/suggestions \
-H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
-d type=emit_46 -d status=open{
"id": "sug_01K2RE2X7Q9V",
"object": "suggestion",
"type": "emit_46",
"status": "open",
"period": "2026-07",
"confidence": 0.96,
"reason": "Cargo en moneda extranjera de un proveedor de servicios digitales sin IVA. Corresponde emitir factura de compra (46) con IVA totalmente retenido.",
"estimated_benefit": { "iva_credit": 190000 },
"source": { "object": "expense", "id": "exp_01K2RE1M4T8P" },
"proposed_document": {
"tipo_dte": 46,
"receptor": { "rut": "55555555-5", "legal_name": "Google Ads", "foreign": true },
"items": [{ "description": "Google Ads — julio 2026", "quantity": 1, "unit_price": 1000000 }],
"withholding": { "iva": "total" }
},
"f29_effect": [ { "code": 39, "value": 190000 }, { "code": 519, "value": 190000 } ],
"created_at": "2026-08-01T03:12:00Z"
}f29_effect es la parte útil: te dice de antemano en qué códigos del F29 va a aterrizar el documento
si lo confirmas.
3. Confirmar o descartar
# Confirmar — emite el tipo 46 y devuelve el documento
curl -X POST https://api.facturia.cl/v1/tax/suggestions/sug_01K2RE2X7Q9V/confirm \
-H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
-H "Idempotency-Key: $(uuidgen)"
# …o descartarla (con un motivo del que aprendemos)
curl -X POST https://api.facturia.cl/v1/tax/suggestions/sug_01K2RE2X7Q9V/dismiss \
-H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
-H "Content-Type: application/json" -d '{"reason":"not_digital_service"}'Con auto_emit_46: true en la empresa, el paso 3 ocurre solo para las sugerencias bajo el tope
configurado (auto_emit_46_max_amount), y te enteras por document.created más
tax.suggestion.auto_confirmed. Por encima del tope, se queda como sugerencia.
El catálogo de sugerencias
type | Detecta |
|---|---|
emit_46 | Servicios digitales extranjeros que corresponde autofacturar |
missing_characterization | Entradas del RCV que van a distorsionar el F29 |
folios_low | Un tipo de documento a punto de quedarse sin folios |
unclaimed_credit | Un documento recibido que sigue en PENDIENTE pasado el cierre del período |
Eventos: tax.suggestion.created, tax.suggestion.auto_confirmed.
De dónde salen los cargos si no los tienes
POST /v1/tax/expenses asume que ya tienes los datos del cargo. Dos conectores de primera parte
quitan ese supuesto, y ambos alimentan exactamente el mismo libro de gastos — un gasto creado por un
conector es indistinguible de uno que publicaste tú, salvo por su source.
Fintoc — movimientos de banco y tarjeta
curl -sS https://api.facturia.cl/v1/connections \
-H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
-H "Idempotency-Key: $(uuidgen)" -H "Content-Type: application/json" \
-d '{"provider":"fintoc","account_types":["checking","credit_card"],"sync_frequency":"daily"}'{
"id": "con_01K2RJ7B2W4M",
"object": "connection",
"provider": "fintoc",
"status": "pending_link",
"link_url": "https://facturia.cl/connect/con_01K2RJ7B2W4M",
"accounts": [],
"sync_frequency": "daily",
"last_synced_at": null,
"created_at": "2026-08-14T15:02:11Z"
}Mandas a la persona por el link_url una vez y empiezan a llegar movimientos. Cada sincronización se
queda con los movimientos en moneda extranjera — eso es todo lo que miramos: esto es una función
tributaria, no un producto de feed bancario — los convierte en un expense con source: "fintoc" y
el tipo de cambio de liquidación que reportó el emisor como fx_rate / fx_source: card_rate, y deja
correr el detector normal.
Las credenciales viven en Fintoc; Facturia guarda un token de enlace, nunca una clave bancaria.
Eventos: connection.linked, connection.sync_succeeded, connection.sync_failed,
connection.requires_relink.
`connection.requires_relink` no es opcional
Es el modo de falla casi universal de los feeds bancarios. Lo publicamos como evento justamente para que un asistente pueda pedirle a la persona que reconecte, en vez de que el feed se apague en silencio y nadie note que dejaron de aparecer gastos.
Cartola — carga de CSV/XLSX
Para los bancos que Fintoc no cubre, y para el contador que ya tiene la cartola en una planilla.
curl -sS https://api.facturia.cl/v1/tax/statements \
-H "Authorization: Bearer $FACTURIA_KEY" -H "Facturia-Empresa: $EMPRESA" \
-H "Idempotency-Key: $(uuidgen)" \
-F "file=@cartola-julio.csv" \
-F "format=auto" \
-F "default_currency=USD"La importación es asíncrona y devuelve un job cuyo result reporta rows_read, expenses_created,
duplicates_skipped y errors[] por fila. format=auto olfatea los layouts bancarios chilenos
comunes; pasa un formato explícito cuando se equivoque.
La deduplicación es por (empresa, date, amount_original, currency, provider) más tu external_id
cuando existe, así que volver a subir una cartola que se traslapa es seguro — que es la forma normal
en que la gente usa archivos de cartola, y un importador que duplica en el traslape es peor que no
tener importador.
Lo que no está en la v1
Traer las facturas directamente de Meta Ads, Google Ads y compañía es el paso siguiente obvio y
está explícitamente fuera de la v1. Cada plataforma es una superficie OAuth distinta con sus propias
rarezas de exportación de facturación, y Fintoc más la carga de cartolas ya capturan los mismos
cargos desde el lado que paga. Mientras tanto, usa POST /v1/tax/expenses para los cargos de
plataforma que quieras anotar con más detalle del que permite una línea de tarjeta.