/tax_id_typesList Supported Types
Returns the tax-ID type catalogue — 138 rows across 111 distinct code values, one row per (country, code) pair.
Served by the gateway's worlddata resource and proxied by the wallet; clients always call the wallet, never the gateway. This route proxies straight through — the copy the wallet format-checks against internally is cached for 5 minutes and degrades to the last good copy if the gateway blips. Safe to cache client-side; the table only changes when the catalogue is rebuilt.
| Field | Notes |
|---|---|
code | Stripe tax-id type — th_vat, eu_vat, us_ein, … not unique across the list (see below) |
country | ISO 3166-1 alpha-2, or EU on the one generic EU VAT row |
country_label | Country name for display — Thailand, Germany |
display_name | Type name for display — Thai VAT, European VAT number |
format | Unanchored regex for the value. May be empty |
placeholder | Example value in that format — 1234567891234 |
is_active | Only offer active rows |
Response shape:
{
"object": "list",
"data": [
{
"id": "<uuid>",
"object": "tax_id_type",
"created_at": "<RFC3339 timestamp>",
"updated_at": "<RFC3339 timestamp>",
"code": "th_vat",
"country": "TH",
"country_label": "Thailand",
"display_name": "Thai VAT",
"format": "[0-9]{13}",
"placeholder": "1234567891234",
"is_active": true
}
],
"page": 1,
"limit": 10,
"total_items": 138,
"total_pages": 14
}
Filter with filter[country], filter[code], filter[is_active]; search with search[code], search[country], search[display_name] or search[country_label] — each is a case-insensitive substring match on that one field, and multiple search keys are ANDed, so send one; sort with sort (created_at, code, country); page with limit/page, or use-cursor=true plus starting_after/ending_before.
Three rules for consumers
1. format is unanchored — wrap it before testing. Build the matcher as ^(?:<format>)$. Without the anchors junk1234567891234junk validates as a Thai VAT number. Compile inside a try/catch and treat a pattern that does not compile as valid — never block a payer on a bad pattern shipped from the server.
2. An empty or absent format means no format validation for that type. Six rows ship no pattern: us_ein, hk_br, jp_trn, ru_inn, ru_kpp, and the generic eu_vat (country: "EU").
3. code is not unique. eu_vat appears once per EU member state — 27 rows, each carrying that country's own format (DE → DE[0-9]{9}, AT → ATU[0-9]{8}, …) — plus one generic row with country: "EU" and an empty format. Within a single filter[country] the code IS unique. Anywhere you render the whole catalogue in one list, de-duplicate by code, and resolve the format with the country the user selected: prefer the row whose country matches, else fall back to the generic row.
Trim only the outer whitespace of a value before matching. Never strip inner spaces or dashes — ch_uid ends in a mandatory HR (CHE-123.456.789 HR) and ca_gst_hst allows inner spaces (123456789RT0002).
Source of truth: backend/gateway/resources/tax_ids.json, generated by scripts/build_tax_ids_resource.py (mirrors https://docs.stripe.com/api/customer_tax_ids).
Request
Example
curl -X GET 'https://api.paycose.com/api/v1/app1/platform/wallet/tax_id_types?limit=10&page=1&use-cursor=true&starting_after=&ending_before=&sort=created_at:desc&q=&filter[code]=&filter[country]=' \
-H 'X-Session-Token: {{session_token}}' \
-H 'X-Country: {{country}}' \
-H 'X-Test-Mode: {{x_test_mode}}'Headers
| Name | Value | Description |
|---|---|---|
| X-Session-Token | {{session_token}} | |
| X-Country | {{country}} | |
| X-Test-Mode | {{x_test_mode}} | true=wallet_test, false=wallet_live (default). Toggle the x_test_mode collection variable to flip every applicable request. |
Responses
Headers
| Name | Value |
|---|---|
| Content-Type | application/json |
Body
{
"object": "list",
"data": [],
"page": 1,
"limit": 10,
"total_items": 1,
"total_pages": 1
}