diff --git a/CLAUDE.md b/CLAUDE.md
index 11c2209..8e19539 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -107,11 +107,11 @@ Page types are inferred from file paths:
`snippets/` contains shared MDX blocks. Import them in any page:
```mdx
-import SandboxNote from '/snippets/sandbox-note.mdx';
-
+import AuthHeader from '/snippets/auth-header.mdx';
+
```
-Available: `auth-header`, `sandbox-note`, `idempotency-note`, `pagination-response`, `error-response`, `money-format`, `version-header`.
+Available: `auth-header`, `idempotency-note`, `pagination-response`, `error-response`, `money-format`, `version-header`.
### CI (GitHub Actions)
diff --git a/apis/fx-account/openapi.yml b/apis/fx-account/openapi.yml
index 03f57bf..8e07cfb 100644
--- a/apis/fx-account/openapi.yml
+++ b/apis/fx-account/openapi.yml
@@ -903,11 +903,32 @@ paths:
schema:
$ref: "#/components/schemas/AccountResponse"
"400":
- description: Invalid request body.
+ description: Invalid request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ invalidTaxId:
+ summary: Owner taxId length is not 11 (individual) or 14 (company)
+ value:
+ code: "INVALID_TAX_ID"
+ message: "TaxId must be 11 or 14 characters"
+ details:
+ taxIdLength: 10
+ unsupportedAsset:
+ summary: Requested asset code is not supported
+ value:
+ code: "UNSUPPORTED_ASSET"
+ message: "Asset not supported by any provider: asset=ETH"
+ details:
+ asset: "ETH"
+ invalidData:
+ summary: Request body failed validation
+ value:
+ code: "INVALID_DATA"
+ message: "Request body is malformed or missing required fields"
+ details: {}
"401":
description: Missing or invalid authentication token.
content:
@@ -921,11 +942,19 @@ paths:
schema:
$ref: "#/components/schemas/ErrorResponse"
"422":
- description: Validation error (e.g., individual customer with mismatched tax ID).
+ description: Business rule violation.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ ubosNotAllowedForIndividual:
+ summary: Individual-owned account cannot have UBOs
+ value:
+ code: "UBOS_NOT_ALLOWED_FOR_INDIVIDUAL"
+ message: "UBOs are not allowed for individual accounts"
+ details:
+ taxId: "12345678900"
get:
operationId: listAccounts
tags:
@@ -986,6 +1015,14 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ invalidUuid:
+ summary: accountId path parameter is not a valid UUID
+ value:
+ code: "INVALID_UUID"
+ message: "accountId must be a valid UUID"
+ details:
+ field: "accountId"
"401":
description: Missing or invalid authentication token.
content:
@@ -998,6 +1035,15 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
/api/accounts/{accountId}/review:
post:
@@ -1025,18 +1071,55 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
"409":
- description: Account has no provider accounts requiring analysis.
+ description: Account state conflict.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ noProviderAccountRequiresAnalysis:
+ summary: Account has no provider accounts awaiting analysis
+ value:
+ code: "NO_PROVIDER_ACCOUNT_REQUIRES_ANALYSIS"
+ message: "Account has no provider accounts requiring analysis"
+ details:
+ accountId: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
"422":
- description: Account has missing documents or unfulfilled requirements.
+ description: Business rule violation.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ missingDocumentsForReview:
+ summary: Required documents are missing or rejected
+ value:
+ code: "MISSING_DOCUMENTS_FOR_REVIEW"
+ message: "Not all documents uploaded for review submission"
+ details:
+ accountId: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ missingDocumentTypes:
+ - "COMPANY_ARTICLES_OF_INCORPORATION"
+ - "COMPANY_PROOF_OF_ADDRESS"
+ missingUboVerification:
+ summary: Company account has no verified UBOs
+ value:
+ code: "MISSING_DOCUMENTS_FOR_REVIEW"
+ message: "Not all documents uploaded for review submission"
+ details:
+ accountId: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ missingDocumentTypes:
+ - "UBO_VERIFICATION"
# ── Funding instructions ─────────────────────────────────────────
/api/accounts/{accountId}/fundingInstructions:
@@ -1080,6 +1163,14 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ invalidUuid:
+ summary: accountId path parameter is not a valid UUID
+ value:
+ code: "INVALID_UUID"
+ message: "accountId must be a valid UUID"
+ details:
+ field: "accountId"
"401":
description: Missing or invalid authentication token.
content:
@@ -1092,6 +1183,15 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
# ── Account documents ────────────────────────────────────────────
/api/accounts/{accountId}/documents:
@@ -1131,11 +1231,33 @@ paths:
schema:
$ref: "#/components/schemas/DocumentResponse"
"400":
- description: Invalid account ID format or missing multipart fields.
+ description: Invalid request or missing multipart fields.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ emptyFile:
+ summary: Uploaded file is empty
+ value:
+ code: "EMPTY_FILE"
+ message: "File must not be empty: fieldName=file"
+ details:
+ fieldName: "file"
+ missingMultipartField:
+ summary: Required multipart field is missing
+ value:
+ code: "MISSING_MULTIPART_FIELD"
+ message: "Missing required multipart field: fieldName=requirementId"
+ details:
+ fieldName: "requirementId"
+ invalidUuid:
+ summary: accountId or requirementId is not a valid UUID
+ value:
+ code: "INVALID_UUID"
+ message: "accountId must be a valid UUID"
+ details:
+ field: "accountId"
"401":
description: Missing or invalid authentication token.
content:
@@ -1148,6 +1270,15 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
"422":
description: No matching requirement for the given requirement ID.
content:
@@ -1194,11 +1325,25 @@ paths:
schema:
$ref: "#/components/schemas/UBOResponse"
"400":
- description: Invalid request body.
+ description: Invalid request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ invalidTaxId:
+ summary: UBO taxId length is not 11 (individual) or 14 (company)
+ value:
+ code: "INVALID_TAX_ID"
+ message: "TaxId must be 11 or 14 characters"
+ details:
+ taxIdLength: 10
+ invalidData:
+ summary: Request body failed validation
+ value:
+ code: "INVALID_DATA"
+ message: "Request body is malformed or missing required fields"
+ details: {}
"401":
description: Missing or invalid authentication token.
content:
@@ -1211,12 +1356,58 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ "409":
+ description: UBO already exists.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorResponse"
+ examples:
+ duplicateUbo:
+ summary: A UBO with this taxId is already registered on the account
+ value:
+ code: "DUPLICATE_UBO"
+ message: "A UBO with this tax ID already exists"
+ details:
+ taxId: "12345678900"
"422":
- description: Validation error.
+ description: Business rule violation.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ ubosNotAllowedForIndividual:
+ summary: Account has an individual owner (UBOs apply only to companies)
+ value:
+ code: "UBOS_NOT_ALLOWED_FOR_INDIVIDUAL"
+ message: "UBOs are not allowed for individual accounts"
+ details:
+ taxId: "12345678900"
+ accountNotModifiable:
+ summary: Account is not in a modifiable state (e.g., already under review)
+ value:
+ code: "ACCOUNT_NOT_MODIFIABLE"
+ message: "Account is not in a modifiable state"
+ details:
+ accountId: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ insufficientOwnership:
+ summary: UBO ownership percentage is below the 25% threshold
+ value:
+ code: "INSUFFICIENT_OWNERSHIP"
+ message: "Partner ownership percentage must be at least 25%"
+ details:
+ taxId: "12345678900"
+ ownershipPercentage: 10.0
get:
operationId: listUbos
tags:
@@ -1247,6 +1438,29 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ "422":
+ description: Business rule violation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorResponse"
+ examples:
+ ubosNotAllowedForIndividual:
+ summary: Account has an individual owner (UBOs apply only to companies)
+ value:
+ code: "UBOS_NOT_ALLOWED_FOR_INDIVIDUAL"
+ message: "UBOs are not allowed for individual accounts"
+ details:
+ taxId: "12345678900"
/api/accounts/{accountId}/ubos/{uboId}:
get:
@@ -1278,6 +1492,37 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ uboNotFound:
+ summary: Beneficial owner does not exist on the account
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "UBO with id 'a1b2c3d4-e5f6-7890-1234-567890abcdef' was not found"
+ details:
+ resource: "UBO"
+ id: "a1b2c3d4-e5f6-7890-1234-567890abcdef"
+ "422":
+ description: Business rule violation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorResponse"
+ examples:
+ ubosNotAllowedForIndividual:
+ summary: Account has an individual owner (UBOs apply only to companies)
+ value:
+ code: "UBOS_NOT_ALLOWED_FOR_INDIVIDUAL"
+ message: "UBOs are not allowed for individual accounts"
+ details:
+ taxId: "12345678900"
patch:
operationId: updateUbo
tags:
@@ -1319,11 +1564,25 @@ paths:
schema:
$ref: "#/components/schemas/UBOResponse"
"400":
- description: Invalid request body.
+ description: Invalid request.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ invalidTaxId:
+ summary: UBO taxId length is not 11 (individual) or 14 (company)
+ value:
+ code: "INVALID_TAX_ID"
+ message: "TaxId must be 11 or 14 characters"
+ details:
+ taxIdLength: 10
+ invalidData:
+ summary: Request body failed validation
+ value:
+ code: "INVALID_DATA"
+ message: "Request body is malformed or missing required fields"
+ details: {}
"401":
description: Missing or invalid authentication token.
content:
@@ -1336,12 +1595,59 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ uboNotFound:
+ summary: Beneficial owner does not exist on the account
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "UBO with id 'a1b2c3d4-e5f6-7890-1234-567890abcdef' was not found"
+ details:
+ resource: "UBO"
+ id: "a1b2c3d4-e5f6-7890-1234-567890abcdef"
"422":
- description: Validation error (e.g., ownership below 25%, UBO already approved).
+ description: Business rule violation.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ ubosNotAllowedForIndividual:
+ summary: Account has an individual owner (UBOs apply only to companies)
+ value:
+ code: "UBOS_NOT_ALLOWED_FOR_INDIVIDUAL"
+ message: "UBOs are not allowed for individual accounts"
+ details:
+ taxId: "12345678900"
+ accountNotModifiable:
+ summary: Account is not in a modifiable state
+ value:
+ code: "ACCOUNT_NOT_MODIFIABLE"
+ message: "Account is not in a modifiable state"
+ details:
+ accountId: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ approvedUbo:
+ summary: Cannot modify a UBO that has already been approved
+ value:
+ code: "APPROVED_UBO"
+ message: "Cannot modify an approved UBO"
+ details:
+ uboId: "a1b2c3d4-e5f6-7890-1234-567890abcdef"
+ insufficientOwnership:
+ summary: UBO ownership percentage is below the 25% threshold
+ value:
+ code: "INSUFFICIENT_OWNERSHIP"
+ message: "Partner ownership percentage must be at least 25%"
+ details:
+ taxId: "12345678900"
+ ownershipPercentage: 10.0
delete:
operationId: removeUbo
tags:
@@ -1367,6 +1673,51 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ uboNotFound:
+ summary: Beneficial owner does not exist on the account
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "UBO with id 'a1b2c3d4-e5f6-7890-1234-567890abcdef' was not found"
+ details:
+ resource: "UBO"
+ id: "a1b2c3d4-e5f6-7890-1234-567890abcdef"
+ "422":
+ description: Business rule violation.
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/ErrorResponse"
+ examples:
+ ubosNotAllowedForIndividual:
+ summary: Account has an individual owner (UBOs apply only to companies)
+ value:
+ code: "UBOS_NOT_ALLOWED_FOR_INDIVIDUAL"
+ message: "UBOs are not allowed for individual accounts"
+ details:
+ taxId: "12345678900"
+ accountNotModifiable:
+ summary: Account is not in a modifiable state
+ value:
+ code: "ACCOUNT_NOT_MODIFIABLE"
+ message: "Account is not in a modifiable state"
+ details:
+ accountId: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ approvedUbo:
+ summary: Cannot remove a UBO that has already been approved
+ value:
+ code: "APPROVED_UBO"
+ message: "Cannot modify an approved UBO"
+ details:
+ uboId: "a1b2c3d4-e5f6-7890-1234-567890abcdef"
# ── UBO documents ────────────────────────────────────────────────
/api/accounts/{accountId}/ubos/{uboId}/documents:
@@ -1412,6 +1763,28 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ emptyFile:
+ summary: Uploaded file is empty
+ value:
+ code: "EMPTY_FILE"
+ message: "File must not be empty: fieldName=file"
+ details:
+ fieldName: "file"
+ missingMultipartField:
+ summary: Required multipart field is missing
+ value:
+ code: "MISSING_MULTIPART_FIELD"
+ message: "Missing required multipart field: fieldName=requirementId"
+ details:
+ fieldName: "requirementId"
+ invalidUuid:
+ summary: accountId, uboId, or requirementId is not a valid UUID
+ value:
+ code: "INVALID_UUID"
+ message: "uboId must be a valid UUID"
+ details:
+ field: "uboId"
"401":
description: Missing or invalid authentication token.
content:
@@ -1424,3 +1797,20 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
+ examples:
+ accountNotFound:
+ summary: Account does not exist for the authenticated customer
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "Account with id '5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c' was not found"
+ details:
+ resource: "Account"
+ id: "5b7c1f2a-3d4e-4f8a-9b1c-2d3e4f5a6b7c"
+ uboNotFound:
+ summary: Beneficial owner does not exist on the account
+ value:
+ code: "RESOURCE_NOT_FOUND"
+ message: "UBO with id 'a1b2c3d4-e5f6-7890-1234-567890abcdef' was not found"
+ details:
+ resource: "UBO"
+ id: "a1b2c3d4-e5f6-7890-1234-567890abcdef"
diff --git a/docs.json b/docs.json
index f2fccc6..7a4fb92 100644
--- a/docs.json
+++ b/docs.json
@@ -10,8 +10,7 @@
"favicon": "/favicon.svg",
"logo": {
"light": "/logo/light.svg",
- "dark": "/logo/dark.svg",
- "href": "https://tracefinance.io"
+ "dark": "/logo/dark.svg"
},
"appearance": {
"default": "dark"
@@ -65,8 +64,7 @@
{
"group": "Journeys",
"pages": [
- "journeys/open-brl-account",
- "journeys/open-crypto-account",
+ "journeys/open-multi-currency-account",
"journeys/deposit",
"journeys/withdrawal",
"journeys/swap"
@@ -146,16 +144,7 @@
}
]
}
- ],
- "global": {
- "anchors": [
- {
- "anchor": "API Status",
- "href": "https://status.tracefinance.io",
- "icon": "signal"
- }
- ]
- }
+ ]
},
"navbar": {
"links": [
diff --git a/index.mdx b/index.mdx
index f24584a..5b6df61 100644
--- a/index.mdx
+++ b/index.mdx
@@ -22,11 +22,8 @@ mode: "wide"
## Build with Trace
-
- Create and manage Brazilian Real accounts for your users.
-
-
- Set up cryptocurrency accounts with full compliance.
+
+ Create accounts that hold fiat and crypto for your users.
Accept deposits via PIX, wire transfer, and crypto networks.
diff --git a/journeys/deposit.mdx b/journeys/deposit.mdx
index 7b0d089..107b9e0 100644
--- a/journeys/deposit.mdx
+++ b/journeys/deposit.mdx
@@ -3,17 +3,13 @@ title: "Make a deposit"
description: "How to create a deposit and track it through to completion."
---
-import SandboxNote from '/snippets/sandbox-note.mdx';
-
-
-
## Overview
Deposits fund an account with BRL (via PIX or bank transfer) or crypto (via blockchain transfer). There are two flows depending on whether you initiate the deposit through the API first or the funds arrive first.
## Prerequisites
-- An [active account](/journeys/open-brl-account) to deposit into.
+- An [active account](/journeys/open-multi-currency-account) to deposit into.
- Valid [authentication credentials](/guides/authentication).
## Steps
diff --git a/journeys/open-brl-account.mdx b/journeys/open-brl-account.mdx
deleted file mode 100644
index 8dec341..0000000
--- a/journeys/open-brl-account.mdx
+++ /dev/null
@@ -1,50 +0,0 @@
----
-title: "Open a BRL account"
-description: "Step-by-step guide to opening a Brazilian Real account for an account owner."
----
-
-import SandboxNote from '/snippets/sandbox-note.mdx';
-
-
-
-## Overview
-
-This guide walks you through creating a BRL (Brazilian Real) account for an account owner. Once the account is active, it can receive deposits via PIX and bank transfer.
-
-## Prerequisites
-
-- Valid [authentication credentials](/guides/authentication).
-- Account owner details (name, document number, date of birth).
-
-## Steps
-
-
-
- Submit a request with the owner's details and the account currency:
-
- ```bash
- curl --request POST \
- --url {{sandboxUrl}}/api/accounts \
- --header 'Authorization: Bearer ' \
-
- --header 'X-Idempotency-Key: ' \
- --header 'Content-Type: application/json' \
- --data '{
- "asset": "BRL",
- "type": "CHECKING"
- }'
- ```
-
- The account is returned in `PENDING` status.
-
-
- The account goes through internal validation. Listen for the `account.activated` webhook event or poll the account endpoint until the status changes to `ACTIVE`.
-
-
- Once the account is active, retrieve its banking details (branch, account number) to share with the account owner for incoming transfers.
-
-
-
-## What happens next
-
-- [Make a deposit](/journeys/deposit) — fund the account via PIX or bank transfer.
diff --git a/journeys/open-crypto-account.mdx b/journeys/open-crypto-account.mdx
deleted file mode 100644
index 10d7eb1..0000000
--- a/journeys/open-crypto-account.mdx
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "Open a crypto account"
-description: "Step-by-step guide to opening a crypto asset account for an account owner."
----
-
-import SandboxNote from '/snippets/sandbox-note.mdx';
-
-
-
-## Overview
-
-This guide walks you through creating a crypto asset account for an account owner. Once active, the account provides a wallet address for receiving crypto deposits.
-
-## Prerequisites
-
-- Valid [authentication credentials](/guides/authentication).
-- Account owner details.
-
-## Steps
-
-
-
- Submit a request specifying the crypto asset:
-
- ```bash
- curl --request POST \
- --url {{sandboxUrl}}/api/accounts \
- --header 'Authorization: Bearer ' \
-
- --header 'X-Idempotency-Key: ' \
- --header 'Content-Type: application/json' \
- --data '{
- "asset": "BTC",
- "type": "CRYPTO"
- }'
- ```
-
- The account is returned in `PENDING` status.
-
-
- The account goes through compliance checks. Listen for the `account.activated` webhook event or poll the account endpoint until the status changes to `ACTIVE`.
-
-
- Once active, retrieve the account details to obtain the wallet address for receiving crypto deposits.
-
-
-
-## What happens next
-
-- [Make a deposit](/journeys/deposit) — receive crypto into the wallet.
-- [Execute a swap](/journeys/swap) — convert crypto to BRL or other currencies.
diff --git a/journeys/open-multi-currency-account.mdx b/journeys/open-multi-currency-account.mdx
new file mode 100644
index 0000000..3c51389
--- /dev/null
+++ b/journeys/open-multi-currency-account.mdx
@@ -0,0 +1,67 @@
+---
+title: "Open a multi-currency account"
+description: "Step-by-step guide to opening an account that holds one or more currencies for an account owner."
+---
+
+## Overview
+
+An account in Trace FX is multi-currency: every account includes crypto support by default, and you declare which fiat assets (like BRL) to enable when you create it. Each fiat asset and the crypto wallet run their own onboarding pipelines, and the account becomes `ACTIVE` as soon as the first one finishes — typically the crypto wallet, since it has no manual steps.
+
+## Prerequisites
+
+- Valid [authentication credentials](/guides/authentication).
+- Account owner details (company legal name, tax ID, industry, and address).
+
+## Steps
+
+
+
+ Submit a request with the fiat assets to enable and the account owner's details. Crypto support is always included — you don't need to declare it.
+
+ ```bash
+ curl --request POST \
+ --url {{sandboxUrl}}/api/accounts \
+ --header 'Authorization: Bearer ' \
+ --header 'X-Idempotency-Key: ' \
+ --header 'Content-Type: application/json' \
+ --data '{
+ "assets": [
+ { "code": "BRL", "isVirtual": false }
+ ],
+ "owner": {
+ "type": "COMPANY",
+ "legalName": "Acme Ltda",
+ "taxId": "12345678000101",
+ "industry": "INFORMATION_TECHNOLOGY",
+ "address": {
+ "addressLine1": "Rua das Flores, 100",
+ "addressLine2": "Suite 456",
+ "city": "São Paulo",
+ "state": "SP",
+ "country": "BR",
+ "postalCode": "01234-567"
+ }
+ }
+ }'
+ ```
+
+ The response returns the account in `REQUESTED` status along with the document types required for onboarding. Fiat onboarding requires document uploads; crypto has none.
+
+
+ For each document type returned in the creation response, upload the file using [`POST /api/accounts/{accountId}/documents`](/api-reference/fx-account/documents/upload-account-document).
+
+
+ Once all required documents are uploaded, call [`POST /api/accounts/{accountId}/review`](/api-reference/fx-account/accounts/submit-account-for-review) to trigger identity analysis. The account transitions to `REVIEWING`.
+
+
+ After analysis is approved, each asset activates on its own pipeline. Listen for the `account.activated` webhook event or poll [`GET /api/accounts/{accountId}`](/api-reference/fx-account/accounts/get-account) — the account becomes `ACTIVE` as soon as the first asset finishes onboarding.
+
+
+ Once the account is active, call [`GET /api/accounts/{accountId}/fundingInstructions`](/api-reference/fx-account/funding-instructions/list-funding-instructions) to retrieve incoming transfer details per active asset: PIX key and bank account for BRL, wallet address for crypto.
+
+
+
+## What happens next
+
+- [Make a deposit](/journeys/deposit) — fund the account with BRL or crypto.
+- [Execute a swap](/journeys/swap) — convert between the account's assets.
diff --git a/journeys/swap.mdx b/journeys/swap.mdx
index e33b6fb..ba174a1 100644
--- a/journeys/swap.mdx
+++ b/journeys/swap.mdx
@@ -3,17 +3,13 @@ title: "Execute a swap"
description: "How to convert between currencies using the swap endpoint."
---
-import SandboxNote from '/snippets/sandbox-note.mdx';
-
-
-
## Overview
Swaps convert funds between currencies within the platform — for example, BRL to USD or BTC to BRL. The flow is forward-only: once a swap is executed at the quoted rate, it cannot be reversed.
## Prerequisites
-- An [active account](/journeys/open-brl-account) with sufficient balance in the source currency.
+- An [active account](/journeys/open-multi-currency-account) with sufficient balance in the source currency.
- Valid [authentication credentials](/guides/authentication).
## Steps
diff --git a/journeys/withdrawal.mdx b/journeys/withdrawal.mdx
index b047187..bc110e6 100644
--- a/journeys/withdrawal.mdx
+++ b/journeys/withdrawal.mdx
@@ -3,17 +3,13 @@ title: "Make a withdrawal"
description: "How to create a withdrawal and handle the review process."
---
-import SandboxNote from '/snippets/sandbox-note.mdx';
-
-
-
## Overview
Withdrawals move funds from an account to an external destination — a bank account (via TED or PIX) or a crypto wallet. Some withdrawals go through a compliance review before being processed.
## Prerequisites
-- An [active account](/journeys/open-brl-account) with sufficient balance.
+- An [active account](/journeys/open-multi-currency-account) with sufficient balance.
- A registered **beneficiary** for the destination (bank account or wallet).
- Valid [authentication credentials](/guides/authentication).
diff --git a/quickstart.mdx b/quickstart.mdx
index 357c32a..7cd601e 100644
--- a/quickstart.mdx
+++ b/quickstart.mdx
@@ -3,10 +3,6 @@ title: "Quickstart"
description: "Make your first API request to Trace FX in under five minutes."
---
-import SandboxNote from '/snippets/sandbox-note.mdx';
-
-
-
## Prerequisites
- A **client ID** and **client secret** provided during onboarding.
@@ -47,6 +43,6 @@ import SandboxNote from '/snippets/sandbox-note.mdx';
## What's next
-- [Open a BRL account](/journeys/open-brl-account) — create your first account
+- [Open a multi-currency account](/journeys/open-multi-currency-account) — create your first account
- [Authentication](/guides/authentication) — learn about token management
- [Environments](/guides/environments) — understand sandbox vs production
diff --git a/snippets/sandbox-note.mdx b/snippets/sandbox-note.mdx
deleted file mode 100644
index 12d5c5a..0000000
--- a/snippets/sandbox-note.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
-
- This guide uses the **sandbox** environment.
- See [Environments](/guides/environments) for details.
-