# Foreign digital services and tipo 46 (/en/docs/impuestos/tipo-46)

Since Ley 21.210, when a Chilean IVA (value-added tax) taxpayer buys digital services from a foreign
provider, the buyer becomes the taxable party: the provider charges no IVA, the buyer self-issues a
**factura de compra (tipo 46) with the IVA fully withheld** — a purchase invoice it raises in the
supplier's name — and takes that IVA as an input credit.

On a million pesos a month of advertising spend, that is CLP 190.000 a month recovered. Almost nobody
does it, because it means noticing every foreign charge and issuing a document for each one.

The API models it as a three-step cycle.

## 1. Enter the charge [#1-enter-the-charge]

```bash
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"
  }'
```

> **Trap — You supply the exchange rate**
>
> `fx_rate` is &#x2A;*required every time `currency` is not `CLP`**. Omit it and the call fails with
> `400 fx_rate_required`.
>
> We don't invent an exchange rate, because that figure sets the peso base of a tax document, and
> guessing it would make us the authors of your tax position.

### Which `fx_source` to use [#which-fx_source-to-use]

* **Recommended: `card_rate`** — the settlement rate your card issuer actually applied, that is, the
  pesos that really left the account. It is the figure you can defend with a cartola (a bank
  statement), and it is the one this documentation recommends.
* `sii_observado` (the *dólar observado* published for that date) and `custom` are accepted too, and
  are stored verbatim on the expense and on the resulting document.

> **A documented caveat**
>
> Which exchange rate is *definitively* correct for a tipo 46 over foreign digital services is not
> settled by any ruling we are willing to cite. Our recommendation is a practitioner's, not tax advice,
> and it is under review with an accountant. If that review changes the guidance, we will say so in the
> changelog instead of quietly changing the default.
>
> What you send is what we use, and it stays visible on the document forever — which is the property
> that matters if the criterion is ever questioned.

## 2. Read the suggestion [#2-read-the-suggestion]

```bash
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
```

```json
{
  "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` is the useful part: it tells you up front which codes on the F29 (the monthly IVA
return) the document will land in if you confirm it.

## 3. Confirm or dismiss [#3-confirm-or-dismiss]

```bash
# 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"}'
```

With `auto_emit_46: true` on the empresa, step 3 happens on its own for suggestions under the
configured cap (`auto_emit_46_max_amount`), and you find out through `document.created` plus
`tax.suggestion.auto_confirmed`. Above the cap, it stays a suggestion.

## The suggestion catalogue [#el-catalogo-de-sugerencias]

| `type`                     | Detects                                                                                |
| -------------------------- | -------------------------------------------------------------------------------------- |
| `emit_46`                  | Foreign digital services that ought to be self-invoiced                                |
| `missing_characterization` | Entries in the RCV (the purchase-and-sales register) that are going to distort the F29 |
| `folios_low`               | A document type about to run out of folios (its pre-authorised numbers)                |
| `unclaimed_credit`         | A received document still in `PENDIENTE` past the close of the period                  |

Events: `tax.suggestion.created`, `tax.suggestion.auto_confirmed`.

## Where the charges come from if you don't have them [#where-the-charges-come-from-if-you-dont-have-them]

`POST /v1/tax/expenses` assumes you already have the charge's data. Two first-party connectors take
that assumption away, and both feed exactly the same expense ledger — an expense created by a
connector is indistinguishable from one you posted yourself, except for its `source`.

### Fintoc — bank and card transactions [#fintoc--bank-and-card-transactions]

```bash
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"}'
```

```json
{
  "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"
}
```

You send the person through `link_url` once and transactions start arriving. Each sync keeps the
foreign-currency transactions — that is all we look at: this is a tax function, not a bank-feed
product — turns them into an `expense` with `source: "fintoc"` and the settlement rate the issuer
reported as `fx_rate` / `fx_source: card_rate`, and lets the normal detector run.

The credentials live at Fintoc; Facturia stores a link token, never a bank password.

Events: `connection.linked`, `connection.sync_succeeded`, `connection.sync_failed`,
`connection.requires_relink`.

> **`connection.requires_relink` is not optional**
>
> It is the near-universal failure mode of bank feeds. We publish it as an event precisely so an
> assistant can ask the person to reconnect, instead of the feed going quiet and nobody noticing that
> expenses stopped appearing.

### Cartola — CSV/XLSX upload [#cartola--csvxlsx-upload]

For the banks Fintoc doesn't cover, and for the accountant who already has the cartola in a
spreadsheet.

```bash
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"
```

The import is asynchronous and returns a job whose `result` reports `rows_read`, `expenses_created`,
`duplicates_skipped` and per-row `errors[]`. `format=auto` sniffs the common Chilean bank layouts;
pass an explicit format when it gets one wrong.

Deduplication is on `(empresa, date, amount_original, currency, provider)` plus your `external_id`
when there is one, so re-uploading an overlapping cartola is safe — which is how people normally use
statement files, and an importer that duplicates on the overlap is worse than no importer at all.

### What is not in v1 [#what-is-not-in-v1]

Pulling the invoices straight from Meta Ads, Google Ads and company is the obvious next step and is
explicitly out of scope for v1. Every platform is a different OAuth surface with its own
billing-export quirks, and Fintoc plus statement upload already catch the same charges from the
paying side. In the meantime, use `POST /v1/tax/expenses` for the platform charges you want to record
in more detail than a card line allows.
