diff --git a/.gitignore b/.gitignore index c18dd8d..8ae8ce5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__/ +.idea/ diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..2bd5a0a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22 diff --git a/docs.json b/docs.json index 1b9f874..1cc0c28 100644 --- a/docs.json +++ b/docs.json @@ -1,21 +1,45 @@ { "$schema": "https://mintlify.com/docs.json", - "theme": "mint", - "name": "Trace Finance Developer Docs", + "theme": "palm", + "name": "Trace Finance", "colors": { "primary": "#15803D", - "light": "#07C983", - "dark": "#15803D" + "light": "#18E299", + "dark": "#0C8C5E" }, "favicon": "/favicon.svg", "logo": { "light": "/logo/light.svg", - "dark": "/logo/dark.svg" + "dark": "/logo/dark.svg", + "href": "https://tracefinance.io" + }, + "appearance": { + "default": "dark" + }, + "background": { + "decoration": "gradient" + }, + "fonts": { + "heading": { + "family": "Inter", + "weight": 600 + }, + "body": { + "family": "Inter", + "weight": 400 + } + }, + "styling": { + "eyebrows": "breadcrumbs", + "codeblocks": { + "theme": "tokyo-night" + } }, "navigation": { "tabs": [ { "tab": "Guides", + "icon": "book-open", "groups": [ { "group": "Getting started", @@ -32,7 +56,9 @@ "guides/principles/versioning", "guides/principles/idempotency", "guides/principles/pagination", + "guides/principles/filtering", "guides/principles/money", + "guides/principles/datetime", "guides/principles/errors" ] }, @@ -45,13 +71,6 @@ "journeys/withdrawal", "journeys/swap" ] - }, - { - "group": "Webhooks", - "pages": [ - "webhooks/overview", - "webhooks/events" - ] } ] } @@ -72,7 +91,12 @@ "label": "Support", "href": "mailto:support@tracefinance.io" } - ] + ], + "primary": { + "type": "button", + "label": "Get started", + "href": "/quickstart" + } }, "api": { "baseUrl": [ @@ -83,7 +107,12 @@ "method": "bearer" } }, - "description": "API documentation for Trace Finance's multi-currency account and payment platform.", + "description": "Explore guides, examples, and API references to build with Trace Finance.", + "variables": { + "sandboxUrl": "https://faas.sandbox.tracefinance.io", + "productionUrl": "https://faas.tracefinance.io", + "authUrl": "https://auth.tracefinance.io" + }, "seo": { "indexing": "navigable" }, diff --git a/favicon.svg b/favicon.svg index d50ceed..77bc037 100644 --- a/favicon.svg +++ b/favicon.svg @@ -1,5 +1,4 @@ - - - - + + + diff --git a/guides/authentication.mdx b/guides/authentication.mdx index 52c4e61..c6c1b16 100644 --- a/guides/authentication.mdx +++ b/guides/authentication.mdx @@ -1,7 +1,66 @@ --- title: "Authentication" -description: "Obtain and use Auth0 JWT tokens to authenticate requests to the Trace FX API." +description: "Obtain and use JWT tokens to authenticate requests to the Trace FX API." sidebarTitle: "Authentication" --- -{/* TODO: Write auth guide — Auth0 flow, obtaining tokens, X-Customer-Id claim, token rotation */} +## Overview + +Every request to the Trace FX API must include a valid JSON Web Token (JWT) in the `Authorization` header. + +During onboarding you receive a **client ID** and **client secret**. Use these to obtain an access token from the Trace authentication service. + +## Details + +### Obtaining a token + +Request an access token from the token endpoint: + +```bash +curl --request POST \ + --url {{authUrl}}/api/oauth/client/token \ + --header 'Content-Type: application/json' \ + --data '{ + "clientId": "YOUR_CLIENT_ID", + "clientSecret": "YOUR_CLIENT_SECRET" + }' +``` + +A successful response includes the token and its lifetime: + +```json +{ + "accessToken": "eyJhbGciOiJSUzI1NiIs...", + "tokenType": "Bearer", + "expiresIn": 3600 +} +``` + +### Using the token + +Include the token in the `Authorization` header of every request: + +```bash +curl --request GET \ + --url {{sandboxUrl}}/api/accounts \ + --header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' +``` + +The token contains your customer identity — no separate customer ID header is needed. + +### Token lifecycle + +Tokens are valid for **1 hour** (3,600 seconds). Follow these best practices: + +1. **Store securely** — keep the token in memory after obtaining it. +2. **Check before use** — inspect the `exp` claim in the JWT payload to confirm it has not expired. +3. **Rotate proactively** — request a new token before the current one expires rather than waiting for a `401` response. + + + Do not request a new token for every API call. Reuse tokens until they expire. + + +## Related + +- [Environments](/guides/environments) — sandbox and production base URLs +- [Quickstart](/quickstart) — make your first API call diff --git a/guides/environments.mdx b/guides/environments.mdx index 65c4433..cd53901 100644 --- a/guides/environments.mdx +++ b/guides/environments.mdx @@ -3,4 +3,41 @@ title: "Environments" description: "Sandbox and production base URLs, and what differs between them." --- -{/* TODO: Write environments guide — sandbox vs production URLs, what resets, rate limits */} +## Overview + +Trace FX provides two environments. Use sandbox for development and testing, and production for live integrations. + +| Environment | Base URL | +| --- | --- | +| Sandbox | `{{sandboxUrl}}` | +| Production | `{{productionUrl}}` | + +## Details + +### Sandbox + +The sandbox is an isolated environment that replicates production behavior with test data. Use it to build and validate your integration before going live. + +- No real money is moved. +- Test credentials are provided during onboarding. +- Data may be reset periodically. + +### Production + +The production environment processes real transactions and serves live users. Access is granted after your integration has been validated in sandbox. + +- All operations affect real accounts and funds. +- Subject to full compliance and security requirements. + +### Rate limits + +API requests are subject to rate limits in both environments. See [Errors](/guides/principles/errors) for status codes and retry guidance. + +### Availability + +The platform maintains **99.8% uptime** with the exception of scheduled maintenance or unforeseeable events. Scheduled maintenance is communicated at least **21 business days** in advance through official channels. + +## Related + +- [Authentication](/guides/authentication) — how to obtain tokens for each environment +- [Quickstart](/quickstart) — make your first sandbox API call diff --git a/guides/principles/datetime.mdx b/guides/principles/datetime.mdx new file mode 100644 index 0000000..5c82db9 --- /dev/null +++ b/guides/principles/datetime.mdx @@ -0,0 +1,46 @@ +--- +title: "Date and time" +description: "How dates and timestamps are formatted in the API." +--- + +## Overview + +All dates and timestamps in the Trace FX API use **UTC** in ISO 8601 format. No other timezones are accepted or returned. + +## How it works + +### Format + +```text +yyyy-MM-ddTHH:mm:ss.SSSZ +``` + +Example: `2025-01-15T14:30:00.000Z` + +| Component | Description | Example | +| --- | --- | --- | +| `yyyy` | Four-digit year | `2025` | +| `MM` | Two-digit month (01–12) | `01` | +| `dd` | Two-digit day (01–31) | `15` | +| `T` | Date/time separator | `T` | +| `HH` | Hours in 24-hour format (00–23) | `14` | +| `mm` | Minutes (00–59) | `30` | +| `ss` | Seconds (00–59) | `00` | +| `.SSS` | Milliseconds (optional) | `.000` | +| `Z` | UTC timezone indicator | `Z` | + +## Examples + +A resource creation timestamp: + +```json +{ + "createdAt": "2025-01-15T14:30:00.000Z" +} +``` + +Filtering by date range: + +```bash +?filters=and(createdAt[gte]=2025-01-01T00:00:00.000Z,createdAt[lte]=2025-01-31T23:59:59.999Z) +``` diff --git a/guides/principles/errors.mdx b/guides/principles/errors.mdx index 264067f..a5007eb 100644 --- a/guides/principles/errors.mdx +++ b/guides/principles/errors.mdx @@ -3,4 +3,89 @@ title: "Errors" description: "How errors are structured and how to handle them." --- -{/* TODO: Write errors guide — ErrorResponse shape (code, message, details), HTTP status codes, retry guidance */} +## Overview + +The Trace FX API uses standard HTTP status codes and returns structured error responses. Every response includes an `X-Request-Id` header you can reference when contacting support. + +## How it works + +### Error response structure + +All errors follow the same shape: + +```json +{ + "code": "INVALID_DATA", + "message": "The field 'amount.value' must be a positive integer.", + "details": {} +} +``` + +| Field | Type | Description | +| --- | --- | --- | +| `code` | string | Machine-readable error code for programmatic handling | +| `message` | string | Human-readable description of what went wrong | +| `details` | object | Additional context (may be empty) | + +### HTTP status codes + +| Code | Meaning | When it happens | +| --- | --- | --- | +| `200` | OK | Request succeeded | +| `201` | Created | Resource was created | +| `204` | No content | Request succeeded with no response body | +| `400` | Bad request | Invalid or malformed request data | +| `401` | Unauthorized | Missing or invalid authentication token | +| `404` | Not found | Resource does not exist | +| `408` | Request timeout | Request took too long to process | +| `409` | Conflict | Idempotency key conflict or state conflict | +| `422` | Unprocessable entity | Valid syntax but business rule violation | +| `429` | Too many requests | Rate limit exceeded | +| `500` | Internal server error | Unexpected server failure | + +### Common error codes + +| Code | HTTP status | Description | +| --- | --- | --- | +| `INVALID_DATA` | 400 | Request body failed validation | +| `RESOURCE_NOT_FOUND` | 404 | The requested resource does not exist | +| `IDEMPOTENT_ID_CONFLICT` | 409 | Idempotency key was already used | +| `INVALID_STATUS_CHANGE` | 422 | The resource cannot transition to the requested state | +| `MFA_NOT_ENABLED` | 422 | Multi-factor authentication is required but not configured | + +### Retry guidance + +| Status code | Should retry? | Strategy | +| --- | --- | --- | +| `400`, `401`, `404`, `422` | No | Fix the request before retrying | +| `408`, `429` | Yes | Back off and retry after the indicated period | +| `409` | Depends | Check if the original request succeeded | +| `500` | Yes | Retry with exponential backoff | + + + Include the `X-Request-Id` from the response when opening a support ticket. This helps the team trace your request through the system. + + +## Examples + +A validation error: + +```json +{ + "code": "INVALID_DATA", + "message": "The field 'amount.value' must be a positive integer.", + "details": { + "field": "amount.value" + } +} +``` + +A resource not found: + +```json +{ + "code": "RESOURCE_NOT_FOUND", + "message": "Account with id 'abc-123' was not found.", + "details": {} +} +``` diff --git a/guides/principles/filtering.mdx b/guides/principles/filtering.mdx new file mode 100644 index 0000000..604b603 --- /dev/null +++ b/guides/principles/filtering.mdx @@ -0,0 +1,87 @@ +--- +title: "Filtering" +description: "Refine list results using the filters query parameter." +--- + +## Overview + +List endpoints support a `filters` query parameter that lets you narrow results by field values, ranges, and patterns using LHS Brackets syntax. + +## How it works + +### Syntax + +Filters follow the format `field[operator]=value`: + +```text +?filters=field[operator]=value +``` + +Combine multiple filters with a semicolon (`;`) — groups separated by `;` are implicitly AND-ed. Group conditions with logical operators `and(...)` and `or(...)`, separating conditions inside with commas. + +Use the string `null` to filter for null values: `field[eq]=null`. + +### Operators + +| Operator | Description | Example | +| --- | --- | --- | +| `eq` | Equals | `id[eq]=abc-123` | +| `ne` | Not equals | `status[ne]=CLOSED` | +| `gt` | Greater than | `amount.value[gt]=1000` | +| `gte` | Greater than or equal | `createdAt[gte]=2025-01-01T00:00:00Z` | +| `lt` | Less than | `amount.value[lt]=50000` | +| `lte` | Less than or equal | `createdAt[lte]=2025-12-31T23:59:59Z` | +| `in` | Matches any value in list (pipe-separated) | `type[in]=CHECKING\|SAVING` | +| `nin` | Excludes values in list (pipe-separated) | `status[nin]=CLOSED\|SUSPENDED` | +| `like` | Case-insensitive partial match | `name[like]=trace` | +| `text` | Full-text search (case-insensitive) | `description[text]=payment` | +| `last` | Last element of array equals | `states.status[last]=ACTIVE` | +| `last_ne` | Last element of array not equals | `states.status[last_ne]=CLOSED` | + +### Logical operators + +Combine conditions using `and(...)` or `or(...)`: + +```text +?filters=and(amount.value[gt]=1000,amount.value[lt]=50000) +``` + +## Examples + +**Filter by ID:** + +```bash +?filters=id[eq]=399ca839-abd5-4a7d-981b-f187e7777ec8 +``` + +**Filter by date range:** + +```bash +?filters=and(createdAt[gte]=2025-01-01T00:00:00Z,createdAt[lte]=2025-01-31T23:59:59Z) +``` + +**Filter by type (multiple values):** + +```bash +?filters=type[in]=CHECKING|SAVING +``` + +**Filter by current status:** + +```bash +?filters=states.status[last]=ACTIVE +``` + +**Combined filters:** + +```bash +?filters=states.status[last]=ACTIVE;and(amount.value[gt]=1000,amount.value[lt]=50000) +``` + +Full request example: + +```bash +curl --request GET \ + --url '{{sandboxUrl}}/api/accounts?limit=10&filters=states.status[last]=ACTIVE' \ + --header 'Authorization: Bearer ' +``` diff --git a/guides/principles/idempotency.mdx b/guides/principles/idempotency.mdx index d603df3..9494d29 100644 --- a/guides/principles/idempotency.mdx +++ b/guides/principles/idempotency.mdx @@ -3,4 +3,74 @@ title: "Idempotency" description: "Use the X-Idempotency-Key header to safely retry requests." --- -{/* TODO: Write idempotency guide — X-Idempotency-Key header, when required, conflict behavior (409) */} +## Overview + +Idempotency ensures that performing the same operation multiple times produces the same result as performing it once. This protects against duplicate operations when requests are retried due to timeouts or network failures. + +## How it works + +### The X-Idempotency-Key header + +Mutating endpoints (POST, PUT, PATCH) require the `X-Idempotency-Key` header. This client-generated key lets the API detect and deduplicate repeated requests. + +```bash +curl --request POST \ + --url {{sandboxUrl}}/api/operations \ + --header 'Authorization: Bearer ' \ + --header 'X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000' \ + --header 'Content-Type: application/json' \ + --data '{ ... }' +``` + +### When it is required + +The `X-Idempotency-Key` header is required on any request that creates or modifies a resource. GET and DELETE requests do not require it. + +### Conflict behavior + +If a request arrives with an idempotency key that was already used, the API returns HTTP `409 Conflict`: + +```json +{ + "code": "IDEMPOTENT_ID_CONFLICT", + "message": "A request with this idempotency key has already been processed.", + "details": {} +} +``` + +## Examples + +Generate a UUID v4 for each unique operation: + + + + +```python +import uuid + +idempotency_key = str(uuid.uuid4()) +``` + + + + +```javascript +const idempotencyKey = crypto.randomUUID(); +``` + + + + +Retrying safely after a timeout: + +```bash +# First attempt — times out +curl ... --header 'X-Idempotency-Key: 550e8400-...' + +# Retry with the same key — safe, returns original result +curl ... --header 'X-Idempotency-Key: 550e8400-...' +``` + + + Never reuse an idempotency key for a different operation. Each unique operation must have its own key. + diff --git a/guides/principles/money.mdx b/guides/principles/money.mdx index ca92745..e63bbf7 100644 --- a/guides/principles/money.mdx +++ b/guides/principles/money.mdx @@ -3,4 +3,68 @@ title: "Money and currencies" description: "How monetary amounts are represented in the API." --- -{/* TODO: Write money guide — value in minor units (integer), asset as ISO 4217 currency code, supported currencies */} +## Overview + +All monetary amounts in the Trace FX API are represented as integers in **minor units** (e.g. cents) paired with an ISO 4217 currency code. This avoids floating-point precision issues. + +## How it works + +### Amount object + +Every amount in the API uses the same structure: + +```json +{ + "value": 11, + "decimalValue": "0.11", + "asset": "BRL", + "decimals": 2 +} +``` + +| Field | Type | Description | +| --- | --- | --- | +| `value` | integer | Amount in the smallest currency unit (e.g. centavos for BRL, cents for USD) | +| `decimalValue` | string | Human-readable decimal representation of the amount | +| `asset` | string | ISO 4217 currency code | +| `decimals` | integer | Number of decimal places for the currency | + +### Examples by currency + +| `value` | `decimals` | `asset` | `decimalValue` | +| --- | --- | --- | --- | +| `500000` | `2` | `BRL` | `"5000.00"` | +| `1050` | `2` | `USD` | `"10.50"` | +| `100000000` | `8` | `BTC` | `"1.00000000"` | + + + Always use integer arithmetic when working with `value`. The `decimalValue` field is provided for display purposes only. + + +## Examples + +A deposit of R$ 1.250,00: + +```json +{ + "amount": { + "value": 125000, + "decimalValue": "1250.00", + "asset": "BRL", + "decimals": 2 + } +} +``` + +A withdrawal of $500.00: + +```json +{ + "amount": { + "value": 50000, + "decimalValue": "500.00", + "asset": "USD", + "decimals": 2 + } +} +``` diff --git a/guides/principles/pagination.mdx b/guides/principles/pagination.mdx index f75fec8..e0e6ade 100644 --- a/guides/principles/pagination.mdx +++ b/guides/principles/pagination.mdx @@ -3,4 +3,83 @@ title: "Pagination" description: "Navigate large result sets with cursor-based pagination." --- -{/* TODO: Write pagination guide — cursor-based, meta object (previousCursor, nextCursor, total, totalMatches) */} +## Overview + +List endpoints return paginated responses using cursor-based pagination. This approach provides stable results even when data changes between requests. + +## How it works + +### Query parameters + +| Parameter | Type | Default | Description | +| --- | --- | --- | --- | +| `limit` | integer | `10` | Maximum number of items to return per page | +| `cursor` | string | — | Cursor returned from a previous response | +| `direction` | string | — | Pagination direction: `NEXT` or `PREVIOUS` | +| `sortOrder` | string | `DESCENDING` | Sort direction: `ASCENDING` or `DESCENDING` | +| `includeTotalMatches` | boolean | `false` | Whether to include the total matching count in the response | + +### Response structure + +Every list response includes a `meta` object alongside the `data` array: + +```json +{ + "data": [ + { "id": "acc_001", "type": "CHECKING" }, + { "id": "acc_002", "type": "SAVING" } + ], + "meta": { + "previousCursor": null, + "nextCursor": "eyJpZCI6ImFjY18wMDIifQ", + "total": 45, + "totalMatches": 45 + } +} +``` + +| Field | Description | +| --- | --- | +| `previousCursor` | Cursor to fetch the previous page. `null` on the first page. | +| `nextCursor` | Cursor to fetch the next page. `null` on the last page. | +| `total` | Number of items returned in the current page. | +| `totalMatches` | Total items matching the current filters. Only present when `includeTotalMatches=true`. | + +## Examples + +**First page:** + +```bash +curl --request GET \ + --url '{{sandboxUrl}}/api/accounts?limit=10' \ + --header 'Authorization: Bearer ' +``` + +**Next page** — pass the `nextCursor` value as `cursor`: + +```bash +curl --request GET \ + --url '{{sandboxUrl}}/api/accounts?limit=10&cursor=eyJpZCI6ImFjY18wMDIifQ' \ + --header 'Authorization: Bearer ' +``` + +**Iterating through all pages:** + +```python +cursor = None + +while True: + params = {"limit": 10} + if cursor: + params["cursor"] = cursor + + response = client.get("/api/accounts", params=params) + data = response.json() + + for item in data["data"]: + process(item) + + cursor = data["meta"]["nextCursor"] + if cursor is None: + break +``` diff --git a/guides/principles/versioning.mdx b/guides/principles/versioning.mdx index 8f236cd..d18ae34 100644 --- a/guides/principles/versioning.mdx +++ b/guides/principles/versioning.mdx @@ -3,4 +3,68 @@ title: "Versioning" description: "How API versioning works via the X-Trace-Version header." --- -{/* TODO: Write versioning guide — X-Trace-Version header, default version behavior, deprecation policy */} +## Overview + +The Trace FX API uses the `X-Trace-Version` header to route requests to a specific API version. This lets you pin your integration to a known version while newer versions are released. + +## How it works + +### Setting the version + +Include the `X-Trace-Version` header in your requests: + +```bash +curl --request GET \ + --url {{sandboxUrl}}/api/accounts \ + --header 'Authorization: Bearer ' \ + --header 'X-Trace-Version: 2' +``` + +If the header is omitted, empty, or contains a non-existent version, the request is routed to the **default version** configured by Trace. + + + Always pin a version in production to avoid unexpected behavior when the default changes. + + +### Non-breaking changes + +The following changes do not require a new version. They can be released at any time: + +- Adding new **optional** fields to responses +- Adding new endpoints +- Adding new optional query parameters + + + Configure your client to ignore unknown fields in responses. Strict validation may cause failures when optional fields are added. + + +### Breaking changes + +The following changes trigger a **new major version**: + +- Removing or renaming existing fields +- Changing a field's data type (e.g. integer to string) +- Making an optional field required +- Reorganizing the response structure +- Changing endpoint behavior, status codes, or error responses +- Adding new enum values that affect strict validation + +### Deprecation policy + +When a new version is released, the previous version remains available for a migration period. Deprecation timelines are communicated in advance so you can plan your upgrade. + +## Examples + +Pinned version: + +```bash +X-Trace-Version: 2 +``` + +No version header (uses default): + +```bash +curl --request GET \ + --url {{sandboxUrl}}/api/accounts \ + --header 'Authorization: Bearer ' +``` diff --git a/index.mdx b/index.mdx index 6672c29..f24584a 100644 --- a/index.mdx +++ b/index.mdx @@ -1,6 +1,40 @@ --- -title: "Trace Finance Developer Docs" -description: "Build multi-currency account and payment experiences with the Trace FX API." +title: "Home" +sidebarTitle: "Home" +description: "Explore guides, examples, and API references to build with Trace Finance." +mode: "wide" --- -{/* TODO: Write landing page content — what Trace FX is, who it's for, quick navigation cards */} +## Get started + + + + Set up your sandbox and make your first API call in minutes. + + + Learn how to authenticate requests with bearer tokens. + + + Understand sandbox and production environments. + + + +## Build with Trace + + + + Create and manage Brazilian Real accounts for your users. + + + Set up cryptocurrency accounts with full compliance. + + + Accept deposits via PIX, wire transfer, and crypto networks. + + + Process withdrawals to bank accounts and crypto wallets. + + + Exchange between BRL, USD, and crypto assets. + + diff --git a/journeys/deposit.mdx b/journeys/deposit.mdx index 5a6116e..7b0d089 100644 --- a/journeys/deposit.mdx +++ b/journeys/deposit.mdx @@ -3,4 +3,56 @@ title: "Make a deposit" description: "How to create a deposit and track it through to completion." --- -{/* TODO: Write journey — intent-first and money-first deposit flows, webhook events, status transitions */} +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. +- Valid [authentication credentials](/guides/authentication). + +## Steps + +### Intent-first flow + +Use this when you create the deposit intent before the funds arrive. + + + + ```bash + curl --request POST \ + --url {{sandboxUrl}}/api/operations \ + --header 'Authorization: Bearer ' \ + + --header 'X-Idempotency-Key: ' \ + --header 'Content-Type: application/json' \ + --data '{ + "type": "DEPOSIT", + "accountId": "", + "amount": { + "value": 500000, + "asset": "BRL" + } + }' + ``` + + The operation is created in `PENDING` status. + + + Listen for `operation.created`, `operation.completed`, and `operation.failed` webhook events as the deposit progresses. + + + +### Money-first flow + +When funds arrive at the account before an explicit deposit intent is created, the platform automatically creates the operation and notifies you via webhook events. + +## What happens next + +- [Make a withdrawal](/journeys/withdrawal) — move funds out of the account. +- [Execute a swap](/journeys/swap) — convert between currencies. diff --git a/journeys/open-brl-account.mdx b/journeys/open-brl-account.mdx index b79b49c..8dec341 100644 --- a/journeys/open-brl-account.mdx +++ b/journeys/open-brl-account.mdx @@ -3,4 +3,48 @@ title: "Open a BRL account" description: "Step-by-step guide to opening a Brazilian Real account for an account owner." --- -{/* TODO: Write journey — end-to-end flow from create-account to active account with BRL funding instructions */} +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 index 4fb5e98..10d7eb1 100644 --- a/journeys/open-crypto-account.mdx +++ b/journeys/open-crypto-account.mdx @@ -3,4 +3,49 @@ title: "Open a crypto account" description: "Step-by-step guide to opening a crypto asset account for an account owner." --- -{/* TODO: Write journey — end-to-end flow from create-account to active account with crypto wallet */} +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/swap.mdx b/journeys/swap.mdx index e83c649..8a9cfad 100644 --- a/journeys/swap.mdx +++ b/journeys/swap.mdx @@ -3,4 +3,69 @@ title: "Execute a swap" description: "How to convert between currencies using the swap endpoint." --- -{/* TODO: Write journey — swap flow, quote integration, forward-only execution */} +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. +- Valid [authentication credentials](/guides/authentication). + +## Steps + + + + Get the current exchange rate and confirm the amounts before executing: + + ```bash + curl --request POST \ + --url {{sandboxUrl}}/api/quotes \ + --header 'Authorization: Bearer ' \ + + --header 'Content-Type: application/json' \ + --data '{ + "from": "BRL", + "to": "USD", + "amount": { + "value": 500000, + "asset": "BRL" + } + }' + ``` + + The response includes the quoted rate and the resulting amount. Quotes are valid for a limited time. + + + Submit the swap using the quote ID: + + ```bash + curl --request POST \ + --url {{sandboxUrl}}/api/operations \ + --header 'Authorization: Bearer ' \ + + --header 'X-Idempotency-Key: ' \ + --header 'Content-Type: application/json' \ + --data '{ + "type": "SWAP", + "quoteId": "", + "accountId": "" + }' + ``` + + + Listen for `operation.created`, `operation.completed`, and `operation.failed` webhook events. + + + + + Swaps are forward-only. Once executed, they cannot be reversed. Always verify the quoted rate before submitting. + + +## What happens next + +- [Make a withdrawal](/journeys/withdrawal) — send the converted funds to an external destination. diff --git a/journeys/withdrawal.mdx b/journeys/withdrawal.mdx index 3aacb66..b047187 100644 --- a/journeys/withdrawal.mdx +++ b/journeys/withdrawal.mdx @@ -3,4 +3,65 @@ title: "Make a withdrawal" description: "How to create a withdrawal and handle the review process." --- -{/* TODO: Write journey — withdrawal flow with and without compliance review, beneficiary setup */} +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. +- A registered **beneficiary** for the destination (bank account or wallet). +- Valid [authentication credentials](/guides/authentication). + +## Steps + + + + Before withdrawing to a new destination, register the beneficiary: + + ```bash + curl --request POST \ + --url {{sandboxUrl}}/api/beneficiaries \ + --header 'Authorization: Bearer ' \ + + --header 'X-Idempotency-Key: ' \ + --header 'Content-Type: application/json' \ + --data '{ + "name": "Beneficiary Name", + "type": "BANK_ACCOUNT" + }' + ``` + + Wait for the `beneficiary.approved` webhook event before proceeding. The beneficiary may be rejected during compliance review. + + + ```bash + curl --request POST \ + --url {{sandboxUrl}}/api/operations \ + --header 'Authorization: Bearer ' \ + + --header 'X-Idempotency-Key: ' \ + --header 'Content-Type: application/json' \ + --data '{ + "type": "WITHDRAWAL", + "accountId": "", + "beneficiaryId": "", + "amount": { + "value": 100000, + "asset": "BRL" + } + }' + ``` + + + The withdrawal may go through compliance review. Listen for `operation.created`, `operation.completed`, and `operation.failed` webhook events. + + + +## What happens next + +- [Execute a swap](/journeys/swap) — convert currencies before withdrawing. diff --git a/logo/dark.svg b/logo/dark.svg index 54a338a..f029ed6 100644 --- a/logo/dark.svg +++ b/logo/dark.svg @@ -1,13 +1,16 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/logo/light.svg b/logo/light.svg index 75fca1c..b6aceee 100644 --- a/logo/light.svg +++ b/logo/light.svg @@ -1,13 +1,16 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/quickstart.mdx b/quickstart.mdx index 587714c..c49c99c 100644 --- a/quickstart.mdx +++ b/quickstart.mdx @@ -3,4 +3,51 @@ title: "Quickstart" description: "Make your first API request to Trace FX in under five minutes." --- -{/* TODO: Write quickstart — get credentials, hit sandbox, see a response */} +import SandboxNote from '/snippets/sandbox-note.mdx'; + + + +## Prerequisites + +- A **client ID** and **client secret** provided during onboarding. +- [curl](https://curl.se/) or any HTTP client. + +## Steps + + + + Follow the [Authentication](/guides/authentication) guide to exchange your client credentials for a JWT. Copy the `access_token` from the response. + + + List accounts in the sandbox: + + ```bash + curl --request GET \ + --url {{sandboxUrl}}/api/accounts \ + --header 'Authorization: Bearer YOUR_ACCESS_TOKEN' + ``` + + + You should see a paginated response: + + ```json + { + "data": [], + "meta": { + "previousCursor": null, + "nextCursor": null, + "total": 0, + "totalMatches": 0 + } + } + ``` + + An empty `data` array is expected — you haven't created any accounts yet. You're connected and authenticated. + + + +## What's next + +- [Open a BRL account](/journeys/open-brl-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 index bb193e9..12d5c5a 100644 --- a/snippets/sandbox-note.mdx +++ b/snippets/sandbox-note.mdx @@ -1,5 +1,4 @@ - This guide uses the **sandbox** environment. Replace `faas.sandbox.tracefinance.io` - with `faas.tracefinance.io` when you move to production. + This guide uses the **sandbox** environment. See [Environments](/guides/environments) for details. diff --git a/webhooks/events.mdx b/webhooks/events.mdx deleted file mode 100644 index 4e91367..0000000 --- a/webhooks/events.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: "Event reference" -description: "Complete catalog of webhook events grouped by domain." -sidebarTitle: "Event reference" ---- - -{/* TODO: Write event reference — grouped by domain: - Account events: account.created, account.activated, account.deactivated, etc. - Payment events: operation.created, operation.completed, operation.failed, etc. - Beneficiary events: beneficiary.created, beneficiary.approved, beneficiary.rejected -*/} diff --git a/webhooks/overview.mdx b/webhooks/overview.mdx deleted file mode 100644 index c9789f1..0000000 --- a/webhooks/overview.mdx +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "Webhooks overview" -description: "Receive real-time notifications when events occur on the Trace FX platform." -sidebarTitle: "Overview" ---- - -{/* TODO: Write webhook overview — setup, endpoint requirements, signatures, retry policy, delivery guarantees */}