Paycose Docs
Tax ID
GET/tax_id_types

List 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.

FieldNotes
codeStripe tax-id type — th_vat, eu_vat, us_ein, … not unique across the list (see below)
countryISO 3166-1 alpha-2, or EU on the one generic EU VAT row
country_labelCountry name for display — Thailand, Germany
display_nameType name for display — Thai VAT, European VAT number
formatUnanchored regex for the value. May be empty
placeholderExample value in that format — 1234567891234
is_activeOnly 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

NameValueDescription
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

200200 OK

Headers

NameValue
Content-Typeapplication/json

Body

{
  "object": "list",
  "data": [],
  "page": 1,
  "limit": 10,
  "total_items": 1,
  "total_pages": 1
}

On this page