> ## Documentation Index
> Fetch the complete documentation index at: https://dev.enterprise.moonpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TIN Format Validation

> Expected tax identification number (TIN) format per country, how separators and whitespace are handled, and the errors a malformed TIN returns.

MoonPay Enterprise checks the format of every tax identification number (TIN) you submit for an individual customer. The format depends on `tax_residence_country`, not on the customer's address or nationality. Match the format below and the TIN passes on the first attempt.

The check runs on two endpoints:

* `POST /api/customers/{id}/identifications/v2` with a `Person` submission. See [Create Customer Identification](/reference/customer/create-customer-identification-v2).
* `PATCH /api/customers/{id}/identification-data`, used to backfill a TIN on an existing customer. See [Update Customer Identification Data](/reference/customer/update-customer-identification-data).

<Note>
  Beneficiary TINs on a `Business` submission aren't checked against this table.
</Note>

## Tax residence country

Send `tax_residence_country` as an ISO 3166-1 alpha-2 code (`DE`, `US`) whenever you send `tax_identification_number`.

* On a `Person` submission, you can omit it only when `identity.identity_country_code` is `US`. The TIN is then checked against the US format.
* On `PATCH /api/customers/{id}/identification-data`, it's always required with a TIN.

## Formatting rules

* **Whitespace is ignored.** Spaces anywhere in the value, including between groups of digits, are removed before the check.
* **Separators are accepted.** Dashes (`-`), periods (`.`), and slashes (`/`) used between groups pass, so a US SSN like `123-45-6789` is accepted the same as `123456789`.
* **Finland is the exception.** The century marker is part of the format, so `010101-123A` passes and `0101011234` fails. See the table below.
* **Letters are case-insensitive.** Wherever a format allows a letter, upper and lower case both pass.

## Country formats

| Country | Format | Example |
| - | - | - |
| Austria (AT) | 9 digits | `123456789` |
| Belgium (BE) | 11 digits | `12345678999` |
| Brazil (BR) | 11 digits | `12345678900` |
| Bulgaria (BG) | 10 digits | `1234567890` |
| Croatia (HR) | 11 digits | `12345678901` |
| Cyprus (CY) | 8 digits + 1 letter | `12345678A` |
| Czech Republic (CZ) | 9-10 digits | `1234567890` |
| Denmark (DK) | 10 digits: day (`01`-`31`) + month (`01`-`12`) + 6 digits | `0101901234` |
| Estonia (EE) | 11 digits, starting `1`-`8` | `12345678901` |
| Finland (FI) | 6 digits + century marker + 3 digits + 1 digit or letter. The century marker is one of `-`, `+`, `A`-`F`, `U`-`Y`. | `010101-123A` |
| France (FR) | 13 digits starting `0`-`3`, or 7 digits starting `1`-`2`, or 5 digits + 1 letter | `0123456789012` |
| Germany (DE) | 11 digits | `12345678901` |
| Greece (GR) | 9 digits | `123456789` |
| Hungary (HU) | 10 digits, starting `8` | `8123456789` |
| Iceland (IS) | 10 digits, starting `0`-`3` | `0123456789` |
| Ireland (IE) | 7 digits + 1-2 letters | `1234567A` |
| Italy (IT) | 6 letters + 2 digits + 1 letter + 2 digits + 1 letter + 3 digits + 1 letter | `ABCDEF12A01A012A` |
| Japan (JP) | 12 digits | `123456789012` |
| Jersey (JE) | 10 digits, or 2 letters + 6 digits + 1 letter | `0123456789` or `AB123456A` |
| Latvia (LV) | 11 digits, starting `0`-`3` | `12345678901` |
| Liechtenstein (LI) | 4-12 digits | `123456789012` |
| Lithuania (LT) | 11 digits, starting `1`-`6` | `12345678901` |
| Luxembourg (LU) | 13 digits, starting `19` or `20` | `1912345678901` |
| Malta (MT) | 7 digits + 1 of `M`, `G`, `A`, `P`, `L`, `H`, `B`, `Z`, or 9 digits | `1234567A` |
| Netherlands (NL) | 9 digits | `123456789` |
| Norway (NO) | 11 digits, starting `0`-`7` | `12345678901` |
| Poland (PL) | 10-11 digits | `1234567890` |
| Portugal (PT) | 9 digits, starting `1`, `2`, `3`, or `45` | `123456789` |
| Romania (RO) | 13 digits starting `1`-`8`, or `9000` + 9 digits | `1234567890123` |
| San Marino (SM) | 2-9 digits | `123456789` |
| Slovakia (SK) | 9-10 digits | `123456789` |
| Slovenia (SI) | 8 digits, starting `1`-`9` | `12345678` |
| South Africa (ZA) | 10 digits, starting `0`, `1`, `2`, `3`, or `9` | `0123456789` |
| Spain (ES) | 8 digits + 1 letter, or 1 of `K`, `L`, `M`, `X`, `Y`, `Z` + 7 digits + 1 letter | `12345678Z` or `Z1234567Z` |
| Sweden (SE) | 10 digits: 2 digits + month (`01`-`12`) + 6 digits | `9910123456` |
| United Kingdom (GB) | 10 digits, or 2 letters + 6 digits + 1 of `A`-`D`, or 2 digits + 1 letter + 5 digits | `0123456789` or `AB123456A` |
| United States (US) | 9 digits | `123456789` |

### Other countries

For a `tax_residence_country` not in the table, the TIN must:

* Contain only letters, digits, `+`, and `-` (plus the whitespace and separators from [Formatting rules](#formatting-rules))
* Include 4-20 digits. Letters and punctuation don't count toward that total.

## Errors

A TIN that doesn't match the format returns `400`. The message names the country and an example of the expected format.

On a `Person` submission under `X-API-Version: 2026-08-01` or later, the error code is [`invalid_request`](/errors#invalid_request):

```json theme={null}
[
  {
    "code": "invalid_request",
    "message": "Tax identification number for country DE must match format: 12345678901",
    "docs_url": "https://docs.iron.xyz/errors#invalid_request",
    "beneficiary_index": null
  }
]
```

Earlier API versions, and `PATCH /api/customers/{id}/identification-data`, return the same message as a plain string:

```json theme={null}
"Tax identification number for country DE must match format: 12345678901"
```

A TIN without `tax_residence_country` returns [`tin_required`](/errors#tin_required) on a `Person` submission, and this plain string on `PATCH /api/customers/{id}/identification-data`:

```json theme={null}
"Tax residence country is required when a tax identification number is provided"
```

<Info>
  Run the same format check in your own UI before you submit. Your customer fixes a typo on the spot instead of your integration handling a `400`.
</Info>

If a TIN is rejected and you believe it matches the format for its country, [contact support](/support) with the customer ID and the country. Don't send the full TIN.
