From 37470185d12fa5c8a60ae78ce38a9b8219eab3ac Mon Sep 17 00:00:00 2001 From: Diego Pereira Date: Wed, 29 Apr 2026 10:30:32 -0300 Subject: [PATCH 1/3] docs(api): align TaxId schemas with shared development-utils type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fx-account: drop redundant `country` field and rename `value` → `number` on TaxIdRequest/TaxIdResponse to match the shared TaxId domain type. Update 3 invalidTaxId error examples and 4 inline body examples to the new shape. Add a markdown country-mapping table to TaxIdType so consumers can discover the right type for their jurisdiction without the redundant field. fx-payment: factor out TaxIdType as a proper enum schema (all 59 values) with the same markdown country table, replacing the previous untyped `type: string`. Existing inline body examples already use {type, number} so no example changes were needed. Companion to fx-account PR #122. Co-Authored-By: Claude Opus 4.7 (1M context) --- apis/fx-account/openapi.yml | 101 ++++++++++++++++++++------------ apis/fx-payment/openapi.yml | 111 ++++++++++++++++++++++++++++++++++-- 2 files changed, 171 insertions(+), 41 deletions(-) diff --git a/apis/fx-account/openapi.yml b/apis/fx-account/openapi.yml index 410d7b9..a86bee2 100644 --- a/apis/fx-account/openapi.yml +++ b/apis/fx-account/openapi.yml @@ -243,20 +243,17 @@ components: - address TaxIdRequest: type: object - description: Tax identifier for the owner or beneficial owner. Validated against the country and type. + description: Tax identifier for the owner or beneficial owner. Validated against the type's country-specific format. properties: - value: - type: string - description: Tax identifier digits or alphanumeric value (depending on type). - example: "11222333000181" type: $ref: "#/components/schemas/TaxIdType" - country: - $ref: "#/components/schemas/Country" + number: + type: string + description: Tax identifier digits or alphanumeric characters (depending on type), with no formatting separators. + example: "11222333000181" required: - - value - type - - country + - number AddressRequest: type: object properties: @@ -548,17 +545,14 @@ components: type: object description: Tax identifier returned for an owner or beneficial owner. properties: - value: - type: string - example: "11222333000181" type: $ref: "#/components/schemas/TaxIdType" - country: - $ref: "#/components/schemas/Country" + number: + type: string + example: "11222333000181" required: - - value - type - - country + - number AddressResponse: type: object properties: @@ -810,9 +804,48 @@ components: example: "BRL" TaxIdType: type: string - description: > - Country-specific tax identifier type. The `country` field on the same - TaxId object must match the country implied by the type. + description: | + Tax identifier type. Each value implies a single issuing country — no separate `country` field is needed on the request. + + **South America** + - Brazil (BR): `CPF` (individual), `CNPJ` (company) + - Argentina (AR): `CUIT`, `CUIL` + - Chile (CL): `RUT_CL` + - Uruguay (UY): `RUT_UY`, `CI_UY` + - Peru (PE): `RUC`, `DNI_PE` + - Colombia (CO): `NIT`, `CC` + - Paraguay (PY): `RUC_PY`, `CI_PY` + + **North America** + - Mexico (MX): `RFC` + - USA (US): `EIN`, `SSN`, `ITIN` + - Canada (CA): `BN_CA`, `SIN` + + **Europe** + - Portugal (PT): `NIPC`, `NIF_PT` + - Spain (ES): `CIF`, `NIF_ES`, `NIE` + - France (FR): `SIREN`, `SIRET`, `NIF_FR` + - Italy (IT): `PARTITA_IVA`, `CODICE_FISCALE` + - Germany (DE): `UST_IDNR`, `STEUER_ID` + - Netherlands (NL): `KVK`, `BSN` + - Belgium (BE): `BCE`, `NN_BE` + - Sweden (SE): `ORGANISATIONSNUMMER`, `PERSONNUMMER` + - Norway (NO): `ORGANISASJONSNUMMER`, `FODSELSNUMMER` + - Switzerland (CH): `UID_CH`, `AHV` + - United Kingdom (GB): `VAT_GB`, `NIN` + + **Asia & Pacific** + - China (CN): `USCC` + - Japan (JP): `CORPORATE_NUMBER_JP`, `MY_NUMBER` + - South Korea (KR): `BRN_KR`, `RRN` + - India (IN): `GSTIN`, `PAN` + - Russia (RU): `INN_RU` + - Australia (AU): `ABN`, `TFN` + + **Middle East & Africa** + - Israel (IL): `COMPANY_NUMBER_IL`, `TEUDAT_ZEHUT` + - UAE (AE): `TRADE_LICENSE`, `EMIRATES_ID` + - South Africa (ZA): `CIPC`, `SA_ID` enum: - CPF - CNPJ @@ -1541,9 +1574,8 @@ paths: type: "COMPANY" legalName: "Acme Ltda" taxId: - value: "11222333000181" type: "CNPJ" - country: "BR" + number: "11222333000181" industry: "INFORMATION_TECHNOLOGY" incorporateDate: "2018-05-12" address: @@ -1564,9 +1596,8 @@ paths: firstName: "Maria" lastName: "Silva" taxId: - value: "12345678909" type: "CPF" - country: "BR" + number: "12345678909" birthDate: "1990-03-21" address: addressLine1: "Rua das Flores, 100" @@ -1589,15 +1620,15 @@ paths: $ref: "#/components/schemas/ErrorResponse" examples: invalidTaxId: - summary: Owner taxId fails the country/type-specific validator + summary: Owner taxId fails the type-specific validator value: code: "INVALID_DATA" message: "Object contains invalid data" details: errors: - code: "VALIDATE_TAX_ID" - message: "Tax ID is invalid for the given type and country" - field: "body:owner.taxId.value" + message: "Tax ID is invalid for the given type" + field: "body:owner.taxId.number" params: {} unsupportedAsset: summary: Requested asset code is not supported @@ -2042,9 +2073,8 @@ paths: value: name: "João Silva" taxId: - value: "12345678909" type: "CPF" - country: "BR" + number: "12345678909" address: addressLine1: "Rua das Flores, 100" city: "São Paulo" @@ -2067,15 +2097,15 @@ paths: $ref: "#/components/schemas/ErrorResponse" examples: invalidTaxId: - summary: UBO taxId fails the country/type-specific validator + summary: UBO taxId fails the type-specific validator value: code: "INVALID_DATA" message: "Object contains invalid data" details: errors: - code: "VALIDATE_TAX_ID" - message: "Tax ID is invalid for the given type and country" - field: "body:taxId.value" + message: "Tax ID is invalid for the given type" + field: "body:taxId.number" params: {} invalidData: summary: Request body failed validation @@ -2257,9 +2287,8 @@ paths: value: name: "João Carlos Silva" taxId: - value: "98765432100" type: "CPF" - country: "BR" + number: "98765432100" address: addressLine1: "Av. Paulista, 1000" city: "São Paulo" @@ -2282,15 +2311,15 @@ paths: $ref: "#/components/schemas/ErrorResponse" examples: invalidTaxId: - summary: UBO taxId fails the country/type-specific validator + summary: UBO taxId fails the type-specific validator value: code: "INVALID_DATA" message: "Object contains invalid data" details: errors: - code: "VALIDATE_TAX_ID" - message: "Tax ID is invalid for the given type and country" - field: "body:taxId.value" + message: "Tax ID is invalid for the given type" + field: "body:taxId.number" params: {} invalidData: summary: Request body failed validation diff --git a/apis/fx-payment/openapi.yml b/apis/fx-payment/openapi.yml index 525b6c5..4130dbe 100644 --- a/apis/fx-payment/openapi.yml +++ b/apis/fx-payment/openapi.yml @@ -292,11 +292,7 @@ components: `CNPJ` must be 14 digits with valid check digits). properties: type: - type: string - description: > - Tax identifier kind. Brazilian beneficiaries use `CPF` (individual) or `CNPJ` - (company); other jurisdictions use the local code (e.g. `SSN`, `EIN`, `CUIT`). - example: "CPF" + $ref: "#/components/schemas/TaxIdType" number: type: string description: Tax identifier number, digits only (no dots, dashes, or slashes). @@ -304,6 +300,111 @@ components: required: - type - number + TaxIdType: + type: string + description: | + Tax identifier type. Each value implies a single issuing country — no separate `country` field is needed on the request. + + **South America** + - Brazil (BR): `CPF` (individual), `CNPJ` (company) + - Argentina (AR): `CUIT`, `CUIL` + - Chile (CL): `RUT_CL` + - Uruguay (UY): `RUT_UY`, `CI_UY` + - Peru (PE): `RUC`, `DNI_PE` + - Colombia (CO): `NIT`, `CC` + - Paraguay (PY): `RUC_PY`, `CI_PY` + + **North America** + - Mexico (MX): `RFC` + - USA (US): `EIN`, `SSN`, `ITIN` + - Canada (CA): `BN_CA`, `SIN` + + **Europe** + - Portugal (PT): `NIPC`, `NIF_PT` + - Spain (ES): `CIF`, `NIF_ES`, `NIE` + - France (FR): `SIREN`, `SIRET`, `NIF_FR` + - Italy (IT): `PARTITA_IVA`, `CODICE_FISCALE` + - Germany (DE): `UST_IDNR`, `STEUER_ID` + - Netherlands (NL): `KVK`, `BSN` + - Belgium (BE): `BCE`, `NN_BE` + - Sweden (SE): `ORGANISATIONSNUMMER`, `PERSONNUMMER` + - Norway (NO): `ORGANISASJONSNUMMER`, `FODSELSNUMMER` + - Switzerland (CH): `UID_CH`, `AHV` + - United Kingdom (GB): `VAT_GB`, `NIN` + + **Asia & Pacific** + - China (CN): `USCC` + - Japan (JP): `CORPORATE_NUMBER_JP`, `MY_NUMBER` + - South Korea (KR): `BRN_KR`, `RRN` + - India (IN): `GSTIN`, `PAN` + - Russia (RU): `INN_RU` + - Australia (AU): `ABN`, `TFN` + + **Middle East & Africa** + - Israel (IL): `COMPANY_NUMBER_IL`, `TEUDAT_ZEHUT` + - UAE (AE): `TRADE_LICENSE`, `EMIRATES_ID` + - South Africa (ZA): `CIPC`, `SA_ID` + enum: + - CPF + - CNPJ + - CUIT + - CUIL + - RUT_CL + - RUT_UY + - CI_UY + - RUC + - DNI_PE + - NIT + - CC + - RFC + - RUC_PY + - CI_PY + - NIPC + - NIF_PT + - CIF + - NIF_ES + - NIE + - SIREN + - SIRET + - NIF_FR + - PARTITA_IVA + - CODICE_FISCALE + - UST_IDNR + - STEUER_ID + - KVK + - BSN + - BCE + - NN_BE + - ORGANISATIONSNUMMER + - PERSONNUMMER + - ORGANISASJONSNUMMER + - FODSELSNUMMER + - UID_CH + - AHV + - VAT_GB + - NIN + - EIN + - SSN + - ITIN + - BN_CA + - SIN + - ABN + - TFN + - USCC + - CORPORATE_NUMBER_JP + - MY_NUMBER + - BRN_KR + - RRN + - GSTIN + - PAN + - INN_RU + - COMPANY_NUMBER_IL + - TEUDAT_ZEHUT + - TRADE_LICENSE + - EMIRATES_ID + - CIPC + - SA_ID + example: "CPF" Country: type: string description: ISO 3166-1 alpha-2 country code. From 5ab2829acf76c55297b31c3793484874ac2065e8 Mon Sep 17 00:00:00 2001 From: Diego Pereira Date: Wed, 29 Apr 2026 10:36:47 -0300 Subject: [PATCH 2/3] docs(journeys): align taxId examples with new TaxId schema Two journey docs still showed stale taxId shapes that the openapi.yml update (previous commit) made inconsistent with the spec: - open-multi-currency-account.mdx: two curl bodies used the old {value, type, country} shape from fx-account. Updated to {type, number}. - withdrawal.mdx: the fx-payment beneficiary example sent taxId as a bare string ("12345678901"); the fx-payment spec defines TaxId as an object {type, number}. Pre-existing inconsistency, fixed for clarity. Co-Authored-By: Claude Opus 4.7 (1M context) --- journeys/open-multi-currency-account.mdx | 6 ++---- journeys/withdrawal.mdx | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/journeys/open-multi-currency-account.mdx b/journeys/open-multi-currency-account.mdx index e0b8516..5e54986 100644 --- a/journeys/open-multi-currency-account.mdx +++ b/journeys/open-multi-currency-account.mdx @@ -32,9 +32,8 @@ An account in Trace FX is multi-currency: every account includes crypto support "type": "COMPANY", "legalName": "Acme Ltda", "taxId": { - "value": "11222333000181", "type": "CNPJ", - "country": "BR" + "number": "11222333000181" }, "industry": "INFORMATION_TECHNOLOGY", "incorporateDate": "2018-05-12", @@ -78,9 +77,8 @@ An account in Trace FX is multi-currency: every account includes crypto support --data '{ "name": "João Silva", "taxId": { - "value": "12345678909", "type": "CPF", - "country": "BR" + "number": "12345678909" }, "address": { "addressLine1": "Rua das Flores, 100", diff --git a/journeys/withdrawal.mdx b/journeys/withdrawal.mdx index 80491e6..86a2918 100644 --- a/journeys/withdrawal.mdx +++ b/journeys/withdrawal.mdx @@ -29,7 +29,7 @@ Withdrawals move funds out of an account to an external destination — a bank a "type": "INDIVIDUAL", "firstName": "John", "lastName": "Doe", - "taxId": "12345678901", + "taxId": {"type": "CPF", "number": "12345678901"}, "dateOfBirth": "1990-01-15" }, "paymentInstruction": { From ffebc4491b9f5c40e20ef734bb76a8d49c5938b3 Mon Sep 17 00:00:00 2001 From: Diego Pereira Date: Wed, 29 Apr 2026 12:09:06 -0300 Subject: [PATCH 3/3] docs(api): rename TaxId.number to value across schemas and examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aligns fx-account and fx-payment OpenAPI specs with development-utils 2.79.0, which renamed `TaxId.number` → `TaxId.value`. Updates: - TaxIdRequest / TaxIdResponse schema (fx-account) - TaxId schema (fx-payment) - All inline JSON/YAML examples in path operations - Error response field paths (e.g., `body:owner.taxId.number` → `body:owner.taxId.value`) - Journey examples (open-multi-currency-account, withdrawal) The `number` name implied a numeric format, but several types are alphanumeric (ABN, VAT_GB, RFC, USCC, GSTIN, NIF_ES, NIE, etc.). Co-Authored-By: Claude Opus 4.7 (1M context) --- apis/fx-account/openapi.yml | 22 +++++++++++----------- apis/fx-payment/openapi.yml | 19 ++++++++++--------- journeys/open-multi-currency-account.mdx | 4 ++-- journeys/withdrawal.mdx | 2 +- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/apis/fx-account/openapi.yml b/apis/fx-account/openapi.yml index a86bee2..8583c96 100644 --- a/apis/fx-account/openapi.yml +++ b/apis/fx-account/openapi.yml @@ -247,13 +247,13 @@ components: properties: type: $ref: "#/components/schemas/TaxIdType" - number: + value: type: string description: Tax identifier digits or alphanumeric characters (depending on type), with no formatting separators. example: "11222333000181" required: - type - - number + - value AddressRequest: type: object properties: @@ -547,12 +547,12 @@ components: properties: type: $ref: "#/components/schemas/TaxIdType" - number: + value: type: string example: "11222333000181" required: - type - - number + - value AddressResponse: type: object properties: @@ -1575,7 +1575,7 @@ paths: legalName: "Acme Ltda" taxId: type: "CNPJ" - number: "11222333000181" + value: "11222333000181" industry: "INFORMATION_TECHNOLOGY" incorporateDate: "2018-05-12" address: @@ -1597,7 +1597,7 @@ paths: lastName: "Silva" taxId: type: "CPF" - number: "12345678909" + value: "12345678909" birthDate: "1990-03-21" address: addressLine1: "Rua das Flores, 100" @@ -1628,7 +1628,7 @@ paths: errors: - code: "VALIDATE_TAX_ID" message: "Tax ID is invalid for the given type" - field: "body:owner.taxId.number" + field: "body:owner.taxId.value" params: {} unsupportedAsset: summary: Requested asset code is not supported @@ -2074,7 +2074,7 @@ paths: name: "João Silva" taxId: type: "CPF" - number: "12345678909" + value: "12345678909" address: addressLine1: "Rua das Flores, 100" city: "São Paulo" @@ -2105,7 +2105,7 @@ paths: errors: - code: "VALIDATE_TAX_ID" message: "Tax ID is invalid for the given type" - field: "body:taxId.number" + field: "body:taxId.value" params: {} invalidData: summary: Request body failed validation @@ -2288,7 +2288,7 @@ paths: name: "João Carlos Silva" taxId: type: "CPF" - number: "98765432100" + value: "98765432100" address: addressLine1: "Av. Paulista, 1000" city: "São Paulo" @@ -2319,7 +2319,7 @@ paths: errors: - code: "VALIDATE_TAX_ID" message: "Tax ID is invalid for the given type" - field: "body:taxId.number" + field: "body:taxId.value" params: {} invalidData: summary: Request body failed validation diff --git a/apis/fx-payment/openapi.yml b/apis/fx-payment/openapi.yml index 4130dbe..f08e48b 100644 --- a/apis/fx-payment/openapi.yml +++ b/apis/fx-payment/openapi.yml @@ -287,19 +287,20 @@ components: TaxId: type: object description: > - Tax identifier as a typed value object. The `number` must match the format expected + Tax identifier as a typed value object. The `value` must match the format expected for the supplied `type` (e.g. a `CPF` must be 11 digits with valid check digits, a - `CNPJ` must be 14 digits with valid check digits). + `CNPJ` must be 14 digits with valid check digits). Some types are alphanumeric + (e.g. `RFC`, `ABN`, `VAT_GB`). properties: type: $ref: "#/components/schemas/TaxIdType" - number: + value: type: string - description: Tax identifier number, digits only (no dots, dashes, or slashes). + description: Tax identifier digits or alphanumeric characters (depending on type), with no formatting separators. example: "52998224725" required: - type - - number + - value TaxIdType: type: string description: | @@ -2217,7 +2218,7 @@ paths: lastName: "Doe" taxId: type: "CPF" - number: "52998224725" + value: "52998224725" dateOfBirth: "1990-01-15" address: addressLine1: "Rua Augusta, 500" @@ -2982,7 +2983,7 @@ paths: lastName: "Silva" taxId: type: "CPF" - number: "52998224725" + value: "52998224725" dateOfBirth: "1985-03-15" address: addressLine1: "Av. Paulista, 1000" @@ -3006,7 +3007,7 @@ paths: tradeName: "Acme" taxId: type: "CNPJ" - number: "27922482000193" + value: "27922482000193" address: addressLine1: "Rua da Consolação, 222" city: "São Paulo" @@ -3029,7 +3030,7 @@ paths: lastName: "Doe" taxId: type: "CPF" - number: "11144477735" + value: "11144477735" dateOfBirth: "1990-07-22" address: addressLine1: "123 Main St" diff --git a/journeys/open-multi-currency-account.mdx b/journeys/open-multi-currency-account.mdx index 5e54986..018c3b0 100644 --- a/journeys/open-multi-currency-account.mdx +++ b/journeys/open-multi-currency-account.mdx @@ -33,7 +33,7 @@ An account in Trace FX is multi-currency: every account includes crypto support "legalName": "Acme Ltda", "taxId": { "type": "CNPJ", - "number": "11222333000181" + "value": "11222333000181" }, "industry": "INFORMATION_TECHNOLOGY", "incorporateDate": "2018-05-12", @@ -78,7 +78,7 @@ An account in Trace FX is multi-currency: every account includes crypto support "name": "João Silva", "taxId": { "type": "CPF", - "number": "12345678909" + "value": "12345678909" }, "address": { "addressLine1": "Rua das Flores, 100", diff --git a/journeys/withdrawal.mdx b/journeys/withdrawal.mdx index 86a2918..10b4c41 100644 --- a/journeys/withdrawal.mdx +++ b/journeys/withdrawal.mdx @@ -29,7 +29,7 @@ Withdrawals move funds out of an account to an external destination — a bank a "type": "INDIVIDUAL", "firstName": "John", "lastName": "Doe", - "taxId": {"type": "CPF", "number": "12345678901"}, + "taxId": {"type": "CPF", "value": "12345678901"}, "dateOfBirth": "1990-01-15" }, "paymentInstruction": {