Factuarea API

International customers

Identifying a non-Spanish recipient with the AEAT alternative-ID catalogue, and the scenario-to-qualification map for intra-EU supplies, reverse charge, exports and one-stop-shop sales.

Invoicing outside Spain raises two questions the domestic case never does: how do you identify a recipient who has no Spanish tax ID, and what does the AEAT receive for an operation that is exempt, reverse-charged or located abroad. They are independent, and this page answers them in that order.

When this applies

Whenever the recipient is not a Spanish taxpayer, or the operation is located outside mainland Spanish VAT territory. Identification is a property of the customer; qualification is a property of the operation, and the same customer can appear in operations of different kinds.

Identifying the customer

A non-Spanish customer is identified with alternative_id, an object of {type, value, country_code} that is mutually exclusive with the Spanish tax_id (BR-CLI-017). The type belongs to the AEAT identification catalogue, list L7, and each case has its own numeric code that travels in the VeriFactu chain:

typeAEAT codeMeaning
nif_iva02Intra-community VAT operator number.
passport03Passport.
country_id04Official identification document of the country of residence.
residence_certificate05Tax residence certificate.
other_document06Other supporting document.
not_registered07Not listed on the AEAT census (No censado).

The type-country matrix is a hard invariant, not a suggestion: nif_iva is legal only for EU countries, because it is the intra-community operator number; the other types are valid for any non-Spanish country; and country_code: "ES" is always refused, because Spain uses tax_id. An illegal combination answers 422:

curl -X POST https://api.factuarea.com/v1/clients \
  -H "Authorization: Bearer fact_live_3pXnR2VbY7TcA9eFmN5z8KqW" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Müller GmbH",
        "alternative_id": { "type": "nif_iva", "value": "DE811569869", "country_code": "DE" }
      }'

The legacy values tax_id_foreign and national_id are still accepted so that existing integrations do not break. Normalisation is country-aware: national_id becomes country_id unconditionally, while tax_id_foreign becomes nif_iva for an EU country and other_document otherwise — because a tax_id_foreign from outside the EU cannot be an intra-community number, and the matrix would refuse it.

If you do not send alternative_id at all — a foreign customer with only a country and a tax identifier — the VeriFactu chain falls back to identification type 02, the most common intra-community case. Sending the field explicitly is strictly better.

vat_id is free text, and it is not verified

The intra-community VAT number field accepts any string up to 20 characters. It is not validated against the VIES registry, not format-checked per country, and not cross-checked against tax_id (BR-CLI-003). A wrong country prefix is accepted. A customer who should be under the intra-community regime but has no vat_id is neither blocked nor flagged.

vat_id and tax_id are separate fields that coexist: a Spanish company can carry a national tax ID and the same number with the country prefix as its intra-community VAT number.

Verifying a Spanish recipient before invoicing

For recipients that do have a Spanish tax ID, POST /v1/clients/census-verification (scope clients:read) checks the name-and-tax-ID pair against the AEAT census before you invoice, anticipating the most frequent VeriFactu rejection — the one for a recipient the census does not identify (BR-CLI-015).

It is deliberately informative: it never blocks saving a customer or issuing an invoice, it persists nothing, and it is fail-open — an unreachable AEAT answers 200 with an unavailable status, never a 5xx. It is throttled, because it may reach the AEAT network. See Census verification for the full flow.

The scenario map

This is the map from business scenario to what the AEAT receives (BR-VFC-029):

ScenarioHeader operation regimeWhat reaches the AEAT
Intra-community supply of goodsintracomunitariaE5 — subject and exempt, art. 25 LIVA
Services with reverse chargeispS2 — subject and not exempt, charged quota 0 (the recipient self-charges)
Export outside the EUimportacion_exportacionE2 — subject and exempt, art. 21 LIVA
Distance sales under the one-stop shop(general)regime_key: 17 — Chapter XI of Title IX, OSS and IOSS

Reverse charge is not an exemption. It is a qualification derived from the header regime — S2, subject and not exempt, with the charged quota forced to zero because the recipient accounts for the tax. It is not a line exemption cause, and in particular it is not E4: that code is the exemption under arts. 23 and 24 LIVA, for customs warehouses and suspension arrangements, which is a different thing entirely. An invoice that declares reverse charge as an exempt operation misstates both the qualification and the quota.

