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:
type | AEAT code | Meaning |
|---|---|---|
nif_iva | 02 | Intra-community VAT operator number. |
passport | 03 | Passport. |
country_id | 04 | Official identification document of the country of residence. |
residence_certificate | 05 | Tax residence certificate. |
other_document | 06 | Other supporting document. |
not_registered | 07 | Not 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):
| Scenario | Header operation regime | What reaches the AEAT |
|---|---|---|
| Intra-community supply of goods | intracomunitaria | E5 — subject and exempt, art. 25 LIVA |
| Services with reverse charge | isp | S2 — subject and not exempt, charged quota 0 (the recipient self-charges) |
| Export outside the EU | importacion_exportacion | E2 — 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:
| Scenario | How you express it in v1 |
|---|---|
| Intra-community supply of goods | tax_rate: 0 + exemption_reason: "E5" per line. |
| Export outside the EU | tax_rate: 0 + exemption_reason: "E2", usually with regime_key: "02". |
| One-stop-shop distance sales | regime_key: "17" per line, with the destination-country rate. |
| Reverse charge | Not 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-003—vat_idas free text, without VIES validation, independent oftax_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,E5andE2derived 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.