The four qualifications reachable from the header regime are S1 (general), S2 (reverse charge), E5 (intra-community) and E2 (import or export). The other exemption codes — E1, E3, E4, E6 — exist in the AEAT catalogue but are reachable only as a line exemption cause.

What the API sends

Here is the part that decides how you build the payload, and it is a real constraint rather than a style preference.

The header operation regime is read-only over v1. Neither POST /v1/invoices nor PUT /v1/invoices/{id} accepts operation_regime; the invoice object returns it, and every invoice created through the public API is born under the general regime. The document-level exemption cause is read-only for the same reason.

The customer's preferred_operation_regime — accepted on POST /v1/clients with the values general, intracomunitaria, importacion_exportacion and isp — is stored and returned, but it does not set the regime of the invoices you create. It is a declarative preference for your own use.

What you can express per line is the exemption cause. So:

ScenarioHow you express it in v1
Intra-community supply of goodstax_rate: 0 + exemption_reason: "E5" per line.
Export outside the EUtax_rate: 0 + exemption_reason: "E2", usually with regime_key: "02".
One-stop-shop distance salesregime_key: "17" per line, with the destination-country rate.
Reverse chargeNot expressible. S2 derives from the header regime, and the line catalogue contains no S codes by design.

That last row is the honest answer, and it matters: an invoice with reverse charge created through the public API will be qualified S1 with a charged quota, which is not what you mean. Until the header regime becomes writable, issue those invoices from the dashboard. It is recorded in Scope and limitations.

The published intracomunitario_bienes example on the create operation is exactly this shape — zero rate plus E5 plus an explicit regime key — rather than a header regime it could not set:

{
  "client_id": "0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42",
  "series_id": "019e5584-7a72-7038-a8f6-561ed180b699",
  "issued_on": "2026-06-01",
  "due_on": "2026-07-01",
  "notes": "Entrega intracomunitaria de bienes exenta (art. 25 LIVA)",
  "lines": [
    {
      "description": "Suministro de maquinaria a cliente UE (DE)",
      "quantity": 1,
      "unit_price": 5000,
      "tax_rate": 0,
      "exemption_reason": "E5",
      "regime_key": "01"
    }
  ]
}

A simplified invoice is never an option for any of these scenarios: the eligibility check blocks intra-community operations, reverse charge and any recipient outside Spain before the amount is even considered. See Simplified or full invoices.

What appears on the PDF

The recipient block prints the alternative identification exactly as supplied, frozen at issue time like the rest of the recipient snapshot (BR-INV-024).

The legal mention — art. 25 LIVA for an intra-community supply, art. 21 for a third-country operation, art. 84.Uno.2 for reverse charge — derives from the header regime, and therefore does not appear automatically on an invoice created through v1 (BR-TAX-024). Two options: put the wording in notes, or use the line-level exemption_reason_text, which prints under the line description and is presentation only.

What reaches the AEAT

In the VeriFactu record, the recipient's identification type travels as the AEAT code from the L7 table above, and the breakdown carries the qualification described in The scenario map — exempt-operation codes for E5 and E2, S2 with a zero quota for reverse charge.

In the annual third-party operations return (Modelo 347), intra-community operations and imports or exports are excluded (BR-TXR-022): they are declared through their own returns — the recapitulative statement for intra-community operations, and customs documentation for the rest — and declaring them twice would produce a cross-declaration mismatch.

Reverse charge behaves the opposite way: it is a domestic operation and does appear in that return. The classification uses the invoice's header regime, so a mixed invoice is classified as a whole.

Traceability

Derived from the domain rules of the Factuarea backend:

  • BR-CLI-003vat_id as free text, without VIES validation, independent of tax_id.
  • BR-CLI-015 — census verification of the recipient: informative, fail-open and stateless.
  • BR-CLI-017 — the AEAT L7 alternative-identification catalogue, the type-country matrix and the accepted legacy aliases.
  • BR-INV-024 — the immutable recipient snapshot.
  • BR-INV-031 — the closed regime-key catalogue used for one-stop-shop and export lines.
  • BR-INV-032 — line exemption causes and their fallback to the header.
  • BR-TAX-024 — the document-level exemption cause and its automatic legal mention.
  • BR-VFC-029 — the qualification map: S1, S2, E5 and E2 derived from the header regime, and reverse charge as a qualification rather than an exemption.
  • BR-TXR-022 — exclusion of intra-community and import or export operations from the annual third-party return, and the inclusion of domestic reverse charge.

On this page