# Create Connections Source: https://docs.yativo.com/api-reference/accounts/connections-create POST /v1/accounts/create-connections Connect an account to one or more blockchain networks Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the account to connect to blockchain networks. Array of blockchain network identifiers to connect. Supported values: `ethereum`, `solana`, `bitcoin`, `polygon`, `bsc`, `base`, `arbitrum`, `optimism`, `xdc`. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/accounts/create-connections' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chains": ["ethereum", "solana", "polygon"] }' ``` ```json theme={null} { "status": "success", "message": "Connections created successfully", "data": { "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "connections": [ { "connection_id": "con_01HX9KZMB3F7VNQP8R2WDGT4E7", "chain": "ethereum", "status": "active" }, { "connection_id": "con_01HX9KZMB3F7VNQP8R2WDGT4E8", "chain": "solana", "status": "active" }, { "connection_id": "con_01HX9KZMB3F7VNQP8R2WDGT4E9", "chain": "polygon", "status": "active" } ] } } ``` # List Connections Source: https://docs.yativo.com/api-reference/accounts/connections-list GET /v1/accounts/get-connections Retrieve blockchain network connections for an account Bearer token: `Bearer YOUR_ACCESS_TOKEN` Filter connections by account ID. If omitted, returns all connections for the authenticated user. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/accounts/get-connections?account_id=acc_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} {"data":[],"status":true,"message":"No Connections Available!"} ``` # Create Account Source: https://docs.yativo.com/api-reference/accounts/create POST /v1/accounts/create-account Create a new account to organize wallets and assets Bearer token: `Bearer YOUR_ACCESS_TOKEN` A human-readable name for the account. Optional type classification for the account, e.g. `personal`, `business`, `customer`. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/accounts/create-account' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_name": "Main Treasury", "account_type": "business" }' ``` ```json theme={null} { "status": "success", "message": "Account created successfully", "data": { "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "account_name": "Main Treasury", "account_type": "business", "created_at": "2026-03-26T12:00:00Z" } } ``` # List Accounts Source: https://docs.yativo.com/api-reference/accounts/list GET /v1/accounts/get-accounts Retrieve all accounts associated with the authenticated user Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/accounts/get-accounts' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "data": [ { "_id": "acc_6615c3b2e55d9ff7bc0a5678", "account_name": "Default Account", "user_id": "usr_6615c3a1e55d9ff7bc0a1234", "assets": "1", "account_value": 0.3, "portfolio": "0.00", "archived": "0", "subaccount": false, "createdAt": "2026-01-13T22:06:20.231Z", "updatedAt": "2026-03-08T10:30:03.778Z" } ], "status": true, "message": "Accounts and assets listed successfully" } ``` # Activate Wallet Source: https://docs.yativo.com/api-reference/agentic-wallets/activate POST /v1/agentic-wallets/{walletId}/activation/activate Activate an agentic wallet after OTP verification Bearer token: `Bearer YOUR_ACCESS_TOKEN` The wallet ID to activate. The email OTP code received after calling the send-email-otp endpoint. TOTP code from your authenticator app (required if 2FA is enabled on your account). ```bash theme={null} curl -X POST '/v1/agentic-wallets/aw_01abc123/activation/activate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "email_otp": "123456" }' ``` ```json theme={null} { "success": true, "message": "Wallet activated successfully", "data": { "wallet_id": "aw_01abc123", "status": "active" } } ``` # Add Connector Source: https://docs.yativo.com/api-reference/agentic-wallets/add-connector POST /v1/agentic-wallets/{walletId}/connectors Create a new connector (API key) for an agentic wallet Bearer token: `Bearer YOUR_ACCESS_TOKEN` The wallet ID to add a connector to. Human-readable name for the connector (e.g., "Claude Agent", "GPT Agent"). Maximum USD amount per single transaction. Defaults to the wallet's global limit. Maximum USD amount per 24-hour period. Maximum USD amount per calendar month. ```bash theme={null} curl -X POST '/v1/agentic-wallets/aw_01abc123/connectors' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "name": "Claude Agent", "per_transaction_limit": 50, "daily_limit": 500, "monthly_limit": 5000 }' ``` ```json theme={null} { "success": true, "data": { "connector_id": "conn_01abc123", "name": "Claude Agent", "api_key": "yac_a1b2c3d4e5f6...", "per_transaction_limit": 50, "daily_limit": 500, "monthly_limit": 5000, "status": "active", "created_at": "2026-04-01T12:00:00Z" } } ``` The `api_key` is shown **only once** in this response. Store it securely. If lost, revoke the connector and create a new one. # Agent Balance Source: https://docs.yativo.com/api-reference/agentic-wallets/balance GET /v1/agent/balance Check the balance of an agentic wallet (used by AI agents) Connector API key: `Bearer yac_...` The agentic wallet ID to check. ```bash theme={null} curl -X GET '/v1/agent/balance?wallet_id=aw_01abc123' \ -H 'Authorization: Bearer yac_connector_api_key' ``` ```json theme={null} { "success": true, "data": { "wallet_id": "aw_01abc123", "wallet_address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "chain": "base", "balance": 250.00, "assets": { "USDC": 250.00 } } } ``` # Create Agentic Wallet Source: https://docs.yativo.com/api-reference/agentic-wallets/create POST /v1/agentic-wallets/create Create a new agentic wallet for AI agent use Bearer token: `Bearer YOUR_ACCESS_TOKEN` Human-readable name for the wallet (e.g., "Production Agent Wallet"). Preferred blockchain for the wallet. Defaults to the platform default. ```bash theme={null} curl -X POST '/v1/agentic-wallets/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "name": "Production Agent Wallet" }' ``` ```json theme={null} { "success": true, "data": { "wallet_id": "aw_01abc123", "name": "Production Agent Wallet", "wallet_address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "chain": "base", "status": "created", "balance": 0, "created_at": "2026-04-01T12:00:00Z" } } ``` # Get Agentic Wallet Source: https://docs.yativo.com/api-reference/agentic-wallets/get GET /v1/agentic-wallets/{walletId} Get details of a specific agentic wallet Bearer token: `Bearer YOUR_ACCESS_TOKEN` The wallet ID (starts with `aw_`). ```bash theme={null} curl -X GET '/v1/agentic-wallets/aw_01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "wallet_id": "aw_01abc123", "name": "Production Agent Wallet", "wallet_address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "chain": "base", "status": "active", "balance": 250.00, "assets": { "USDC": 250.00 }, "limits": { "per_transaction": 100, "daily": 1000, "monthly": 10000 }, "auto_fund": { "enabled": false }, "x402": { "enabled": true, "max_amount": 1.00 }, "connectors_count": 2, "total_spent": 1250.00, "total_transactions": 45, "created_at": "2026-04-01T12:00:00Z" } } ``` # List Agentic Wallets Source: https://docs.yativo.com/api-reference/agentic-wallets/list GET /v1/agentic-wallets List all agentic wallets for the authenticated user Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET '/v1/agentic-wallets' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "wallets": [ { "wallet_id": "aw_01abc123", "name": "Production Agent Wallet", "wallet_address": "0x742d35Cc...", "chain": "base", "status": "active", "balance": 250.00, "connectors_count": 2, "created_at": "2026-04-01T12:00:00Z" } ] } } ``` # Agent Transact Source: https://docs.yativo.com/api-reference/agentic-wallets/transact POST /v1/agent/transact Send a crypto payment from an agentic wallet (used by AI agents) Connector API key: `Bearer yac_...` The agentic wallet ID to send from. Amount in USD to send. Asset to send. Defaults to `USDC`. Chain override (e.g., `base`, `ethereum`, `solana`). The destination wallet address. Name of the service being paid (for audit trail). URL of the service being paid. Why this payment is being made (for audit trail). Category: `ai_service`, `prediction_market`, `legal_escrow`, `subscription`, `purchase`, `transfer`, `settlement`, `other`. Defaults to `other`. ```bash theme={null} curl -X POST '/v1/agent/transact' \ -H 'Authorization: Bearer yac_connector_api_key' \ -H 'Content-Type: application/json' \ -d '{ "wallet_id": "aw_01abc123", "amount": 5.00, "asset": "USDC", "recipient_address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "service_name": "OpenAI API", "service_url": "https://api.openai.com", "payment_reason": "GPT-4 inference for customer support bot", "payment_category": "ai_service" }' ``` ```json theme={null} { "success": true, "data": { "transaction_id": "atx_01pqr456", "tx_hash": "0xabc123def456...", "amount": 5.00, "asset": "USDC", "recipient_address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "chain": "base", "status": "completed", "fee": 0.00, "is_free_transaction": true, "service_name": "OpenAI API", "payment_category": "ai_service" } } ``` # x402 Fetch Source: https://docs.yativo.com/api-reference/agentic-wallets/x402-fetch POST /v1/agent/x402-fetch Fetch a URL with automatic x402 payment — if the URL returns HTTP 402, the wallet pays and retries Connector API key: `Bearer yac_...` The agentic wallet ID to pay from. The URL to fetch. If it returns HTTP 402, payment is made automatically. HTTP method: `GET`, `POST`, `PUT`, `DELETE`, `PATCH`. Defaults to `GET`. Additional headers to include in the request. Request body (for POST/PUT/PATCH requests). ```bash theme={null} curl -X POST '/v1/agent/x402-fetch' \ -H 'Authorization: Bearer yac_connector_api_key' \ -H 'Content-Type: application/json' \ -d '{ "wallet_id": "aw_01abc123", "url": "https://api.example.com/premium-data", "method": "GET" }' ``` ```json theme={null} { "success": true, "data": { "status": 200, "paid": true, "payment": { "amount_usd": 0.01, "asset": "USDC", "network": "base", "pay_to": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4" }, "body": { "premium_data": "..." } } } ``` # Analytics Overview Source: https://docs.yativo.com/api-reference/analytics/overview GET /v1/analytics/dashboard-analytics Get dashboard analytics including total account value, transaction volume chart, and user growth. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Start date for the reporting period. ISO 8601 format: `2026-03-01` End date for the reporting period. ISO 8601 format: `2026-03-31` ```typescript theme={null} interface AnalyticsOverviewResponse { data: { totalAccountValue: number; depositTransactions: any[]; chartTransactions: Array<{ _id: { year: number; month: number }; totalAmount: number; count: number; }>; chartUsers: Array<{ _id: { year: number; month: number }; count: number; }>; }; status: boolean; message: string; } ``` ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/analytics/dashboard-analytics' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "data": { "totalAccountValue": 2.47, "depositTransactions": [], "chartTransactions": [ {"_id": {"year": 2026, "month": 1}, "totalAmount": 0, "count": 117}, {"_id": {"year": 2026, "month": 2}, "totalAmount": 0, "count": 304}, {"_id": {"year": 2026, "month": 3}, "totalAmount": 0, "count": 345} ], "chartUsers": [ {"_id": {"year": 2026, "month": 1}, "count": 4}, {"_id": {"year": 2026, "month": 2}, "count": 3}, {"_id": {"year": 2026, "month": 3}, "count": 2} ] }, "status": true, "message": "Analytics Listed Successfully" } ``` # Transaction Analytics Source: https://docs.yativo.com/api-reference/analytics/transactions GET /v1/analytics/transaction-analytics Get transaction analytics broken down by status: pending, processing, failed, and approved. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Start date. ISO 8601 format: `2026-03-01` End date. ISO 8601 format: `2026-03-31` Time bucket size. Accepted values: `hour`, `day`, `week`, `month`. Default: `day` Filter by asset symbol (e.g. `USDC`, `ETH`). Filter by network (e.g. `polygon`, `ethereum`, `solana`). ```typescript theme={null} interface TransactionAnalyticsResponse { pendingTransactions: any[]; processingTransactions: any[]; failedTransactions: any[]; approvedTransactions: any[]; status: boolean; message: string; } ``` ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/analytics/transaction-analytics' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "pendingTransactions": [], "processingTransactions": [], "failedTransactions": [], "approvedTransactions": [], "status": true, "message": "Transaction Analytics Listed Successfully" } ``` # Volume Analytics Source: https://docs.yativo.com/api-reference/analytics/volume Volume analytics are included in the Dashboard Analytics endpoint. Volume and chart data are returned as part of the [Analytics Overview](/api-reference/analytics/overview) endpoint (`GET /api/analytics/dashboard-analytics`). The `chartTransactions` array in the response contains monthly volume breakdowns including `totalAmount` and `count`. # Create API Key Source: https://docs.yativo.com/api-reference/api-keys/create POST /v1/apikey/generate Generate a new API key and secret for programmatic access Bearer token: `Bearer YOUR_ACCESS_TOKEN` A human-readable label for this key (e.g. `"Production Backend"`, `"Staging Integration"`). List of permission scopes. Omit to grant all scopes. Available values: `transactions:read`, `transactions:write`, `accounts:read`, `accounts:write`, `webhooks:manage`, `analytics:read` Optional expiry timestamp (ISO 8601). The key will be automatically revoked after this time. The `api_secret` is returned **only once** at creation. Store it securely — it cannot be retrieved again. If lost, revoke the key and create a new one. **Using your API key:** After generating a key, call `POST /auth/token` with your `api_key` and `api_secret` to generate a Bearer token. Bearer tokens expire in 60 minutes — refresh as needed. API keys themselves never expire unless you set `expires_at` at creation time. ```typescript theme={null} interface CreateApiKeyRequest { name: string; permissions?: string[]; expires_at?: string; } interface CreateApiKeyResponse { status: "success"; data: { key_id: string; api_key: string; // Public key — safe to reference in logs api_secret: string; // Secret — shown ONCE, store securely name: string; permissions: string[]; expires_at: string | null; created_at: string; }; } ``` ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/apikey/generate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "name": "Production Backend", "permissions": ["transactions:read", "transactions:write", "accounts:read"] }' ``` ```json Success theme={null} { "success": true, "message": "API key generated successfully", "warning": "Save the API Secret securely. It will not be shown again!", "data": { "api_key": "yativo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "api_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "key_name": "Production API Key", "scopes": ["read", "write", "transactions"], "expires_at": null, "rate_limit": { "requests_per_minute": 60, "requests_per_hour": 3000, "requests_per_day": 50000 }, "token_expiry_minutes": 60 } } ``` # List API Keys Source: https://docs.yativo.com/api-reference/api-keys/list GET /v1/apikey List all API keys for your account. Secrets are never returned in list responses. Bearer token: `Bearer YOUR_ACCESS_TOKEN` The `api_secret` is never returned in list or get responses — only at creation. To rotate a secret, revoke the key and create a new one. ```typescript theme={null} interface ApiKeySummary { key_id: string; api_key: string; // Public key only — secret is never returned name: string; permissions: string[]; status: "active" | "revoked" | "expired"; last_used_at: string | null; expires_at: string | null; created_at: string; } interface ListApiKeysResponse { status: "success"; data: { keys: ApiKeySummary[]; }; } ``` ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/apikey' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "success": true, "count": 1, "data": [ { "id": "key_69c799d9f1fba3928d8a12ac", "key_name": "Production API Key", "api_key": "yativo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "scopes": ["read", "write", "transactions"], "is_active": true, "is_revoked": false, "allowed_ips": [], "allowed_origins": [], "rate_limit": { "requests_per_minute": 60, "requests_per_hour": 3000, "requests_per_day": 50000 }, "expires_at": null } ] } ``` # Revoke API Key Source: https://docs.yativo.com/api-reference/api-keys/revoke DELETE /v1/apikey/{keyId} Permanently revoke an API key. This action is immediate and irreversible. Bearer token: `Bearer YOUR_ACCESS_TOKEN` The key ID to revoke (e.g. `key_01HX9KZMB3F7VNQP8R2WDGT4E5`). Revoking a key is **immediate and irreversible**. Any services using this key will lose API access instantly. Ensure you have updated all dependent services before revoking. ```bash cURL theme={null} curl -X DELETE 'https://crypto-api.yativo.com/api/v1/apikey/key_69c799d9f1fba3928d8a12ac' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "success": true, "message": "API key revoked successfully", "data": { "id": "key_69c799d9f1fba3928d8a12ac", "is_revoked": true, "revoked_at": "2026-03-28T11:00:00.000Z" } } ``` # Get Bearer Token Source: https://docs.yativo.com/api-reference/api-keys/token POST /v1/auth/token Exchange your API key and secret for a Bearer token. This is the starting point for all API authentication. **Start here.** All API endpoints require `Authorization: Bearer `. Exchange your API key credentials for a token using this endpoint — no login session required. Tokens expire after **60 minutes**; call this endpoint again to get a fresh one. Your API key never expires. Your API key (starts with `yativo_`). Obtained when you created the key. Your API secret. Shown **only once** at key creation — store it securely. This endpoint does **not** require an `Authorization` header — use it to bootstrap your authentication. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/auth/token' \ -H 'Content-Type: application/json' \ -d '{ "api_key": "yativo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "api_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }' ``` ```typescript TypeScript theme={null} const response = await fetch('https://crypto-api.yativo.com/api/v1/auth/token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ api_key: process.env.YATIVO_API_KEY, api_secret: process.env.YATIVO_API_SECRET, }), }); const { access_token } = await response.json(); ``` ```json Success theme={null} { "success": true, "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600, "expires_at": "2026-03-28T11:00:00.000Z", "scopes": ["read", "write", "transactions"], "refresh_recommendation": { "refresh_before_seconds": 300, "auto_refresh_enabled": true } } ``` ```json Error — Invalid credentials theme={null} { "success": false, "error": "Invalid, expired, or revoked API key" } ``` # Archive Asset Source: https://docs.yativo.com/api-reference/assets/archive POST /v1/assets/archive-asset Archive a wallet asset to prevent it from appearing in active listings Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the asset to archive. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/assets/archive-asset' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4EA" }' ``` ```json theme={null} { "status": "success", "message": "Asset archived successfully", "data": { "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4EA", "status": "archived", "archived_at": "2026-03-26T12:00:00Z" } } ``` # Check Balance Source: https://docs.yativo.com/api-reference/assets/balance POST /v1/balance/check Check the current balance of a specific asset wallet Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the asset wallet to check the balance for. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/balance/check' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4EA" }' ``` ```json theme={null} { "status": "success", "message": "Balance retrieved successfully", "data": { "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4EA", "chain": "solana", "ticker": "USDC_SOL", "wallet_address": "7nZ9X4mQkLpR3sVwC8tF2bG6hJ5nM1yK", "balance": "1250.000000", "balance_usd": "1250.00", "last_updated": "2026-03-26T12:00:00Z" } } ``` # Batch Create Wallets Source: https://docs.yativo.com/api-reference/assets/batch-create POST /v1/assets/batch-add-asset Create multiple cryptocurrency wallets for an account in a single request Bearer token: `Bearer YOUR_ACCESS_TOKEN` The account ID to create the wallets under. Array of blockchain network identifiers, e.g. `["solana", "ethereum", "polygon"]`. Array of token ticker symbols corresponding to each chain, e.g. `["USDC_SOL", "USDC_ETH", "USDC_MATIC"]`. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/assets/batch-add-asset' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chains": ["solana", "ethereum", "polygon"], "tickers": ["USDC_SOL", "USDC_ETH", "USDC_MATIC"] }' ``` ```json theme={null} { "status": "success", "message": "Assets created successfully", "data": [ { "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4EA", "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chain": "solana", "ticker": "USDC_SOL", "wallet_address": "7nZ9X4mQkLpR3sVwC8tF2bG6hJ5nM1yK", "status": "active" }, { "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4EB", "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chain": "ethereum", "ticker": "USDC_ETH", "wallet_address": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b", "status": "active" }, { "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4EC", "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chain": "polygon", "ticker": "USDC_MATIC", "wallet_address": "0x9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f0e", "status": "active" } ] } ``` # Create Wallet Source: https://docs.yativo.com/api-reference/assets/create POST /v1/assets/add-asset Create a new cryptocurrency wallet for an account Bearer token: `Bearer YOUR_ACCESS_TOKEN` The account ID to create the wallet under. The blockchain network. One of: `ethereum`, `solana`, `bitcoin`, `polygon`, `bsc`, `base`, `arbitrum`, `optimism`, `xdc`. The token ticker symbol, e.g. `USDC_SOL`, `ETH`, `BTC`. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/assets/add-asset' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chain": "solana", "ticker": "USDC_SOL" }' ``` ```json theme={null} { "status": "success", "message": "Asset created successfully", "data": { "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4E6", "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chain": "solana", "ticker": "USDC_SOL", "wallet_address": "7nZ9X4mQkLpR3sVwC8tF2bG6hJ5nM1yK", "status": "active", "created_at": "2026-03-26T12:00:00Z" } } ``` # List User Assets Source: https://docs.yativo.com/api-reference/assets/list POST /v1/assets/get-user-assets Retrieve all wallets and assets belonging to the authenticated user Bearer token: `Bearer YOUR_ACCESS_TOKEN` Filter assets by a specific account ID. If omitted, all assets across all accounts are returned. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/assets/get-user-assets' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5" }' ``` ```json theme={null} { "data": [ { "id": "ast_6615c3c3e55d9ff7bc0a9012", "user_id": "usr_6615c3a1e55d9ff7bc0a1234", "account_id": "acc_6615c3b2e55d9ff7bc0a5678", "asset_id": "67db5f72ebea822c360d568d", "asset_name": "USD Coin (Solana)", "asset_short_name": "USDC", "ticker_name": "USDC_SOL", "chain": "SOL", "address": "7xKt3Bm4NZpQhsWn1YvJd2Lr8Pk5Cq9eAw6Fu0GiRHs", "amount": "0.300000", "token_type": "token", "image": "https://cdn.yativo.com/assets/tokens/usdc.png", "layer_type": null, "parent_chain": null, "created_at": "2026-01-13T22:06:33.284Z", "updated_at": "2026-03-08T10:02:32.849Z" } ], "status": true, "message": "Assets Listed Successfully" } ``` # List Supported Chains Source: https://docs.yativo.com/api-reference/assets/list-chains GET /v1/assets/get-chains Retrieve all supported blockchain networks Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/assets/get-chains' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "status": true, "message": "Chains fetched successfully", "data": [ {"id": "BNB", "name": "BNB Smart Chain", "image": "https://cdn.yativo.com/assets/chains/bnb.png", "rpc": "https://bsc-dataseed.binance.org", "explorer": "https://bscscan.com"}, {"id": "SOL", "name": "Solana", "image": "https://cdn.yativo.com/assets/chains/sol.png", "rpc": "https://api.mainnet-beta.solana.com", "explorer": "https://solscan.io"}, {"id": "ETH", "name": "Ethereum on Base", "image": "https://cdn.yativo.com/assets/chains/eth.png", "rpc": "https://mainnet.base.org", "explorer": "https://basescan.org"}, {"id": "BTC", "name": "Bitcoin", "image": "https://cdn.yativo.com/assets/chains/btc.png", "rpc": "https://bitcoin-rpc.publicnode.com", "explorer": "https://blockstream.info"} ] } ``` # List Supported Assets Source: https://docs.yativo.com/api-reference/assets/list-supported GET /v1/assets/get-all-assets Retrieve all supported cryptocurrency assets and tokens Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/assets/get-all-assets' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "data": [ { "_id": "67db59c4ebea822c360d5091", "asset_name": "BNB Smart Chain", "asset_short_name": "BNB", "chain": "BSC", "chain_id": 56, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://cdn.yativo.com/assets/chains/bnb.png", "active": true, "price": 613.45, "ticker_name": "BNB", "layer_type": "L1", "parent_chain": null, "suspended": false }, { "_id": "67db5f72ebea822c360d568d", "asset_name": "USD Coin (Solana)", "asset_short_name": "USDC", "chain": "SOL", "chain_id": null, "network_type": "mainnet", "asset_type": "token", "decimals": 6, "image": "https://cdn.yativo.com/assets/tokens/usdc.png", "active": true, "price": 1.00, "ticker_name": "USDC_SOL", "suspended": false } ], "status": true } ``` # Refresh Token Source: https://docs.yativo.com/api-reference/authentication/refresh POST /v1/auth/refresh-token Exchange a refresh token for a new access token Pass the refresh token in the Authorization header: `Bearer YOUR_REFRESH_TOKEN` ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/auth/refresh-token' \ -H 'Authorization: Bearer YOUR_REFRESH_TOKEN' ``` ```json theme={null} { "status": true, "data": { "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } ``` # Verify OTP Source: https://docs.yativo.com/api-reference/authentication/verify-otp POST /v1/auth/otp-verification Verify a one-time password to complete two-factor authentication The one-time password sent to the user's email or authenticator app. The user's email address. Required if not already established in the session. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/auth/otp-verification' \ -H 'Content-Type: application/json' \ -d '{ "otp": "123456", "email": "user@example.com" }' ``` ```json theme={null} { "status": "success", "message": "OTP verified successfully", "data": { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } ``` # Create Rule Source: https://docs.yativo.com/api-reference/auto-forwarding/create POST /v1/auto-forwarding Create an auto-forwarding rule for automatic deposit forwarding Bearer token: `Bearer YOUR_ACCESS_TOKEN` The source asset/wallet to monitor for deposits. The address to forward funds to. The chain of the destination address. Minimum deposit amount (in token units) required to trigger forwarding. Deposits below this threshold are not forwarded. Whether the rule is active. Defaults to `true`. ```bash theme={null} curl -X POST '/v1/auto-forwarding' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "asset_id": "asset_01xyz789", "destination_address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "destination_chain": "ethereum", "min_amount": "10.00", "enabled": true }' ``` ```json theme={null} { "success": true, "data": { "rule_id": "af_01abc123", "asset_id": "asset_01xyz789", "destination_address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "destination_chain": "ethereum", "min_amount": "10.00", "enabled": true, "total_forwarded": "0.00", "forward_count": 0, "created_at": "2026-04-01T12:00:00Z" } } ``` # Delete Rule Source: https://docs.yativo.com/api-reference/auto-forwarding/delete DELETE /v1/auto-forwarding/{rule_id} Delete an auto-forwarding rule Bearer token: `Bearer YOUR_ACCESS_TOKEN` The rule ID to delete. ```bash theme={null} curl -X DELETE '/v1/auto-forwarding/af_01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "message": "Forwarding rule deleted" } ``` # List Rules Source: https://docs.yativo.com/api-reference/auto-forwarding/list GET /v1/auto-forwarding List all auto-forwarding rules Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET '/v1/auto-forwarding' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "rules": [ { "rule_id": "af_01abc123", "asset_id": "asset_01xyz789", "destination_address": "0x9F8b...", "destination_chain": "ethereum", "min_amount": "10.00", "enabled": true, "total_forwarded": "500.00", "forward_count": 12, "created_at": "2026-04-01T12:00:00Z" } ] } } ``` # Update Rule Source: https://docs.yativo.com/api-reference/auto-forwarding/update PUT /v1/auto-forwarding/{rule_id} Update an auto-forwarding rule Bearer token: `Bearer YOUR_ACCESS_TOKEN` The rule ID to update. New destination address. New minimum amount threshold. Enable or disable the rule. ```bash theme={null} curl -X PUT '/v1/auto-forwarding/af_01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "min_amount": "50.00", "enabled": false }' ``` ```json theme={null} { "success": true, "data": { "rule_id": "af_01abc123", "min_amount": "50.00", "enabled": false, "updated_at": "2026-04-01T13:00:00Z" } } ``` # Accept Terms Source: https://docs.yativo.com/api-reference/cards/accept-terms POST /v1/yativo-card/{yativoCardId}/terms Accept the Yativo Card terms and conditions to proceed with card issuance Bearer token: `Bearer YOUR_ACCESS_TOKEN` This endpoint works for **both own-account users and B2B customer cards**. * **Own-account users** (`POST /v1/yativo-card/onboard`): call this after KYC is approved and before creating a card. * **B2B Card Issuer customers**: terms are auto-accepted by the platform when KYC is first approved. However, the auto-accept can fail silently. If card creation returns `LEGAL_ACCEPTANCE_REQUIRED`, call this endpoint using the **customer's `yativo_card_id`** as the path parameter — it is idempotent and safe to call even if terms were already accepted upstream. Accepting terms is a one-time operation per card account. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068/terms' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' ``` ```json theme={null} { "success": true, "message": "Terms accepted successfully", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "terms_accepted": true, "version": "TOS_GENERAL_VERSION_1", "accepted_at": "2026-04-25T12:00:00.000Z", "legal_acceptances": { "terms_and_conditions": true, "privacy_policy": true, "age_confirmation": true, "issuer_disclosure": true, "fees_disclosure": true, "confirmed_at": "2026-04-25T12:00:00.000Z", "policy_version": "2026-04", "disclosure_version": "2026-04" }, "legal_acceptances_complete": true } } ``` # Set Account Card Limits (Admin) Source: https://docs.yativo.com/api-reference/cards/admin-account-card-limits PATCH /v1/yativo-card/admin/{yativoCardId}/card-limits Admin: set per-account card limits for any user or customer card This is an **admin-only** endpoint. It sets card limits directly on a specific account, bypassing the program ceiling. Platform hard cap is 5 active cards. The `yativo_card_id` of the account (user or customer card) to update. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Maximum virtual cards for this account. Must be 0–5. Maximum physical cards for this account. Must be 0–5. Maximum total active cards (virtual + physical combined) for this account. Must be 0–5. At least one field must be provided. ```bash cURL theme={null} curl -X PATCH 'https://crypto-api.yativo.com/api/v1/yativo-card/admin/yativo_card_customer_8f9a_abc_1769031332068/card-limits' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "max_virtual": 3, "max_physical": 2, "max_total": 5 }' ``` ```json 200 OK theme={null} { "success": true, "message": "Account card limits updated", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "card_limits": { "max_virtual": 3, "max_physical": 2, "max_total": 5, "set_by": "admin_user_id", "set_at": "2026-05-05T12:00:00.000Z" } } } ``` ```json 400 Invalid limit theme={null} { "success": false, "error_code": "INVALID_LIMIT", "message": "max_virtual must be 0–5" } ``` ```json 400 No changes theme={null} { "success": false, "error_code": "NO_CHANGES", "message": "Provide at least one limit field to update" } ``` ```json 404 Not found theme={null} { "success": false, "error_code": "NOT_FOUND", "message": "Card not found" } ``` # Reset Customer Onboarding (Admin) Source: https://docs.yativo.com/api-reference/cards/admin-reset POST /v1/yativo-card/admin/{yativoCardId}/reset Admin: force-reset any card onboarding record, including accounts with issued cards This is an **admin-only** endpoint. Unlike the issuer reset, this endpoint has no restriction on card status — it can reset accounts even after a payment card has been issued. Deletes the customer's Yativo record entirely, allowing re-onboarding from scratch with a new identity verification flow and a fresh wallet. **The email address used previously cannot be reused.** It remains registered with the card network. The customer must re-onboard with a different email address. The `yativo_card_id` of the account to reset. Works for both user and customer card accounts. Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/admin/yativo_card_customer_8f9a_abc_1769031332068/reset' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "message": "Customer onboarding reset. Re-onboard this customer via POST /api/yativo-card/customers/onboard with a different email address.", "data": { "deleted_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "email_masked": "sa***@hotmail.com", "external_customer_id": "usr_8821", "next_step": "POST /api/yativo-card/customers/onboard", "email_warning": "The email address used previously remains registered with the card network and cannot be reused. Use a different email address when re-onboarding this customer." } } ``` ```json 404 Not found theme={null} { "success": false, "error_code": "NOT_FOUND", "message": "Customer card not found" } ``` # Get Card Account Source: https://docs.yativo.com/api-reference/cards/create GET /v1/yativo-card/my-account Get the authenticated user's Yativo Card account details, including all linked cards, wallet info, and onboarding status. Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/my-account' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "account": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "email": "merchant@example.com", "flow_status": "safe_deployed", "current_step": 4, "progress_percentage": 100, "steps": [ {"step": 1, "name": "Initiate Program", "completed": true}, {"step": 2, "name": "Verify Email", "completed": true}, {"step": 3, "name": "Start KYC", "completed": true}, {"step": 4, "name": "Complete KYC", "completed": true}, {"step": 5, "name": "Create Card", "completed": true} ], "kyc_status": "approved", "source_of_funds_completed": true, "phone_verified": true, "terms_accepted": true, "safe_deployed": true, "wallet_address": "0xAB7a028c1c5483e9507C61F25335C64C52B9FBcc", "funding_address": "DwPq8k2XbNmJhvRs5TcLu4Ye9AgFp3ZoVi7Bn1KqWMeS", "funding_network": "solana", "cards_count": 1, "cards": [ { "card_id": "b2dc97ab-03f9-49eb-c72f-95be13815278", "last_four": "0892", "type": "virtual", "status": "Active", "is_frozen": false, "created_at": "2026-02-02T13:04:23.773Z" } ], "created_at": "2026-01-21T21:35:32.076Z", "updated_at": "2026-03-28T08:15:57.023Z" } } } ``` # Create Card Customer Source: https://docs.yativo.com/api-reference/cards/create-customer POST /v1/yativo-card/customers/onboard Register a new card customer under your issuer program and trigger email OTP verification **Issuer program required.** This endpoint is only available to users with an approved [Card Issuer Program](/api-reference/issuer/apply). Each customer gets a dedicated `yativo_card_id` used for all subsequent onboarding steps. Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's email address. Yativo sends a one-time verification code to this address. Must be unique per active customer card under your account — you cannot reuse your own issuer account email. Your own reference ID for this customer (e.g., a user ID from your platform). Stored as-is and returned on all customer records so you can correlate them on your side. No two active customer sessions may share the same `external_customer_id` under your account. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/onboard' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "email": "customer@example.com", "external_customer_id": "usr_8821" }' ``` ```javascript Node.js theme={null} const response = await fetch( 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/onboard', { method: 'POST', headers: { Authorization: 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ email: 'customer@example.com', external_customer_id: 'usr_8821', }), } ); const data = await response.json(); // data.data.yativo_card_id — save this for all subsequent calls ``` ```json 201 Created theme={null} { "success": true, "message": "Customer card onboarding initiated. Verification code sent to customer email.", "data": { "yativo_card_id": "yativo_card_customer_8f9a2b3c4d5e6f7a8b9c0d1e_1769031332068", "customer_id": "6627f3a2c5d4e100123abcde", "external_customer_id": "usr_8821", "email_masked": "cu***@example.com", "next_step": "verify_otp", "otp_expires_in_seconds": 600 } } ``` ```json 400 Invalid email theme={null} { "success": false, "error_code": "INVALID_EMAIL", "message": "Valid customer email is required" } ``` ```json 400 Issuer's own email used theme={null} { "success": false, "error_code": "ISSUER_EMAIL_NOT_ALLOWED", "message": "You cannot use your own account email as a customer email. Use a different email for this customer." } ``` ```json 400 Email already in use by personal card theme={null} { "success": false, "error_code": "EMAIL_ALREADY_IN_USE", "message": "This email is already associated with your personal card. Each card must use a unique email address.", "data": { "account_type": "user", "flow_status": "card_created" } } ``` ```json 409 Customer already exists for this email theme={null} { "success": false, "error_code": "CUSTOMER_CARD_ALREADY_ACTIVE", "message": "A customer card with this email already exists. Use the returned card ID to continue onboarding.", "data": { "yativo_card_id": "yativo_card_customer_8f9a2b3c4d5e6f7a8b9c0d1e_1769031332068", "flow_status": "otp_verified", "next_step": "kyc_link", "external_customer_id": "usr_8821" } } ``` ```json 400 Duplicate external_customer_id theme={null} { "success": false, "error_code": "CUSTOMER_CARD_ALREADY_ACTIVE", "message": "Customer card onboarding already in progress", "data": { "yativo_card_id": "yativo_card_customer_8f9a2b3c4d5e6f7a8b9c0d1e_1769031332068", "flow_status": "otp_requested", "next_step": "verify_otp" } } ``` ```json 409 Customer fully onboarded theme={null} { "success": false, "error_code": "CUSTOMER_ALREADY_ONBOARDED", "message": "This customer has already completed card onboarding. No further action is needed.", "data": { "yativo_card_id": "yativo_card_customer_8f9a2b3c4d5e6f7a8b9c0d1e_1769031332068", "flow_status": "active", "external_customer_id": "usr_8821", "next_step": "none" } } ``` ## Response Fields | Field | Type | Description | | ------------------------ | -------------- | ----------------------------------------------------------------------------------------------- | | `yativo_card_id` | string | Unique customer card identifier. **Save this** — required for every subsequent onboarding call. | | `customer_id` | string | Internal Yativo database ID for this customer record. | | `external_customer_id` | string \| null | Your reference ID, echoed back unchanged. | | `email_masked` | string | Partially masked version of the customer's email for display purposes. | | `next_step` | string | Always `"verify_otp"` on creation. | | `otp_expires_in_seconds` | number | How long the emailed code is valid (600 = 10 minutes). | ## Idempotency This endpoint is safe to retry. If you call it again with the same `email` or `external_customer_id` while a session is already active, the API returns the existing card rather than creating a duplicate. ### Handling `CUSTOMER_CARD_ALREADY_ACTIVE` When you receive this error code, treat it as a resume signal — not a failure. The customer's card was already created and their OTP was already sent. Read `next_step` from `data` and continue the onboarding flow from there: | `next_step` | What to do next | | ------------ | -------------------------------------------------------------------- | | `verify_otp` | OTP has been sent — call `POST /customers/{yativoCardId}/verify-otp` | | `kyc_link` | OTP verified — call `GET /customers/{yativoCardId}/kyc-link` | | `continue` | Resume from the current `flow_status` | | `none` | Customer is fully onboarded — no action needed | If the customer has already completed onboarding (`flow_status` is `active`, `safe_deployed`, or `kyc_approved`), the API returns `409 CUSTOMER_ALREADY_ONBOARDED` with `next_step: "none"` — no further action is needed for this customer. ## Next Steps After a `201` response, direct your customer to check their email and proceed: 1. **Verify OTP** — `POST /v1/yativo-card/customers/{yativoCardId}/verify-otp` 2. **Get KYC link** — `GET /v1/yativo-card/customers/{yativoCardId}/kyc-link` 3. **Poll KYC status** — `GET /v1/yativo-card/customers/{yativoCardId}/kyc-status` 4. **Submit source of funds** — `POST /v1/yativo-card/customers/{yativoCardId}/source-of-funds` 5. **Create virtual card** — `POST /v1/yativo-card/customers/{yativoCardId}/cards/virtual` # Create Physical Card Source: https://docs.yativo.com/api-reference/cards/create-physical POST /v1/yativo-card/{id}/cards/physical/order Issue a new physical card that will be shipped to the provided address Physical card activation requires a **12.00 USDC** one-time activation fee (paid on Solana). The fee is charged at activation time, not at order time. Fees are subject to review. Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the account to associate the card with. Must be `physical` for a physical card. The card network to use. One of: `VISA`, `MASTERCARD`. The billing currency for the card. Defaults to `USD`. An optional human-readable nickname for the card, e.g. `"Operations Card"`. The full name of the recipient to print on the shipping label. The delivery address for the physical card. Street address line 1. City name. ISO 3166-1 alpha-2 country code, e.g. `US`. Postal or ZIP code. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068/cards/physical/order' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "card_type": "physical", "card_program": "MASTERCARD", "currency": "USD", "label": "Operations Card", "shipping_name": "Jane Doe", "shipping_address": { "line1": "123 Main Street", "city": "New York", "country": "US", "postal_code": "10001" } }' ``` ```json theme={null} { "status": "success", "message": "Physical card created successfully", "data": { "card_id": "crd_01HX9KZMB3F7VNQP8R2WDGT4FK", "card_type": "physical", "card_program": "MASTERCARD", "currency": "USD", "label": "Operations Card", "status": "pending", "masked_pan": "5200 **** **** 3456", "expiry_month": "03", "expiry_year": "2029", "shipping_tracking_number": null, "created_at": "2026-03-26T12:00:00Z" } } ``` # Create Virtual Card Source: https://docs.yativo.com/api-reference/cards/create-virtual POST /v1/yativo-card/customers/{yativoCardId}/cards/virtual Issue a virtual Visa/Mastercard for a customer who has completed onboarding Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. **Prerequisites before calling this endpoint:** 1. KYC approved 2. Source of funds questionnaire completed 3. Phone number verified 4. Card wallet ready (provisioned automatically after KYC approval) If any prerequisite is missing the API returns a descriptive error. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/cards/virtual' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```json 201 Created theme={null} { "success": true, "message": "Virtual card created successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "card_id": "b2dc97ab-03f9-49eb-c72f-95be13815278", "card_type": "virtual", "status": "active", "status_name": "Active", "activated_at": "2026-04-01T12:30:00.000Z", "total_cards": 1, "funding_wallet": { "address": "SoLFundingWalletAddressXXXXXXXXXXXXXX", "network": "solana", "asset": "USDC" } } } ``` ```json 400 Prerequisites not met theme={null} { "success": false, "error_code": "SOURCE_OF_FUNDS_NOT_COMPLETED", "message": "Source of Funds must be completed before creating a card. Use GET /source-of-funds to get questions and POST /source-of-funds to submit answers." } ``` After card creation, use [Get Secure Card View URL](/api-reference/cards/customer-secure-view) to display the card number and CVV securely in your UI. # Set Customer Card Limits Source: https://docs.yativo.com/api-reference/cards/customer-card-limits PATCH /v1/yativo-card/customers/{yativoCardId}/card-limits Set per-customer card limits, up to the issuer program ceiling Override the card count limits for a specific customer. Limits are capped by the ceiling set on your issuer program — you cannot grant a customer more cards than your program allows. **Limit hierarchy:** ``` Admin sets program ceiling → you set per-customer override (≤ ceiling) → Platform hard cap (5 total) ``` The `yativo_card_id` of the customer. Returned when the customer was onboarded. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Maximum virtual cards for this customer. Must be 0 to your program's `max_virtual_per_customer` ceiling. Maximum physical cards for this customer. Must be 0 to your program's `max_physical_per_customer` ceiling. Maximum total active cards (virtual + physical combined) for this customer. Must be 0 to your program's `max_total_per_customer` ceiling. At least one field must be provided. ```bash cURL theme={null} curl -X PATCH 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a_abc_1769031332068/card-limits' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "max_virtual": 2, "max_physical": 1, "max_total": 3 }' ``` ```json 200 OK theme={null} { "success": true, "message": "Customer card limits updated", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "card_limits": { "max_virtual": 2, "max_physical": 1, "max_total": 3 }, "program_ceilings": { "max_virtual": 3, "max_physical": 2, "max_total": 5 } } } ``` `program_ceilings` shows the maximum values your program permits for each limit type. ```json 400 Exceeds program ceiling theme={null} { "success": false, "error_code": "LIMIT_EXCEEDS_PROGRAM", "message": "max_virtual must be 0–3 (your program ceiling)" } ``` ```json 400 No changes theme={null} { "success": false, "error_code": "NO_CHANGES", "message": "Provide at least one limit field to update" } ``` ```json 403 Program not approved theme={null} { "success": false, "error_code": "PROGRAM_NOT_APPROVED", "message": "Card issuer program not approved" } ``` ```json 404 Not found theme={null} { "success": false, "error_code": "NOT_FOUND", "message": "Customer card not found" } ``` # List Customer Cards Source: https://docs.yativo.com/api-reference/cards/customer-cards GET /v1/yativo-card/customers/{yativoCardId}/cards List all cards issued to a specific customer Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/cards' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "cards": [ { "card_id": "b2dc97ab-03f9-49eb-c72f-95be13815278", "card_type": "virtual", "status_name": "Active", "is_frozen": false, "last_four_digits": "0892", "holder_name": "PRIYA CUSTOMER", "activated_at": "2026-04-01T12:30:00.000Z" } ], "total": 1 } } ``` # File Customer Card Dispute Source: https://docs.yativo.com/api-reference/cards/customer-dispute POST /v1/yativo-card/customers/{yativoCardId}/transactions/{transactionId}/dispute File a dispute for a customer's card transaction Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. The transaction ID to dispute. Dispute reason code. Retrieve valid codes from [Get Dispute Reasons](/api-reference/cards/dispute-reasons). Optional additional context for the dispute. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/transactions/txn_abc123/dispute' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "reasonCode": "NOT_AS_DESCRIBED", "description": "Item received was significantly different from what was shown" }' ``` ```json 201 Dispute filed theme={null} { "success": true, "message": "Dispute filed successfully", "data": { "dispute_id": "dsp_01HX9ABC123", "transaction_id": "txn_abc123", "status": "submitted", "reason_code": "NOT_AS_DESCRIBED", "filed_at": "2026-04-01T14:30:00.000Z" } } ``` # Freeze Customer Card Source: https://docs.yativo.com/api-reference/cards/customer-freeze POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/freeze Temporarily freeze a customer's card to block new transactions Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. The card ID to freeze. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/cards/b2dc97ab-03f9-49eb-c72f-95be13815278/freeze' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' ``` ```json 200 OK theme={null} { "success": true, "message": "Card frozen successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167", "is_frozen": true, "frozen_at": "2026-04-25T19:07:14.917Z" } } ``` # Check Customer KYC Status Source: https://docs.yativo.com/api-reference/cards/customer-kyc-status GET /v1/yativo-card/customers/{yativoCardId}/kyc-status Poll the KYC verification status for a customer. Card wallet is deployed automatically when KYC is first approved. Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. When KYC status first changes to `approved`, Yativo automatically provisions the customer's card wallet in the background (typically completes within 60 seconds). You do **not** need to call a separate wallet deployment endpoint. Once `kyc_status` is `approved`, proceed directly to Source of Funds questions. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/kyc-status' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 Approved theme={null} { "success": true, "message": "KYC status retrieved", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "kyc_status": "approved", "verification_level": "STANDARD", "terms_accepted": true, "next_step": "source_of_funds" } } ``` ```json 200 Pending theme={null} { "success": true, "message": "KYC status retrieved", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "kyc_status": "pending", "verification_level": null, "terms_accepted": false, "next_step": null } } ``` ```json 200 Rejected theme={null} { "success": true, "message": "KYC status retrieved", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "kyc_status": "rejected", "rejection_reason": "Document not accepted", "next_step": "retry_kyc" } } ``` ### KYC Status Values | Status | Meaning | | ---------------- | ------------------------------------------------------------------------------- | | `pending` | Not yet started, documents requested, or awaiting submission | | `in_progress` | Documents submitted — under active review | | `pending_review` | Resubmission requested — customer must supply additional or corrected documents | | `approved` | Identity verified — proceed to source of funds | | `rejected` | Verification failed — customer must restart onboarding | # Reset Customer Onboarding Source: https://docs.yativo.com/api-reference/cards/customer-reset POST /v1/yativo-card/customers/{yativoCardId}/reset Delete a customer's onboarding record so they can restart with a fresh verification flow Deletes the customer's Yativo record, allowing re-onboarding from scratch with a new verification flow. Use this when a customer is stuck in a state that cannot be recovered — for example, repeated KYC failures or an account that was set up with wrong details. **The email address used previously cannot be reused.** It remains registered with the card network. You must re-onboard the customer with a different email address. Attempting to use the same email will return `EMAIL_ALREADY_REGISTERED`. **Restrictions:** * Blocked if the customer already has a payment card issued (`card_created` or `active` status). Once a card exists, this endpoint returns `CARD_ALREADY_ISSUED` — contact support for admin-level resets. * Only resets customers belonging to your issuer program (`account_type: customer`). The `yativo_card_id` of the customer to reset. Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a_abc_1769031332068/reset' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "message": "Customer onboarding reset. Re-onboard this customer via POST /api/yativo-card/customers/onboard with a different email address.", "data": { "deleted_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "email_masked": "sa***@hotmail.com", "external_customer_id": "usr_8821", "next_step": "POST /api/yativo-card/customers/onboard", "email_warning": "The email address used previously remains registered with the card network and cannot be reused. Use a different email address when re-onboarding this customer." } } ``` ```json 400 Card already issued theme={null} { "success": false, "error_code": "CARD_ALREADY_ISSUED", "message": "Cannot reset: a payment card has already been issued for this customer. Contact support." } ``` ```json 404 Not found theme={null} { "success": false, "error_code": "NOT_FOUND", "message": "Customer card not found" } ``` # Get Secure Card View URL Source: https://docs.yativo.com/api-reference/cards/customer-secure-view POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/view-token Generate a short-lived hosted URL that displays sensitive card data (PAN, CVV, expiry, PIN) to the cardholder — no SDK integration required Yativo hosts the card data page and handles all cryptography internally. Your backend requests a URL, then passes it to your customer via your app, an email, or an iframe. The cardholder opens it in any browser or WebView. The response includes `pin_set` — the last known state from the `physical.card.pin.changed` webhook (not from a direct card network API lookup). Use it to decide whether to prompt the cardholder to set their PIN. To show the PIN setup or change form, request `enabled_views: ["pin"]`. Your `theme` customization applies to the PIN page as well. Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. The card ID to display. Which panels to show. Options: `"data"` (PAN, CVV, expiry) and `"pin"`. Defaults to `["data", "pin"]`. If `true`, the cardholder must enter a code before card data is revealed. The access code the cardholder must enter. Setting this automatically enables `require_access_code`. Customize the hosted page to match your brand. | Field | Type | Description | | ------------------ | ------ | ------------------------------------ | | `accent_color` | string | Hex color for buttons and highlights | | `background_color` | string | Page background | | `panel_color` | string | Card panel background | | `text_color` | string | Primary text | | `logo_url` | string | Your logo shown at the top | | `border_radius` | number | Corner radius in px (8–36) | | `font_family` | string | CSS font-family string | ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/cards/afeb85fe-02f8-48da-b61e-84ad02704167/view-token' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "enabled_views": ["data", "pin"], "require_access_code": true, "access_code": "1234", "theme": { "accent_color": "#6366f1", "logo_url": "https://yourapp.com/logo.png" } }' ``` ```json 200 OK theme={null} { "success": true, "data": { "secure_view_url": "https://crypto-api.yativo.com/api/v1/yativo-card/view/eyJhbGciOiJIUzI1NiJ9...", "url": "https://crypto-api.yativo.com/api/v1/yativo-card/view/eyJhbGciOiJIUzI1NiJ9...", "expires_at": "2026-04-25T19:09:00.000Z", "last_four": "4291", "card_type": "virtual", "holder_name": "John Doe", "pin_set": true, "enabled_views": ["data", "pin"], "requires_access_code": true, "theme": { "accentColor": "#6366f1", "backgroundColor": "#f5f1ea", "panelColor": "#fffaf7", "textColor": "#1e2a24", "mutedColor": "#6b746e", "borderRadius": 24, "fontFamily": "Inter, sans-serif", "logoUrl": "https://yourapp.com/logo.png" }, "usage_notes": [ "Open secure_view_url in a browser, iframe, or WebView hosted on your side", "The hosted page renders card data securely and does not auto-refresh", "Request a fresh view URL whenever the previous one expires" ] } } ``` # Get Customer Spending Limits Source: https://docs.yativo.com/api-reference/cards/customer-spending-limits-get GET /v1/yativo-card/customers/{yativoCardId}/wallet/limits Retrieve the current daily spending limit and usage for a customer's card Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/wallet/limits' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "currency": "USD", "limits": { "daily": { "limit": 7999, "used": 0, "remaining": 7999 }, "monthly": {}, "per_transaction": {} } } } ``` # Set Customer Spending Limit Source: https://docs.yativo.com/api-reference/cards/customer-spending-limits-set PUT /v1/yativo-card/customers/{yativoCardId}/wallet/limits Update the daily spending limit for a customer's card via Gelato relay Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. The new daily spending limit in USD. Must be a positive number and cannot exceed the admin-set ceiling for your program. Limit changes are processed via a Gelato relay with a 3-minute delay. A `gelato_status: "ExecSuccess"` confirms the transaction was enqueued. Poll `GET /wallet/limits` after 3 minutes to confirm the updated limit is active. ```bash cURL theme={null} curl -X PUT 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/wallet/limits' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "dailyLimit": 2500 }' ``` ```json 200 OK theme={null} { "success": true, "data": { "current_limit": null, "requested_limit": 2500, "admin_limit": null, "delay_seconds": 180, "note": "Limit changes are processed through a delay relay. Refresh after 3 minutes to see the updated limit.", "gelato_status": "ExecSuccess", "enqueue_task_id": "0xa1e2123efeb346823ed82bb44a5597d0ee70fcbbbbe52f8660c4e360c5e083ed" } } ``` # Void Customer Card Source: https://docs.yativo.com/api-reference/cards/customer-terminate POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/void Permanently void a customer's virtual card. This action is irreversible and only applies to virtual cards. Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. The virtual card ID to void. Voiding is permanent and irreversible — the card is cancelled on the card network immediately. Only **virtual cards** can be voided. For physical cards, use [Freeze](/api-reference/cards/customer-freeze) to block transactions instead. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/cards/b2dc97ab-03f9-49eb-c72f-95be13815278/void' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' ``` ```json 200 OK theme={null} { "success": true, "message": "Card marked as void successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "card_id": "b2dc97ab-03f9-49eb-c72f-95be13815278", "is_void": true, "voided_at": "2026-04-01T14:00:00.000Z" } } ``` ```json 422 Physical card theme={null} { "success": false, "error_code": "VIRTUAL_CARD_ONLY", "message": "Only virtual cards can be voided" } ``` ```json 422 Already voided theme={null} { "success": false, "error_code": "CARD_ALREADY_VOIDED", "message": "Card is already voided" } ``` # Customer Card Transactions Source: https://docs.yativo.com/api-reference/cards/customer-transactions GET /v1/yativo-card/customers/{yativoCardId}/transactions List all transactions across all cards for a customer Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. Number of results. Defaults to `20`. Records to skip. Defaults to `0`. Filter by status: `pending`, `completed`, `declined`, `refunded`, `disputed`. ISO 8601 start date filter. ISO 8601 end date filter. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/transactions?limit=20&status=completed' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "transactions": [ { "kind": "Payment", "transaction_type": "Purchase", "merchant_name": "Coffee Shop NYC", "merchant_city": "New York", "merchant_country": "United States", "merchant_country_code": "US", "mcc_code": "5812", "amount": 4.50, "currency": "EUR", "status": "completed", "transaction_date": "2026-04-01T09:14:00.000Z" } ], "total": 47 } } ``` # Unfreeze Customer Card Source: https://docs.yativo.com/api-reference/cards/customer-unfreeze POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/unfreeze Unfreeze a previously frozen customer card to re-enable transactions Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. The card ID to unfreeze. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/cards/b2dc97ab-03f9-49eb-c72f-95be13815278/unfreeze' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' ``` ```json 200 OK theme={null} { "success": true, "message": "Card unfrozen successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167", "is_frozen": false, "unfrozen_at": "2026-04-25T19:07:20.065Z" } } ``` # Customer Wallet Source: https://docs.yativo.com/api-reference/cards/customer-wallet GET /v1/yativo-card/customers/{yativoCardId}/wallet Get the card wallet details and funding address for a customer Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/wallet' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "currency": "EUR", "token": "EUR", "wallet_ready": true, "balance": { "available": 245.50, "pending": 0.00, "currency": "EUR" }, "funding_address": { "address": "SoLFundingWalletAddressXXXXXXXXXXXXXX", "network": "solana", "asset": "USDC", "memo": null }, "spending_limits": { "daily": { "limit": 7999, "used": 54.50, "remaining": 7944.50 } } } } ``` # Initialize Card Wallet Source: https://docs.yativo.com/api-reference/cards/deploy-wallet POST /v1/yativo-card/{yativoCardId}/safe/deploy Initialize the card wallet to enable funding and card creation Bearer token: `Bearer YOUR_ACCESS_TOKEN` The card wallet must be initialized before you can fund it or create cards. This is a one-time setup step that activates the on-chain wallet infrastructure for the card account. **For B2B Card Issuer customers** use the customer-scoped path: `/v1/yativo-card/customers/{yativoCardId}/safe/deploy`. Call this explicitly after KYC approval before proceeding to card creation. Even when the platform deploys the Safe automatically in the background, card creation checks the local DB state — not the card network directly — so this call is needed to sync the record. It is idempotent: if already deployed you will receive `"already_deployed": true`. ```bash Own Account theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068/safe/deploy' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' ``` ```bash B2B Customer theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/safe/deploy' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' ``` ```json 202 Deployment Initiated theme={null} { "success": true, "message": "Safe deployment initiated. Deployment typically takes up to 1 minute.", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "deployment_accepted": true, "estimated_completion": "~1 minute", "next_step": "monitor_deployment", "monitor_endpoint": "/api/yativo-card/yativo_card_customer_8f9a...abc_1769031332068/safe/deploy" } } ``` ```json 200 Already Deployed theme={null} { "success": true, "message": "Safe is already deployed and ready", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "already_deployed": true, "safe_address": "0x7eA0940F469913c1167A2397eb5a3E9AE8DAC0dE", "token_symbol": "USDCe", "fiat_symbol": "USD", "account_status": 0, "account_status_meaning": "Ok", "is_ready": true, "monitor_endpoint": "/api/yativo-card/yativo_card_customer_8f9a...abc_1769031332068/safe/deploy" } } ``` ### Response fields | Field | Type | Description | | ------------------------ | ------- | -------------------------------------------------------------------------------------- | | `already_deployed` | boolean | `true` when the Safe was already deployed before this call | | `safe_address` | string | On-chain Safe address (present when already deployed) | | `token_symbol` | string | Card token symbol (e.g. `USDCe`, `EURe`, `GBPe`) | | `fiat_symbol` | string | Fiat currency code (e.g. `USD`, `EUR`, `GBP`) | | `account_status` | number | Card network account status code. `0` = Ok, `7` = DelayQueueNotEmpty (both mean ready) | | `account_status_meaning` | string | Human-readable status — `"Ok"` or `"DelayQueueNotEmpty"` | | `is_ready` | boolean | `true` when the Safe is fully deployed and ready for card creation | | `deployment_accepted` | boolean | `true` when a new deployment was initiated (202 response) | | `monitor_endpoint` | string | Poll this `GET` endpoint to track deployment progress | # File Dispute Source: https://docs.yativo.com/api-reference/cards/dispute POST /v1/yativo-card/{yativoCardId}/transactions/{transactionId}/dispute File a dispute for a card transaction Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. The ID of the transaction to dispute. The reason code for the dispute. Retrieve valid codes from the [Get Dispute Reasons](/api-reference/cards/dispute-reasons) endpoint. Optional additional description providing more context about the dispute. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/transactions/ctxn_01HX9KZMB3F7VNQP8R2WDGT4EL/dispute' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "reasonCode": "unauthorized", "description": "I did not make this purchase. My card details may have been compromised." }' ``` ```json theme={null} { "status": "success", "message": "Dispute filed successfully", "data": { "dispute_id": "dsp_01HX9KZMB3F7VNQP8R2WDGT4EM", "transaction_id": "ctxn_01HX9KZMB3F7VNQP8R2WDGT4EL", "reasonCode": "unauthorized", "status": "open", "created_at": "2026-03-26T12:00:00Z" } } ``` # Get Dispute Reasons Source: https://docs.yativo.com/api-reference/cards/dispute-reasons GET /v1/yativo-card/{yativoCardId}/transactions/dispute-reasons Retrieve the list of available reason codes for filing a transaction dispute Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/transactions/dispute-reasons' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "status": "success", "message": "Dispute reasons retrieved successfully", "data": [ { "reason_code": "unauthorized", "description": "I did not authorize this transaction" }, { "reason_code": "not_received", "description": "Goods or services not received" }, { "reason_code": "duplicate", "description": "Duplicate charge for the same transaction" }, { "reason_code": "incorrect_amount", "description": "Amount charged was incorrect" }, { "reason_code": "credit_not_processed", "description": "Expected credit or refund not processed" } ] } ``` # Get Card View Token Source: https://docs.yativo.com/api-reference/cards/ephemeral-token POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/view-token Issue a short-lived token for a hosted secure card view — embed the returned URL in an iframe Card details and PIN are both served from a single hosted page. Control which views appear using `enabled_views`. The returned `secure_view_url` is ready to use as an iframe `src` — no additional SDK is required. Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID (`yativo_card_id`) from onboarding. The card ID from card creation. Which views to enable. Accepted values: `"data"` (PAN, CVV, expiry), `"pin"` (view/set PIN). Omit to show all. Optional unlock code the user must enter before card details are revealed. Optional theme overrides: `accent_color`, `background_color`, `panel_color`, `text_color`, `muted_color`, `border_radius`, `font_family`, `logo_url`. Never cache or log `secure_view_url`. Always request a fresh token immediately before rendering. ```bash Card data only theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/card_01HX9KZMB3F7VNQP8R2WDGT4E5/view-token' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "enabled_views": ["data"] }' ``` ```bash Card data + PIN theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/card_01HX9KZMB3F7VNQP8R2WDGT4E5/view-token' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "enabled_views": ["data", "pin"] }' ``` ```json Success theme={null} { "status": "success", "data": { "secure_view_url": "https://crypto-api.yativo.com/card-view?token=eyJhbGciOiJIUzI1NiIs...", "expires_at": "2026-03-26T12:01:00Z", "last_four": "4242", "enabled_views": ["data", "pin"], "requires_access_code": false } } ``` ```typescript theme={null} interface ViewTokenResponse { secure_view_url: string; // Hosted page URL — use as iframe src expires_at: string; // ISO 8601 expiry last_four: string; // Safe to display without the iframe enabled_views: string[]; // Active views: ["data"] | ["pin"] | ["data", "pin"] requires_access_code: boolean; // User must enter access_code before details are shown } ``` ## Embedding the URL ```html theme={null} ``` See the full integration guide — backend proxy pattern, React/vanilla JS examples, access code flow, and testing — in [Secure Card Display](/yativo-crypto/cards/secure-display). # Freeze Card Source: https://docs.yativo.com/api-reference/cards/freeze POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/freeze Temporarily freeze a card to prevent any new transactions Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the card to freeze. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068/cards/b2dc97ab-03f9-49eb-c72f-95be13815278/freeze' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' ``` ```json theme={null} { "status": "success", "message": "Card frozen successfully", "data": { "card_id": "crd_01HX9KZMB3F7VNQP8R2WDGT4EJ", "status": "frozen", "frozen_at": "2026-03-26T12:00:00Z" } } ``` # Fund Card Source: https://docs.yativo.com/api-reference/cards/fund POST /v1/yativo-card/fund Add funds to a card from a source wallet asset Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the card to fund. The ID of the source wallet asset to debit funds from. The USD equivalent amount to load onto the card, e.g. `"100.00"`. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/fund' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "card_id": "crd_01HX9KZMB3F7VNQP8R2WDGT4EJ", "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT5AA", "amount": "250.00" }' ``` ```json theme={null} { "status": "success", "message": "Card funded successfully", "data": { "funding_id": "fnd_01HX9KZMB3F7VNQP8R2WDGT6BB", "card_id": "crd_01HX9KZMB3F7VNQP8R2WDGT4EJ", "amount": "250.00", "status": "completed", "created_at": "2026-03-26T12:00:00Z" } } ``` # Get Funding Address Source: https://docs.yativo.com/api-reference/cards/funding-address GET /v1/yativo-card/{yativoCardId}/wallet/funding-address Get the deposit address to fund the card wallet with cryptocurrency Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/wallet/funding-address' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "address": "DwPq8k2XbNmJhvRs5TcLu4Ye9AgFp3ZoVi7Bn1KqWMeS", "network": "solana", "funding_method": "auto_bridge", "card_currency": "USDCe", "supported_tokens": [ { "symbol": "USDC", "name": "USD Coin", "contract": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "decimals": 6, "network": "solana" } ], "funding_sources": { "usdc_sol": { "address": "DwPq8k2XbNmJhvRs5TcLu4Ye9AgFp3ZoVi7Bn1KqWMeS", "network": "solana", "token": "USDC_SOL", "bridge_type": "automatic", "bridge_time": "2-5 minutes", "description": "Send USDC on Solana — automatically bridged to your card" } }, "minimum_deposit": "5.00", "instructions": "Send USDC (SPL) on Solana to this address. Auto-bridge starts once balance reaches 5.00 USDC." } } ``` # Get Card Source: https://docs.yativo.com/api-reference/cards/get GET /v1/yativo-card/my-account Retrieve full details for a specific card Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/my-account' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "account": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "email": "merchant@example.com", "flow_status": "safe_deployed", "current_step": 4, "progress_percentage": 100, "kyc_status": "approved", "terms_accepted": true, "safe_deployed": true, "wallet_address": "0xAB7a028c1c5483e9507C61F25335C64C52B9FBcc", "funding_address": "DwPq8k2XbNmJhvRs5TcLu4Ye9AgFp3ZoVi7Bn1KqWMeS", "funding_network": "solana", "cards_count": 1, "cards": [ { "card_id": "b2dc97ab-03f9-49eb-c72f-95be13815278", "last_four": "0892", "type": "virtual", "status": "Active", "is_frozen": false, "created_at": "2026-02-02T13:04:23.773Z" } ], "created_at": "2026-01-21T21:35:32.076Z", "updated_at": "2026-03-28T08:15:57.023Z" } } } ``` # Get Card Wallet Source: https://docs.yativo.com/api-reference/cards/get-wallet GET /v1/yativo-card/{yativoCardId}/wallet Retrieve the card wallet details including balance and funding address Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/wallet' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "wallet_address": "DwPq8k2XbNmJhvRs5TcLu4Ye9AgFp3ZoVi7Bn1KqWMeS", "wallet_network": "solana", "funding_method": "auto_bridge", "currency": "EUR", "is_deployed": true, "is_deployed": true, "balances": { "available": "47.66", "on_hold": "0", "total": "47.66" }, "spending_limits": { "daily_limit": 7999, "daily_used": 0, "daily_remaining": 7999, "currency": "USDC" } } } ``` # Activate Card IBAN Source: https://docs.yativo.com/api-reference/cards/iban-activate POST /v1/yativo-card/{yativoCardId}/iban/activate Activate an IBAN for the card wallet to enable bank transfers Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. The KYC verification method to use. One of: * `platform_kyc` — KYC handled by the platform * `user_kyc` — User completes KYC directly via the hosted verification flow * `direct_docs` — KYC via direct document submission A KYC access token, required when `kyc_method` is `user_kyc`. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/iban/activate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "kyc_method": "platform_kyc" }' ``` ```json theme={null} { "status": "success", "message": "IBAN activation initiated", "data": { "yativo_card_id": "yvc_01HX9KZMB3F7VNQP8R2WDGT4EI", "iban_status": "pending_kyc", "kyc_method": "platform_kyc", "initiated_at": "2026-03-26T12:00:00Z" } } ``` # Get Card IBAN Status Source: https://docs.yativo.com/api-reference/cards/iban-status GET /v1/yativo-card/{yativoCardId}/iban/status Check the status of the IBAN linked to the card wallet Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/iban/status' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "activated": true, "profile_status": "approved", "iban": { "iban": "EE740205417800000001", "bic": "FAKEFK01", "currency": "EUR", "status": "active" }, "usage": "standalone_onramp" } } ``` # Get Customer KYC Link Source: https://docs.yativo.com/api-reference/cards/kyc-link GET /v1/yativo-card/customers/{yativoCardId}/kyc-link Generate a KYC verification link for the customer to complete identity verification Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. Call this endpoint after OTP verification. Open `sumsub_link` in the customer's browser or embed it in your app. They will complete identity verification (government ID upload + liveness check) through the hosted Sumsub flow. After completion, poll [Check KYC Status](/api-reference/cards/kyc-status) until `kyc_status` is `approved` — KYC completion is not delivered as a webhook. **Link expiry:** The Sumsub link is valid for **1 hour** from when it was generated. If the customer has not completed KYC within that window, call this endpoint again — a fresh link is returned automatically. You do not need to pass any extra parameters to force a refresh. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/kyc-link' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "message": "KYC link retrieved", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "sumsub_link": "https://kyc.sumsub.com/msdk/v2?accessToken=_act-sbx-...", "sumsub_sdk_token": "_act-sbx-...", "applicant_id": "6627f3a2c5d4e100123abcde", "next_step": "kyc_status" } } ``` # Get KYC Status Source: https://docs.yativo.com/api-reference/cards/kyc-status GET /v1/yativo-card/{yativoCardId}/kyc-status Check the KYC verification status for the card program Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068/kyc-status' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 Approved theme={null} { "success": true, "message": "KYC status retrieved", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "kyc_status": "approved", "terms_accepted": true, "next_step": "create_card" } } ``` ```json 200 In Progress theme={null} { "success": true, "message": "KYC status retrieved", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "kyc_status": "in_progress", "terms_accepted": false, "next_step": null } } ``` ```json 200 Pending Review theme={null} { "success": true, "message": "KYC status retrieved", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "kyc_status": "pending_review", "terms_accepted": false, "next_step": null } } ``` ```json 200 Rejected theme={null} { "success": true, "message": "KYC status retrieved", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "kyc_status": "rejected", "rejection_reason": "Document not accepted", "terms_accepted": false, "next_step": "retry_kyc" } } ``` ### KYC Status Values | Status | Meaning | | ---------------- | ------------------------------------------------- | | `pending` | Not yet started, or documents have been requested | | `in_progress` | Documents submitted — processing under review | | `pending_review` | Resubmission requested — additional info needed | | `approved` | Identity verified — proceed to accept terms | | `rejected` | Verification failed — retry KYC | | `expired` | KYC session expired — re-initiate the KYC link | # List Cards Source: https://docs.yativo.com/api-reference/cards/list GET /v1/yativo-card/{yativoCardId}/cards Retrieve all cards issued under the authenticated user's card account Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068/cards' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "message": "Cards retrieved successfully", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "cardholder_email": "merchant@example.com", "cards": [ { "card_id": "b2dc97ab-03f9-49eb-c72f-95be13815278", "last_four_digits": "0892", "card_type": "virtual", "is_virtual": true, "status_code": 1000, "status_name": "Active", "activated_at": "2026-02-02T13:04:23.704Z", "holder_name": "JOHN MERCHANT", "billing": { "line1": "123 Test Street", "city": "New York", "postalCode": "10001", "countryCode": "US" } } ], "total": 1 } } ``` # Start Card Onboarding Source: https://docs.yativo.com/api-reference/cards/own-onboard POST /v1/yativo-card/onboard Initiate Yativo Card onboarding for your own account. Generates a wallet, authenticates with the card provider, and sends an OTP to your email. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Your email address. Yativo sends a one-time verification code here. Must not already be in use by an active card session under your account. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/onboard' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"email": "you@example.com"}' ``` ```javascript Node.js theme={null} const response = await fetch( 'https://crypto-api.yativo.com/api/v1/yativo-card/onboard', { method: 'POST', headers: { Authorization: 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ email: 'you@example.com' }), } ); const { data } = await response.json(); // data.yativo_card_id — save this for all subsequent calls ``` ```json 201 Created theme={null} { "success": true, "message": "Card onboarding initiated. Check your email for verification code.", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "email_masked": "yo***@example.com", "next_step": "verify_otp", "otp_expires_in_seconds": 600 } } ``` ```json 400 Invalid email theme={null} { "success": false, "error_code": "INVALID_EMAIL", "message": "Valid email is required" } ``` ```json 400 Already in progress theme={null} { "success": false, "error_code": "CARD_ALREADY_ACTIVE", "message": "Card onboarding already in progress", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "flow_status": "otp_requested", "next_step": "verify_otp" } } ``` ```json 400 Session expired theme={null} { "success": false, "error_code": "JWT_EXPIRED", "message": "Session expired. Please re-authenticate.", "data": { "yativo_card_id": "yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068", "needs_reauth": true, "flow_status": "kyc_initiated" } } ``` ## Next Steps After a `201` response, check your email for the OTP and continue: 1. **Verify OTP** — `POST /v1/yativo-card/{yativoCardId}/verify-otp` 2. **Get KYC link** — `GET /v1/yativo-card/{yativoCardId}/kyc-link` 3. **Poll KYC status** — `GET /v1/yativo-card/{yativoCardId}/kyc-status` 4. **Deploy card wallet** — `POST /v1/yativo-card/{yativoCardId}/safe/deploy` 5. **Create virtual card** — `POST /v1/yativo-card/{yativoCardId}/cards/virtual` # Phone Verification Source: https://docs.yativo.com/api-reference/cards/phone-verification Request and verify a phone number for the customer's card account Phone verification is required before card creation. There are two endpoints: 1. **`POST /v1/yativo-card/customers/:yativoCardId/phone/request-verification`** — send OTP to phone 2. **`POST /v1/yativo-card/customers/:yativoCardId/phone/verify`** — verify the OTP *** ## Request Phone Verification Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. Customer's phone number in international format (e.g. `+14155552671`). ```bash Request OTP theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/phone/request-verification' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"phoneNumber": "+14155552671"}' ``` ```json 200 OTP sent theme={null} { "success": true, "message": "Verification code sent to your phone", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "phone_number": "+14155****", "otp_requested_at": "2026-04-01T12:20:00.000Z", "next_step": "Verify OTP using POST /phone/verify" } } ``` *** ## Verify Phone Number The customer's `yativo_card_id`. The OTP code received via SMS. ```bash Verify OTP theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/phone/verify' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"code": "382910"}' ``` ```json 200 Verified theme={null} { "success": true, "message": "Phone number verified successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "phone_number": "+14155****", "is_verified": true, "next_step": "Create virtual card using POST /cards/virtual" } } ``` # Order Physical Card Source: https://docs.yativo.com/api-reference/cards/physical-order POST /v1/yativo-card/{yativoCardId}/cards/physical/order Place an order for a physical card to be shipped to an address Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. The shipping address for the physical card. Street address line 1. Street address line 2 (apartment, suite, etc.). City name. State or province code. Postal or ZIP code. ISO 3166-1 alpha-2 country code, e.g. `US`, `GB`, `DE`. Optional card personalization options such as cardholder name to emboss. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/cards/physical/order' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "shipping_address": { "line1": "123 Main Street", "line2": "Apt 4B", "city": "New York", "state": "NY", "postal_code": "10001", "country": "US" }, "personalization": { "cardholder_name": "JANE DOE" } }' ``` ```json theme={null} { "status": "success", "message": "Physical card order placed successfully", "data": { "order_id": "ord_01HX9KZMB3F7VNQP8R2WDGT4EN", "yativo_card_id": "yvc_01HX9KZMB3F7VNQP8R2WDGT4EI", "card_type": "physical", "status": "processing", "estimated_delivery": "2026-04-02", "shipping_address": { "line1": "123 Main Street", "city": "New York", "state": "NY", "postal_code": "10001", "country": "US" }, "created_at": "2026-03-26T12:00:00Z" } } ``` # Physical Card Order Status Source: https://docs.yativo.com/api-reference/cards/physical-order-status GET /v1/yativo-card/{yativoCardId}/cards/physical/order/{orderId}/status Track the status and shipment details of a physical card order Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. The physical card order ID. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/cards/physical/order/ord_01HX9KZMB3F7VNQP8R2WDGT4EN/status' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "status": "success", "message": "Order status retrieved successfully", "data": { "order_id": "ord_01HX9KZMB3F7VNQP8R2WDGT4EN", "yativo_card_id": "yvc_01HX9KZMB3F7VNQP8R2WDGT4EI", "status": "shipped", "tracking_number": "1Z999AA10123456784", "carrier": "UPS", "estimated_delivery": "2026-04-02", "shipped_at": "2026-03-27T09:00:00Z", "created_at": "2026-03-26T12:00:00Z" } } ``` # Set Card PIN Source: https://docs.yativo.com/api-reference/cards/set-pin Let a cardholder set their PIN through Yativo's secure hosted page — no PIN ever touches your server. Card PINs are set — and changed — through Yativo's **hosted secure page**, powered by the card network's Partner Secure Elements (PSE) service. The cardholder types their PIN directly inside a sandboxed iframe. Your backend never receives or processes the PIN value. **First-time PIN setup and PIN changes use different response shapes.** * **First-time setup** (`pin_set: false`): any call to `view-token` returns `422 PIN_NOT_SET`. The response body includes `data.pin_setup_url` — open that URL for PIN setup. You do not need to pass `enabled_views: ["pin"]`; the API auto-selects the PIN-setup view. * **PIN change** (`pin_set: true`): call `view-token` with `enabled_views: ["pin"]`. You get `200` with `data.secure_view_url` — open that for PIN change. **`pin_set` is informational, not a hard gate.** Yativo tracks `pin_set` from the `physical.card.pin.changed` webhook — the card network does not expose this value via a direct lookup. The flag may lag behind reality if the webhook was missed or the cardholder set their PIN through another path. Use it as a UI hint (e.g. show a "Set PIN" prompt) rather than blocking access server-side. *** ## How it works ### First-time PIN setup (`pin_set: false`) Call `POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/view-token`. You do not need to pass `enabled_views: ["pin"]` — the API detects that the PIN is not set and overrides the view automatically. The API returns HTTP 422 with `error_code: "PIN_NOT_SET"`. The response body includes `data.pin_setup_url` — a short-lived URL pre-configured for PIN setup. Pass `data.pin_setup_url` to your frontend. The cardholder enters and confirms their 4-digit PIN directly in the hosted page. The PIN never leaves the iframe. Once saved, the card network sends a `physical.card.pin.changed` event. Yativo updates `pin_set: true` on the card record automatically. ### PIN change (`pin_set: true`) Call `POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/view-token` with `enabled_views: ["pin"]`. The API returns HTTP 200 with `data.secure_view_url` — open that in an iframe or WebView for the PIN change form. *** ## Step 1 — Request a PIN view token ``` POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/view-token ``` The Yativo Card account ID (`yativo_card_id`). The card ID to set the PIN for. Pass `["pin"]` to open the PIN-setting form. Pass `["data", "pin"]` to show both card details and PIN (only works after PIN is already set). Optional brand customization — `accent_color`, `logo_url`, `background_color`, etc. See [Secure Card Display](/yativo-crypto/cards/secure-display) for all options. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234_1769031332068/cards/afeb85fe-02f8-48da-b61e-84ad02704167/view-token' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "enabled_views": ["pin"], "theme": { "accent_color": "#6366f1", "logo_url": "https://yourapp.com/logo.png" } }' ``` ```javascript Node.js theme={null} const response = await fetch( 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234_1769031332068/cards/afeb85fe-02f8-48da-b61e-84ad02704167/view-token', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_ACCESS_TOKEN', 'Content-Type': 'application/json', }, body: JSON.stringify({ enabled_views: ['pin'], theme: { accent_color: '#6366f1' }, }), } ); const { data } = await response.json(); // Send data.secure_view_url to your frontend ``` ```json 200 Token created theme={null} { "success": true, "data": { "secure_view_url": "https://crypto-api.yativo.com/api/v1/yativo-card/view/eyJhbGci...", "url": "https://crypto-api.yativo.com/api/v1/yativo-card/view/eyJhbGci...", "expires_at": "2026-05-18T12:05:00.000Z", "last_four": "4291", "card_type": "physical", "holder_name": "Jane Doe", "pin_set": false, "enabled_views": ["pin"], "requires_access_code": false } } ``` *** ## Step 2 — Embed the hosted PIN page Pass `secure_view_url` as the `src` of an iframe. No SDK or client-side JavaScript required. ```html theme={null} ``` Recommended dimensions for PIN-only view: `420 × 520px`. For combined card details + PIN view: `420 × 740px`. *** ## Theme customization Pass a `theme` object in the view-token request to brand the hosted PIN page. All theme fields are optional. ```bash theme={null} curl -X POST '.../view-token' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "enabled_views": ["pin"], "theme": { "accent_color": "#6366f1", "background_color": "#f5f1ea", "logo_url": "https://yourapp.com/logo.png", "border_radius": 16, "font_family": "Inter, sans-serif" } }' ``` Theme fields: `accent_color`, `background_color`, `panel_color`, `text_color`, `muted_color`, `border_radius`, `font_family`, `logo_url`. See [Secure Card Display](/yativo-crypto/cards/secure-display) for the full reference. *** ## Checking `pin_set` status After the PIN is set, the card network's `physical.card.pin.changed` webhook fires and Yativo updates `pin_set: true` on the card record. You can read this via: * **Card issuers** — `GET /v1/card-issuer/customers/{customerId}` → `data.cards[n].pin_set` * **End users** — `GET /v1/yativo-card/my-account` → `data.account.cards[n].pin_set` * **View-token response** — `data.pin_set` is returned on every `POST .../view-token` call The `next_action` field on the issuer customer record will read: > `"Card is active — customer must set card PIN before in-store (PSE) payments will work"` until `pin_set` becomes `true`. `pin_set` reflects the **last known state from the webhook**. The card network does not expose this flag via a direct API lookup, so if the webhook was missed or the PIN was set through another path, the value may be stale. Treat it as a UI hint — not an authoritative server-side gate. *** ## Notes | Detail | Value | | --------------------- | --------------------------------------------------------------------------------- | | PIN input | Cardholder types directly into the hosted iframe — PIN never reaches your server | | PIN format | 4 digits (`0000`–`9999`) | | Initial set & change | Same `enabled_views: ["pin"]` view handles both | | Confirmation | `physical.card.pin.changed` webhook → `pin_set: true` in DB | | `pin_set` reliability | Informational — sourced from webhook only, not a direct card network API lookup | | Issuer theme | Pass `theme` in the view-token request — applies to the hosted PIN page | | Online vs chip PIN | PSE updates the **online PIN**. The chip PIN syncs automatically on first ATM use | | Works for | Virtual and physical cards | # Source of Funds Source: https://docs.yativo.com/api-reference/cards/source-of-funds Retrieve the source of funds questionnaire and submit the customer's answers Source of funds declaration is required after KYC approval and before card creation. There are two endpoints: 1. **`GET /v1/yativo-card/customers/:yativoCardId/source-of-funds`** — fetch the questions 2. **`POST /v1/yativo-card/customers/:yativoCardId/source-of-funds`** — submit answers *** ## Get Questions Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's `yativo_card_id`. Language for questions, e.g. `en`, `de`, `fr`. Defaults to `en`. ```bash Get questions theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/source-of-funds' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Questions response theme={null} { "success": true, "message": "Source of Funds questions retrieved", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "status": "questions_retrieved", "questions": [ { "question": "EMPLOYMENT_STATUS", "label": "What is your employment status?", "options": ["EMPLOYED", "SELF_EMPLOYED", "UNEMPLOYED", "STUDENT", "RETIRED"] }, { "question": "SOURCE_OF_INCOME", "label": "What is your primary source of income?", "options": ["SALARY", "BUSINESS_INCOME", "INVESTMENT", "PENSION", "OTHER"] } ], "next_step": "Submit answers using POST /source-of-funds" } } ``` *** ## Submit Answers Array of answer objects. Each must have `question` (the question ID from GET) and `answer` (selected option). ```bash Submit answers theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/source-of-funds' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "answers": [ {"question": "EMPLOYMENT_STATUS", "answer": "EMPLOYED"}, {"question": "SOURCE_OF_INCOME", "answer": "SALARY"} ] }' ``` ```json 200 Submitted theme={null} { "success": true, "message": "Source of Funds submitted successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "status": "completed", "submitted_at": "2026-04-01T12:15:00.000Z", "next_step": "Verify phone number using POST /phone/request-verification" } } ``` # Get Spending Limits Source: https://docs.yativo.com/api-reference/cards/spending-limits-get GET /v1/yativo-card/{yativoCardId}/wallet/limits Retrieve the current spending limits for the card wallet Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/wallet/limits' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "currency": "USDCe", "limits": { "daily": {"limit": 7999, "used": 0, "remaining": 7999}, "monthly": {}, "per_transaction": {} } } } ``` # Set Spending Limits Source: https://docs.yativo.com/api-reference/cards/spending-limits-set PUT /v1/yativo-card/{yativoCardId}/wallet/limits Update the daily spending limit for the card wallet Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. The new daily spending limit in USD. ```bash theme={null} curl -X PUT 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/wallet/limits' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "daily_limit": 3000 }' ``` ```json theme={null} { "success": true, "data": { "currency": "USDCe", "limits": { "daily": {"limit": 7999, "used": 0, "remaining": 7999}, "monthly": {}, "per_transaction": {} } } } ``` # Card Transactions Source: https://docs.yativo.com/api-reference/cards/transactions GET /v1/yativo-card/{yativoCardId}/cards/{cardId}/transactions Retrieve the transaction history for a specific card Bearer token: `Bearer YOUR_ACCESS_TOKEN` The Yativo Card account ID. The card ID to retrieve transactions for. Number of transactions to return. Defaults to `20`. Number of records to skip. Defaults to `0`. Filter by transaction status. One of: `pending`, `completed`, `declined`, `refunded`, `disputed`. Start date filter in ISO 8601 format, e.g. `2026-01-01T00:00:00Z`. End date filter in ISO 8601 format, e.g. `2026-03-26T23:59:59Z`. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yvc_01HX9KZMB3F7VNQP8R2WDGT4EI/cards/crd_01HX9KZMB3F7VNQP8R2WDGT4EJ/transactions?limit=20&status=completed&from_date=2026-03-01T00:00:00Z' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "transactions": [ { "kind": "Payment", "transaction_type": "Purchase", "merchant_name": "Coffee Shop NYC", "merchant_city": "New York", "merchant_country": "United States", "merchant_country_code": "US", "mcc_code": "5812", "mcc_description": "Eating Places, Restaurants", "mcc_category": "Food & Beverage", "billing_amount": 5.31, "billing_currency": "USD", "billing_formatted": "$5.31", "transaction_amount": 5.31, "transaction_currency": "USD", "amount": 5.31, "currency": "USD", "status": "approved", "status_label": "Approved", "status_note": "Payment settled successfully.", "is_pending": false, "authorized_at": "2026-03-10T20:54:34.501Z", "cleared_at": "2026-03-13T16:25:58.395Z", "blockchain_transactions": [ { "status": "ExecSuccess", "hash": "0xabc123def456789012345678901234567890abcdef1234567890abcdef123456" } ] } ], "pagination": {"total": 1, "limit": 50, "offset": 0, "has_more": false} } } ``` # Unfreeze Card Source: https://docs.yativo.com/api-reference/cards/unfreeze POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/unfreeze Unfreeze a previously frozen card to re-enable transactions Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the card to unfreeze. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yativo_card_0xAbCd1234EfGh5678IjKl9012_1769031332068/cards/b2dc97ab-03f9-49eb-c72f-95be13815278/unfreeze' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' ``` ```json theme={null} { "status": "success", "message": "Card unfrozen successfully", "data": { "card_id": "crd_01HX9KZMB3F7VNQP8R2WDGT4EJ", "status": "active", "unfrozen_at": "2026-03-26T12:05:00Z" } } ``` # Verify Customer OTP Source: https://docs.yativo.com/api-reference/cards/verify-otp POST /v1/yativo-card/customers/{yativoCardId}/verify-otp Verify the one-time code sent to the customer's email address to confirm their identity Bearer token: `Bearer YOUR_ACCESS_TOKEN` The `yativo_card_id` returned by the [Onboard Customer](/api-reference/cards/onboard) endpoint. The 6-digit verification code sent to the customer's email. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yativo_card_customer_8f9a..._1769031332068/verify-otp' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"otp": "847291"}' ``` ```json 200 Verified theme={null} { "success": true, "message": "Email verified successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "flow_status": "otp_verified", "next_step": "kyc_link" } } ``` ```json 400 Invalid OTP theme={null} { "success": false, "error_code": "OTP_VERIFICATION_FAILED", "message": "Invalid OTP" } ``` ```json 400 OTP expired theme={null} { "success": false, "error_code": "OTP_EXPIRED", "message": "OTP has expired. Request a new one." } ``` # Create Customer Source: https://docs.yativo.com/api-reference/customers/create POST /v1/customers/create-customer Register a new customer in your account Bearer token: `Bearer YOUR_ACCESS_TOKEN` The customer's email address. Must be unique within your account. Customer's legal first name. Customer's legal last name. Customer's phone number in E.164 format (e.g. `+14155552671`). Arbitrary key-value pairs you can attach to the customer for your own reference. ```typescript theme={null} interface CreateCustomerRequest { email: string; first_name: string; last_name: string; phone?: string; metadata?: Record; } interface CreateCustomerResponse { status: "success"; data: { id: string; email: string; first_name: string; last_name: string; phone?: string; status: "pending"; kyc_status: "not_started"; created_at: string; }; } ``` ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/customers/create-customer' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "email": "jane@example.com", "first_name": "Jane", "last_name": "Doe", "phone": "+14155552671" }' ``` ```typescript TypeScript SDK theme={null} const customer = await sdk.customers.create({ email: 'jane@example.com', first_name: 'Jane', last_name: 'Doe', }); console.log('Customer ID:', customer.data.id); ``` ```json Success theme={null} { "status": true, "message": "Customer created successfully", "data": { "_id": "cust_67e54665e759c943cd376abc", "username": "new_customer", "email": "customer@example.com", "phone_number": "", "user_id": "usr_6615c3a1e55d9ff7bc0a1234", "createdAt": "2026-03-28T10:00:00.000Z", "updatedAt": "2026-03-28T10:00:00.000Z" } } ``` # List Customers Source: https://docs.yativo.com/api-reference/customers/list POST /v1/customers/get-customers Retrieve a paginated list of all customers in your account Bearer token: `Bearer YOUR_ACCESS_TOKEN` Page number for pagination. Default: `1` Results per page. Default: `20`, max: `100` Filter by customer status. Accepted values: `active`, `suspended`, `pending` Search by email or name (partial match supported). Pass a specific customer ID to retrieve a single customer instead of the full list. ```typescript theme={null} interface Customer { id: string; email: string; first_name: string; last_name: string; status: "active" | "suspended" | "pending"; kyc_status: "not_started" | "pending" | "approved" | "rejected"; created_at: string; updated_at: string; } interface ListCustomersResponse { status: "success"; data: { customers: Customer[]; pagination: { page: number; limit: number; total: number; total_pages: number; }; }; } ``` ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/customers/get-customers' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```typescript TypeScript SDK theme={null} const customers = await sdk.customers.list({ page: 1, limit: 20 }); console.log(customers.data.customers); ``` ```json Success theme={null} { "data": [ { "_id": "cust_67d01994740754bbf304abcd", "username": "alice_merchant", "email": "alice@example.com", "phone_number": "+1234567890", "user_id": "usr_6615c3a1e55d9ff7bc0a1234", "createdAt": "2026-01-11T11:08:04.559Z", "updatedAt": "2026-01-11T11:08:04.559Z" }, { "_id": "cust_67d2d2a5740754bbf308efgh", "username": "bob_trader", "email": "bob@example.com", "phone_number": "", "user_id": "usr_6615c3a1e55d9ff7bc0a1234", "createdAt": "2026-01-13T12:42:13.562Z", "updatedAt": "2026-01-13T12:42:13.562Z" } ], "status": true } ``` # Update Customer Source: https://docs.yativo.com/api-reference/customers/update Update a customer's profile information The Update Customer endpoint is coming soon. To modify customer details, create a new customer with the updated information using the [Create Customer](/api-reference/customers/create) endpoint. # Coming Soon Source: https://docs.yativo.com/api-reference/iban/initialize This endpoint is coming soon This endpoint is coming soon. The standalone IBAN product is currently in sandbox and not yet available for production use. # Coming Soon Source: https://docs.yativo.com/api-reference/iban/kyc This endpoint is coming soon This endpoint is coming soon. The standalone IBAN product is currently in sandbox and not yet available for production use. # Coming Soon Source: https://docs.yativo.com/api-reference/iban/options This endpoint is coming soon This endpoint is coming soon. The standalone IBAN product is currently in sandbox and not yet available for production use. # Coming Soon Source: https://docs.yativo.com/api-reference/iban/request This endpoint is coming soon This endpoint is coming soon. The standalone IBAN product is currently in sandbox and not yet available for production use. # Coming Soon Source: https://docs.yativo.com/api-reference/iban/status This endpoint is coming soon This endpoint is coming soon. The standalone IBAN product is currently in sandbox and not yet available for production use. # Crypto API References Source: https://docs.yativo.com/api-reference/introduction Complete reference for all Yativo Crypto API endpoints The **Try It** panel on every endpoint page defaults to **Sandbox** (testnet, no real funds). Use the Base URL dropdown to switch to Production when you're ready to go live. [Jump to playground instructions →](#using-the-api-playground) ## Status & Monitoring Yativo provides two public status pages for production/live/main environments: * [status.yativo.com](https://status.yativo.com) — primary status and uptime monitoring * [status2.yativo.com](https://status2.yativo.com) — open-source backup status page Check these pages for real-time uptime, incident history, and scheduled maintenance. ## Before you start **Account creation and login happen at the dashboard — not through the API.** | Environment | Dashboard | API Base URL | | ----------- | -------------------------------------------------------------- | ------------------------------------------ | | Live | [crypto.yativo.com](https://crypto.yativo.com) | `https://crypto-api.yativo.com/api/v1` | | Sandbox | [sandbox-crypto.yativo.com](https://sandbox-crypto.yativo.com) | `https://crypto-sandbox.yativo.com/api/v1` | Sign up is **passwordless** — enter your email, confirm the one-time code, and you're in. Once logged in, go to **Settings → API Keys** to generate credentials for API access. *** ## Authentication Every API endpoint (except `POST /auth/token`) requires: ``` Authorization: Bearer YOUR_ACCESS_TOKEN ``` ### Getting a Bearer token Exchange your API key and secret for a short-lived token. Tokens expire after **60 minutes**; API keys never expire. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/auth/token' \ -H 'Content-Type: application/json' \ -d '{ "api_key": "yativo_...", "api_secret": "..." }' ``` ```json Response theme={null} { "success": true, "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600, "expires_at": "2026-03-28T11:00:00.000Z" } ``` Refresh by calling `POST /auth/token` again before the token expires — no separate refresh endpoint needed. See [Authentication](/yativo-crypto/authentication) for the full flow including scopes and the auto-refresh pattern. *** ## Common headers | Header | Required | Description | | ----------------- | -------------- | ------------------------------- | | `Authorization` | Yes | `Bearer YOUR_ACCESS_TOKEN` | | `Content-Type` | Yes (POST/PUT) | `application/json` | | `Idempotency-Key` | Optional | Prevents duplicate transactions | *** ## Response format ```json theme={null} { "status": true, "message": "Human-readable message", "data": { ... } } ``` Errors return `"status": false` with an appropriate HTTP status code (400, 401, 403, 404, 422, 429, 500). *** ## Sandbox The sandbox at `https://crypto-sandbox.yativo.com/api` uses testnet blockchains — **no real funds**. ### Using the API playground Every endpoint page has a **Try It** panel on the right. Here's how to use it: Use the **Base URL** dropdown at the top of the panel to switch between: * `https://crypto-sandbox.yativo.com/api` — **Sandbox** (testnet, no real funds) * `https://crypto-api.yativo.com/api` — **Production** (mainnet, real funds) The playground defaults to **Sandbox** so you can experiment safely. Paste your access token into the **Authorization** field. The playground adds the `Bearer` prefix automatically. Don't have a token yet? See [Getting a Bearer token](#getting-a-bearer-token) below, or use the shared sandbox credentials. Populate the required fields, then click **Send** to execute the request against the selected environment. ### Shared sandbox credentials A pre-populated sandbox account is available for immediate testing: ```bash theme={null} curl -X POST '/auth/token' \ -H 'Content-Type: application/json' \ -d '{ "api_key": "yativo_e072b3ef7e30fcb420183aa86ddd8452abd28a9ac8f5d04d", "api_secret": "df8da4d6b855c7e89bd3b4216dd0a1f4b30de1963c9bff0dcd666b15a0f836a5" }' ``` For isolated sandbox data, sign up at [sandbox-crypto.yativo.com](https://sandbox-crypto.yativo.com) and generate your own sandbox keys. *** ## Further reading * [Authentication guide](/yativo-crypto/authentication) * [API Keys](/yativo-crypto/api-keys) * [Webhooks](/yativo-crypto/webhooks) * [Error codes](/yativo-crypto/errors) * [Sandbox overview](/sandbox/overview) # Aggregate Customer Balances Source: https://docs.yativo.com/api-reference/issuer/aggregate-balances GET /v1/card-issuer/customers/aggregate-balances Sum the live on-chain balances of all customers' account wallets, grouped by currency Balances are fetched live from the blockchain and reflect the actual token balance held in each customer's account wallet. This call queries each wallet individually and may take a few seconds for large programs. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Use this endpoint to see the total float across your card issuer program without querying each customer individually. Results are grouped by currency (USD, EUR, GBP) and include a count of wallets successfully fetched. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers/aggregate-balances' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "by_currency": [ { "currency": "USD", "total_ledger_balance": 12345.67, "total_available_balance": 11890.23, "total_pending_balance": 455.44, "customer_count": 42, "realtime_count": 40, "on_chain_count": 1 }, { "currency": "EUR", "total_ledger_balance": 4321.00, "total_available_balance": 4321.00, "total_pending_balance": 0.00, "customer_count": 15, "realtime_count": 15, "on_chain_count": 0 }, { "currency": "GBP", "total_ledger_balance": 890.50, "total_available_balance": 820.00, "total_pending_balance": 70.50, "customer_count": 7, "realtime_count": 6, "on_chain_count": 1 } ], "total_customers": 64, "customers_with_wallets": 63, "fetched_at": "2026-05-12T14:30:00.000Z" } } ``` ```json 403 Not approved theme={null} { "success": false, "error": "NOT_APPROVED", "message": "Card issuer program not approved" } ``` ## Response fields | Field | Description | | --------------------------------------- | -------------------------------------------------------------------------------------------- | | `by_currency` | Array of balance summaries, one entry per currency in your program | | `by_currency[].currency` | Currency code (`USD`, `EUR`, `GBP`) | | `by_currency[].total_ledger_balance` | Sum of total token balances across all wallets for this currency | | `by_currency[].total_available_balance` | Sum of spendable balances (ledger minus pending holds) | | `by_currency[].total_pending_balance` | Sum of amounts held for authorized-but-unsettled transactions | | `by_currency[].customer_count` | Total customers with this card currency (deployed wallets) | | `by_currency[].realtime_count` | Wallets whose balance came from live card notifications | | `by_currency[].on_chain_count` | Wallets where balances were fetched directly from the blockchain (no pending info available) | | `total_customers` | Total customers across all currencies | | `customers_with_wallets` | Customers whose account wallet has been deployed | | `fetched_at` | ISO 8601 timestamp of when the response was generated | When `on_chain_count > 0` for a currency, the `total_available_balance` for those wallets equals their `total_ledger_balance` — pending transaction holds are not visible from the blockchain alone. `total_available_balance` may be slightly overstated in that case. # Apply for Issuer Program Source: https://docs.yativo.com/api-reference/issuer/apply POST /v1/card-issuer/apply Submit an application to join the Yativo Card Issuer Program Bearer token: `Bearer YOUR_ACCESS_TOKEN` Funding model for the program. | Value | Description | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `master_wallet` | You maintain a shared balance and push funds to each customer card via the Fund Customer API. Best for platforms that want centralised control over top-ups. | | `non_master` | Each customer funds their own card wallet independently. Best for self-service crypto-funded cards. | The chain your master wallet will receive deposits on. `SOL` (default) or `XDC`. Yativo auto-provisions a wallet for the chosen chain on approval. Most issuers use `SOL`. Whether to enable IBAN functionality for cardholders in your program. Defaults to `false`. The Issuer Program requires prior eligibility approval. Check `GET /v1/card-issuer/eligibility` first. If not eligible, contact your account manager or [support@yativo.com](mailto:support@yativo.com). ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/apply' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "funding_structure": "master_wallet", "preferred_chain": "SOL", "iban_enabled": false }' ``` ```json 201 Created theme={null} { "success": true, "message": "Application submitted. An admin will review your request.", "data": { "id": "69ecc05a4fc8c9c148ed1a9a", "status": "pending", "funding_structure": "master_wallet", "preferred_chain": "SOL", "iban_enabled": false } } ``` ```json 409 Already applied theme={null} { "success": false, "error": "ALREADY_APPLIED", "message": "Application already exists with status: pending", "data": { "status": "pending", "applied_at": "2026-04-01T10:00:00.000Z" } } ``` ```json 403 Not eligible theme={null} { "success": false, "error": "NOT_ELIGIBLE", "message": "Your account is not yet eligible for the Card Issuer Program. Contact support to request access." } ``` # List Card Transactions Source: https://docs.yativo.com/api-reference/issuer/card-transactions GET /v1/card-issuer/card-transactions List card spending transactions across all customers in your issuer program Bearer token: `Bearer YOUR_ACCESS_TOKEN` Page number. Defaults to `1`. Results per page. Defaults to `20`, max `100`. Filter by transaction status. One of: `authorized`, `settled`, `declined`, `reversed`, `partially_reversed`, `failed`, `expired`. Filter by customer — pass a `yativo_card_id` to see transactions for a specific customer. ```bash All transactions theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/card-transactions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Settled only theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/card-transactions?status=settled&limit=50' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash For one customer theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/card-transactions?customer_id=yativo_card_customer_8f9a...' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "transactions": [ { "transaction_id": "tx_9d8e7f6a5b4c3d2e", "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "type": "purchase", "amount": 12.50, "currency": "EUR", "status": "settled", "merchant": "Starbucks", "merchant_category": "5812", "merchant_city": "Paris", "merchant_country": "FR", "authorized_at": "2026-05-12T14:15:00.000Z", "settled_at": "2026-05-13T02:00:00.000Z", "created_at": "2026-05-12T14:15:00.000Z" }, { "transaction_id": "tx_1a2b3c4d5e6f7g8h", "yativo_card_id": "yativo_card_customer_ab12...", "card_id": "card_token_def456", "type": "purchase", "amount": 45.00, "currency": "USD", "status": "authorized", "merchant": "Amazon", "merchant_category": "5999", "merchant_city": "Seattle", "merchant_country": "US", "authorized_at": "2026-05-12T16:30:00.000Z", "settled_at": null, "created_at": "2026-05-12T16:30:00.000Z" } ], "total": 318, "page": 1, "limit": 20 } } ``` ```json 403 Not approved theme={null} { "success": false, "error": "NOT_APPROVED", "message": "Card issuer program not approved" } ``` ## Transaction fields | Field | Description | | ------------------- | ------------------------------------------------------------------ | | `transaction_id` | Unique identifier for this transaction | | `yativo_card_id` | The Yativo customer identifier who owns the card | | `card_id` | The card token the transaction was charged to | | `type` | Transaction kind — typically `purchase`, `refund`, or `withdrawal` | | `amount` | Transaction amount | | `currency` | Currency code (`USD`, `EUR`, `GBP`) | | `status` | Current status (see below) | | `merchant` | Merchant name | | `merchant_category` | Merchant category code (MCC) | | `merchant_city` | Merchant city | | `merchant_country` | Two-letter ISO country code | | `authorized_at` | When the transaction was authorized | | `settled_at` | When the transaction settled (`null` if still pending) | | `created_at` | When the transaction record was first created | ## Transaction statuses | Status | Meaning | | -------------------- | ------------------------------------------------------------ | | `authorized` | Approved at point of sale; funds are held pending settlement | | `settled` | Transaction has settled and funds have been debited | | `declined` | Transaction was declined | | `reversed` | Transaction was fully reversed | | `partially_reversed` | Transaction was partially reversed | | `failed` | Transaction failed after authorization | | `expired` | Authorization expired before settlement | Transactions are recorded in real time as card events arrive. For per-customer transaction history, use [Customer Card Transactions](/api-reference/issuer/customer-card-transactions). Transaction events are also delivered via [webhooks](/api-reference/issuer/webhooks) (`transaction.authorized`, `transaction.settled`, `transaction.declined`, `transaction.reversed`). # Get Customer Source: https://docs.yativo.com/api-reference/issuer/customer GET /v1/card-issuer/customers/{customerId} Return the full customer record — balance, KYC status, and all card details Bearer token: `Bearer YOUR_ACCESS_TOKEN` Customer identifier — accepts `yativo_card_id`, MongoDB `_id`, or `external_customer_id`. ```bash By yativo_card_id theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers/yativo_card_customer_8f9a...' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash By external_id theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers/usr_8821' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 Active customer theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "external_id": "usr_8821", "email": "priya@yourapp.com", "flow_status": "active", "step": 6, "next_action": "Card is active — customer can spend", "kyc_status": "approved", "currency": "EUR", "safe_deployed": true, "ledger_balance": 145.50, "ledger_balance_minor": 14550, "available_balance": 132.00, "available_balance_minor": 13200, "pending_balance": 13.50, "pending_balance_minor": 1350, "balance_freshness": "realtime", "balance_updated_at": "2026-05-12T14:30:00.000Z", "cards_count": 2, "pin_set": true, "cards": [ { "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167", "last_four": "4242", "card_type": "virtual", "status": "active", "is_frozen": false, "is_lost": false, "is_stolen": false, "is_blocked": false, "is_void": false, "pin_set": true, "activated_at": "2026-04-25T12:00:00.000Z", "created_at": "2026-04-25T10:00:00.000Z" }, { "card_id": "b3c19f2e-14a7-41bc-9e2d-93bf14815028", "last_four": "9876", "card_type": "virtual", "status": "frozen", "is_frozen": true, "is_lost": false, "is_stolen": false, "is_blocked": false, "is_void": false, "pin_set": true, "activated_at": "2026-05-01T08:00:00.000Z", "created_at": "2026-05-01T07:45:00.000Z" } ], "created_at": "2026-04-25T10:00:00.000Z" } } ``` ```json 200 KYC pending theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_customer_ab12..._1769031332999", "external_id": "usr_7714", "email": "bob@yourapp.com", "flow_status": "kyc_initiated", "step": 3, "next_action": "Awaiting KYC verification", "kyc_status": "pending_review", "currency": null, "safe_deployed": false, "ledger_balance": null, "ledger_balance_minor": null, "available_balance": null, "available_balance_minor": null, "pending_balance": null, "pending_balance_minor": null, "balance_freshness": null, "balance_updated_at": null, "cards_count": 0, "cards": [], "created_at": "2026-04-28T09:00:00.000Z" } } ``` ```json 404 Not found theme={null} { "success": false, "error": "CUSTOMER_NOT_FOUND" } ``` ```json 403 Not approved theme={null} { "success": false, "error": "NOT_APPROVED" } ``` ## Customer fields | Field | Description | | ---------------- | --------------------------------------------------------------------------------------------- | | `yativo_card_id` | Yativo's canonical customer identifier | | `external_id` | Your own reference ID supplied at onboarding | | `email` | Customer email | | `flow_status` | Onboarding stage — see [onboarding stages](/api-reference/issuer/customers#onboarding-stages) | | `step` | Numeric step (1–6) | | `next_action` | What needs to happen next for this customer | | `kyc_status` | `pending`, `in_progress`, `pending_review`, `approved`, `rejected`, or `expired` | | `currency` | Card currency (`USD`, `EUR`, `GBP`) — `null` until a region is assigned during KYC | | `safe_deployed` | Whether the customer's account wallet has been deployed | ## Balance fields Balance is wallet-level — all cards issued to a customer share the same balance. Fields are `null` until the account wallet is deployed. Values are returned as both a decimal float and an integer in minor units (cents) — e.g. `$145.50` → `ledger_balance: 145.50`, `ledger_balance_minor: 14550`. Balances are kept current by two mechanisms: instant updates from live card network notifications, and a background reconciliation job that re-checks any balance not updated within 2 hours directly against the on-chain token balance. You do not need to poll this endpoint — subscribe to `customer.balance.updated` webhooks instead. | Field | Type | Description | | ------------------------- | --------------- | ----------------------------------------------------------------------------------------------------- | | `ledger_balance` | float \| null | Total token balance in the customer's account wallet | | `ledger_balance_minor` | integer \| null | `ledger_balance` in minor units (cents) | | `available_balance` | float \| null | Spendable balance after deducting pending authorizations | | `available_balance_minor` | integer \| null | `available_balance` in minor units (cents) | | `pending_balance` | float \| null | Amount held for authorized but not yet settled transactions | | `pending_balance_minor` | integer \| null | `pending_balance` in minor units (cents) | | `balance_freshness` | string \| null | `"realtime"` — from live card notifications; `"on_chain"` — fetched from blockchain (no pending info) | | `balance_updated_at` | string \| null | ISO 8601 timestamp of the last balance notification (`null` for on-chain fallback) | ## Card fields Each object in `cards` represents one card issued to this customer. Full card numbers and CVVs are never returned. | Field | Description | | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `card_id` | Card account identifier. Note: webhook events carry a separate `card_id` that is the card token — use `yativo_card_id` to correlate across both. | | `last_four` | Last four digits of the card number | | `card_type` | `virtual` or `physical` | | `status` | `active`, `frozen`, `blocked`, `lost`, or `voided` | | `is_frozen` | Card is temporarily frozen | | `is_lost` | Card reported lost | | `is_stolen` | Card reported stolen (treated as permanently voided) | | `is_blocked` | Card blocked by program or compliance | | `is_void` | Card permanently disabled | | `activated_at` | When the card was first activated | | `created_at` | When the card was issued | To retrieve this customer's transaction history use [Customer Card Transactions](/api-reference/issuer/customer-card-transactions). To fund the customer use [Fund Customer](/api-reference/issuer/fund-customer). # Customer Card Transactions Source: https://docs.yativo.com/api-reference/issuer/customer-card-transactions GET /v1/card-issuer/customers/{customerId}/card-transactions List card spending transactions for a specific customer Bearer token: `Bearer YOUR_ACCESS_TOKEN` Customer identifier — accepts `yativo_card_id`, MongoDB `_id`, or `external_customer_id`. Page number. Defaults to `1`. Results per page. Defaults to `20`, max `100`. Filter by transaction status. One of: `authorized`, `settled`, `declined`, `reversed`, `partially_reversed`, `failed`, `expired`. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers/yativo_card_customer_8f9a.../card-transactions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Settled only theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers/yativo_card_customer_8f9a.../card-transactions?status=settled' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "customer_id": "yativo_card_customer_8f9a...", "currency": "EUR", "transactions": [ { "transaction_id": "tx_9d8e7f6a5b4c3d2e", "type": "purchase", "amount": 12.50, "currency": "EUR", "status": "settled", "merchant": "Starbucks", "merchant_category": "5812", "merchant_city": "Paris", "merchant_country": "FR", "authorized_at": "2026-05-12T14:15:00.000Z", "settled_at": "2026-05-13T02:00:00.000Z", "created_at": "2026-05-12T14:15:00.000Z" }, { "transaction_id": "tx_3f4g5h6i7j8k9l0m", "type": "purchase", "amount": 8.99, "currency": "EUR", "status": "authorized", "merchant": "Netflix", "merchant_category": "7922", "merchant_city": null, "merchant_country": "NL", "authorized_at": "2026-05-12T10:00:00.000Z", "settled_at": null, "created_at": "2026-05-12T10:00:00.000Z" } ], "total": 24, "page": 1, "limit": 20 } } ``` ```json 404 Not found theme={null} { "success": false, "error": "CUSTOMER_NOT_FOUND" } ``` ```json 403 Not approved theme={null} { "success": false, "error": "NOT_APPROVED", "message": "Card issuer program not approved" } ``` ## Response fields The response includes a top-level `currency` field showing the customer's card currency, followed by a paginated `transactions` array. | Field | Description | | ---------------------------------- | ----------------------------------------------------------------------------- | | `customer_id` | The identifier passed in the path | | `currency` | The customer's card currency (`USD`, `EUR`, `GBP`) | | `transactions[].transaction_id` | Unique identifier for this transaction | | `transactions[].type` | Transaction kind — typically `purchase`, `refund`, or `withdrawal` | | `transactions[].amount` | Transaction amount | | `transactions[].currency` | Transaction currency (may differ from card currency for foreign transactions) | | `transactions[].status` | Current status (see below) | | `transactions[].merchant` | Merchant name | | `transactions[].merchant_category` | Merchant category code (MCC) | | `transactions[].merchant_city` | Merchant city | | `transactions[].merchant_country` | Two-letter ISO country code | | `transactions[].authorized_at` | When the transaction was authorized | | `transactions[].settled_at` | When the transaction settled (`null` if still pending) | | `transactions[].created_at` | When the transaction record was first created | ## Transaction statuses | Status | Meaning | | -------------------- | ------------------------------------------------------------ | | `authorized` | Approved at point of sale; funds are held pending settlement | | `settled` | Transaction has settled and funds have been debited | | `declined` | Transaction was declined | | `reversed` | Transaction was fully reversed | | `partially_reversed` | Transaction was partially reversed | | `failed` | Transaction failed after authorization | | `expired` | Authorization expired before settlement | To view transactions across all customers at once, use [List Card Transactions](/api-reference/issuer/card-transactions). Real-time transaction events are also delivered via [webhooks](/api-reference/issuer/webhooks). # List Customer Transfers Source: https://docs.yativo.com/api-reference/issuer/customer-transfers GET /v1/card-issuer/customers/:customerId/transfers List all funding transfers sent to a specific customer's card Bearer token: `Bearer YOUR_ACCESS_TOKEN` Any customer identifier: `yativo_card_id`, `customer_id`, or your own `external_id`. Page number. Defaults to `1`. Results per page. Defaults to `20`, max `100`. Filter by status: `pending`, `completed`, `failed`, `refunded`. ```bash cURL (by yativo_card_id) theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers/yativo_card_customer_8f9a...abc/transfers' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash cURL (by external_id) theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers/usr_8821/transfers' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "customer_id": "yativo_card_customer_8f9a...abc_1769031332068", "transfers": [ { "transfer_id": "bridge_1746541800_2ea87af00de1", "source_chain": "SOL", "source_amount": 201.80, "destination_currency": "EUR", "destination_amount": 200.00, "status": "completed", "initiated_at": "2026-05-06T14:30:00Z", "completed_at": "2026-05-06T14:33:22Z" }, { "transfer_id": "bridge_1746443564_3fb98bc11ef2", "source_chain": "SOL", "source_amount": 51.00, "destination_currency": "EUR", "destination_amount": 50.00, "status": "completed", "initiated_at": "2026-05-05T09:12:44Z", "completed_at": "2026-05-05T09:16:01Z" } ], "total": 2, "page": 1, "limit": 20 } } ``` ```json 404 Customer not found theme={null} { "success": false, "error": "CUSTOMER_NOT_FOUND", "message": "No customer found matching the provided identifier" } ``` # List Card Customers Source: https://docs.yativo.com/api-reference/issuer/customers GET /v1/card-issuer/customers List all customers onboarded under your card issuer program **Card customers are separate from WaaS customers.** This endpoint returns all customer card records regardless of onboarding stage. For wallet sub-accounts (crypto deposits/withdrawals/transfers), see [WaaS Customers](/api-reference/customers/list). Bearer token: `Bearer YOUR_ACCESS_TOKEN` Page number. Defaults to `1`. Results per page. Defaults to `20`, max `100`. Filter by onboarding status. One of: `otp_requested`, `otp_verified`, `kyc_initiated`, `kyc_completed`, `card_created`, `active`. Include balance fields for each customer's account wallet. Defaults to `true`. Pass `false` for faster responses when balances are not needed. ```bash All customers theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Filter by status theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers?status=kyc_initiated' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Skip balances (faster) theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/customers?include_balances=false' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "customers": [ { "customer_id": "69f0bdf29a84752db9cc8ff9", "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068", "external_customer_id": "usr_8821", "email": "alice@yourapp.com", "flow_status": "active", "step": 6, "next_action": "Card is active — customer can spend", "safe_deployed": true, "currency": "USD", "ledger_balance": 45.23, "available_balance": 38.50, "pending_balance": 6.73, "balance_freshness": "realtime", "cards_count": 1, "created_at": "2026-04-20T08:00:00.000Z" }, { "customer_id": "6627f3a2c5d4e100123abcde", "yativo_card_id": "yativo_card_customer_ab12..._1769031332999", "external_customer_id": "usr_7714", "email": "bob@yourapp.com", "flow_status": "kyc_initiated", "step": 3, "next_action": "Awaiting KYC verification", "safe_deployed": false, "currency": null, "ledger_balance": null, "available_balance": null, "pending_balance": null, "balance_freshness": null, "cards_count": 0, "created_at": "2026-04-25T10:00:00.000Z" } ], "total": 87, "page": 1, "limit": 20, "balances_included": true } } ``` ```json 403 Not approved theme={null} { "success": false, "error": "NOT_APPROVED", "message": "Card issuer program not approved" } ``` ## Balance fields Each customer object includes three balance fields (all `null` when the wallet is not deployed or `include_balances=false`): | Field | Description | | ------------------- | -------------------------------------------------------------------------------------------------------------- | | `ledger_balance` | Total token balance in the customer's account wallet | | `available_balance` | Spendable balance after deducting pending authorizations | | `pending_balance` | Amount held for authorized but not yet settled transactions | | `balance_freshness` | `"realtime"` when sourced from live card notifications, `"on_chain"` when fetched directly from the blockchain | Balances are updated in real time whenever the card provider sends a balance change notification (e.g. after a card purchase). For wallets where no such notification has been received yet, a live on-chain query is made as a fallback — in that case `available_balance` equals `ledger_balance` since pending information is not available from the chain alone. ## Onboarding stages | `flow_status` | `step` | `next_action` | | ------------------------- | ------ | ----------------------------------------------------- | | `otp_requested` | 1 | Customer must verify the OTP sent to their email | | `otp_verified` | 2 | Complete KYC — call the kyc-link endpoint | | `kyc_initiated` | 3 | Awaiting KYC verification | | `kyc_completed` | 4 | Submit source-of-funds questionnaire | | `safe_deploying` | 5 | Account wallet is being deployed — wait a few minutes | | `card_created` / `active` | 6 | Card is active — customer can spend | ## Using customer identifiers The `id` field is the canonical identifier for a customer card record. You can also use `yativo_card_id`, `external_customer_id`, or `email` interchangeably in endpoints that accept a customer identifier (e.g. [Fund Customer](/api-reference/issuer/fund-customer), [Look Up Customer](/api-reference/issuer/lookup-customer)). Customers with `safe_deployed: false` cannot be funded yet — the account wallet deploys automatically once KYC is approved. # List Funding Deposits Source: https://docs.yativo.com/api-reference/issuer/deposits GET /v1/card-issuer/deposits List all inbound deposits to your issuer program — SOL auto-funding and XDC manual deposits Bearer token: `Bearer YOUR_ACCESS_TOKEN` Page number. Defaults to `1`. Results per page. Defaults to `20`, max `100`. Filter by deposit status. One of: `pending`, `auto_funding`, `awaiting_manual`, `funding`, `funded`, `failed`. Filter by source chain. One of: `SOL`, `XDC`. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/deposits?chain=SOL&status=funded' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "deposits": [ { "id": "6627f3a2c5d4e100123abcde", "tx_hash": "5KtP3MzXYZABCDE1234567890abcdef12345678901234567890abcdef1234567", "chain": "SOL", "amount": 500.00, "token": "USDC", "funding_status": "funded", "funding_type": "auto", "net_amount": 499.00, "fees": 1.00, "detected_at": "2026-04-25T10:00:00.000Z", "funded_at": "2026-04-25T10:06:12.000Z", "can_fund": false } ], "total": 1, "page": 1, "limit": 20 } } ``` # Check Eligibility Source: https://docs.yativo.com/api-reference/issuer/eligibility GET /v1/card-issuer/eligibility Check whether your account has been granted access to apply for the Card Issuer Program Bearer token: `Bearer YOUR_ACCESS_TOKEN` Eligibility is granted by a Yativo admin. If `eligible` is `false`, contact your account manager — there is no API call to change this yourself. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/eligibility' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 Eligible, not yet enrolled theme={null} { "success": true, "data": { "eligible": true, "enrolled": false, "status": null, "visibility": null, "funding_structure": null, "eligible_since": "2026-03-15T09:00:00.000Z" } } ``` ```json 200 Already enrolled theme={null} { "success": true, "data": { "eligible": true, "enrolled": true, "status": "approved", "visibility": "visible", "funding_structure": "master_wallet", "eligible_since": "2026-03-15T09:00:00.000Z" } } ``` ```json 200 Not eligible theme={null} { "success": true, "data": { "eligible": false, "enrolled": false, "status": null, "visibility": null, "funding_structure": null, "eligible_since": null } } ``` # Fund Customer Card Source: https://docs.yativo.com/api-reference/issuer/fund-customer POST /v1/card-issuer/fund-customer Push funds from your master wallet to a customer's card wallet. Only available for `master_wallet` programs. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Supply exactly one customer identifier. The customer must have completed onboarding (KYC approved, wallet ready) before funding. The `customer_id` from the [List Customers](/api-reference/issuer/customers) or [Look Up Customer](/api-reference/issuer/lookup-customer) response. You may supply any one identifier: `customer_id`, `card_id`, `external_id`, or `email`. Card ID from card creation. Your own reference (`external_customer_id`) set at onboarding. Customer email address. Amount in USD. How this is interpreted depends on `pricing_mode` — see below. Minimum `5`. Your master wallet chain to use as the funding source. `SOL` or `XDC`. Controls whether `amount` is what you **send** or what the customer **receives**. * **`send_x`** (default) — Your master wallet is debited exactly `amount`. Any applicable fees are deducted before the customer's card is credited. * **`receive_x`** — The customer's card is credited exactly `amount`. The system works backwards through the fee schedule to calculate how much your master wallet must supply. Use this when the customer is owed an exact payout. **Example — funding \$200:** | `pricing_mode` | You send | Customer receives | | -------------- | -------------------- | -------------------- | | `send_x` | \$200 | \~\$198 (after fees) | | `receive_x` | \~\$202 (fees added) | \$200 exactly | Optional target currency (`USD`, `EUR`, `GBP`). Defaults to the customer's card currency. Must match — mismatches return an error with the correct required currency. ```bash cURL — receive_x (customer gets exactly $10) theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/fund-customer' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "email": "fernando@truther.io", "amount": 10, "source_chain": "SOL", "pricing_mode": "receive_x" }' ``` ```bash cURL — send_x (debit exactly $200 from your wallet) theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/fund-customer' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "email": "fernando@truther.io", "amount": 200, "source_chain": "SOL", "pricing_mode": "send_x" }' ``` ```json 200 Completed theme={null} { "success": true, "message": "Customer funded successfully", "data": { "transfer_id": "bridge_1778501099297_2ea87af00de1", "status": "completed", "source": { "chain": "SOL", "amount": 10 }, "destination": { "token": "USD" }, "pricing_mode": "receive_x", "estimated_amount": "10.000000", "estimated_time": "immediate" } } ``` ```json 200 Pending (top-up in progress) theme={null} { "success": true, "message": "Funding initiated for customer", "data": { "transfer_id": "bridge_1778501099297_2ea87af00de1", "status": "pending", "source": { "chain": "SOL", "amount": 10.00105711 }, "destination": { "token": "USD" }, "pricing_mode": "receive_x", "estimated_amount": "9.998943", "estimated_time": "2–5 minutes" } } ``` ```json 400 Token mismatch theme={null} { "success": false, "error": "TOKEN_MISMATCH", "message": "This customer's card requires EUR. You requested USD. Please swap to EUR first.", "required_token": "EUR", "requested_token": "USD" } ``` ```json 400 Daily limit exceeded theme={null} { "success": false, "error": "DAILY_LIMIT_EXCEEDED", "message": "Daily funding limit exceeded. Used: $48200.00, limit: $50000" } ``` When `estimated_time` is `"immediate"` the transfer is already settled — no polling needed. When `estimated_time` is `"2–5 minutes"`, save the `transfer_id` and poll [Get Transfer Status](/api-reference/issuer/transfer-status) until `status` is `completed`. # Look Up Customer Source: https://docs.yativo.com/api-reference/issuer/lookup-customer GET /v1/card-issuer/lookup-customer Find a card customer record by any identifier Bearer token: `Bearer YOUR_ACCESS_TOKEN` Yativo's internal card customer ID (e.g. `yativo_card_customer_8f9a..._1769031332068`). Customer ObjectId, or falls back to `yativo_card_id` lookup if not a valid ObjectId. Card ID returned from card creation. Your reference ID set at onboarding. Customer email address. MongoDB `_id` of the customer document. Pass exactly one identifier. `yativo_card_id` and `external_id` are the most reliable — prefer them over `email` if you have either. ```bash By external_id theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/lookup-customer?external_id=usr_8821' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash By yativo_card_id theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/lookup-customer?yativo_card_id=yativo_card_customer_8f9a..._1769031332068' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash By email theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/lookup-customer?email=priya%40yourapp.com' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 Found theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "external_id": "usr_8821", "email": "priya@yourapp.com", "flow_status": "card_created", "currency": "USD", "token": "USD", "safe_deployed": true, "cards_count": 1, "cards": [ { "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167", "last_four": "4242", "card_type": "virtual", "is_frozen": false, "is_lost": false, "is_blocked": false, "status": "active" } ], "created_at": "2026-04-25T10:00:00.000Z" } } ``` ```json 400 No identifier provided theme={null} { "success": false, "error": "MISSING_IDENTIFIER", "message": "Provide one of: id, yativo_card_id, customer_id, card_id, external_id, email" } ``` ```json 404 Not found theme={null} { "success": false, "error": "CUSTOMER_NOT_FOUND" } ``` # Get Master Wallets Source: https://docs.yativo.com/api-reference/issuer/master-wallets GET /v1/card-issuer/master-wallets Retrieve your master wallet addresses and current balances for all supported currencies Bearer token: `Bearer YOUR_ACCESS_TOKEN` Fund your master wallets by depositing crypto to the addresses shown here. Once funded, use [Fund Customer](/api-reference/issuer/fund-customer) to push balances to individual customer cards. Master wallets are only available for `master_wallet` funding programs. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/master-wallets' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "wallets": { "sol": { "address": "SoLMasterWalletAddressXXXXXXXXXXXXXXXXXXXXXXXX", "balance": 12450.50, "last_balance_check": "2026-04-01T11:55:00.000Z" }, "xdc": { "address": "0xXDCMasterWalletAddress", "balance": 3200.00, "last_balance_check": "2026-04-01T11:55:00.000Z" }, "usdc": { "balance": 8340.00, "last_balance_check": "2026-04-01T11:55:00.000Z" }, "eur": { "balance": 3100.00, "last_balance_check": "2026-04-01T11:55:00.000Z" }, "gbp": { "balance": 1200.00, "last_balance_check": "2026-04-01T11:55:00.000Z" } } } } ``` ### Wallet Reference | Key | Currency | Notes | | ------ | ----------------- | ------------------------------------------------------------------------- | | `sol` | USDC on Solana | Primary deposit chain — send USDC here | | `xdc` | USDC on XDC | Alternative deposit chain — `null` if XDC is not enabled for your program | | `usdc` | USD spend balance | Available for funding USD-denomination cards | | `eur` | EUR spend balance | Available for funding EUR-denomination cards | | `gbp` | GBP spend balance | Available for funding GBP-denomination cards | `usdc`, `eur`, and `gbp` balances have no `address` field — they are settlement balances managed internally. `sol` and `xdc` include an `address` field for depositing USDC. Use [Swap Token](/api-reference/issuer/swap-token) to convert between `usdc`, `eur`, and `gbp` balances. # Get Issuer Program Status Source: https://docs.yativo.com/api-reference/issuer/program GET /v1/card-issuer/status Retrieve the status and configuration of your Card Issuer Program Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/status' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 Approved program theme={null} { "success": true, "data": { "enrolled": true, "status": "approved", "visibility": "visible", "funding_structure": "master_wallet", "preferred_chain": "SOL", "enabled_chains": ["SOL"], "iban_enabled": false, "card_reissue_enabled": false, "master_wallets": { "sol": { "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgHkv", "balance": 1024.50 }, "xdc": null, "usdc": { "balance": 8200.00, "last_balance_check": "2026-05-12T14:00:00.000Z" }, "eur": { "balance": 3100.00, "last_balance_check": "2026-05-12T14:00:00.000Z" }, "gbp": { "balance": 950.00, "last_balance_check": "2026-05-12T14:00:00.000Z" } }, "stats": { "total_cards_issued": 87, "total_funded_amount": 142350.00, "total_transfer_fees_paid": 284.70 }, "limits": { "max_cards": 500, "daily_funding_limit": 50000, "monthly_funding_limit": 500000 }, "approved_at": "2026-04-01T12:00:00.000Z" } } ``` ```json 200 Pending theme={null} { "success": true, "data": { "enrolled": true, "status": "pending", "funding_structure": "master_wallet", "iban_enabled": false } } ``` ```json 200 Not enrolled theme={null} { "success": true, "data": { "enrolled": false } } ``` ## Response fields | Field | Description | | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | `enrolled` | Whether you have submitted an application | | `status` | Current program status (see below) | | `funding_structure` | `master_wallet` — you fund customers from your master wallet; `non_master` — customers fund themselves | | `preferred_chain` | Source chain used for master-wallet funding (`SOL` or `XDC`) | | `enabled_chains` | Source chains enabled for your program | | `master_wallets` | Present when `funding_structure` is `master_wallet`. `sol`/`xdc` are source wallets; `usdc`/`eur`/`gbp` are settlement wallets for customer card funding | | `stats.total_cards_issued` | Total cards issued across all customers | | `stats.total_funded_amount` | Cumulative amount funded to customers | | `stats.total_transfer_fees_paid` | Cumulative transfer fees incurred | | `limits.max_cards` | Maximum customer cards allowed under your program | | `limits.daily_funding_limit` | Maximum daily funding volume | | `limits.monthly_funding_limit` | Maximum monthly funding volume | ## Status values | Status | Meaning | | ----------- | ----------------------------------------------------------- | | `pending` | Application under review — typically 1–2 business days | | `approved` | Program is live — you can onboard customers and issue cards | | `rejected` | Application declined — contact support | | `suspended` | Program temporarily suspended | # Set Program Card Limits Source: https://docs.yativo.com/api-reference/issuer/program-card-limits PATCH /v1/card-issuer/admin/{programId}/card-limits Admin: set the per-customer card limit ceiling for an issuer program This is an **admin-only** endpoint. It sets the maximum number of cards each customer in the program can hold. Issuers cannot set per-customer limits above these ceilings. The ID of the issuer program to update. Returned by `GET /v1/card-issuer/status` as `data.id`. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Maximum virtual cards allowed per customer. Must be 0–5. Default: `1`. Maximum physical cards allowed per customer. Must be 0–5. Default: `1`. Maximum total active cards (virtual + physical combined) allowed per customer. Must be 0–5. Default: `2`. Platform hard cap is 5. At least one field must be provided. Fields not sent are left unchanged. ```bash cURL theme={null} curl -X PATCH 'https://crypto-api.yativo.com/api/v1/card-issuer/admin/69ecc05a4fc8c9c148ed1a9a/card-limits' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "max_virtual_per_customer": 3, "max_physical_per_customer": 1, "max_total_per_customer": 4 }' ``` ```json 200 OK theme={null} { "success": true, "message": "Card limits updated", "data": { "program_id": "69ecc05a4fc8c9c148ed1a9a", "card_limits": { "max_virtual_per_customer": 3, "max_physical_per_customer": 1, "max_total_per_customer": 4 } } } ``` ```json 400 Invalid limit theme={null} { "success": false, "error": "INVALID_LIMIT", "message": "max_virtual_per_customer must be 0–5" } ``` ```json 400 No changes theme={null} { "success": false, "error": "NO_CHANGES", "message": "Provide at least one limit field to update" } ``` ```json 404 Not found theme={null} { "success": false, "error": "NOT_FOUND" } ``` # Swap Master Wallet Token Source: https://docs.yativo.com/api-reference/issuer/swap-token POST /v1/card-issuer/master-wallets/swap Swap between USD, EUR, and GBP balances in your master wallet Bearer token: `Bearer YOUR_ACCESS_TOKEN` Source currency: `USDC`, `EUR`, or `GBP`. Target currency: `USDC`, `EUR`, or `GBP`. Amount to swap from the source currency balance. Customer card currency is determined by the customer's country at the time their card wallet is created. Use this endpoint to convert your USDC balance to the correct currency before funding customers whose cards are denominated in EUR or GBP. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/master-wallets/swap' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "from_token": "USDC", "to_token": "EUR", "amount": 1000 }' ``` ```json 200 Swap initiated theme={null} { "success": true, "message": "Swap initiated: 1000 USD → EUR", "data": { "swap_id": "0x7a8b9c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f", "status": "submitted", "from_token": "USD", "to_token": "EUR", "amount": 1000, "expected_output": 924.50, "fee_amount": "1.20", "estimated_time": "1-5 minutes" } } ``` # Get Transfer or Withdrawal Status Source: https://docs.yativo.com/api-reference/issuer/transfer-status GET /v1/card-issuer/transfers/:transferId Retrieve the current status and details of a single master-wallet → customer-card transfer, or a customer-card → master-wallet withdrawal This single endpoint looks up **both** directions of fund movement — it checks funding transfers first, then falls back to withdrawals if the ID doesn't match one. The response's `type` field tells you which one you got back. Bearer token: `Bearer YOUR_ACCESS_TOKEN` Either the `transfer_id` returned by [Fund Customer Card](/api-reference/issuer/fund-customer) (or the `transfer_id` on `customer.funded`/`customer.balance.updated` webhooks with `trigger: "funding"`), **or** the `withdrawal_id` returned by the withdraw-from-card endpoint (or `transfer_id` on `customer.balance.updated` with `trigger: "withdraw"`). ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/transfers/tx_1745123456_2ea87af00de1' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 Funding — in progress theme={null} { "success": true, "data": { "type": "funding", "transfer_id": "tx_1745123456_2ea87af00de1", "status": "hop1_processing", "source": { "chain": "SOL", "amount": 201.80 }, "destination": { "currency": "EUR", "amount": null }, "tx_hash": null, "fees": { "platform_fee": 0.50, "total_fee": 0.90, "fee_currency": "USDC" }, "customer_id": "6627f3a2c5d4e100123def", "initiated_at": "2026-05-06T14:30:00Z", "completed_at": null } } ``` ```json 200 Funding — completed theme={null} { "success": true, "data": { "type": "funding", "transfer_id": "tx_1745123456_2ea87af00de1", "status": "completed", "source": { "chain": "SOL", "amount": 201.80 }, "destination": { "currency": "EUR", "amount": 200.00 }, "tx_hash": "0x3fbd8b6c6a1e2e6f0a1b8f6a5b4c3d2e1f0a1b8f6a5b4c3d2e1f0a1b8f6a5b4c", "fees": { "platform_fee": 0.50, "total_fee": 0.90, "fee_currency": "USDC" }, "customer_id": "6627f3a2c5d4e100123def", "initiated_at": "2026-05-06T14:30:00Z", "completed_at": "2026-05-06T14:33:22Z" } } ``` ```json 200 Withdrawal — settled theme={null} { "success": true, "data": { "type": "withdrawal", "transfer_id": "cwd_1781020459781_7plaq8", "status": "settled", "source": { "yativo_card_id": "yativo_card_customer_8f9a...", "amount": 50.00, "currency": "USD" }, "destination": { "address": "0x920abe21a7eb39DF5f5A42AE97F4Cd061d5AdD9b", "amount": 50.00, "currency": "USD" }, "tx_hash": "0xedbca669196b14ddc4b5a8b6fd6c313a1400795cdabe686b3d4b908d8e8279bb", "failure_reason": null, "customer_id": "6627f3a2c5d4e100123def", "initiated_at": "2026-05-06T14:30:00Z", "completed_at": "2026-05-06T14:33:22Z" } } ``` ## Status reference **Funding (`type: "funding"`)** | Status | Meaning | | ----------------- | -------------------------------------------------- | | `pending` | Transfer queued, not yet started | | `hop1_processing` | First transfer leg in progress | | `hop1_complete` | First leg done, second leg starting | | `hop2_processing` | Final delivery to customer card wallet in progress | | `completed` | Funds delivered — customer card is credited | | `failed` | Transfer failed | | `refunded` | Funds returned to your master wallet | **Withdrawal (`type: "withdrawal"`)** | Status | Meaning | | ------------ | ------------------------------------------------------------- | | `initiated` | Withdrawal submitted, in the card network's delay-relay queue | | `processing` | Delay relay executing | | `settled` | Funds arrived in your master wallet — `tx_hash` is populated | | `failed` | Withdrawal failed — see `failure_reason` | Poll this endpoint every 10–15 seconds until `status` reaches a terminal value (`completed`/`failed`/`refunded` for funding, `settled`/`failed` for withdrawals). Funding transfers typically complete in **2–5 minutes**; withdrawals go through a **\~3 minute** delay-relay before settling. # List Transfers Source: https://docs.yativo.com/api-reference/issuer/transfers GET /v1/card-issuer/transfers List all master-wallet → customer-card transfers initiated from your issuer program Bearer token: `Bearer YOUR_ACCESS_TOKEN` Page number. Defaults to `1`. Results per page. Defaults to `20`, max `100`. Filter by status. One of: `pending`, `hop1_processing`, `hop1_complete`, `hop2_processing`, `completed`, `failed`, `refunded`. Filter by customer ID. Filter by source chain: `SOL` or `XDC`. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/card-issuer/transfers?status=completed&limit=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json 200 OK theme={null} { "success": true, "data": { "transfers": [ { "transfer_id": "bridge_1743508800_2ea87af00de1", "source_chain": "SOL", "source_amount": 201.80, "destination_currency": "EUR", "destination_amount": 200.00, "status": "completed", "customer_id": "6627f3a2c5d4e100123def", "initiated_at": "2026-04-01T12:00:00.000Z", "completed_at": "2026-04-01T12:08:42.000Z" } ], "total": 142, "page": 1, "limit": 20 } } ``` `GET /v1/card-issuer/funding-history` is a backward-compatible alias for this endpoint and returns the same response shape. # Webhook Events Source: https://docs.yativo.com/api-reference/issuer/webhooks Real-time notifications for card issuer program events. ## Setup Yativo sends webhook notifications to your registered HTTPS endpoint via HTTP POST whenever a program event occurs. Each request is signed with HMAC-SHA256 so you can verify it genuinely came from Yativo. Register your endpoint at the unified webhook endpoint. Card issuer events and general crypto events share the same service — subscribe to any combination. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/webhook/create-webhook' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "url": "https://api.yourapp.com/webhooks/yativo", "events": ["customer.funded", "customer.funding.failed", "transaction.authorized", "transaction.settled"], "description": "Production card issuer webhook" }' ``` ```json theme={null} { "status": true, "message": "Webhook created successfully", "data": { "webhook_id": "68241abc2f3d4e5f6a7b8c9d", "url": "https://api.yourapp.com/webhooks/yativo", "events": ["customer.funded", "customer.funding.failed", "transaction.authorized", "transaction.settled"], "secret": "whsec_a8f3c2e1d4b7f9e2c5a3b6d8f1e4c7a2b5d8e1f4c7a2b5d8", "created_at": "2026-05-12T14:00:00.000Z" } } ``` Store the `secret` securely — use a secrets manager or environment variable. The secret is also retrievable later via `GET /v1/yativo-card/webhooks/:webhookId`. If compromised, rotate it via `POST /v1/yativo-card/webhooks/:webhookId/rotate-secret`. Pass `"events": ["*"]` to receive all event types. Other management endpoints: | Method | Path | Action | | -------- | ------------------------------------------------------- | --------------------------------------------------- | | `GET` | `/v1/yativo-card/webhooks` | List all subscriptions | | `GET` | `/v1/yativo-card/webhooks/:webhookId` | Get one subscription (returns secret) | | `PUT` | `/v1/yativo-card/webhooks/:webhookId` | Update URL, events, or enabled state | | `DELETE` | `/v1/yativo-card/webhooks/:webhookId` | Delete subscription | | `POST` | `/v1/yativo-card/webhooks/:webhookId/rotate-secret` | Rotate signing secret | | `GET` | `/v1/yativo-card/webhooks/:webhookId/deliveries` | Delivery history for one webhook | | `GET` | `/v1/yativo-card/webhooks/deliveries/all` | All deliveries across all webhooks | | `GET` | `/v1/yativo-card/webhooks/deliveries/:deliveryId` | Single delivery detail (full payload + attempt log) | | `POST` | `/v1/yativo-card/webhooks/deliveries/:deliveryId/retry` | Retry a failed delivery | ## Event categories | Category | Events | | --------------------- | --------------------------------------------------------------------------------------- | | **Master Wallet** | Deposits, token swaps, customer funding | | **Customer Funding** | Funds received or failed into a customer's card wallet, balance updates | | **Card Lifecycle** | Card created, activated, frozen, unfrozen, voided, lost, stolen, cancelled, deactivated | | **Card Transactions** | Authorization, settlement, decline, reversal, refund | ## Event reference | Event | Trigger | | ------------------------------- | -------------------------------------------------------------------------------------- | | `master_wallet.deposit` | Funds received into your master wallet | | `master_wallet.swap` | Token swap submitted (e.g. USD → EUR) | | `master_wallet.customer_funded` | Master wallet debited to fund a customer | | `customer.funded` | Customer's card wallet received funds | | `customer.funding.failed` | Funding transfer failed (wallet misconfigured, insufficient balance, or network error) | | `customer.balance.updated` | Customer's card balance changed (after spend, top-up, or authorization) | | `card.created` | New card issued to a customer | | `card.activated` | Card activated | | `card.frozen` | Card frozen | | `card.unfrozen` | Card unfrozen | | `card.voided` | Card voided (permanently disabled) | | `card.lost` | Card reported lost | | `card.stolen` | Card reported stolen | | `card.cancelled` | Card cancelled | | `card.deactivated` | Card deactivated | | `transaction.authorized` | Card transaction authorized | | `transaction.settled` | Transaction settled | | `transaction.declined` | Transaction declined | | `transaction.reversed` | Transaction reversed | | `transaction.refund.created` | Refund created | ## Payload structure All webhook events share a common envelope. The `data` object contains event-specific fields. The event type is also sent in the `X-Yativo-Event` request header. ```json theme={null} { "id": "evt_1747058400000_abc123", "type": "customer.funded", "created_at": "2026-05-12T14:30:00.000Z", "data": { ... } } ``` ## Payload examples ### `master_wallet.deposit` You will receive this event **twice** for a single deposit: once immediately when funds are detected (`processing`), and again when settlement is confirmed (`settled`). The payload shape differs between the two states. **`status: "processing"`** — fired as soon as the incoming deposit is detected. ```json theme={null} { "id": "evt_1747058400000_abc123", "type": "master_wallet.deposit", "created_at": "2026-05-12T14:00:00.000Z", "data": { "settlement_id": "dep_1745123456_2ea87af00de1", "source_amount": 500.00, "tx_hash": "5KtP3MzXYZABCDE1234567890abcdef12345678901234567890abcdef1234567", "status": "processing" } } ``` **`status: "settled"`** — fired once the funds are settled into your master wallet. ```json theme={null} { "id": "evt_1747058520000_def456", "type": "master_wallet.deposit", "created_at": "2026-05-12T14:02:00.000Z", "data": { "settlement_id": "dep_1745123456_2ea87af00de1", "source_amount": 500.00, "settled_amount": 499.75, "status": "settled" } } ``` ### `master_wallet.swap` Fired when a token swap is submitted from your master wallet. ```json theme={null} { "id": "evt_1747058700000_def456", "type": "master_wallet.swap", "created_at": "2026-05-12T14:05:00.000Z", "data": { "swap_id": "0x4a1b2c3d...", "from_token": "USD", "to_token": "EUR", "amount": 1000.00, "expected_output": 921.50, "status": "submitted" } } ``` ### `customer.funded` Fired when a customer's card wallet has been credited. The `transfer_id` can be looked up via [Get Transfer](/api-reference/issuer/transfer-status). ```json theme={null} { "id": "evt_1747059000000_ghi789", "type": "customer.funded", "created_at": "2026-05-12T14:10:00.000Z", "data": { "transfer_id": "tx_1745128800_9fc12ab3e4d5", "customer_id": "69f0bdf29a84752db9cc8ff9", "amount": 50.00, "currency": "USD", "status": "completed" } } ``` ### `customer.funding.failed` Fired when a funding transfer to a customer's card wallet fails. ```json theme={null} { "id": "evt_1747059000000_fail01", "type": "customer.funding.failed", "created_at": "2026-05-12T14:10:00.000Z", "data": { "customer_id": "69f0bdf29a84752db9cc8ff9", "yativo_card_id": "yativo_card_customer_8f9a...", "amount": 50.00, "currency": "USD" } } ``` ### `master_wallet.customer_funded` Fired alongside `customer.funded` whenever your master wallet is debited. Includes `remaining_balance` when the transfer settles immediately; omitted when the balance updates asynchronously. ```json theme={null} { "id": "evt_1747059001000_mwf01", "type": "master_wallet.customer_funded", "created_at": "2026-05-12T14:10:00.000Z", "data": { "transfer_id": "tx_1745128800_9fc12ab3e4d5", "customer_id": "69f0bdf29a84752db9cc8ff9", "amount": 50.00, "currency": "USD", "status": "completed", "remaining_balance": 114.98 } } ``` ### `card.frozen` Fired when a card is frozen, either by your program or by the customer. ```json theme={null} { "id": "evt_1747059600000_mno345", "type": "card.frozen", "created_at": "2026-05-12T14:20:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "status": "Frozen", "timestamp": "2026-05-12T14:20:00.000Z" } } ``` The `card_id` field in webhook events is the card token identifier. This may differ from the `card_id` returned by the [Get Customer](/api-reference/issuer/customer) endpoint. Use `yativo_card_id` as the stable cross-reference between webhook events and API responses. ### `customer.balance.updated` Fired whenever the card provider reports a balance change — after a purchase authorization, settlement, top-up, or reversal. Provides the full balance breakdown so you can update your UI in real time without polling. ```json theme={null} { "id": "evt_1747060200000_stu901", "type": "customer.balance.updated", "created_at": "2026-05-12T14:30:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "ledger_balance": 45.23, "available_balance": 38.50, "pending_balance": 6.73, "currency": "EUR", "timestamp": "2026-05-12T14:30:00.000Z" } } ``` ### `transaction.authorized` Fired when a card transaction is authorized at the point of sale. A `customer.balance.updated` event typically follows immediately. ```json theme={null} { "id": "evt_1747059300000_jkl012", "type": "transaction.authorized", "created_at": "2026-05-12T14:15:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "transaction_id": "tx_9d8e7f...", "type": "purchase", "amount": 12.50, "currency": "EUR", "billing_amount": 12.50, "billing_currency": "EUR", "fx_rate": 1, "merchant": "Starbucks", "merchant_category": "5812", "merchant_city": "Paris", "merchant_country": "FR", "status": "AUTHORIZED", "timestamp": "2026-05-12T14:15:00.000Z" } } ``` `billing_amount`/`billing_currency` reflect the card's own settlement currency and are present on every transaction event, not just foreign-currency ones — on a same-currency purchase like this one they simply equal `amount`/`currency`. See the [full transaction event reference](/guides/card-issuer-webhooks#transaction-event-field-reference) for the foreign-currency case and the `fx_rate` calculation. ### `card.lost` Fired when a card is reported lost. ```json theme={null} { "id": "evt_1747059900000_pqr678", "type": "card.lost", "created_at": "2026-05-12T14:25:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "status": "Lost", "timestamp": "2026-05-12T14:25:00.000Z" } } ``` ## Signature verification Every webhook request includes an `X-Yativo-Signature` header and an `X-Yativo-Timestamp` header. The event type is also in the `X-Yativo-Event` header and the unique delivery ID in `X-Yativo-Delivery-Id`. Verify signature and timestamp before processing the event. The signature is computed over the raw request body (the exact JSON bytes received), prefixed with the timestamp. ```javascript theme={null} const crypto = require('crypto'); // Use express.raw({ type: 'application/json' }) so req.body is a Buffer, not a parsed object. // req.headers['x-yativo-signature'] — the HMAC signature // req.headers['x-yativo-timestamp'] — Unix timestamp (string) function verifyWebhook(rawBody, signature, timestamp, secret) { if (!signature || !timestamp) return false; // Reject replays older than 5 minutes if (Math.abs(Date.now() / 1000 - parseInt(timestamp, 10)) > 300) return false; const signed = `${timestamp}.${rawBody.toString('utf8')}`; const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(signed).digest('hex'); try { return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)); } catch { return false; } } ``` Always verify the signature before trusting the payload. Use `express.raw({ type: 'application/json' })` (not `express.json()`) so you have the raw bytes for verification. ## Delivery history Both delivery history endpoints accept the same query parameters: | Parameter | Type | Default | Description | | ----------- | ------ | ------- | ------------------------------------------------------ | | `limit` | number | `50` | Number of records to return. Maximum `100`. | | `offset` | number | `0` | Number of records to skip — use for pagination. | | `status` | string | — | Filter by delivery status: `success` or `failed`. | | `eventType` | string | — | Filter by event type, e.g. `card.transaction.created`. | Results are sorted newest first. ```bash Examples theme={null} # Last 30 deliveries GET /v1/yativo-card/webhooks/deliveries/all?limit=30 # Only failed deliveries GET /v1/yativo-card/webhooks/deliveries/all?status=failed # Failed transaction events, most recent 20 GET /v1/yativo-card/webhooks/deliveries/all?status=failed&eventType=card.transaction.created&limit=20 # Failed deliveries for one specific webhook GET /v1/yativo-card/webhooks/{webhookId}/deliveries?status=failed ``` Each record in the response includes: | Field | Description | | -------------------- | ---------------------------------------------------------- | | `delivery_id` | ID used to fetch details or trigger a manual retry | | `event_type` | The event that triggered this delivery | | `status` | `success` or `failed` | | `attempt_count` | How many delivery attempts have been made | | `last_response_code` | HTTP status code from your endpoint on the last attempt | | `delivered_at` | Timestamp of successful delivery (`null` if still failing) | | `created_at` | When the delivery was first attempted | To see the full payload and per-attempt log for a delivery, call `GET /v1/yativo-card/webhooks/deliveries/:deliveryId`. ## Retry policy Yativo retries failed webhook deliveries using exponential backoff. Respond with any HTTP `2xx` status code to acknowledge receipt and prevent retries. | Attempt | Delay after previous attempt | | ----------- | ---------------------------- | | 1 (initial) | — | | 2 | 1 minute | | 3 | 5 minutes | | 4 | 30 minutes | | 5 | 2 hours | | 6 | 12 hours | | 7 | 24 hours | After 7 failed attempts the delivery is marked **permanently failed** — no further automatic retries. You can manually replay individual deliveries via `POST /v1/yativo-card/webhooks/deliveries/:deliveryId/retry`. If your endpoint fails 100 consecutive deliveries, Yativo will automatically disable the subscription to protect your program's event queue. Re-enable it via `PUT /v1/yativo-card/webhooks/:webhookId` with `{ "enabled": true }` after fixing the issue. To avoid processing duplicate events, use the top-level `id` field (e.g. `evt_1747058400000_abc123`) as an idempotency key. The `X-Yativo-Delivery-Id` header carries the delivery record ID (a separate identifier used to retry individual deliveries via the API). # Create Payment Source: https://docs.yativo.com/api-reference/payment-gateway/create POST /v1/crypto-gateway/payments Create a new payment intent with a hosted checkout URL Bearer token: `Bearer YOUR_ACCESS_TOKEN` Title shown on the checkout page (e.g. `"Invoice #1234"` or `"Pro Plan — Monthly"`). Amount expected from the customer, in USD. One or more asset codes to accept. Must be from the [supported payment assets](/yativo-crypto/payment-gateway#supported-payment-assets) list. Example: `["USDC_SOL", "USDT_POL", "USDC_BASE"]`. Optional description of the goods or service being purchased (max 1000 characters). Shown on the hosted checkout page and included in the customer receipt email. Pre-fill the customer email on the checkout page. URL to POST payment event notifications to. See [Webhooks](/yativo-crypto/webhooks). Logo URL displayed on the hosted checkout page. Your internal order/reference ID attached to this payment for reconciliation. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/crypto-gateway/payments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "title": "Invoice #1234", "description": "Pro Plan subscription — April 2026", "requested_amount": 49.99, "accepted_assets": ["USDC_SOL", "USDT_POL", "USDC_BASE"], "customer_email": "alice@example.com", "webhook_url": "https://yourapp.com/webhooks/payments", "external_reference": "order_abc123" }' ``` ```json theme={null} { "success": true, "data": { "payment_id": "pay_a1b2c3d4e5f6", "title": "Invoice #1234", "description": "Pro Plan subscription — April 2026", "requested_amount": 49.99, "status": "awaiting_payment", "checkout_url": "https://crypto-checkout.yativo.com/pay/pay_a1b2c3d4e5f6", "embed_url": "https://crypto-checkout.yativo.com/embed/pay_a1b2c3d4e5f6", "accepted_options": [ { "asset_code": "USDC_SOL", "network": "solana", "deposit_address": "7xKXtg..." }, { "asset_code": "USDT_POL", "network": "polygon", "deposit_address": "0xAbCd..." }, { "asset_code": "USDC_BASE", "network": "base", "deposit_address": "0x1234..." } ], "customer_email": "alice@example.com", "external_reference": "order_abc123", "payment_window_expires_at": "2026-04-18T13:00:00Z", "monitoring_ends_at": "2026-04-18T13:20:00Z", "created_at": "2026-04-18T12:00:00Z" } } ``` # List Payments Source: https://docs.yativo.com/api-reference/payment-gateway/list GET /v1/crypto-gateway/payments List your 10 most recent payment intents Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/crypto-gateway/payments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "payments": [ { "payment_id": "pay_a1b2c3d4e5f6", "title": "Invoice #1234", "requested_amount": 49.99, "status": "paid", "accepted_options": [ { "asset_code": "USDC_SOL", "network": "solana", "deposit_address": "7xKXtg..." }, { "asset_code": "USDT_POL", "network": "polygon", "deposit_address": "0xAbCd..." } ], "asset_code": "USDC_SOL", "network": "solana", "settled_amount": 49.99, "external_reference": "order_abc123", "created_at": "2026-04-18T12:00:00Z" } ] } } ``` # Gateway Overview Source: https://docs.yativo.com/api-reference/payment-gateway/overview GET /v1/crypto-gateway/overview Get a summary of your payment gateway activity Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/crypto-gateway/overview' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "totals": { "pending_payments": 10, "paid_payments": 120, "paid_late": 5, "active_wallets": 3 }, "wallets": [ { "wallet_id": "6634abc...", "asset_code": "USDC_SOL", "network": "solana", "wallet_address": "7xKXtg...", "status": "available", "cooldown_until": null } ] } } ``` # Payment Status Source: https://docs.yativo.com/api-reference/payment-gateway/status GET /v1/crypto-gateway/pay/{paymentId}/status Check the status of a payment (public — no auth required) The payment ID returned when the payment intent was created. **Possible `status` values** | Status | Description | | ------------------------ | -------------------------------------------------------------- | | `awaiting_payment` | Waiting for the customer to send funds | | `monitoring_late_window` | Primary window closed; still accepting payment in grace period | | `paid` | Confirmed on-chain within the primary window | | `paid_late` | Confirmed on-chain during the late monitoring window | | `expired` | Monitoring window closed with no payment detected | | `cancelled` | Cancelled by the merchant | ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/crypto-gateway/pay/pay_a1b2c3d4e5f6/status' ``` ```json theme={null} { "success": true, "data": { "payment_id": "pay_a1b2c3d4e5f6", "title": "Invoice #1234", "requested_amount": 49.99, "status": "paid", "asset_code": "USDC_SOL", "network": "solana", "deposit_address": "7xKXtg...", "settled_amount": 49.99, "transaction_hash": "5K3pXa...", "late_payment": false, "payment_window_expires_at": "2026-04-18T13:00:00Z", "monitoring_ends_at": "2026-04-18T13:20:00Z", "confirmed_at": "2026-04-18T12:08:00Z" } } ``` # Batch Screen Source: https://docs.yativo.com/api-reference/screener/batch-check POST /v1/screener/batch-check Screen multiple blockchain addresses in one request No authentication required — this is a public endpoint. Array of blockchain addresses to screen. Maximum 100 addresses per request. ```bash theme={null} curl -X POST '/screener/batch-check' \ -H 'Content-Type: application/json' \ -d '{ "addresses": [ "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1" ] }' ``` ```json theme={null} { "success": true, "data": { "results": [ { "address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "risk_level": "low", "flagged": false }, { "address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "risk_level": "low", "flagged": false } ], "checked_at": "2026-04-01T12:00:00Z" } } ``` # Screen Address Source: https://docs.yativo.com/api-reference/screener/check POST /v1/screener/check Check a blockchain address against sanctions and risk databases No authentication required — this is a public endpoint. The blockchain address to screen. ```bash theme={null} curl -X POST '/screener/check' \ -H 'Content-Type: application/json' \ -d '{ "address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4" }' ``` ```json theme={null} { "success": true, "data": { "address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "risk_level": "low", "flagged": false, "checks": { "sanctions": false, "fraud": false, "darknet": false, "mixer": false }, "checked_at": "2026-04-01T12:00:00Z" } } ``` # Current Subscription Source: https://docs.yativo.com/api-reference/subscriptions/current GET /v1/subscription/current Get the current subscription status Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET '/subscription/current' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "tier_id": "tier_pro", "tier_name": "Pro", "status": "active", "auto_renew": true, "current_period_start": "2026-04-01T00:00:00Z", "current_period_end": "2026-05-01T00:00:00Z", "price_usd": 49, "features": { "rate_limit": 300, "wallets": 50, "api_keys": 10, "webhooks": 20 } } } ``` # List Plans Source: https://docs.yativo.com/api-reference/subscriptions/plans GET /v1/subscription/plans List all available subscription pricing tiers Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET '/subscription/plans' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "tiers": [ { "id": "tier_free", "name": "Free", "price_usd": 0, "billing_period": "monthly", "features": { "rate_limit": 60, "wallets": 5, "api_keys": 2, "webhooks": 3 } }, { "id": "tier_pro", "name": "Pro", "price_usd": 49, "billing_period": "monthly", "features": { "rate_limit": 300, "wallets": 50, "api_keys": 10, "webhooks": 20 } } ] } } ``` # Subscribe Source: https://docs.yativo.com/api-reference/subscriptions/subscribe POST /v1/subscription/subscribe Subscribe to a pricing tier Bearer token: `Bearer YOUR_ACCESS_TOKEN` The tier ID to subscribe to (e.g., `tier_pro`, `tier_enterprise`). ```bash theme={null} curl -X POST '/subscription/subscribe' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "tier_id": "tier_pro" }' ``` ```json theme={null} { "success": true, "message": "Subscription activated", "data": { "tier_id": "tier_pro", "tier_name": "Pro", "status": "active", "auto_renew": true, "current_period_start": "2026-04-01T00:00:00Z", "current_period_end": "2026-05-01T00:00:00Z" } } ``` # List Swap Assets Source: https://docs.yativo.com/api-reference/swap/assets GET /v1/swap/assets Retrieve all assets available for swapping Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/swap/assets' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": [ { "id": "ast_6615c3c3e55d9ff7bc0a9012", "name": "USD Coin (Solana)", "symbol": "USDC", "ticker_name": "USDC_SOL", "address": "7xKt3Bm4NZpQhsWn1YvJd2Lr8Pk5Cq9eAw6Fu0GiRHs", "chain": "SOL", "balance": "0.300000", "type": "user", "decimals": 6, "contract_address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" } ], "message": "User assets retrieved successfully" } ``` # Execute Swap Source: https://docs.yativo.com/api-reference/swap/execute POST /v1/swap/execute Execute a swap using a previously generated quote Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the quote to execute, obtained from the [Get Swap Quote](/api-reference/swap/quote) endpoint. Quotes expire after a short window. The asset ID of the source wallet to deduct funds from. The destination wallet address to receive the swapped tokens. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/swap/execute' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "quote_id": "qte_01HX9KZMB3F7VNQP8R2WDGT4EG", "from_asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4EA", "to_address": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b" }' ``` ```json theme={null} { "status": "success", "message": "Swap initiated successfully", "data": { "swap_id": "swp_01HX9KZMB3F7VNQP8R2WDGT4EH", "quote_id": "qte_01HX9KZMB3F7VNQP8R2WDGT4EG", "from_chain": "solana", "from_ticker": "USDC_SOL", "to_chain": "ethereum", "to_ticker": "USDC_ETH", "from_amount": "500.00", "to_amount": "497.25", "status": "pending", "from_tx_hash": "5KgF7hJ2mN4pQ8rT9vX1yC3bA6wD0eG2jL5nP8sU1z4", "created_at": "2026-03-26T12:00:00Z" } } ``` # Swap History Source: https://docs.yativo.com/api-reference/swap/history GET /v1/swap/history Retrieve the history of swap transactions Bearer token: `Bearer YOUR_ACCESS_TOKEN` Maximum number of swaps to return. Defaults to `20`. Number of records to skip for pagination. Defaults to `0`. Filter by swap status. One of: `pending`, `completed`, `failed`. ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/swap/history?limit=20&offset=0&status=completed' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} {"success": true, "data": []} ``` # Get Swap Quote Source: https://docs.yativo.com/api-reference/swap/quote POST /v1/swap/quote Get a price quote for a cross-chain or same-chain token swap Bearer token: `Bearer YOUR_ACCESS_TOKEN` The source asset identifier, e.g. `USDC_SOL`, `ETH`. The destination asset identifier, e.g. `USDC_ETH`, `MATIC`. The amount to swap in the source token's native units, e.g. `"100.00"`. The source wallet address. Optional — defaults to the user's wallet for the source asset. The destination wallet address. Optional — defaults to the user's wallet for the destination asset. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/swap/quote' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "sourceAsset": "USDC_SOL", "destinationAsset": "ETH_Base", "amount": "10", "destinationAddress": "0xAbCd1234EfGh5678IjKl9012MnOp3456QrSt7890" }' ``` ```json theme={null} { "success": true, "data": { "quoteId": "qt_abc123def456", "sourceAsset": "USDC_SOL", "destinationAsset": "ETH_Base", "inputAmount": "10", "estimatedOutput": "0.003812", "exchangeRate": "0.0003812", "fee": { "amount": "0.15", "currency": "USDC" }, "expiresAt": "2026-03-28T10:05:00.000Z" } } ``` # List Swap Routes Source: https://docs.yativo.com/api-reference/swap/routes GET /v1/swap/routes Retrieve all available swap routes between assets and chains Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/swap/routes' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "sources": [ {"ticker_name": "SOL", "asset_name": "Solana", "chain": "SOL"}, {"ticker_name": "USDC_SOL", "asset_name": "USD Coin (Solana)", "chain": "SOL"}, {"ticker_name": "ETH_Base", "asset_name": "Ethereum on Base", "chain": "Base"}, {"ticker_name": "EURe_GNO", "asset_name": "Euro Bridged (GNO)", "chain": "GNO"} ] }, "message": "Swap route catalog retrieved successfully" } ``` # Get Gas Fee Source: https://docs.yativo.com/api-reference/transactions/gas-fee POST /v1/transactions/get-gas-price Estimate the gas fee for a transaction on a given blockchain network Bearer token: `Bearer YOUR_ACCESS_TOKEN` The blockchain network to estimate gas for. One of: `ethereum`, `solana`, `bitcoin`, `polygon`, `bsc`, `base`, `arbitrum`, `optimism`, `xdc`. Transaction priority affecting confirmation speed and fee. One of: `slow`, `medium`, `fast`. Defaults to `medium`. Optional transaction amount in USD, used to calculate gas as a percentage of the transfer. Optional asset ID to get a fee estimate specific to that asset's token type. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/transactions/get-gas-price' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "chainType": "ETH", "priority": "low" }' ``` ```json theme={null} { "success": true, "data": { "estimatedFee": 0.00063, "gasFee": 0.00063, "platformFees": 0, "priority": "low", "chainType": "ETH", "breakdown": { "gas_cost_usd": "0.00063000", "platform_fees_usd": "0.00000000", "total_cost_usd": "0.00063000", "platform_fee_details": [] } } } ``` # Get Transaction Source: https://docs.yativo.com/api-reference/transactions/get POST /v1/transactions/get-transactions Retrieve details of a specific transaction by its ID Bearer token: `Bearer YOUR_ACCESS_TOKEN` The ID of the transaction to retrieve. Pass this as the `search` parameter to filter the results. This endpoint uses the same route as List Transactions. Pass the `search` field with a transaction ID or hash to retrieve a specific transaction. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/transactions/get-transactions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "search": "txn_01HX9KZMB3F7VNQP8R2WDGT4EF" }' ``` ```json theme={null} { "data": [ { "_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4EF", "user_id": "usr_6615c3a1e55d9ff7bc0a1234", "type": "send", "chain": "solana", "asset_name": "USDC", "amount": "50.00", "status": "confirmed", "transaction_hash": "4xKp9qLmKv3xFjNw4aBcYhUeT8sGkZoP2iMnDuWr5Cx", "createdAt": "2026-03-25T14:00:00Z" } ], "status": true, "message": "Transactions fetched successfully" } ``` # List Transactions Source: https://docs.yativo.com/api-reference/transactions/list POST /v1/transactions/get-transactions Retrieve a paginated list of transactions with optional filters Bearer token: `Bearer YOUR_ACCESS_TOKEN` Page number for pagination. Defaults to `1`. Number of transactions per page. Defaults to `20`, maximum `100`. Filter by transaction status. One of: `pending`, `confirmed`, `failed`, `cancelled`. Filter by blockchain network, e.g. `solana`, `ethereum`. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/transactions/get-transactions' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "page": 1, "limit": 20, "status": "confirmed", "chain": "solana" }' ``` ```json theme={null} { "data": [ { "_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4EF", "user_id": "usr_6615c3a1e55d9ff7bc0a1234", "type": "send", "chain": "solana", "asset_name": "USDC", "amount": "50.00", "status": "confirmed", "transaction_hash": "4xKp9qLmKv3xFjNw4aBcYhUeT8sGkZoP2iMnDuWr5Cx", "createdAt": "2026-03-25T14:00:00Z" } ], "status": true, "message": "Transactions fetched successfully" } ``` # Send Funds Source: https://docs.yativo.com/api-reference/transactions/send POST /v1/transactions/send-funds Send cryptocurrency from a wallet asset to an external address or another account Bearer token: `Bearer YOUR_ACCESS_TOKEN` Unique key to prevent duplicate transactions. Strongly recommended — if omitted, no deduplication is applied. Re-submit the same key to safely retry without double-spending. Keys expire after 24 hours. The MongoDB ObjectId of the **account** that owns the source asset. The MongoDB ObjectId of the **asset** (wallet) to send from. Returned when you [list account assets](/api-reference/assets/list). The destination blockchain address. Must be a valid address on the target chain. Amount to send, denominated in the token's native units (e.g. `100` for 100 USDC). The asset ticker / short name of the token being sent (e.g. `"ETH"`, `"USDC"`, `"SOL"`). Must match the asset record. The blockchain network (e.g. `"ethereum"`, `"solana"`, `"polygon"`). Must match the asset's chain. Transaction category for reporting and compliance. Common values: `"personal"`, `"business"`, `"payment"`, `"auto-forward"`, `"other"`. Gas / speed priority. One of: `"low"`, `"medium"`, `"high"`. Defaults to `"medium"`. Optional human-readable note attached to the transaction. When `true`, gas fees are paid from the sending wallet's own native token balance instead of a configured Gas Station. Only valid for native token assets (ETH, SOL, etc.). Defaults to `false`. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/transactions/send-funds' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: idem_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -d '{ "account": "64b1f9e2a3c4d5e6f7a8b9c0", "assets": "64b1f9e2a3c4d5e6f7a8b9d1", "receiving_address": "9xZ7Y4mQkLpR3sVwC8tF2bG6hJ5nM1yK", "amount": 100, "type": "USDC", "chain": "solana", "category": "payment", "priority": "medium", "description": "Invoice #1042 settlement" }' ``` ```typescript TypeScript theme={null} const tx = await client.transactions.sendFunds({ account: '64b1f9e2a3c4d5e6f7a8b9c0', assets: '64b1f9e2a3c4d5e6f7a8b9d1', receiving_address: '9xZ7Y4mQkLpR3sVwC8tF2bG6hJ5nM1yK', amount: 100, type: 'USDC', chain: 'solana', category: 'payment', priority: 'medium', description: 'Invoice #1042 settlement', }); ``` ```python Python theme={null} tx = client.transactions.send_funds( account='64b1f9e2a3c4d5e6f7a8b9c0', assets='64b1f9e2a3c4d5e6f7a8b9d1', receiving_address='9xZ7Y4mQkLpR3sVwC8tF2bG6hJ5nM1yK', amount=100, type='USDC', chain='solana', category='payment', priority='medium', description='Invoice #1042 settlement', ) ``` ```json 200 — Success theme={null} { "status": true, "message": "Transaction Created Successfully", "data": { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E5", "transaction_hash": "5KtMKNmZtEbXq3RrsPkjDqNJVA5rtzEPvR8WBa7kLnZm", "gas_tx_hash": null, "platform_fee_tx_hash": null, "gas_amount": "0", "platform_fee": "0.50000000", "gas_funding_markup": "0.12000000", "total_fee": "0.62000000", "fee_breakdown": "N/A" } } ``` ```json 400 — Validation error theme={null} { "status": false, "message": "Withdrawal amount must be greater than total fees. Amount: 0.5, Platform fee: 0.5, Gas funding fee: 0.12" } ``` ```json 400 — Self-funding on token theme={null} { "status": false, "message": "Self funding is only available for native token transactions. For USDC transactions on polygon, you need approximately 0.002 POL" } ``` ```json 403 — Account suspended theme={null} { "status": false, "message": "Account is suspended from withdrawals", "suspension": { "type": "withdrawal", "reason": "Compliance review", "expires_at": null } } ``` ```json 409 — Duplicate in-progress (idempotency) theme={null} { "success": false, "message": "Request is already being processed", "error": "DUPLICATE_REQUEST_IN_PROGRESS", "idempotencyKey": "payout_ORD-9821" } ``` ```json 500 — Transaction blocked (high-risk address) theme={null} { "status": false, "message": "Transaction blocked due to high-risk receiving address" } ``` ## Gas Funding When sending **token** assets (USDC, USDT, etc.) the platform automatically funds native gas from a configured Gas Station. A 20% service markup on the gas cost is deducted from your withdrawal amount as `gas_funding_markup`. | Scenario | Behaviour | | --------------------------------------------- | -------------------------------------------------------------------- | | Gas Station configured by user | Gas funded from user's gas station — `gas_funding_markup` applied | | No user Gas Station | Platform Gas Station used as fallback — `gas_funding_markup` applied | | `use_self_funding: true` (native tokens only) | Gas deducted from the wallet's own native balance — no markup | | `use_self_funding: true` on a token asset | Returns `400` — self-funding is not available for token transactions | Ensure `amount` is large enough to cover `platform_fee + gas_funding_markup`. The API returns a `400` if the amount cannot cover total fees. ## Idempotency Supply an `Idempotency-Key` header to enable safe retries. If the same key is submitted again for the same user, the original response is returned instead of creating a duplicate transaction. Without a key, no deduplication is applied. **Best practices:** * Derive the key from your internal record ID: `payout_${orderId}` * Keys must be unique per operation — reusing a key for a different transfer returns the original transaction * Keys expire after 24 hours Always verify `receiving_address` before sending. Blockchain transactions are irreversible — funds sent to the wrong address cannot be recovered. # Transaction Analytics Source: https://docs.yativo.com/api-reference/unified-transactions/analytics GET /v1/unified-transactions/analytics-with-fees Get aggregated transaction analytics with fee breakdowns Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET '/unified-transactions/analytics-with-fees' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "total_transactions": 450, "total_volume_usd": 125000.00, "total_fees_usd": 312.50, "by_type": { "deposit": { "count": 200, "volume": 80000, "fees": 0 }, "withdrawal": { "count": 100, "volume": 30000, "fees": 150 }, "swap": { "count": 80, "volume": 10000, "fees": 125 }, "card_transaction": { "count": 50, "volume": 3000, "fees": 22.50 }, "agentic_transaction": { "count": 20, "volume": 2000, "fees": 15 } }, "period": { "from": "2026-03-01T00:00:00Z", "to": "2026-04-01T00:00:00Z" } } } ``` # Download Export Source: https://docs.yativo.com/api-reference/unified-transactions/download GET /v1/unified-transactions/export/{exportId}/download Download a previously requested transaction export Bearer token: `Bearer YOUR_ACCESS_TOKEN` The export ID returned when the export was requested. ```bash theme={null} curl -X GET '/unified-transactions/export/exp_01abc123/download' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --output transactions.pdf ``` ```json theme={null} { "info": "Returns the file directly as application/pdf or text/csv depending on the export format. Save the response body to a file." } ``` # Export Transactions Source: https://docs.yativo.com/api-reference/unified-transactions/export POST /v1/unified-transactions/export Request a PDF or CSV export of transaction history Bearer token: `Bearer YOUR_ACCESS_TOKEN` Export format: `pdf` or `csv`. Start date filter (ISO 8601 date, e.g., `2026-03-01`). End date filter (ISO 8601 date, e.g., `2026-03-31`). Filter by transaction types. If omitted, all types are included. ```bash theme={null} curl -X POST '/unified-transactions/export' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "format": "pdf", "date_from": "2026-03-01", "date_to": "2026-03-31", "types": ["deposit", "withdrawal", "swap"] }' ``` ```json theme={null} { "success": true, "data": { "export_id": "exp_01abc123", "format": "pdf", "status": "processing", "filters": { "date_from": "2026-03-01", "date_to": "2026-03-31", "types": ["deposit", "withdrawal", "swap"] }, "created_at": "2026-04-01T12:00:00Z" } } ``` Export files are available for download for **24 hours** after generation. Use the [Download Export](/api-reference/unified-transactions/download) endpoint to retrieve the file. # Get Transaction Source: https://docs.yativo.com/api-reference/unified-transactions/get GET /v1/unified-transactions/{transaction_id} Get details of a unified transaction Bearer token: `Bearer YOUR_ACCESS_TOKEN` The unified transaction ID. ```bash theme={null} curl -X GET '/unified-transactions/utx_01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "transaction_id": "utx_01abc123", "type": "deposit", "status": "completed", "amount": "500.00", "asset": "USDC", "chain": "solana", "from_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", "to_address": "GY1EZGdpiJNyx2BSKq8rfTDRe5K8Bb6Cf2Bn1pdmE2o1", "tx_hash": "5xYz...", "block_number": 250000000, "confirmations": 32, "fee_amount": "0.00", "fee_asset": "USDC", "source_reference": { "type": "blockchain", "id": "5xYz..." }, "created_at": "2026-03-26T10:00:00Z", "completed_at": "2026-03-26T10:00:30Z" } } ``` # List Unified Transactions Source: https://docs.yativo.com/api-reference/unified-transactions/list GET /v1/unified-transactions/list List all transactions across all types in a single unified view Bearer token: `Bearer YOUR_ACCESS_TOKEN` Page number. Defaults to 1. Results per page. Defaults to 20. Filter by transaction type: `deposit`, `withdrawal`, `swap`, `fee`, `auto_forwarding`, `card_transaction`, `iban_transfer`, `gateway_payment`, `agentic_transaction`. Filter by status: `pending`, `processing`, `completed`, `failed`. ```bash theme={null} curl -X GET '/unified-transactions/list?page=1&limit=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "success": true, "data": { "transactions": [ { "transaction_id": "utx_01abc123", "type": "deposit", "status": "completed", "amount": "500.00", "asset": "USDC", "chain": "solana", "from_address": "7xKXtg2CW87d...", "to_address": "GY1EZGdpiJNyx...", "tx_hash": "5xYz...", "fee_amount": "0.00", "created_at": "2026-03-26T10:00:00Z" }, { "transaction_id": "utx_02def456", "type": "card_transaction", "status": "completed", "amount": "25.99", "asset": "EUR", "service_data": { "merchant_name": "Amazon", "card_last_four": "4242" }, "created_at": "2026-03-26T11:00:00Z" } ], "pagination": { "page": 1, "limit": 20, "total": 150 } } } ``` # Create Webhook Source: https://docs.yativo.com/api-reference/webhooks/create POST /v1/webhook/create-webhook Register a webhook endpoint to receive real-time event notifications Bearer token: `Bearer YOUR_ACCESS_TOKEN` The HTTPS URL that will receive webhook POST requests. Array of event slugs to subscribe to. Pass `["*"]` (or omit) to receive all events. Includes both general crypto events and card issuer events. Example slugs: * `deposit.detected` * `deposit.confirmed` * `transaction.failed` * `card.created` * `transaction.authorized` * `transaction.settled` * `customer.funded` * `master_wallet.deposit` A human-readable name for this webhook. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/webhook/create-webhook' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "url": "https://your-app.com/webhooks/yativo", "events": ["deposit.detected", "deposit.confirmed", "transaction.failed", "transaction.authorized", "transaction.settled", "customer.funded"], "description": "Production webhook" }' ``` ```json theme={null} { "status": true, "message": "Webhook created successfully", "data": { "webhook_id": "68241abc2f3d4e5f6a7b8c9d", "url": "https://your-app.com/webhooks/yativo", "events": ["deposit.detected", "deposit.confirmed", "transaction.failed", "transaction.authorized", "transaction.settled", "customer.funded"], "secret": "whsec_a8f3c2e1d4b7f9e2c5a3b6d8f1e4c7a2b5d8e1f4c7a2b5d8", "created_at": "2026-03-28T10:00:00.000Z" } } ``` # List Webhooks Source: https://docs.yativo.com/api-reference/webhooks/list GET /v1/webhook/get-webhooks Retrieve all registered webhook endpoints Bearer token: `Bearer YOUR_ACCESS_TOKEN` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/webhook/get-webhooks' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "data": { "webhooks": [ { "_id": "whk_67e91cbe7747bdb0ba25415f", "webhook_name": "Production Webhook", "webhook_url": "https://your-app.com/webhooks/yativo", "account_id": "acc_6615c3b2e55d9ff7bc0a5678", "user_id": "usr_6615c3a1e55d9ff7bc0a1234", "version_id": "1", "receive_all_events": "true", "whitelist_ips": [], "status": "active", "createdAt": "2026-01-30T10:28:14.829Z", "updatedAt": "2026-03-28T10:04:41.998Z" } ], "pagination": {"total": 1, "page": 1, "limit": 20, "pages": 1} }, "status": true, "message": "Webhooks retrieved successfully" } ``` # Chrome Extension Source: https://docs.yativo.com/extensions/chrome Yativo Crypto Chrome extension — coming soon # Chrome Extension The Yativo Crypto Chrome extension is currently in development and is not yet available in the Chrome Web Store. [Join the beta list](mailto:support@yativo.com) to be notified when it launches. The Chrome extension will add a persistent toolbar button giving you instant access to your wallets, cards, swap, and deposit notifications — powered by Manifest v3. ## Planned Features * **Wallet monitoring** — view balances for all your Yativo wallets * **Deposit notifications** — real-time alerts via background service worker * **Card management** — view, freeze, and unfreeze virtual cards * **Price alerts** — SOL and XDC threshold notifications * **Swap** — execute swaps directly from the popup ## Compatibility Will support Chrome 88+ and all Chromium-based browsers (Brave, Edge, Arc). *** Check the [Browser Extensions overview](/extensions/overview) for launch updates. # Firefox Extension Source: https://docs.yativo.com/extensions/firefox Yativo Crypto Firefox extension — coming soon # Firefox Extension The Yativo Crypto Firefox extension is currently in development and is not yet available on Firefox Add-ons (AMO). [Join the beta list](mailto:support@yativo.com) to be notified when it launches. The Firefox extension will provide the same feature set as the Chrome extension — wallet monitoring, real-time deposit notifications, card management, price alerts, and swap — powered by Manifest v3. ## Planned Features * **Wallet monitoring** — view balances for all your Yativo wallets * **Deposit notifications** — real-time alerts via background service worker * **Card management** — view, freeze, and unfreeze virtual cards * **Price alerts** — SOL and XDC threshold notifications * **Swap** — execute swaps directly from the popup ## Compatibility Will require Firefox 128 or later. Desktop and Firefox for Android. *** Check the [Browser Extensions overview](/extensions/overview) for launch updates. # Browser Extensions Source: https://docs.yativo.com/extensions/overview Yativo Crypto browser extensions for Chrome and Firefox — coming soon # Browser Extensions The Yativo Crypto browser extensions are currently in development and will be available soon. Stay tuned for updates. The Yativo browser extensions will bring your crypto dashboard directly into your browser toolbar. Monitor wallet balances, receive real-time deposit notifications, manage virtual cards, set price alerts, and execute swaps — without leaving your current tab. Coming soon — Chrome Web Store. Built on Manifest v3. Coming soon — Firefox Add-ons (AMO). Built on Manifest v3. *** ## Planned Features ### Wallet Monitoring View all your Yativo wallet balances at a glance directly from the browser popup. ### Real-Time Deposit Notifications Receive instant browser notifications the moment a new deposit arrives on any monitored wallet. ### Yativo Card Management View card details, check balances, see recent transactions, and freeze or unfreeze cards from the popup. ### Price Alerts Set threshold-based alerts for supported assets. Get notified when prices cross your target. ### Swap Get a live quote and execute a swap between supported assets without navigating away from your page. *** Want early access? [Contact us](mailto:support@yativo.com) to join the beta list. # Generate Token Source: https://docs.yativo.com/fiat-api-reference/auth/token Authenticate and obtain a Bearer token for API access Generate an access token by providing your Account ID and App Secret. The token is required for all subsequent API requests. ``` POST /auth/login ``` Tokens expire after **600 seconds** (10 minutes). Refresh before expiry using `GET /auth/refresh-token`. ## Request body Your Yativo Account ID. Found in your dashboard under Settings → Account. Your App Secret generated from Dashboard → Developer → API Key. Keep this confidential and never expose it in client-side code. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/auth/login' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "your-account-id", "app_secret": "your-app-secret" }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ account_id: process.env.YATIVO_ACCOUNT_ID, app_secret: process.env.YATIVO_APP_SECRET, }), }); const { data } = await response.json(); const token = data.access_token; ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Authentication successful", "data": { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...", "token_type": "bearer", "expires_in": 600 } } ``` ```json Unauthorized theme={null} { "status": "error", "status_code": 401, "message": "Invalid credentials", "data": null } ``` *** ## Refresh Token Refresh an expiring token without re-authenticating with your credentials: ``` GET /auth/refresh-token ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/auth/refresh-token' \ -H 'Authorization: Bearer YOUR_CURRENT_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...", "expires_in": 600 } } ``` # Archive Beneficiary Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/archive Archive a beneficiary to hide them from active lists without deleting Archive a beneficiary. Archived beneficiaries are retained in the system and can be restored at any time using the unarchive endpoint. Use this instead of deleting when you may need to reference the beneficiary again in the future. ``` PUT /v1/beneficiaries/{id}/archive ``` Requires an `Idempotency-Key` header. ## Path parameters The ID of the beneficiary to archive. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/beneficiaries/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d/archive' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "message": "Beneficiary archived successfully" } ``` # Create Beneficiary Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/create Create a new beneficiary for sending payments Create a beneficiary record to store recipient information for future payouts. After creating a beneficiary, add their payment method details using the payment methods endpoint. ``` POST /v1/beneficiaries ``` Requires an `Idempotency-Key` header. ## Request body Beneficiary type: `"individual"` or `"business"`. Full name of the beneficiary (individual) or legal business name. Beneficiary's email address. Beneficiary's physical address. Beneficiary's country code (e.g. `CHL`, `MEX`, `BRA`). A short label for this beneficiary. Defaults to `customer_name` if omitted. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "recipient_type": "individual", "customer_name": "Maria Gonzalez", "customer_email": "maria.gonzalez@example.com", "customer_address": "123 Main Street, Santiago", "country": "CHL", "customer_nickname": "Maria" }' ``` ```json Success theme={null} { "status": "success", "data": { "id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "user_id": "usr-001", "recipient_type": "individual", "customer_name": "Maria Gonzalez", "customer_email": "maria.gonzalez@example.com", "customer_nickname": "Maria", "country": "CHL", "customer_address": "123 Main Street, Santiago", "is_archived": false, "created_at": "2026-04-02T10:00:00.000000Z", "updated_at": "2026-04-02T10:00:00.000000Z" } } ``` # Delete Beneficiary Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/delete Permanently delete a beneficiary record Delete a beneficiary and all their associated payment methods. This action is irreversible. ``` DELETE /v1/beneficiaries/{id} ``` ## Path parameters The ID of the beneficiary to delete. Deleting a beneficiary is permanent and cannot be undone. All associated payment methods will also be deleted. Consider archiving instead if you may need to reference this beneficiary later. ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/beneficiaries/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "message": "Beneficiary deleted successfully" } ``` # Get Beneficiary Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/get Retrieve details for a specific beneficiary Returns full details for a specific beneficiary. ``` GET /v1/beneficiaries/{id} ``` ## Path parameters The ID of the beneficiary to retrieve. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/beneficiaries/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": { "id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "user_id": "usr-001", "recipient_type": "individual", "customer_name": "Maria Gonzalez", "customer_email": "maria.gonzalez@example.com", "customer_nickname": "Maria", "country": "CHL", "customer_address": "123 Main Street, Santiago", "is_archived": false, "created_at": "2026-04-02T10:00:00.000000Z", "updated_at": "2026-04-02T10:00:00.000000Z" } } ``` # List Beneficiaries Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/list Retrieve all saved beneficiaries in your account Returns a paginated list of all beneficiaries associated with your account. ``` GET /v1/beneficiaries/list ``` ## Query parameters Number of records per page (default: 20). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/beneficiaries/list?per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/beneficiaries/list?per_page=20', { headers: { 'Authorization': `Bearer ${token}` }, }); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "data": [ { "id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "user_id": "usr-001", "recipient_type": "individual", "customer_name": "Maria Gonzalez", "customer_email": "maria.gonzalez@example.com", "customer_nickname": "Maria", "country": "CHL", "customer_address": "123 Main Street, Santiago", "is_archived": false, "created_at": "2026-04-02T10:00:00.000000Z", "updated_at": "2026-04-02T10:00:00.000000Z" }, { "id": "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e", "user_id": "usr-001", "recipient_type": "business", "customer_name": "Tech Solutions SA", "customer_email": "payments@techsolutions.mx", "customer_nickname": "Tech Solutions", "country": "MEX", "customer_address": "789 Reforma Ave, Mexico City", "is_archived": false, "created_at": "2026-03-20T09:00:00.000000Z", "updated_at": "2026-03-20T09:00:00.000000Z" } ], "pagination": { "total": 45, "per_page": 20, "current_page": 1, "last_page": 3, "next_page_url": "https://api.yativo.com/api/v1/beneficiaries/list?page=2", "prev_page_url": null } } ``` # Add Payment Method Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/payment-methods-create Add a payment method (bank account, wallet) to a beneficiary Add a payment method to a beneficiary. The structure of the `payment_data` object varies by payment method type — retrieve the required fields for a specific payout method from the payout methods endpoint. ``` POST /v1/beneficiaries/payment-methods ``` Requires an `Idempotency-Key` header. ## Request body The ID of the payout method (gateway) to use. Obtain available IDs from the payout methods endpoint. Key/value pairs of account details required for this payment method. The fields vary depending on the selected `gateway_id`. Currency code for this payment method (e.g. `CLP`, `MXN`, `BRL`). A label to identify this payment method. The ID of the beneficiary to link this payment method to. ## Payment data examples ```json theme={null} { "account_number": "12345678", "bank_code": "001", "account_type": "checking", "rut": "12.345.678-9" } ``` ```json theme={null} { "clabe": "012345678901234567" } ``` ```json theme={null} { "account_number": "12345-6", "branch_number": "0001", "bank_code": "341", "account_type": "checking", "cpf": "123.456.789-00" } ``` ```bash cURL — Chile Bank Transfer theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: pm-create-001' \ -d '{ "gateway_id": 42, "currency": "CLP", "nickname": "Maria CLP Account", "beneficiary_id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "payment_data": { "account_number": "12345678", "bank_code": "001", "account_type": "checking", "rut": "12.345.678-9" } }' ``` ```bash cURL — Mexico SPEI theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: pm-create-001' \ -d '{ "gateway_id": 15, "currency": "MXN", "nickname": "Tech Solutions SPEI", "beneficiary_id": "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e", "payment_data": { "clabe": "012345678901234567" } }' ``` ```json Success theme={null} { "status": "success", "data": { "id": "pm-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "user_id": "usr-001", "gateway_id": 42, "currency": "CLP", "nickname": "Maria CLP Account", "payment_data": { "account_number": "12345678", "bank_code": "001", "account_type": "checking", "rut": "12.345.678-9" }, "beneficiary_id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "created_at": "2026-04-02T10:30:00.000000Z", "updated_at": "2026-04-02T10:30:00.000000Z" } } ``` # Delete Payment Method Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/payment-methods-delete Remove a saved payment method from a beneficiary Permanently delete a saved payment method. This action is irreversible. ``` DELETE /v1/beneficiaries/payment-methods/delete/{id} ``` ## Path parameters The ID of the beneficiary payment method to delete. Deleting a payment method is permanent and cannot be undone. ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/beneficiaries/payment-methods/delete/pm-a1b2c3d4-e5f6-7890-abcd-ef1234567890' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "message": "Record deleted successfully" } ``` # List Payment Methods Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/payment-methods-list Retrieve all saved payment methods across all beneficiaries Returns all payment methods saved for beneficiaries in your account. ``` GET /v1/beneficiaries/payment-methods/all ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/beneficiaries/payment-methods/all' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": [ { "id": "pm-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "user_id": "usr-001", "gateway_id": 42, "currency": "CLP", "nickname": "Maria CLP Account", "payment_data": { "account_number": "12345678", "bank_code": "001", "account_type": "checking" }, "beneficiary_id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "created_at": "2026-04-02T10:30:00.000000Z", "updated_at": "2026-04-02T10:30:00.000000Z" }, { "id": "pm-b2c3d4e5-f6a7-8901-bcde-f12345678901", "user_id": "usr-001", "gateway_id": 15, "currency": "MXN", "nickname": "Tech Solutions SPEI", "payment_data": { "clabe": "012345678901234567" }, "beneficiary_id": "8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e", "created_at": "2026-03-20T09:30:00.000000Z", "updated_at": "2026-03-20T09:30:00.000000Z" } ] } ``` # Update Payment Method Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/payment-methods-update Update a saved beneficiary payment method Update an existing beneficiary payment method. All required fields must be provided — this is a full replacement of the payment method record. ``` PUT /v1/beneficiaries/payment-methods/update/{id} ``` Requires an `Idempotency-Key` header. ## Path parameters The ID of the beneficiary payment method to update. ## Request body The ID of the payout method (gateway). Currency code for this payment method (e.g. `CLP`, `MXN`, `BRL`). Updated key/value pairs of account details. Must include all fields required by the selected gateway. A label to identify this payment method. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/beneficiaries/payment-methods/update/pm-a1b2c3d4-e5f6-7890-abcd-ef1234567890' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: pm-update-001' \ -d '{ "gateway_id": 42, "currency": "CLP", "nickname": "Maria Savings Account", "payment_data": { "account_number": "98765432", "bank_code": "014", "account_type": "savings", "rut": "12.345.678-9" } }' ``` ```json Success theme={null} { "status": "success", "data": { "id": "pm-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "user_id": "usr-001", "gateway_id": 42, "currency": "CLP", "nickname": "Maria Savings Account", "payment_data": { "account_number": "98765432", "bank_code": "014", "account_type": "savings", "rut": "12.345.678-9" }, "beneficiary_id": "7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "created_at": "2026-04-02T10:30:00.000000Z", "updated_at": "2026-04-02T15:00:00.000000Z" } } ``` # Unarchive Beneficiary Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/unarchive Restore an archived beneficiary to active status Restore an archived beneficiary, making them active again. After unarchiving, the beneficiary will appear in list responses and can be used for payouts. ``` PUT /v1/beneficiaries/{id}/unarchive ``` Requires an `Idempotency-Key` header. ## Path parameters The ID of the beneficiary to unarchive. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/beneficiaries/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d/unarchive' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "message": "Beneficiary unarchived successfully" } ``` # Update Beneficiary Source: https://docs.yativo.com/fiat-api-reference/beneficiaries/update Replace all profile fields on an existing beneficiary Fully replace a beneficiary's profile information. This is a **full replacement** — all required fields must be included in every request. Omitting a required field will overwrite it with an empty or default value. ``` PUT /v1/beneficiaries/{id} ``` Requires an `Idempotency-Key` header. ## Path parameters The ID of the beneficiary to update. ## Request body Beneficiary type: `"individual"` or `"business"`. Full name of the beneficiary (individual) or legal business name. Beneficiary's email address. Beneficiary's physical address. Beneficiary's country code (e.g. `CHL`, `MEX`, `BRA`). A short label for this beneficiary. Defaults to `customer_name` if omitted. This endpoint performs a **full replacement**. You must send all required fields on every call, not just the fields you want to change. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/beneficiaries/7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "recipient_type": "individual", "customer_name": "Maria Gonzalez", "customer_email": "maria.g@newemail.com", "customer_address": "456 New Street, Santiago", "country": "CHL", "customer_nickname": "Maria G" }' ``` ```json Success theme={null} { "message": "Beneficiary updated successfully" } ``` # Create Customer Source: https://docs.yativo.com/fiat-api-reference/customers/create Create a new customer profile for an individual or business Create a customer record before initiating any KYC verification or payments for that customer. ``` POST /customer ``` Requires an `Idempotency-Key` header. ## Request body Full name of the customer (individual) or legal business name (business). Customer's email address. Must be unique per account. Customer's phone number in E.164 format (e.g. `+15551234567`). Customer's country of residence in ISO 3166-1 alpha-3 format (e.g. `USA`, `BRA`, `MEX`). Customer type: `"individual"` or `"business"`. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: create-customer-alex-smith-001' \ -d '{ "customer_name": "Alex Smith", "customer_email": "alex.smith@example.com", "customer_phone": "+15551234567", "customer_country": "USA", "customer_type": "individual" }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Customer created successfully", "data": { "id": 1, "customer_id": "c586066b-0f29-468f-b775-15483871a202", "customer_name": "Alex Smith", "customer_email": "alex.smith@example.com", "customer_phone": "+15551234567", "customer_country": "USA", "customer_type": "individual", "customer_status": "active", "created_at": "2026-04-02T10:00:00.000000Z", "updated_at": "2026-04-02T10:00:00.000000Z" } } ``` ```json Validation Error theme={null} { "status": "error", "status_code": 422, "message": "Validation failed", "errors": { "customer_email": ["The customer email has already been taken."] } } ``` # Get Customer Source: https://docs.yativo.com/fiat-api-reference/customers/get Retrieve a customer's profile, optionally embedding related data with the include parameter Returns a customer's profile. By default only core profile fields are returned. Use the `include` query parameter to embed related data — deposits, payouts, virtual accounts, virtual cards, and/or crypto wallets — in the same response. ``` GET /customer/{customer_id} ``` ## Path parameters The UUID of the customer to retrieve. ## Query parameters Comma-separated list of relations to embed in the response. | Value | Embeds | | ----------------- | -------------------------------- | | `deposits` | `customer_deposit` array | | `payouts` | `customer_payouts` array | | `virtualaccounts` | `customer_virtualaccounts` array | | `virtual_cards` | `customer_virtual_cards` array | | `crypto_wallets` | `customer_crypto_wallets` array | | `all` | All of the above | Multiple values can be combined: `?include=deposits,payouts` ```bash All relations theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/c586066b-0f29-468f-b775-15483871a202?include=all' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Specific relations theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/c586066b-0f29-468f-b775-15483871a202?include=deposits,virtualaccounts' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Profile only theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/c586066b-0f29-468f-b775-15483871a202' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success (?include=all) theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "customer_id": "c586066b-0f29-468f-b775-15483871a202", "customer_name": "Alex Smith", "customer_email": "alex.smith@example.com", "customer_phone": "+15551234567", "customer_country": "USA", "customer_type": "individual", "customer_status": "active", "customer_kyc_status": "approved", "kyc_verified_date": "2026-04-02T12:00:00.000000Z", "created_at": "2026-04-02T10:00:00.000000Z", "customer_deposit": [ { "transaction_id": "txn_xxxxxx", "transaction_amount": "500.00", "transaction_currency": "USD", "transaction_status": "Complete", "transaction_purpose": "Top-up", "created_at": "2026-04-03T08:00:00.000000Z" } ], "customer_payouts": [ { "transaction_id": "txn_yyyyyy", "transaction_amount": "200.00", "transaction_currency": "USD", "transaction_payout_details": { "status": "Complete" }, "created_at": "2026-04-04T09:00:00.000000Z" } ], "customer_virtualaccounts": [ { "account_id": "va-001", "currency": "USD", "account_number": "8881234567", "routing_number": "021000021", "status": "active" } ], "customer_virtual_cards": [], "customer_crypto_wallets": [] } } ``` ```json Profile only (no include) theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "customer_id": "c586066b-0f29-468f-b775-15483871a202", "customer_name": "Alex Smith", "customer_email": "alex.smith@example.com", "customer_phone": "+15551234567", "customer_country": "USA", "customer_type": "individual", "customer_status": "active", "customer_kyc_status": "approved", "kyc_verified_date": "2026-04-02T12:00:00.000000Z", "created_at": "2026-04-02T10:00:00.000000Z" } } ``` ```json Not Found theme={null} { "status": "error", "status_code": 404, "message": "Customer not found", "data": null } ``` The `include` parameter is **additive** — keys for un-requested relations are omitted from the response entirely. This keeps response payloads lean when you only need specific data. # List Customers Source: https://docs.yativo.com/fiat-api-reference/customers/list Retrieve a paginated list of all customers in your account Returns all customers associated with your account, with support for filtering and pagination. ``` GET https://api.yativo.com/api/v1/customer ``` ## Query parameters Number of records per page (default: 20). Filter by email (partial match). Filter by ISO 3166-1 alpha-3 country code (e.g. `"USA"`, `"BRA"`). Filter by KYC status. Filter by KYC approval status. Pass `"true"` or `"false"`. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer?per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/customer?per_page=20', { headers: { 'Authorization': `Bearer ${token}` }, }); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "data": [ { "id": 1, "customer_id": "c586066b-0f29-468f-b775-15483871a202", "customer_name": "Alex Smith", "customer_email": "alex.smith@example.com", "customer_phone": "+15551234567", "customer_country": "USA", "customer_type": "individual", "customer_status": "active", "created_at": "2026-04-02T10:00:00.000000Z", "updated_at": "2026-04-02T10:00:00.000000Z" }, { "id": 2, "customer_id": "d47f8a2b-1c3e-4f5a-9b8c-7d6e5f4a3b2c", "customer_name": "Acme Corporation LLC", "customer_email": "compliance@acme.com", "customer_phone": "+13055559876", "customer_country": "USA", "customer_type": "business", "customer_status": "active", "created_at": "2026-03-15T08:30:00.000000Z", "updated_at": "2026-03-15T08:30:00.000000Z" } ], "pagination": { "total": 42, "per_page": 20, "current_page": 1, "last_page": 3, "next_page_url": "https://api.yativo.com/api/v1/customer?page=2", "prev_page_url": null } } ``` # Update Customer Source: https://docs.yativo.com/fiat-api-reference/customers/update Update an existing customer's profile information Update a customer record. This is a **full replacement** — all required fields must be provided, even if you are only changing one of them. ``` PUT https://api.yativo.com/api/v1/customer/{customer_id} ``` Requires an `Idempotency-Key` header. ## Path parameters The UUID of the customer to update. ## Request body Full name of the customer (individual) or legal business name (business). Customer's email address. Customer's phone number. Customer's country in ISO 3166-1 alpha-3 format (e.g. `USA`, `BRA`, `MEX`). Customer's address details. The customer ID. Must match an existing customer record. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/customer/c586066b-0f29-468f-b775-15483871a202' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: update-customer-alex-smith-002' \ -d '{ "customer_id": "c586066b-0f29-468f-b775-15483871a202", "customer_name": "Alex Smith", "customer_email": "alex.smith@example.com", "customer_phone": "+15559876543", "customer_country": "USA", "customer_address": { "street": "123 Main St", "city": "New York", "state": "NY", "postal_code": "10001" } }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Customer updated successfully", "data": { "id": 1, "customer_id": "c586066b-0f29-468f-b775-15483871a202", "customer_name": "Alex Smith", "customer_email": "alex.smith@example.com", "customer_phone": "+15559876543", "customer_country": "USA", "customer_type": "individual", "customer_status": "active", "created_at": "2026-04-02T10:00:00.000000Z", "updated_at": "2026-04-02T14:00:00.000000Z" } } ``` # Create Deposit (Payin) Source: https://docs.yativo.com/fiat-api-reference/deposits/create Initiate an incoming payment using a payin gateway Initiate a customer deposit via a supported payin gateway. Optionally pass a `quote_id` from `POST /exchange-rate` to lock the rate and amount before redirecting the customer. ``` POST https://api.yativo.com/api/v1/wallet/deposits/new ``` Requires `Idempotency-Key` header. Retrieve available gateways and their IDs with `GET /payment-methods/payin?country={iso2}`. ## Request body The payin gateway ID. Get valid IDs from `GET /payment-methods/payin?country={iso2}`. The wallet currency to credit (e.g. `"USD"`, `"BRL"`). Must match one of the gateway's supported base currencies. Amount to deposit in the local (payin) currency. Required if `quote_id` is not provided. If `quote_id` is present, the amount is taken from the quote. A quote ID from `POST /exchange-rate` (created with `method_type: "payin"`). When supplied, the locked amount and rate from the quote are used — `amount` is ignored. URL to redirect the customer to after completing the payment on the gateway's hosted page. ```bash cURL — with quote_id theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/deposits/new' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: deposit-001' \ -d '{ "gateway": 20, "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "currency": "USD", "redirect_url": "https://your-app.com/deposit/complete" }' ``` ```bash cURL — without quote_id theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/deposits/new' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: deposit-002' \ -d '{ "gateway": 15, "amount": 1000, "currency": "BRL", "redirect_url": "https://your-app.com/deposit/complete" }' ``` ```javascript Node.js theme={null} // Step 1: Create a payin quote const quoteRes = await fetch('https://api.yativo.com/api/v1/exchange-rate', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ from_currency: 'BRL', to_currency: 'USD', method_id: 15, method_type: 'payin', amount: 1000, }), }); const { data: quote } = await quoteRes.json(); // Step 2: Initiate the deposit const depositRes = await fetch('https://api.yativo.com/api/v1/wallet/deposits/new', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `deposit-${Date.now()}`, }, body: JSON.stringify({ gateway: 15, quote_id: quote.quote_id, currency: 'USD', redirect_url: 'https://your-app.com/deposit/complete', }), }); const deposit = await depositRes.json(); // Redirect customer to deposit.data.deposit_url ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "id": "dep-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "gateway": 15, "deposit_currency": "BRL", "amount": 1000.00, "receive_amount": 9.36, "currency_to": "USD", "status": "pending", "deposit_url": "https://checkout.yativo.com/pay/dep-a1b2c3d4", "transaction_id": "txn-2026060101", "created_at": "2026-06-01T10:00:00.000000Z" } } ``` ```json Expired quote theme={null} { "status": "error", "status_code": 400, "message": "Quote has expired. Please generate a new quote." } ``` ```json Invalid gateway theme={null} { "status": "error", "status_code": 404, "message": "Payment gateway not found" } ``` ```json Below minimum theme={null} { "status": "error", "status_code": 400, "message": "Minimum deposit amount is 5 BRL" } ``` ```json Validation error theme={null} { "status": "error", "status_code": 422, "message": "Request failed", "data": { "gateway": ["The gateway field is required."], "currency": ["The currency field is required."] } } ``` After a successful response, redirect the customer to `deposit_url` to complete payment on the gateway's hosted page. Once completed, the customer is returned to your `redirect_url` and a `deposit.completed` webhook fires. # List Deposits Source: https://docs.yativo.com/fiat-api-reference/deposits/list Retrieve all deposit records for your account Returns a list of all payin deposits received into your wallets and virtual accounts. ``` GET https://api.yativo.com/api/v1/wallet/deposits ``` ## Query parameters Page number for pagination (default: 1). Records per page (default: 15). Filter by payment gateway ID. Filter by currency code, e.g. `"PEN"`, `"BRL"`. Filter by customer ID. Filter by start date (`YYYY-MM-DD`). Filter by end date (`YYYY-MM-DD`). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/deposits?page=1&per_page=15' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/wallet/deposits', { headers: { 'Authorization': `Bearer ${token}` }, }); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": "dep-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "gateway": 12, "deposit_currency": "PEN", "amount": 500.00, "receive_amount": 9.36, "currency_to": "USD", "status": "completed", "transaction_id": "txn-2026040201", "created_at": "2026-04-02T09:30:00.000000Z", "updated_at": "2026-04-02T09:32:00.000000Z" }, { "id": "dep-b2c3d4e5-f6a7-8901-bcde-fg2345678901", "gateway": 15, "deposit_currency": "BRL", "amount": 1200.00, "receive_amount": 230.00, "currency_to": "USD", "status": "completed", "transaction_id": "txn-2026040202", "created_at": "2026-04-01T14:00:00.000000Z", "updated_at": "2026-04-01T14:05:00.000000Z" } ], "pagination": { "total": 28, "per_page": 15, "current_page": 1, "last_page": 2, "next_page_url": "https://api.yativo.com/api/v1/wallet/deposits?page=2", "prev_page_url": null } } ``` # Get Event Source: https://docs.yativo.com/fiat-api-reference/developer/event-get Retrieve the full payload of a specific webhook event Returns complete details and payload for a specific event. ``` GET /business/events/show/{id} ``` ## Path Parameters The event ID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/events/show/evt_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "id": "evt_01HX9KZMB3F7VNQP8R2WDGT4E5", "event_type": "virtual_account.deposit", "status": "delivered", "webhook_url": "https://your-app.com/webhooks/yativo", "payload": { "event.type": "virtual_account.deposit", "payload": { "amount": 1000, "currency": "BRL", "status": "completed", "credited_amount": 950, "transaction_id": "TXNMP2HK81BHJ", "customer": { "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "customer_name": "Jane Doe" } } }, "delivered_at": "2026-04-01T10:00:01.000000Z", "created_at": "2026-04-01T10:00:00.000000Z" } } ``` # Events Source: https://docs.yativo.com/fiat-api-reference/developer/events Retrieve all webhook events sent by Yativo Returns a log of all events sent to your configured webhook endpoint. ``` GET /business/events/all ``` ## Query Parameters Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/events/all?per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": "evt_01HX9KZMB3F7VNQP8R2WDGT4E5", "event_type": "virtual_account.deposit", "status": "delivered", "webhook_url": "https://your-app.com/webhooks/yativo", "created_at": "2026-04-01T10:00:00.000000Z" }, { "id": "evt_01HX9KZMB3F7VNQP8R2WDGT4E4", "event_type": "customer.kyc.approved", "status": "delivered", "webhook_url": "https://your-app.com/webhooks/yativo", "created_at": "2026-04-01T09:30:00.000000Z" } ], "pagination": { "total": 58, "per_page": 20, "current_page": 1, "last_page": 3, "next_page_url": "https://api.yativo.com/api/v1/business/events/all?page=2", "prev_page_url": null } } ``` # Generate API Secret Source: https://docs.yativo.com/fiat-api-reference/developer/generate-secret Generate a new App Secret for API authentication Generate a new App Secret for your account. A 4-digit transaction PIN must be verified before calling this endpoint. ``` GET /generate-secret ``` Generating a new secret immediately invalidates your previous App Secret. Update all systems using the old secret before regenerating. Verify your transaction PIN first using `POST /pin/verify` before calling this endpoint. ```bash cURL theme={null} # Step 1: Verify PIN curl -X POST 'https://api.yativo.com/api/v1/pin/verify' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: pin-verify-001' \ -d '{ "pin": "1234" }' # Step 2: Generate new secret curl -X GET 'https://api.yativo.com/api/v1/generate-secret' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "App secret generated successfully", "data": { "app_secret": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" } } ``` The App Secret is only returned once. Copy it immediately and store it securely in a secrets manager or environment variable. # API Request Logs Source: https://docs.yativo.com/fiat-api-reference/developer/logs Retrieve a log of all API requests made against your account Returns an audit log of all API calls made against your business account. Useful for debugging, monitoring, and compliance. ``` GET /business/logs/all ``` ## Query Parameters Filter by HTTP status code (e.g. `200`, `400`, `422`, `500`). Filter by HTTP method: `GET`, `POST`, `PUT`, `DELETE`. Page number. Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/logs/all?method=POST&status=400&per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": "log_01HX9KZMB3F7VNQP8R2WDGT4E5", "method": "POST", "endpoint": "/business/virtual-account/create", "status_code": 201, "ip_address": "203.0.113.42", "created_at": "2026-04-01T10:00:00.000000Z" }, { "id": "log_01HX9KZMB3F7VNQP8R2WDGT4E6", "method": "POST", "endpoint": "/sendmoney/quote", "status_code": 400, "ip_address": "203.0.113.42", "created_at": "2026-04-01T09:55:00.000000Z" } ], "pagination": { "total": 142, "per_page": 20, "current_page": 1, "last_page": 8, "next_page_url": "https://api.yativo.com/api/v1/business/logs/all?page=2", "prev_page_url": null } } ``` # List Gift Card Categories Source: https://docs.yativo.com/fiat-api-reference/giftcards/categories Retrieve available gift card categories Returns all gift card categories available on the platform. Use category IDs to filter the gift card catalog. ``` GET https://api.yativo.com/api/v1/giftcards/categories ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/giftcards/categories' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Categories fetched successfully", "data": [ { "id": 1, "name": "Entertainment" }, { "id": 2, "name": "Gaming" }, { "id": 3, "name": "Shopping" }, { "id": 4, "name": "Food & Dining" }, { "id": 5, "name": "Travel" } ] } ``` # List Gift Cards Source: https://docs.yativo.com/fiat-api-reference/giftcards/list Browse available gift card products by country or category Returns all purchasable gift card products. ``` GET https://api.yativo.com/api/v1/giftcards ``` Filter by ISO 3166-1 alpha-2 country code (e.g. `US`, `BR`, `NG`). Filter by category ID from `GET /giftcards/categories`. ```bash US gift cards theme={null} curl -X GET 'https://api.yativo.com/api/v1/giftcards?country=US' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Operators retrieved successfully", "data": [ { "id": 1, "name": "Amazon US", "brand": "Amazon", "country": "US", "currency": "USD", "min_amount": 1, "max_amount": 500, "fixed_amounts": [10, 25, 50, 100], "category": "Shopping" } ] } ``` # Purchase Gift Card Source: https://docs.yativo.com/fiat-api-reference/giftcards/purchase Buy a digital gift card — cost debited from your USD wallet Purchase a gift card product. The face value is debited from your USD wallet. ``` POST https://api.yativo.com/api/v1/giftcards ``` Requires `Idempotency-Key` header. Gift card purchases are **non-refundable**. The gift card product ID (from `GET /giftcards`). Price per unit in the product's native currency (minimum 0.01). Number of cards to purchase (minimum 1). Name of the sender. Maximum 100 characters. Email address of the gift card recipient. Optional. Link this purchase to a customer in your account. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/giftcards' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: gc-amazon-001' \ -d '{ "productId": 1234, "unitPrice": 10.00, "quantity": 1, "senderName": "John Doe", "recipientEmail": "recipient@example.com", "customer_id": "cust_abc123" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Giftcard request submitted successfully", "data": { "transaction_id": "gc-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "product_name": "Amazon US", "amount": 10.00, "currency": "USD", "status": "completed", "created_at": "2026-06-01T10:00:00.000000Z" } } ``` ```json Insufficient balance theme={null} { "status": "error", "status_code": 402, "message": "Insufficient wallet balance" } ``` # Get Redeem Instructions Source: https://docs.yativo.com/fiat-api-reference/giftcards/redeem Retrieve the redemption code and instructions for a purchased gift card Retrieve the gift card code and redemption instructions for a completed purchase. ``` GET https://api.yativo.com/api/v1/giftcards/redeem/{transactionId} ``` The `transaction_id` from the purchase response. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/giftcards/redeem/gc-a1b2c3d4-e5f6-7890-abcd-ef1234567890' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Giftcard instruction retrieved successfully", "data": { "transaction_id": "gc-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "product_name": "Amazon US", "redemption_code": "AMZN-XXXX-XXXX-XXXX", "pin": "1234", "instructions": "Visit amazon.com/redeem and enter your gift card code.", "expiry_date": "2028-06-01" } } ``` Gift card codes are sensitive. Display them only to the intended recipient — do not log or store them on your servers. # Fiat API References Source: https://docs.yativo.com/fiat-api-reference/introduction Complete API reference for the Yativo Fiat payment platform The Yativo Fiat API enables you to send and receive money globally, manage virtual accounts, perform currency exchange, and verify customer identities. All endpoints return JSON responses. ## Base URLs | Environment | Base URL | | ----------- | -------------------------------- | | Production | `https://api.yativo.com/api/v1` | | Sandbox | `https://smtp.yativo.com/api/v1` | Use the sandbox environment for development and testing. Sandbox transactions do not move real funds. ## Authentication All API requests require a Bearer token obtained from the authentication endpoint. Tokens expire after **600 seconds** (10 minutes). ```bash theme={null} Authorization: Bearer YOUR_ACCESS_TOKEN ``` See [Generate Token](/fiat-api-reference/auth/token) for details on obtaining a token. ## Idempotency All `POST`, `PUT`, and `PATCH` requests require an `Idempotency-Key` header. This ensures that duplicate requests (e.g. due to network retries) are not processed twice. ```bash theme={null} Idempotency-Key: your-unique-key-here ``` Use a UUID or a deterministic string based on the operation (e.g. `payout-{customer_id}-{timestamp}`). Keys are scoped to your account. ## Rate limits Requests are rate-limited per API key. If you exceed the limit, you will receive a `429 Too Many Requests` response. Implement exponential backoff when retrying after rate limit errors. ## Standard response format All successful responses follow this structure: ```json theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { ... } } ``` ## Error codes | Status Code | Meaning | | ----------- | ------------------------------------------------------- | | `200` | OK — Request succeeded | | `201` | Created — Resource created successfully | | `400` | Bad Request — Invalid request parameters | | `401` | Unauthorized — Missing or invalid token | | `404` | Not Found — Resource does not exist | | `422` | Unprocessable Entity — Validation failed | | `429` | Too Many Requests — Rate limit exceeded | | `500` | Internal Server Error — Something went wrong on our end | ### Error response format ```json theme={null} { "status": "error", "status_code": 422, "message": "Validation failed", "errors": { "customer_email": ["The customer email field is required."] } } ``` ## KYC platform Certain KYC submission endpoints are hosted on a separate platform: | Platform | Base URL | | -------------- | ------------------------------------------------- | | KYC API | `https://kyc.yativo.com` | | Individual KYC | `https://kyc.yativo.com/individual/{customer_id}` | | Business KYB | `https://kyc.yativo.com/business/{customer_id}` | # Add IP Addresses Source: https://docs.yativo.com/fiat-api-reference/ip/create Add one or more IP addresses to your API allowlist Add trusted IP addresses to your allowlist. Once any IP is allowlisted, all requests from non-listed IPs are rejected with `403 Forbidden`. ``` POST https://api.yativo.com/api/v1/ip ``` Requires an `Idempotency-Key` header. Confirm your server's outbound IP before adding — adding a wrong IP could lock you out. ## Request body Array of IPv4 address strings to allowlist. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/ip' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: ip-add-001' \ -d '{ "new_ip": ["203.0.113.10", "198.51.100.5"] }' ``` ```json Success theme={null} { "message": "IP addresses whitelisted and added to firewall." } ``` # Remove IP Address Source: https://docs.yativo.com/fiat-api-reference/ip/delete Remove a specific IP address from your allowlist Remove a single IP address from the allowlist. Pass the IP address itself as the path parameter. ``` DELETE https://api.yativo.com/api/v1/ip/{ipAddress} ``` ## Path parameters The IP address to remove (e.g. `203.0.113.10`). ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/ip/203.0.113.10' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "message": "IP address removed from whitelist and firewall." } ``` # Get Allowlisted IPs Source: https://docs.yativo.com/fiat-api-reference/ip/list Retrieve your IP allowlist record Returns your IP allowlist record. The `ip_address` field contains all currently allowlisted IP addresses as an array. ``` GET https://api.yativo.com/api/v1/ip ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/ip' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": { "id": 1, "user_id": "usr_xxxxxxxxxxxxxxxx", "ip_address": ["203.0.113.10", "198.51.100.5"], "created_at": "2026-04-01T10:00:00.000000Z", "updated_at": "2026-04-01T12:00:00.000000Z" } } ``` # Update IP Allowlist Source: https://docs.yativo.com/fiat-api-reference/ip/update Add more IP addresses to an existing allowlist record Append additional IP addresses to your existing allowlist record. This operation **adds** to the existing list — it does not replace it. ``` PUT https://api.yativo.com/api/v1/ip/{id} ``` Requires an `Idempotency-Key` header. ## Path parameters The ID of the allowlist record to update. ## Request body Array of IPv4 address strings to add to the existing allowlist. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/ip/1' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: ip-update-001' \ -d '{ "new_ip": ["203.0.113.20", "198.51.100.10"] }' ``` ```json Success theme={null} { "message": "IP addresses updated and added to firewall." } ``` # Regenerate Endorsement Link Source: https://docs.yativo.com/fiat-api-reference/kyc/endorsement-regenerate Generate a fresh verification link for an expired service endorsement When a customer's endorsement verification link has expired, use this endpoint to generate a new one. Share the new link with the customer to complete verification for the specific payment service. ``` GET https://kyc.yativo.com/api/kyc/regenerate/{customerId}/{service} ``` ## Path parameters The UUID of the customer. The service endorsement to regenerate. One of: `base`, `sepa`, `spei`, `brazil`, `eurde`, `usd_latam`, `eur_latam`, `virtual_card`, `asian`, `native`, `cobo_pobo`. ## Service reference | Service | Description | | -------------- | ------------------------------- | | `base` | USD base payments | | `sepa` | European SEPA transfers | | `spei` | Mexico SPEI transfers | | `brazil` | Brazilian payment rails | | `eurde` | EUR/DE virtual accounts | | `usd_latam` | USD Latin America transfers | | `eur_latam` | EUR Latin America transfers | | `virtual_card` | Virtual card issuance | | `asian` | Asian region payments | | `native` | Native payment rails | | `cobo_pobo` | Collection/Payment-on-behalf-of | ```bash cURL theme={null} curl -X GET 'https://kyc.yativo.com/api/kyc/regenerate/c586066b-0f29-468f-b775-15483871a202/sepa' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "success": true, "message": "Endorsement link regenerated successfully", "data": { "customer_id": "c586066b-0f29-468f-b775-15483871a202", "service": "sepa", "link": "https://kyc.yativo.com/endorsement/sepa/c586066b-0f29-468f-b775-15483871a202?token=abc123xyz", "expires_at": "2026-04-03T10:00:00.000000Z" } } ``` # Get Occupation Codes Source: https://docs.yativo.com/fiat-api-reference/kyc/occupation-codes Retrieve the list of valid occupation codes for KYC submissions Returns all valid occupation codes to use in the `most_recent_occupation_code` field of individual KYC submissions. ``` GET /auth/occupation-codes ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/auth/occupation-codes' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "display_name": "Accountant and auditor", "code": "132011" }, { "display_name": "Actor", "code": "272011" }, { "display_name": "Actuary", "code": "152011" }, { "display_name": "Administrative services manager", "code": "113011" }, { "display_name": "Advertising and promotions manager", "code": "112011" }, { "display_name": "Aerospace engineer", "code": "172011" }, { "display_name": "Agricultural engineer", "code": "172021" }, { "display_name": "Air traffic controller", "code": "532021" }, { "display_name": "Architect", "code": "171011" }, { "display_name": "Financial manager", "code": "113031" }, { "display_name": "Software developer", "code": "151252" }, { "display_name": "Physician", "code": "291062" }, { "display_name": "Teacher", "code": "251099" } ] } ``` # Check KYC Status Source: https://docs.yativo.com/fiat-api-reference/kyc/status Retrieve the current KYC or KYB verification status for a customer Poll this endpoint after a KYC/KYB submission to check the current verification status. When `status` is `"approved"` and `is_va_approved` is `true`, the customer can use payment services. ``` GET /customer/kyc/{customer_id} ``` ## Path parameters The UUID of the customer whose verification status you want to check. ## Status values | Status | Description | | --------------- | ----------------------------------------------------- | | `not_started` | No KYC submission has been made yet | | `submitted` | Submission received, awaiting review | | `manual_review` | Under manual review by compliance team | | `approved` | Customer is fully verified | | `rejected` | Submission was rejected (see `kyc_rejection_reasons`) | | `under_review` | Additional review in progress | When `is_va_approved` is `true`, the customer can use virtual accounts and payment services. Check both `status === "approved"` and `is_va_approved === true` before enabling payment features. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/kyc/c586066b-0f29-468f-b775-15483871a202' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Approved theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "first_name": "Alex", "last_name": "Smith", "status": "approved", "kyc_rejection_reasons": [], "kyc_requirements_due": [], "bio_data": { "customer_kyc_status": "approved", "kyc_verified_date": "2026-04-02T12:00:00.000000Z" }, "kyc_link": "https://kyc.yativo.com/individual/c586066b-0f29-468f-b775-15483871a202", "is_va_approved": true } } ``` ```json Submitted theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "first_name": "Alex", "last_name": "Smith", "status": "submitted", "kyc_rejection_reasons": [], "kyc_requirements_due": [], "bio_data": { "customer_kyc_status": "submitted", "kyc_verified_date": null }, "kyc_link": "https://kyc.yativo.com/individual/c586066b-0f29-468f-b775-15483871a202", "is_va_approved": false } } ``` ```json Rejected theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "first_name": "Alex", "last_name": "Smith", "status": "rejected", "kyc_rejection_reasons": [ "Document image quality is too low", "Selfie does not match ID photo" ], "kyc_requirements_due": ["selfie_image", "identifying_information"], "bio_data": { "customer_kyc_status": "rejected", "kyc_verified_date": null }, "kyc_link": "https://kyc.yativo.com/individual/c586066b-0f29-468f-b775-15483871a202", "is_va_approved": false } } ``` # Submit Business KYB Source: https://docs.yativo.com/fiat-api-reference/kyc/submit-business POST https://kyc.yativo.com/api/business-kyc/submit Submit identity and compliance verification data for a business customer Submit KYB data for a business customer. The customer must already exist with `customer_type: "business"` (created via `POST /customer`). After submission the status will be `"submitted"` and will move to `"approved"` once review is complete. This endpoint is hosted on the KYC platform at `https://kyc.yativo.com`, not the main API base URL. Include an `Idempotency-Key` header on every request. ``` POST https://kyc.yativo.com/api/business-kyc/submit ``` ## Business identity fields The customer UUID returned by `POST /customer`. The customer must have been created with `customer_type: "business"`. The official registered legal name of the business. Max 255 characters. Trade name or DBA ("doing business as") name. Max 255 characters. A description of what the business does. Max 1000 characters. Business contact email address. Legal structure of the business. One of: `"cooperative"`, `"corporation"`, `"llc"`, `"partnership"`, `"sole_prop"`, `"trust"`, `"other"`. Official government registration or incorporation number. Max 100 characters. Date of incorporation in `YYYY-MM-DD` format. Must be before today. Business tax identification number. Max 100 characters. Optional. Country dial code for the business phone. Must match `^\+[1-9]\d{0,3}$`, e.g. `"+1"`, `"+234"`. Business phone number. Digits only, 7–15 characters. Industry category of the business. Optional. Business website URL. Must be a valid URL including scheme (e.g. `"https://acme.com"`). Whether the business is a Decentralised Autonomous Organisation. How the business name appears on customer payment statements. Max 22 characters. Whether the ownership structure includes material intermediary entities. ## Addresses Both `registered_address` and `physical_address` share the same field structure. The official registered address of the business. Street address line 1. Max 255 characters. Street address line 2. Optional. City. Max 100 characters. State or province. Accepts `"US-CA"` or `"CA"` — both are normalised. Postal or ZIP code. Validated per country. ISO 3166-1 alpha-2 country code. Registered address proof document. Hosted URL or base64. Optional. The physical operating address of the business. Must include `proof_of_address_file`. Street address line 1. Street address line 2. Optional. City. State or province. Postal or ZIP code. ISO 3166-1 alpha-2 country code. Physical address proof (e.g. office lease). Hosted URL or base64. ## Associated persons At least one person is required. Include all UBOs (Ultimate Beneficial Owners with ownership ≥ 25%), directors, and authorised signers. Person's first name. Max 100 characters. Person's last name. Max 100 characters. Date of birth in `YYYY-MM-DD`. Must be before today. ISO 3166-1 alpha-2 country code. Person's email address. Phone number. Optional. Job title, e.g. `"CEO"`, `"Director"`. Optional. Ownership percentage, 0–100. Date the relationship with the business was established. `YYYY-MM-DD`, must not be in the future. Person's residential address. Same field structure as the business address above. At least one ID document for this person. Document type (e.g. `"passport"`, `"national_id"`). ISO 3166-1 alpha-2 country code. Document number. `YYYY-MM-DD`, before today. `YYYY-MM-DD`, after today. Front image. Hosted URL or base64. PDF/JPG/JPEG/PNG, max 5 MB. Back image. Required for cards with a reverse side. Whether this person has an ownership stake. Whether this person has operational control. Whether this person is an authorised signer. Whether this person is a director. ## Risk and purpose Intended use of the account. One of: `"business_transactions"`, `"ecommerce_retail_payments"`, `"operating_a_company"`, `"investment_purposes"`, `"charitable_donations"`, `"receive_salary"`, `"receive_payment_for_freelancing"`, `"purchase_goods_and_services"`, `"personal_or_living_expenses"`, `"payments_to_friends_or_family_abroad"`, `"protect_wealth"`, `"other"`. Required when `account_purpose` is `"other"`. Primary source of business funds. One of: `"business_income"`, `"company_funds"`, `"salary"`, `"savings"`, `"investments_loans"`, `"inheritance"`, `"gifts"`, `"government_benefits"`, `"pension_retirement"`, `"sale_of_assets_real_estate"`, `"ecommerce_reseller"`, `"gambling_proceeds"`, `"someone_elses_funds"`. List the high-risk activities the business is involved in. Use `["none_of_the_above"]` if none apply. Accepted values: `"adult_entertainment"`, `"gambling"`, `"hold_client_funds"`, `"investment_services"`, `"lending_banking"`, `"marijuana_or_related_services"`, `"money_services"`, `"operate_foreign_exchange_virtual_currencies_brokerage_otc"`, `"pharmaceuticals"`, `"precious_metals_precious_stones_jewelry"`, `"safe_deposit_box_rentals"`, `"weapons_firearms_and_explosives"`, `"none_of_the_above"`. Required if any high-risk activities are listed. Explain the nature of those activities. Whether the business conducts money services (e.g. remittance, currency exchange). Required when `conducts_money_services` is `true`. Describe the money services. Required when `conducts_money_services` is `true`. Describe compliance screening procedures. Estimated annual revenue in USD. Optional free-text field. Expected monthly payment volume in USD. Optional. `"yes"` or `"no"`. Whether the business operates in any prohibited jurisdictions. Ownership percentage threshold for UBO reporting. Accepted range: 5–25. ## Regulated activity Details about any regulated activities the business conducts. Optional — submit an empty object `{}` if not applicable. Description of regulated activities. ISO 3166-1 alpha-2 country code of the regulator. Name of the regulatory authority. Regulatory licence number. ## Business documents At least one business document is required. Document purpose. One of: `"business_registration"`, `"tax_documents"`, `"compliance_documents"`, `"financial_statements"`. Human-readable description, e.g. `"Certificate of Incorporation"`. Hosted URL or base64-encoded document. Optional at submission time — can be provided via update. ## Business-level identifying information (optional) Optional business-level ID documents (e.g. business licence, regulatory certificate). Document type. ISO 3166-1 alpha-2 country code. Document number. Description of the document. `YYYY-MM-DD`, must be after today. Front image. Hosted URL or base64. Back image. Hosted URL or base64. ```bash cURL theme={null} curl -X POST 'https://kyc.yativo.com/api/business-kyc/submit' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: kyb-acme-2026-001' \ -d '{ "customer_id": "d47f8a2b-1c3e-4f5a-9b8c-7d6e5f4a3b2c", "business_legal_name": "Acme Payments LLC", "business_trade_name": "Acme Pay", "business_description": "International payment processing for SMEs", "email": "compliance@acmepay.com", "business_type": "llc", "registration_number": "LLC-2018-00987", "incorporation_date": "2018-03-12", "tax_id": "47-1234567", "phone_calling_code": "+1", "phone_number": "3055551234", "primary_website": "https://acmepay.com", "registered_address": { "street_line_1": "100 Brickell Ave", "city": "Miami", "state": "FL", "postal_code": "33131", "country": "US" }, "physical_address": { "street_line_1": "100 Brickell Ave", "city": "Miami", "state": "FL", "postal_code": "33131", "country": "US", "proof_of_address_file": "https://storage.yativo.com/documents/abc/lease.pdf" }, "associated_persons": [ { "first_name": "Jane", "last_name": "Doe", "birth_date": "1978-07-22", "nationality": "US", "email": "jane.doe@acmepay.com", "title": "CEO", "ownership_percentage": 60, "relationship_established_at": "2018-03-12", "residential_address": { "street_line_1": "456 Coral Way", "city": "Miami", "state": "FL", "postal_code": "33133", "country": "US" }, "identifying_information": [ { "type": "passport", "issuing_country": "US", "number": "P87654321", "date_issued": "2020-01-10", "expiration_date": "2030-01-10", "image_front_file": "https://storage.yativo.com/documents/abc/jane-passport.jpg" } ], "has_ownership": true, "has_control": true, "is_signer": true, "is_director": true } ], "account_purpose": "business_transactions", "source_of_funds": "business_income", "high_risk_activities": ["none_of_the_above"], "conducts_money_services": false, "regulated_activity": {}, "documents": [ { "purpose": "business_registration", "description": "Certificate of Incorporation", "file": "https://storage.yativo.com/documents/abc/certificate.pdf" }, { "purpose": "tax_documents", "description": "EIN confirmation letter", "file": "https://storage.yativo.com/documents/abc/ein.pdf" } ] }' ``` ```javascript Node.js theme={null} const response = await fetch('https://kyc.yativo.com/api/business-kyc/submit', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `kyb-${customerId}-001`, }, body: JSON.stringify({ customer_id: customerId, business_legal_name: 'Acme Payments LLC', business_trade_name: 'Acme Pay', business_description: 'International payment processing for SMEs', email: 'compliance@acmepay.com', business_type: 'llc', registration_number: 'LLC-2018-00987', incorporation_date: '2018-03-12', registered_address: { street_line_1: '100 Brickell Ave', city: 'Miami', state: 'FL', postal_code: '33131', country: 'US', }, physical_address: { street_line_1: '100 Brickell Ave', city: 'Miami', state: 'FL', postal_code: '33131', country: 'US', proof_of_address_file: officeLeaseUrl, }, associated_persons: [{ first_name: 'Jane', last_name: 'Doe', birth_date: '1978-07-22', nationality: 'US', email: 'jane.doe@acmepay.com', title: 'CEO', ownership_percentage: 60, residential_address: { street_line_1: '456 Coral Way', city: 'Miami', state: 'FL', postal_code: '33133', country: 'US', }, identifying_information: [{ type: 'passport', issuing_country: 'US', number: 'P87654321', date_issued: '2020-01-10', expiration_date: '2030-01-10', image_front_file: passportUrl, }], has_ownership: true, has_control: true, is_signer: true, is_director: true, }], account_purpose: 'business_transactions', source_of_funds: 'business_income', high_risk_activities: ['none_of_the_above'], conducts_money_services: false, regulated_activity: {}, documents: [{ purpose: 'business_registration', description: 'Certificate of Incorporation', file: certUrl, }], }), }); ``` ```json Success theme={null} { "success": true, "message": "Business KYC submission received successfully", "business_data": { "customer_id": "d47f8a2b-1c3e-4f5a-9b8c-7d6e5f4a3b2c", "type": "business", "business_legal_name": "Acme Payments LLC", "status": "submitted", "created_at": "2026-06-01T10:00:00.000000Z" } } ``` ```json Validation error theme={null} { "status": "failed", "status_code": 422, "message": "Request failed", "data": { "business_type": ["The selected business type is invalid."], "associated_persons": ["The associated persons field is required."], "high_risk_activities": ["The high risk activities field is required."], "documents": ["The documents field is required."] } } ``` # Submit Individual KYC Source: https://docs.yativo.com/fiat-api-reference/kyc/submit-individual POST https://kyc.yativo.com/api/individual-kyc/submit Submit identity verification data for an individual customer Submit KYC data for an individual customer. The customer must already exist in your account (created via `POST /customer`). After submission the status will be `"submitted"` and will move to `"approved"` once review is complete. This endpoint is hosted on the KYC platform at `https://kyc.yativo.com`, not the main API base URL. Include an `Idempotency-Key` header on every request. ``` POST https://kyc.yativo.com/api/individual-kyc/submit ``` ## Identity fields The customer UUID returned by `POST /customer`. Customer's first name. Max 1024 characters. Customer's last name. Max 1024 characters. Customer's middle name. Optional. Customer's email address. Country dial code. Must match `^\+\d{1,4}$`, e.g. `"+1"`, `"+44"`, `"+234"`. Phone number digits only, 8–15 characters. Do not include the country code. Date of birth in `YYYY-MM-DD` format. Must be before today. ISO 3166-1 alpha-2 country code, e.g. `"US"`, `"NG"`, `"BR"`. `"male"` or `"female"`. Tax identification number. Max 100 characters. Selfie photo of the customer. Provide as a hosted URL (from `POST /storage/upload`) or a base64-encoded string. Accepted formats: PDF, JPG, JPEG, PNG, HEIC, TIF. Max 5 MB. Bank Verification Number. **Required when `nationality` is `"NG"`**. Exactly 11 digits. National Identification Number. **Required when `nationality` is `"NG"`**. Exactly 11 digits. ## Residential address Customer's current residential address. Street address line 1. Max 256 characters. Street address line 2. Optional. City. Max 256 characters. State or province. Accepts full ISO 3166-2 codes like `"US-CA"` or the subdivision segment `"CA"` — both are normalised. Postal or ZIP code. Validated per country. ISO 3166-1 alpha-2 country code. Proof of address document (utility bill, bank statement, etc.). Hosted URL or base64. PDF/JPG/JPEG/PNG/HEIC/TIF, max 5 MB. ## Identifying information At least one government-issued ID document. Accepted document types depend on `issuing_country` — see the [ID types reference](/yativo-fiat/kyc#id-types-by-country). Document type. Common values: `"passport"`, `"national_id"`, `"other"`. Country-specific types also apply (e.g. `"ssn"` for US, `"bvn"` for NG). ISO 3166-1 alpha-2 country code of the issuing authority. Document number. Issue date in `YYYY-MM-DD` format. Must be before today. Expiration date in `YYYY-MM-DD` format. Must be after today. Front image of the document. Hosted URL or base64. PDF/JPG/JPEG/PNG, max 5 MB. Back image of the document. Required for documents that have a reverse side (e.g. national ID cards). Hosted URL or base64. PDF/JPG/JPEG/PNG, max 5 MB. ## Risk and purpose Customer's employment status. One of: `"employed"`, `"exempt"`, `"homemaker"`, `"retired"`, `"self_employed"`, `"student"`, `"unemployed"`. 6-digit occupation code. Retrieve the full list from `GET /auth/occupation-codes`. Example: `"151252"` (Software developer). Expected monthly transaction volume. One of: `"0_4999"`, `"5000_9999"`, `"10000_49999"`, `"50000_plus"`. Primary source of funds. One of: `"salary"`, `"business_income"`, `"company_funds"`, `"savings"`, `"investments_loans"`, `"inheritance"`, `"gifts"`, `"government_benefits"`, `"pension_retirement"`, `"sale_of_assets_real_estate"`, `"ecommerce_reseller"`, `"gambling_proceeds"`, `"someone_elses_funds"`. Intended use of the account. One of: `"receive_salary"`, `"business_transactions"`, `"purchase_goods_and_services"`, `"personal_or_living_expenses"`, `"payments_to_friends_or_family_abroad"`, `"receive_payment_for_freelancing"`, `"investment_purposes"`, `"protect_wealth"`, `"ecommerce_retail_payments"`, `"operating_a_company"`, `"charitable_donations"`, `"other"`. Required when `account_purpose` is `"other"`. Provide a plain-text description. Set to `true` if the customer is acting on behalf of third parties. Defaults to `false`. ## Supporting documents At least one supporting document is required. A label identifying the document type, e.g. `"bank_statement"`, `"tax_return"`. Hosted URL or base64-encoded file. PDF/JPG/JPEG/PNG, max 5 MB. ```bash cURL theme={null} curl -X POST 'https://kyc.yativo.com/api/individual-kyc/submit' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: kyc-ind-2026-001' \ -d '{ "customer_id": "c586066b-0f29-468f-b775-15483871a202", "first_name": "Alex", "last_name": "Smith", "email": "alex.smith@example.com", "calling_code": "+1", "phone": "5551234567", "gender": "male", "birth_date": "1990-01-15", "nationality": "US", "taxId": "998-88-7766", "selfie_image": "https://storage.yativo.com/documents/abc/selfie.jpg", "residential_address": { "street_line_1": "123 Maple Street", "city": "Austin", "state": "TX", "postal_code": "78701", "country": "US", "proof_of_address_file": "https://storage.yativo.com/documents/abc/utility-bill.pdf" }, "identifying_information": [ { "type": "passport", "issuing_country": "US", "number": "P12345678", "date_issued": "2019-06-01", "expiration_date": "2029-06-01", "image_front_file": "https://storage.yativo.com/documents/abc/passport-front.jpg" } ], "employment_status": "employed", "most_recent_occupation_code": "151252", "expected_monthly_payments_usd": "0_4999", "source_of_funds": "salary", "account_purpose": "receive_salary", "acting_as_intermediary": false, "uploaded_documents": [ { "type": "bank_statement", "file": "https://storage.yativo.com/documents/abc/bank-statement.pdf" } ] }' ``` ```javascript Node.js theme={null} const response = await fetch('https://kyc.yativo.com/api/individual-kyc/submit', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `kyc-${customerId}-${Date.now()}`, }, body: JSON.stringify({ customer_id: customerId, first_name: 'Alex', last_name: 'Smith', email: 'alex.smith@example.com', calling_code: '+1', phone: '5551234567', gender: 'male', birth_date: '1990-01-15', nationality: 'US', taxId: '998-88-7766', selfie_image: selfieUrl, residential_address: { street_line_1: '123 Maple Street', city: 'Austin', state: 'TX', postal_code: '78701', country: 'US', proof_of_address_file: addressProofUrl, }, identifying_information: [{ type: 'passport', issuing_country: 'US', number: 'P12345678', date_issued: '2019-06-01', expiration_date: '2029-06-01', image_front_file: passportFrontUrl, }], employment_status: 'employed', most_recent_occupation_code: '151252', expected_monthly_payments_usd: '0_4999', source_of_funds: 'salary', account_purpose: 'receive_salary', acting_as_intermediary: false, uploaded_documents: [{ type: 'bank_statement', file: statementUrl }], }), }); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( 'https://kyc.yativo.com/api/individual-kyc/submit', headers={ 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json', 'Idempotency-Key': f'kyc-{customer_id}-001', }, json={ 'customer_id': customer_id, 'first_name': 'Alex', 'last_name': 'Smith', 'email': 'alex.smith@example.com', 'calling_code': '+1', 'phone': '5551234567', 'gender': 'male', 'birth_date': '1990-01-15', 'nationality': 'US', 'taxId': '998-88-7766', 'selfie_image': selfie_url, 'residential_address': { 'street_line_1': '123 Maple Street', 'city': 'Austin', 'state': 'TX', 'postal_code': '78701', 'country': 'US', 'proof_of_address_file': address_proof_url, }, 'identifying_information': [{ 'type': 'passport', 'issuing_country': 'US', 'number': 'P12345678', 'date_issued': '2019-06-01', 'expiration_date': '2029-06-01', 'image_front_file': passport_front_url, }], 'employment_status': 'employed', 'most_recent_occupation_code': '151252', 'expected_monthly_payments_usd': '0_4999', 'source_of_funds': 'salary', 'account_purpose': 'receive_salary', 'acting_as_intermediary': False, 'uploaded_documents': [{'type': 'bank_statement', 'file': statement_url}], } ) ``` ```json Submitted theme={null} { "success": true, "message": "KYC submission received successfully", "data": { "submission": { "id": "sub_8f3b2a1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "type": "individual", "status": "submitted", "customer_id": "c586066b-0f29-468f-b775-15483871a202", "first_name": "Alex", "last_name": "Smith", "email": "alex.smith@example.com", "endorsements": [ { "service": "base", "status": "pending", "link": "https://kyc.yativo.com/endorsement/base/c586066b-0f29-468f-b775-15483871a202" } ], "created_at": "2026-06-01T10:00:00.000000Z" } } } ``` ```json Validation error theme={null} { "status": "failed", "status_code": 422, "message": "Request failed", "data": { "nationality": ["The nationality must be 2 characters."], "expected_monthly_payments_usd": ["The selected expected monthly payments usd is invalid."], "identifying_information": ["The identifying information field is required."] } } ``` # Update KYC Submission Source: https://docs.yativo.com/fiat-api-reference/kyc/update Update an existing KYC or KYB submission with corrected or additional information Update a previously submitted KYC or KYB record. Use this endpoint when a customer needs to correct information or provide additional documents — typically after a rejection. Only include fields you want to change. ``` PUT https://api.yativo.com/api/v1/customer/kyc/update ``` Include an `Idempotency-Key` header on every request. Supply `customer_id` and `type`, then any fields you want to update. Fields not included are left unchanged. ## Request body The UUID of the customer whose KYC you are updating. `"individual"` or `"business"` — must match the original submission type. All other fields from the original submission schema can be included to update their values. See [Submit Individual KYC](/fiat-api-reference/kyc/submit-individual) or [Submit Business KYC](/fiat-api-reference/kyc/submit-business) for the full field reference. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/customer/kyc/update' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: kyc-update-2026-002' \ -d '{ "customer_id": "c586066b-0f29-468f-b775-15483871a202", "type": "individual", "selfie_image": "https://storage.yativo.com/documents/abc/selfie-v2.jpg", "identifying_information": [ { "type": "passport", "issuing_country": "US", "number": "P00012345", "date_issued": "2020-01-01", "expiration_date": "2030-01-01", "image_front_file": "https://storage.yativo.com/documents/abc/passport-front-hd.jpg" } ] }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/customer/kyc/update', { method: 'PUT', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `kyc-update-${customerId}-${Date.now()}`, }, body: JSON.stringify({ customer_id: customerId, type: 'individual', selfie_image: newSelfieUrl, identifying_information: [{ type: 'passport', issuing_country: 'US', number: 'P00012345', date_issued: '2020-01-01', expiration_date: '2030-01-01', image_front_file: newPassportFrontUrl, }], }), }); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "KYC submission updated successfully", "data": { "customer_id": "c586066b-0f29-468f-b775-15483871a202", "type": "individual", "status": "submitted", "updated_at": "2026-06-01T15:00:00.000000Z" } } ``` ```json Validation error theme={null} { "status": "failed", "status_code": 422, "message": "Request failed", "data": { "customer_id": ["The customer id field is required."], "type": ["The selected type is invalid."] } } ``` # Get Verification Locations Source: https://docs.yativo.com/fiat-api-reference/kyc/verification-locations Retrieve the list of supported countries for customer registration and verification Returns all countries where Yativo supports customer registration and KYC/KYB verification. Use this to validate customer country selections in your onboarding flow. ``` GET /auth/verification-locations ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/auth/verification-locations' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "country": "United States", "code": "US" }, { "country": "Brazil", "code": "BR" }, { "country": "Mexico", "code": "MX" }, { "country": "Colombia", "code": "CO" }, { "country": "Chile", "code": "CL" }, { "country": "Peru", "code": "PE" }, { "country": "Argentina", "code": "AR" }, { "country": "United Kingdom", "code": "GB" }, { "country": "Germany", "code": "DE" }, { "country": "France", "code": "FR" }, { "country": "Spain", "code": "ES" }, { "country": "Canada", "code": "CA" }, { "country": "Nigeria", "code": "NG" }, { "country": "Ghana", "code": "GH" } ] } ``` # Get Supported Countries Source: https://docs.yativo.com/fiat-api-reference/payments/countries Retrieve the full list of countries supported for payout destinations Returns all countries where Yativo supports outgoing payments. Use this to power country selectors in your application's payout flow. ``` GET /payment-methods/payout/countries ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout/countries' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "iso3": "ARG", "iso2": "AR", "name": "Argentina" }, { "iso3": "BRA", "iso2": "BR", "name": "Brazil" }, { "iso3": "CHL", "iso2": "CL", "name": "Chile" }, { "iso3": "COL", "iso2": "CO", "name": "Colombia" }, { "iso3": "ECU", "iso2": "EC", "name": "Ecuador" }, { "iso3": "MEX", "iso2": "MX", "name": "Mexico" }, { "iso3": "PAN", "iso2": "PA", "name": "Panama" }, { "iso3": "PER", "iso2": "PE", "name": "Peru" }, { "iso3": "USA", "iso2": "US", "name": "United States" }, { "iso3": "URY", "iso2": "UY", "name": "Uruguay" } ] } ``` # Get Exchange Rate / Quote Source: https://docs.yativo.com/fiat-api-reference/payments/exchange-rate Generate a quote with locked rate and fee breakdown for a payout or deposit Returns a real-time exchange rate, fee breakdown, and a `quote_id` valid for **5 minutes**. Pass the `quote_id` to `POST /wallet/payout` or `POST /wallet/deposits/new` to execute the transaction at the quoted rate. ``` POST https://api.yativo.com/api/v1/exchange-rate ``` Requires an `Idempotency-Key` header. Rate-limited to **30 requests per minute**. This endpoint both prices the transaction AND generates a binding `quote_id` — treat it as quote creation, not just a rate lookup. ## Request body Source currency code (ISO 4217), e.g. `"USD"`, `"EUR"`. Target currency code (ISO 4217), e.g. `"USD"`, `"CLP"`, `"BRL"`, `"MXN"`. Amount in the source currency to convert. The payment method ID (from `GET /payment-methods/payout` or `GET /payment-methods/payin`). When provided, the quote is scoped to that specific payment rail and its exact fee structure is applied. Transaction direction: `"payout"` (for sends/withdrawals) or `"payin"` (for deposits). Required when `method_id` is provided. ```bash cURL — payout quote (USD → USD via PayPal, method 21) theme={null} curl -X POST 'https://api.yativo.com/api/v1/exchange-rate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: quote-001' \ -d '{ "from_currency": "USD", "to_currency": "USD", "method_id": 21, "method_type": "payout", "amount": 406 }' ``` ```bash cURL — simple FX quote (no method) theme={null} curl -X POST 'https://api.yativo.com/api/v1/exchange-rate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: quote-001' \ -d '{ "from_currency": "USD", "to_currency": "CLP", "amount": 500 }' ``` ```javascript Node.js — payout quote theme={null} const response = await fetch('https://api.yativo.com/api/v1/exchange-rate', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `quote-${Date.now()}`, }, body: JSON.stringify({ from_currency: 'USD', to_currency: 'USD', method_id: 21, method_type: 'payout', amount: 406, }), }); const { data } = await response.json(); // data.quote_id is valid for 5 minutes — use it in /wallet/payout ``` ```json With method_id (full calculator) theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "from_currency": "USD", "to_currency": "USD", "rate": "1.00000000", "amount": "406.00000000", "converted_amount": "1USD - 1.00000000 USD", "payout_data": { "total_transaction_fee_in_from_currency": "11.15000000", "total_transaction_fee_in_to_currency": "11.15", "customer_sent_amount": "406.00", "customer_receive_amount": "406.00", "customer_total_amount_due": "417.15" }, "calculator": { "total_fee": { "wallet_currency": 11.15, "payout_currency": 11.15, "usd": 11.15 }, "total_amount": { "wallet_currency": 417.15, "payout_currency": 417.15 }, "amount_due": 417.15, "exchange_rate": 1, "adjusted_rate": 1, "target_currency": "USD", "base_currencies": ["USD"], "debit_amount": { "wallet_currency": 417.15, "payout_currency": 417.15 }, "customer_receive_amount": { "wallet_currency": 406, "payout_currency": 406 }, "fee_breakdown": { "float": { "wallet_currency": 10.15, "payout_currency": 10.15 }, "fixed": { "wallet_currency": 1, "payout_currency": 1 }, "total": 11.15 }, "PayoutMethod": { "id": 21, "method_name": "PayPal", "country": "PER", "currency": "USD", "base_currency": "USD", "exchange_rate_float": "0" } } } } ``` ```json Without method_id (FX only) theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "quote_id": "7b91acf8-9d2a-4e38-aa71-9babe9f785cd", "from_currency": "USD", "to_currency": "CLP", "rate": "950.00000000", "amount": "500.00000000", "payout_data": { "total_transaction_fee_in_from_currency": "11.15000000", "total_transaction_fee_in_to_currency": "10592.50", "customer_sent_amount": "500.00", "customer_receive_amount": "462925.00", "customer_total_amount_due": "511.15" }, "calculator": { "fee_breakdown": { "float": { "wallet_currency": 10.15, "payout_currency": 9642.50 }, "fixed": { "wallet_currency": 1, "payout_currency": 950 }, "total": 11.15 }, "exchange_rate": 950, "customer_receive_amount": { "wallet_currency": 500, "payout_currency": 475000 } } } } ``` ## Response fields | Field | Description | | ---------------------------------------------------- | ------------------------------------------------------- | | `quote_id` | Binding quote identifier — valid for **5 minutes** | | `rate` | Exchange rate applied (source → target currency) | | `payout_data.customer_total_amount_due` | Total deducted from your wallet (amount + fees) | | `payout_data.customer_receive_amount` | Amount the recipient receives | | `payout_data.total_transaction_fee_in_from_currency` | Total fees in the source currency | | `calculator.fee_breakdown.float` | Percentage-based fee component | | `calculator.fee_breakdown.fixed` | Flat fee component | | `calculator.amount_due` | Final wallet debit amount | | `calculator.PayoutMethod` | Payment method details (only when `method_id` provided) | ## Using the quote\_id Once you have a `quote_id`, use it in the execution step within 5 minutes: **For payouts:** ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: payout-001' \ -d '{ "debit_wallet": "USD", "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "amount": 406, "payment_method_id": 21 }' ``` **For deposits (payin):** ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/deposits/new' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: deposit-001' \ -d '{ "gateway": 20, "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "currency": "USD", "redirect_url": "https://your-app.com/deposit/complete" }' ``` Quotes expire after **5 minutes** and cannot be reused. Generating a quote and letting it expire before executing wastes a rate lock and a request toward your rate limit. # Get Payout Methods Source: https://docs.yativo.com/fiat-api-reference/payments/methods Retrieve available payout methods for a specific destination country Returns the list of payout methods (banks, mobile wallets, etc.) available for a given country. Use the returned `id` as `payment_method_id` when creating payouts or adding beneficiary payment methods. ``` GET /payment-methods/payout?country={iso3} ``` ## Query parameters The destination country in ISO 3166-1 alpha-3 format (e.g. `CHL` for Chile, `MEX` for Mexico, `PER` for Peru). ```bash cURL — Chile theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout?country=CHL' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success — Chile theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": 42, "method_name": "Bank Transfer", "country": "CHL", "currency": "CLP", "base_currency": "USD" }, { "id": 43, "method_name": "Khipu", "country": "CHL", "currency": "CLP", "base_currency": "USD" } ] } ``` ```json Success — Mexico theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": 15, "method_name": "SPEI", "country": "MEX", "currency": "MXN", "base_currency": "USD" } ] } ``` # Get Payout Form Fields Source: https://docs.yativo.com/fiat-api-reference/payments/methods-form Retrieve the required form fields for a specific payout method Returns the dynamic form fields required to add a beneficiary payment method or execute a payout. Fields vary by country and payment method. ``` GET /beneficiary/form/show/{payment_method_id} ``` ## Path parameters The ID of the payment method, obtained from `GET /payment-methods/payout`. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/beneficiary/form/show/42' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success — Chile Bank Transfer theme={null} { "gateway_id": 42, "currency": "CLP", "form_data": [ { "key": "account_number", "label": "Account Number", "type": "text", "required": true }, { "key": "bank_code", "label": "Bank", "type": "select", "required": true, "options": [ { "value": "001", "label": "Banco de Chile" }, { "value": "009", "label": "Banco Internacional" } ] }, { "key": "account_type", "label": "Account Type", "type": "select", "required": true, "options": [ { "value": "checking", "label": "Checking Account" }, { "value": "savings", "label": "Savings Account" } ] }, { "key": "rut", "label": "RUT (Chilean Tax ID)", "type": "text", "required": true } ], "created_at": "2026-04-01T10:00:00.000000Z", "updated_at": "2026-04-01T10:00:00.000000Z" } ``` ```json Success — Mexico SPEI theme={null} { "gateway_id": 15, "currency": "MXN", "form_data": [ { "key": "clabe", "label": "CLABE", "type": "text", "required": true } ], "created_at": "2026-04-01T10:00:00.000000Z", "updated_at": "2026-04-01T10:00:00.000000Z" } ``` # Initiate Payout Source: https://docs.yativo.com/fiat-api-reference/payments/payout Send money to a beneficiary using a payment method Initiate an outgoing payment to a beneficiary. Use a `quote_id` to lock the exchange rate for 5 minutes and ensure the recipient receives the quoted amount. ``` POST /wallet/payout ``` Requires `Idempotency-Key` header. Use a unique key per payout to prevent duplicate transactions. ## Request body The source wallet currency to debit (e.g. `"USD"`, `"EUR"`). The ID of the beneficiary payment method to use. Obtained from `GET /payment-methods/payout` or saved beneficiary payment methods. A quote ID from `POST /exchange-rate` or `POST /sendmoney/quote`. When provided, the exchange rate is locked and `amount` is taken from the quote. Recommended to guarantee rates. Amount to send in the source wallet currency. Required if `quote_id` is not provided. If `quote_id` is provided, the amount is taken from the quote. The UUID of a saved beneficiary to pay. Using a `quote_id` is strongly recommended for cross-currency payouts to protect both you and your customers from exchange rate fluctuations during processing. ```bash cURL — With quote theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: payout-c586066b-2026-04-02-001' \ -d '{ "debit_wallet": "USD", "payment_method_id": 42, "quote_id": "qte_a1b2c3d4-e5f6-7890-abcd-ef1234567890", "beneficiary_id": "ben-7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d" }' ``` ```bash cURL — Without quote theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: payout-c586066b-2026-04-02-002' \ -d '{ "debit_wallet": "USD", "payment_method_id": 15, "amount": 500.00, "beneficiary_id": "ben-7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d" }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Payout initiated successfully", "data": { "transaction_id": "txn_f1e2d3c4-b5a6-7890-cdef-123456789abc", "status": "processing", "debit_wallet": "USD", "debit_amount": 100.00, "credit_currency": "CLP", "credit_amount": 95240.00, "exchange_rate": 952.40, "fee": 2.50, "payment_method_id": 42, "beneficiary_id": "ben-7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "created_at": "2026-04-02T10:00:00.000000Z" } } ``` ```json Insufficient Funds theme={null} { "status": "error", "status_code": 400, "message": "Insufficient wallet balance", "data": null } ``` # Send Money Source: https://docs.yativo.com/fiat-api-reference/payments/send-money Execute a cross-border payment using a locked quote Execute a cross-border payment using a quote ID obtained from `POST /sendmoney/quote`. The quote locks the exchange rate for 5 minutes. ``` POST /sendmoney ``` Requires an `Idempotency-Key` header. Get a quote first using `POST /sendmoney/quote` to lock your rate. ## Request Body The quote ID from `POST /sendmoney/quote`. Valid for 5 minutes. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/sendmoney' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-sendmoney-key' \ -d '{ "quote_id": "7b91acf8-9d2a-4e38-aa71-9babe9f785cd" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Payment initiated successfully", "data": { "transaction_id": "a0e9e50e-81be-4bd0-9941-0151e68b9e97", "status": "pending", "from_currency": "USD", "to_currency": "MXN", "amount": "200.00", "rate": "17.20", "created_at": "2026-04-01T10:00:00Z" } } ``` *** ## Wallet Payout (Alternative) For a quicker payout without the full send money flow: ``` POST /wallet/payout ``` Currency to debit from your wallet (e.g. `"USD"`). Saved beneficiary payment method ID. Quote ID to lock the rate. Recommended. Amount to send. Required if `quote_id` is not provided. ```bash With quote theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-payout-key' \ -d '{ "debit_wallet": "USD", "quote_id": "7b91acf8-9d2a-4e38-aa71-9babe9f785cd", "payment_method_id": 21 }' ``` # Get Send Money Quote Source: https://docs.yativo.com/fiat-api-reference/payments/send-money-quote Get a locked exchange rate quote for a send money transaction Generates a rate-locked quote for a cross-border payment. The quote guarantees the displayed rate and fee for **5 minutes**. Use the returned `quote_id` when executing the payment with `POST /sendmoney`. ``` POST /sendmoney/quote ``` Requires an `Idempotency-Key` header. ## Request Body Source currency code (e.g. `"USD"`, `"EUR"`). Destination currency code (e.g. `"CLP"`, `"MXN"`, `"BRL"`). Amount in the source currency to send. ```bash USD → CLP theme={null} curl -X POST 'https://api.yativo.com/api/v1/sendmoney/quote' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "from_currency": "USD", "to_currency": "CLP", "amount": 500 }' ``` ```bash USD → MXN theme={null} curl -X POST 'https://api.yativo.com/api/v1/sendmoney/quote' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "from_currency": "USD", "to_currency": "MXN", "amount": 200 }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "quote_id": "7b91acf8-9d2a-4e38-aa71-9babe9f785cd", "from_currency": "USD", "to_currency": "MXN", "rate": "17.20", "amount": "200.00", "payout_data": { "total_transaction_fee_in_from_currency": "8.00", "total_transaction_fee_in_to_currency": "137.60", "customer_sent_amount": "200.00", "customer_receive_amount": "3268.00", "customer_total_amount_due": "208.00" } } } ``` Quotes are valid for **5 minutes**. Execute `POST /sendmoney` with the `quote_id` within this window to guarantee the rate. # Batch Payout Source: https://docs.yativo.com/fiat-api-reference/payouts/batch POST https://api.yativo.com/api/v1/payout/batch Send multiple payments to different beneficiaries in a single request Submit an array of payouts in one request. Each item is processed independently — partial failures return in an `errors` object without rolling back successful items. ``` POST https://api.yativo.com/api/v1/payout/batch ``` Requires `Idempotency-Key` header. If your wallet balance is insufficient for the total amount, the entire batch is rejected before any item is processed. Array of payout objects. Amount to send for this payout. The saved beneficiary payment method ID. Optional beneficiary UUID for tracking. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/payout/batch' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: batch-payroll-june-001' \ -d '{ "payouts": [ { "amount": 500, "beneficiary_details_id": 41 }, { "amount": 750, "beneficiary_details_id": 42 }, { "amount": 300, "beneficiary_details_id": 43 } ] }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/payout/batch', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `batch-${Date.now()}`, }, body: JSON.stringify({ payouts: [ { amount: 500, beneficiary_details_id: 41 }, { amount: 750, beneficiary_details_id: 42 }, ], }), }); ``` ```json All successful theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "0": { "transaction_id": "txn-aaa", "status": "processing", "amount": "500.00" }, "1": { "transaction_id": "txn-bbb", "status": "processing", "amount": "750.00" }, "2": { "transaction_id": "txn-ccc", "status": "processing", "amount": "300.00" } } } ``` ```json Partial failure theme={null} { "status": "error", "status_code": 400, "data": { "errors": { "1": { "error": "Beneficiary not found" } } } } ``` # Get Payout Source: https://docs.yativo.com/fiat-api-reference/payouts/get Retrieve a single payout by ID Returns details for a specific payout. ``` GET https://api.yativo.com/api/v1/payout/fetch/{payout_id} ``` The UUID of the payout to retrieve. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payout/fetch/txn-a1b2c3d4-e5f6-7890-abcd-ef1234567890' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "id": "txn-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "amount": "250.00", "currency": "CLP", "status": "completed", "beneficiary_id": 42, "created_at": "2026-06-01T10:00:00.000000Z", "updated_at": "2026-06-01T10:02:00.000000Z" } } ``` ```json Not found theme={null} { "status": "error", "status_code": 404, "message": "Payout not found" } ``` # List Payouts Source: https://docs.yativo.com/fiat-api-reference/payouts/list Retrieve all payouts for your account Returns a paginated list of all payouts. ``` GET https://api.yativo.com/api/v1/payout/get ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payout/get' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": "txn-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "amount": "250.00", "currency": "CLP", "status": "completed", "beneficiary_id": 42, "created_at": "2026-06-01T10:00:00.000000Z" } ], "pagination": { "total": 48, "per_page": 15, "current_page": 1, "last_page": 4, "next_page_url": "https://api.yativo.com/api/v1/payout/get?page=2", "prev_page_url": null } } ``` # Single Payout Source: https://docs.yativo.com/fiat-api-reference/payouts/simple POST https://api.yativo.com/api/v1/payout/simple Send one payment to a saved beneficiary payment method Send a single payment to a saved beneficiary. Debits your wallet at the time of submission. ``` POST https://api.yativo.com/api/v1/payout/simple ``` Requires `Idempotency-Key` header. Your wallet is charged immediately on submission. The source wallet currency to debit (e.g. `"USD"`, `"EUR"`). Amount to send in the debit wallet currency. The saved beneficiary payment method ID (from `POST /beneficiaries/payment-methods`). Optional beneficiary UUID for tracking. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/payout/simple' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: payout-simple-001' \ -d '{ "debit_wallet": "USD", "amount": 250, "beneficiary_details_id": 42 }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "transaction_id": "txn-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "status": "processing", "amount": "250.00", "created_at": "2026-06-01T10:00:00.000000Z" } } ``` ```json Insufficient balance theme={null} { "status": "error", "status_code": 402, "message": "Insufficient wallet balance" } ``` # Initiate Swap Source: https://docs.yativo.com/fiat-api-reference/swap/init Preview the exchange rate and converted amount before executing a currency swap Preview a currency swap. Returns the live rate and resulting amount without committing any funds. Use this to show customers a confirmation screen before calling `/swap/process`. ``` POST https://api.yativo.com/api/v1/swap/init ``` Requires `Idempotency-Key` header. The rate shown here is indicative — it is fetched live again at execution time. Execute `/swap/process` promptly after previewing. The source wallet currency code (ISO 4217), e.g. `"USD"`, `"EUR"`. The target wallet currency code (ISO 4217), e.g. `"BRL"`, `"MXN"`. Amount in the source currency to convert. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/swap/init' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: swap-init-001' \ -d '{ "from_currency": "USD", "to_currency": "BRL", "amount": 500 }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "from_currency": "USD", "to_currency": "BRL", "from_amount": "500.00", "to_amount": "2491.00", "exchange_rate": "4.9820", "fee": "5.00", "fee_currency": "USD" } } ``` ```json Invalid currencies theme={null} { "status": "error", "status_code": 422, "message": "Invalid currencies supplied" } ``` # Process Swap Source: https://docs.yativo.com/fiat-api-reference/swap/process Execute a currency swap between two wallet balances Execute the currency conversion. Debits the `from_currency` wallet and credits the `to_currency` wallet at the live rate. ``` POST https://api.yativo.com/api/v1/swap/process ``` Requires `Idempotency-Key` header. Use a **new, unique key** for the process step — different from any key used in `/swap/init`. The source wallet currency code. The target wallet currency code. Amount in the source currency to convert. Optional description recorded on the transaction. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/swap/process' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: swap-process-001' \ -d '{ "from_currency": "USD", "to_currency": "BRL", "amount": 500, "transaction_purpose": "Fund BRL wallet for local payouts" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "from_currency": "USD", "to_currency": "BRL", "from_amount": "500.00", "to_amount": "2491.00", "exchange_rate": "4.9820", "transaction_type": "currency_swap", "created_at": "2026-06-01T10:00:00.000000Z" } } ``` ```json Insufficient balance theme={null} { "status": "error", "status_code": 400, "message": "Insufficient wallet balance" } ``` # Get Transaction Source: https://docs.yativo.com/fiat-api-reference/transactions/get Retrieve full details for a specific transaction Returns complete details for a single transaction by its internal numeric ID. ``` GET /business/transaction/show/{id} ``` ## Path Parameters The internal numeric transaction ID (the `id` field, not the `transaction_id` UUID). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/transaction/show/14' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "id": 14, "transaction_id": "a0e9e50e-81be-4bd0-9941-0151e68b9e97", "transaction_amount": "1000.00", "transaction_status": "success", "transaction_type": "deposit", "transaction_memo": "payin", "transaction_purpose": "Deposit", "transaction_currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "payin_method": { "id": 22, "method_name": "PIX", "country": "BRA", "currency": "BRL" }, "payout_method": null, "created_at": "2026-04-01T10:00:00.000000Z" } } ``` ```json Not Found theme={null} { "status": "error", "status_code": 404, "message": "Transaction not found", "data": null } ``` # List Transactions Source: https://docs.yativo.com/fiat-api-reference/transactions/list Retrieve a paginated list of all transactions in your account Returns all transactions (deposits, payouts, virtual account receipts, card transactions) for your business account with support for filtering and pagination. ``` GET /business/transactions/index ``` ## Query Parameters Filter by status: `success`, `complete`, `detected`, `pending`, `In Progress`, `failed`. From date (inclusive), e.g. `2026-04-01`. To date (inclusive), e.g. `2026-04-30`. Filter by exact transaction amount. Filter by customer ID. Filter by type: `deposit`, `payout`, `virtual_account`, `transfer`, `card_transaction`, `crypto_deposit`. Page number. Default: `1`. Results per page. Default: `10`. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/transactions/index?status=success&transaction_type=deposit&start_date=2026-04-01&end_date=2026-04-30&page=1&per_page=10' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Records retrieved successfully", "data": [ { "id": 14, "transaction_id": "a0e9e50e-81be-4bd0-9941-0151e68b9e97", "transaction_amount": "1000.00", "transaction_status": "success", "transaction_type": "deposit", "transaction_memo": "payin", "transaction_purpose": "Deposit", "transaction_currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "created_at": "2026-04-01T10:00:00.000000Z" } ], "meta": { "total": 42, "per_page": 10, "current_page": 1, "last_page": 5, "next_page_url": "https://api.yativo.com/api/v1/business/transactions/index?page=2", "prev_page_url": null } } ``` # Download Receipt Source: https://docs.yativo.com/fiat-api-reference/transactions/receipt Download a receipt for a completed transaction Returns a receipt for any completed transaction. Pass `pdf` as the `type` parameter to receive a base64-encoded PDF, or `json` for a structured data response. ``` GET https://api.yativo.com/api/v1/business/transaction/{transactionId}/{type}/receipt ``` ## Path parameters The UUID of the transaction. Receipt format. Use `"pdf"` to receive a base64-encoded PDF document. ```bash cURL — PDF receipt theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/transaction/a0e9e50e-81be-4bd0-9941-0151e68b9e97/pdf/receipt' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```javascript Node.js theme={null} const transactionId = 'a0e9e50e-81be-4bd0-9941-0151e68b9e97'; const type = 'pdf'; const response = await fetch( `https://api.yativo.com/api/v1/business/transaction/${transactionId}/${type}/receipt`, { headers: { 'Authorization': `Bearer ${token}` } } ); const data = await response.json(); // Decode and save the PDF import fs from 'fs'; const pdfBuffer = Buffer.from(data.data, 'base64'); fs.writeFileSync('receipt.pdf', pdfBuffer); ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": "JVBERi0xLjQKJeLjz9MKMiAwIG9iago8PC9MZW5ndGggMTM4Ni9GaWx0ZXIvRmxhdGVEZWNvZGU+Pg..." } ``` ```json Not found theme={null} { "status": "error", "status_code": 404, "message": "Transaction not found" } ``` The `data` field contains the PDF as a base64-encoded string. Decode it before writing to disk or serving to a client. # Track Transaction Source: https://docs.yativo.com/fiat-api-reference/transactions/track Get a live status timeline for a transaction Returns a step-by-step timeline of a transaction's progress from initiation through completion. ``` GET /v1/transaction/tracking/{quote_id} ``` ## Path Parameters The `quote_id` associated with the transaction. This is the quote ID returned when the transaction or quote was created — not a generic transaction ID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/transaction/tracking/4a72ecf8-6c8a-4e38-9971-8aabe9f785ed' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "tracking_status": "Payment credited to beneficiary", "transaction_type": "withdrawal", "created_at": "2026-04-01T10:03:22.000000Z" }, { "tracking_status": "With Beneficiary's Bank/Rail", "transaction_type": "withdrawal", "created_at": "2026-04-01T10:02:54.000000Z" }, { "tracking_status": "Processed by Yativo", "transaction_type": "withdrawal", "created_at": "2026-04-01T10:01:45.000000Z" }, { "tracking_status": "Send money initiated", "transaction_type": "withdrawal", "created_at": "2026-04-01T10:00:00.000000Z" } ] } ``` # Track Transaction by ID Source: https://docs.yativo.com/fiat-api-reference/transactions/track-by-id Look up a transaction by its transaction ID and type Returns a single transaction record by providing the transaction ID and transaction type. This is distinct from the timeline tracking endpoint (`GET /transaction/tracking/{id}`) which tracks by quote ID — this endpoint performs a direct lookup by the transaction's own ID. ``` GET /v1/transaction/track ``` ## Query Parameters The transaction ID to look up. The type of the transaction. Common values: `"payout"`, `"payin"`, `"swap"`. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/transaction/track?txn_id=TXN123456789&txn_type=payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "id": "a0e9e50e-81be-4bd0-9941-0151e68b9e97", "transaction_id": "TXN123456789", "type": "payout", "amount": "500.00", "currency": "USD", "status": "completed", "created_at": "2026-04-01T10:00:00.000000Z", "updated_at": "2026-04-01T10:03:22.000000Z" } } ``` ```json Not found theme={null} { "status": "error", "status_code": 404, "message": "Transaction not found" } ``` # All Virtual Account Histories Source: https://docs.yativo.com/fiat-api-reference/virtual-accounts/all-histories Retrieve deposit histories across all virtual accounts for your business Returns deposit histories across all virtual accounts associated with the authenticated business. Use this to get a consolidated view of all incoming payments without querying each account individually. ``` GET /v1/business/virtual-account/histories ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account/histories' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "amount": 1000, "currency": "BRL", "status": "completed", "credited_amount": 950, "transaction_id": "TXNMP2HK81BHJ", "sender_name": "John Smith", "account_number": "9900123456", "transaction_fees": 50, "created_at": "2026-04-01T10:00:00Z" }, { "amount": 500, "currency": "CLP", "status": "completed", "credited_amount": 480, "transaction_id": "TXNQR3JL92CIK", "sender_name": "Ana Rodriguez", "account_number": "9900654321", "transaction_fees": 20, "created_at": "2026-04-02T14:30:00Z" } ] } ``` # Create Virtual Account Source: https://docs.yativo.com/fiat-api-reference/virtual-accounts/create Issue a virtual bank account to a customer to receive funds Create a virtual bank account for a customer. The customer must have KYC approved (`is_va_approved: true`) before a virtual account can be issued. ``` POST /v1/business/virtual-account/create ``` Requires an `Idempotency-Key` header. Each customer can hold one virtual account per currency. ## Request Body Currency for the virtual account. Supported values: `MXN`, `BRL`, `USD`, `EUR`, `MXN_USD`, `MXN_BASE`, `MXNBASE`, `EURBASE`, `USDBASE`, `EUR_BASE`, `USD_BASE`, `EURDE`, `USDDE`, `GBP`, `USD_KIRA`, `USDKIRA`. The UUID of the KYC-approved customer. **Required when currency is `USD`**; optional for other currencies. ```bash Brazil (PIX / BRL) theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "currency": "BRL" }' ``` ```bash USD (ACH) theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "USD" }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Virtual account creation in progress", "data": { "account_id": "va_xxxxxx", "account_number": "9900123456", "account_type": "savings", "currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "created_at": "2026-04-01T10:00:00Z" } } ``` # Customer Virtual Accounts Source: https://docs.yativo.com/fiat-api-reference/virtual-accounts/customer-accounts Retrieve all virtual accounts associated with a specific customer Returns all virtual accounts associated with a specific customer, identified by their customer ID. ``` GET /v1/business/virtual-account/customer/accounts/{customerId} ``` ## Path Parameters The unique ID of the customer whose virtual accounts you want to retrieve. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account/customer/accounts/c586066b-0f29-468f-b775-15483871a202' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": "va_a1b2c3d4-e5f6-7890-abcd-ef1234567890", "account_number": "9900123456", "account_name": "John Smith", "currency": "BRL", "bank_name": "Example Bank", "status": "active", "customer_id": "c586066b-0f29-468f-b775-15483871a202", "created_at": "2026-03-15T09:00:00.000000Z" }, { "id": "va_b2c3d4e5-f6a7-8901-bcde-f12345678901", "account_number": "9900654321", "account_name": "John Smith", "currency": "CLP", "bank_name": "Example Bank", "status": "active", "customer_id": "c586066b-0f29-468f-b775-15483871a202", "created_at": "2026-03-20T11:00:00.000000Z" } ], "pagination": { "total": 2, "per_page": 20, "current_page": 1, "last_page": 1, "next_page_url": null, "prev_page_url": null } } ``` ```json Customer not found theme={null} { "status": "error", "status_code": 404, "message": "Customer not found" } ``` # Delete Virtual Account Source: https://docs.yativo.com/fiat-api-reference/virtual-accounts/delete Permanently delete a virtual account Permanently deletes a virtual account. This action is irreversible. ``` DELETE /v1/business/virtual-account/delete-virtual-account/{account_id} ``` ## Path Parameters The ID of the virtual account to delete. ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/business/virtual-account/delete-virtual-account/acct_xxxxxx' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Virtual account deleted successfully", "data": null } ``` Deleting a virtual account is permanent and cannot be undone. Ensure any pending transactions are resolved before deleting. # Get Virtual Account Source: https://docs.yativo.com/fiat-api-reference/virtual-accounts/get Retrieve details for a specific virtual account Returns full details for a specific virtual account by its external ID. ``` GET /v1/business/virtual-account/show/{externalId} ``` ## Path Parameters The external ID of the virtual account. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account/show/va_xxxxxx' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "account_id": "va_xxxxxx", "account_number": "9900123456", "account_type": "savings", "currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "status": "active", "created_at": "2026-04-01T10:00:00Z" } } ``` ```json Not Found theme={null} { "status": "error", "status_code": 404, "message": "Virtual account not found", "data": null } ``` # Virtual Account Transaction History Source: https://docs.yativo.com/fiat-api-reference/virtual-accounts/history Retrieve payment history for a specific virtual account Returns all payments received into a specific virtual account. ``` GET /v1/business/virtual-account/history/{accountNumber} ``` Both GET and POST methods are accepted, but GET is recommended. ## Path Parameters The account number (not the account ID). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account/history/9900123456' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Records retrieved successfully", "data": [ { "amount": 1000, "currency": "BRL", "status": "completed", "credited_amount": 950, "transaction_id": "TXNMP2HK81BHJ", "sender_name": "John Smith", "account_number": "9900123456", "transaction_fees": 50, "created_at": "2026-04-01T10:00:00Z" } ], "pagination": { "total": 12, "per_page": 20, "current_page": 1, "last_page": 1, "next_page_url": null, "prev_page_url": null } } ``` # List Virtual Accounts Source: https://docs.yativo.com/fiat-api-reference/virtual-accounts/list Retrieve all virtual accounts associated with your business Returns all virtual accounts for your business with optional filtering. ``` GET /v1/business/virtual-account ``` ## Query Parameters Filter by currency code (e.g. `BRL`, `USD`). Filter by account status. From date (ISO 8601), e.g. `2026-04-01`. To date (ISO 8601), e.g. `2026-04-30`. Search by account name or account number. Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account?currency=BRL&per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "account_id": "va_xxxxxx", "account_number": "9900123456", "account_type": "savings", "currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "status": "active", "created_at": "2026-04-01T10:00:00Z" } ], "pagination": { "total": 8, "per_page": 20, "current_page": 1, "last_page": 1, "next_page_url": null, "prev_page_url": null } } ``` # Activate Customer for Virtual Cards Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/activate Enroll a customer in the virtual card program Registers a customer for virtual card creation. This enrollment step is required before issuing any virtual cards to the customer. Fields that are already stored on the customer's profile may be omitted. ``` POST https://api.yativo.com/api/v1/customer/virtual/cards/activate ``` Requires an `Idempotency-Key` header. ## Request Body The ID of the customer to activate. Must exist in your customers table. Customer photo (base64 or URL). Required if not already on the customer's profile. Government ID type (e.g. `"passport"`, `"drivers_license"`, `"national_id"`). Required for Nigerian customers. Front image of the customer's government-issued ID. Required if not already on the customer's profile. Government-issued ID number. Required if not already on the customer's profile. Customer address. Each sub-field is required if not already on the customer's profile. ISO 3166-1 alpha-2 country code (e.g. `"US"`). City name. State or region. Postal / ZIP code. Street name. Street number. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/activate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: activate-da44a3e6-001' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "user_photo": "https://example.com/photo.jpg", "idType": "passport", "customer_idFront": "https://example.com/id-front.jpg", "customer_idNumber": "A12345678", "customer_address": { "country": "US", "city": "New York", "state": "NY", "zipcode": "10001", "street": "Main St", "number": "123" } }' ``` ```json Success theme={null} { "success": "User registered successfully." } ``` # Create Virtual Card Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/create Issue a virtual prepaid card to an activated customer Creates a virtual card for a customer who has been activated for the virtual card program. The initial funding amount is debited from your USD wallet. ``` POST https://api.yativo.com/api/v1/customer/virtual/cards/create ``` Requires an `Idempotency-Key` header. ## Request Body The ID of the activated customer. Must exist in your customers table. Initial funding amount in USD. Minimum $3.00, maximum $10,000.00. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: card-create-da44a3e6-001' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "amount": 10.00 }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Virtual card created successfully", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "card_number": "4111 **** **** 1234", "expiry": "04/29", "currency": "USD", "balance": "10.00", "status": "active", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "created_at": "2026-04-01T10:00:00Z" } } ``` # Get Virtual Card Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/get Retrieve details for a specific virtual card Returns full details for a specific virtual card by its ID. ``` GET https://api.yativo.com/api/v1/customer/virtual/cards/get/{card_id} ``` ## Path Parameters The virtual card ID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/virtual/cards/get/card_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "card_number": "4111111111111234", "expiry": "04/29", "cvv": "123", "currency": "USD", "balance": "150.00", "status": "active", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "created_at": "2026-04-01T10:00:00Z" } } ``` # List Virtual Cards Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/list Retrieve all virtual cards issued to customers Returns all virtual cards issued under your business account. ``` GET https://api.yativo.com/api/v1/customer/virtual/cards/list ``` ## Query Parameters Page number. Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/virtual/cards/list?page=1&per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Records retrieved successfully", "data": [ { "id": "e6f2f9d0-2d4f-4b4f-9d9f-2f1f8f9e3a7e", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "customer_card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "card_number": "4111111111111234", "expiry_date": "04/29", "cvv": "123", "card_status": "active", "raw_data": { "cardName": "Main Expense Card", "cardBrand": "visa" } } ], "pagination": { "total": 5, "per_page": 20, "current_page": 1, "last_page": 1, "next_page_url": null, "prev_page_url": null } } ``` # Terminate Card Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/terminate Permanently cancel a virtual card Permanently terminates a virtual card. This action is irreversible. Withdraw any remaining balance before terminating. ``` POST https://api.yativo.com/api/v1/customer/virtual/cards/terminate ``` Requires an `Idempotency-Key` header. ## Request Body The virtual card ID to terminate. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/terminate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: terminate-card-001' \ -d '{ "cardId": "card_01HX9KZMB3F7VNQP8R2WDGT4E5" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Card terminated successfully", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "status": "terminated" } } ``` Card termination is permanent and cannot be undone. Withdraw remaining funds before terminating. # Top Up Card Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/topup Fund a virtual card from your USD wallet balance Adds funds to a virtual card. The amount is always debited from your USD wallet. ``` POST https://api.yativo.com/api/v1/customer/virtual/cards/topup ``` Requires an `Idempotency-Key` header. ## Request Body The virtual card ID to fund. Either `cardId` or `card_id` must be provided. The virtual card ID to fund. Either `cardId` or `card_id` must be provided. Amount to add to the card. Minimum 1.00, maximum 10,000.00 (USD). ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/topup' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: topup-card-001' \ -d '{ "cardId": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 100.00 }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Card topped up successfully", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount_added": "100.00", "new_balance": "250.00", "currency": "USD" } } ``` # Card Transactions Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/transactions Retrieve transaction history for a virtual card Returns all transactions made with a specific virtual card. ``` GET https://api.yativo.com/api/v1/customer/virtual/cards/transactions/{card_id} ``` ## Path Parameters The virtual card ID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/virtual/cards/transactions/card_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": "29.99", "currency": "USD", "merchant_name": "Amazon", "merchant_category": "Online Retail", "status": "completed", "created_at": "2026-04-01T14:22:00Z" }, { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E4", "amount": "12.50", "currency": "USD", "merchant_name": "Spotify", "merchant_category": "Digital Services", "status": "completed", "created_at": "2026-04-01T08:00:00Z" } ] } ``` # Freeze / Unfreeze Card Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/update Temporarily freeze or unfreeze a virtual card Freeze or unfreeze a virtual card. A frozen card declines all transactions until it is unfrozen. ``` PUT https://api.yativo.com/api/v1/customer/virtual/cards/update/{card_id} ``` Requires an `Idempotency-Key` header. ## Path Parameters The virtual card ID. ## Request Body `"freeze"` to block the card, or `"unfreeze"` to re-enable it. ```bash Freeze theme={null} curl -X PUT 'https://api.yativo.com/api/v1/customer/virtual/cards/update/card_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: freeze-card-001' \ -d '{ "action": "freeze" }' ``` ```bash Unfreeze theme={null} curl -X PUT 'https://api.yativo.com/api/v1/customer/virtual/cards/update/card_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: freeze-card-001' \ -d '{ "action": "unfreeze" }' ``` ```json Success theme={null} { "action": { ... } } ``` # Withdraw from Card Source: https://docs.yativo.com/fiat-api-reference/virtual-cards/withdraw Move funds from a virtual card back to your wallet Withdraws funds from a virtual card back to your USD wallet balance. ``` POST https://api.yativo.com/api/v1/customer/virtual/cards/withdraw ``` Requires an `Idempotency-Key` header. ## Request Body The virtual card ID to withdraw from. Amount to withdraw from the card. Minimum 1.00. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/withdraw' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: withdraw-card-001' \ -d '{ "cardId": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 50 }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Withdrawal successful", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount_withdrawn": "50.00", "new_card_balance": "100.00", "currency": "USD" } } ``` # Get Wallet Balance Source: https://docs.yativo.com/fiat-api-reference/wallets/balance Retrieve current balances across all currency wallets Returns the current balance for all wallets on your account. All wallet balances are returned regardless of currency. ``` GET /wallet/balance ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/balance' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "name": "USD", "slug": "usd", "balance": "35585.00", "currency": "USD", "decimal_places": 2, "meta": { "logo": "https://cdn.yativo.com/usd.svg", "symbol": "$", "fullname": "US Dollar", "precision": 2 } }, { "name": "BRL", "slug": "brl", "balance": "14200.00", "currency": "BRL", "decimal_places": 2, "meta": { "logo": "https://cdn.yativo.com/brl.svg", "symbol": "R$", "fullname": "Brazilian Real", "precision": "2" } } ] } ``` *** ## Get Total Balance Returns the sum of all wallet balances converted to USD: ``` GET /wallet/balance/total ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/balance/total' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "total_balance": 37629.18 } } ``` # Create Wallet Source: https://docs.yativo.com/fiat-api-reference/wallets/create Create a new currency wallet for your account Create a new wallet to hold a specific currency. Once created, the wallet appears in your balance list with a zero balance. ``` POST /wallet/create ``` Requires an `Idempotency-Key` header. ## Request Body The currency code for the new wallet (e.g. `COP`, `PEN`, `ARS`, `CLP`). ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "currency": "COP" }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Wallet created successfully", "data": { "currency": "COP", "balance": "0.00", "created_at": "2026-04-01T10:00:00Z" } } ``` # List Wallet Payouts Source: https://docs.yativo.com/fiat-api-reference/wallets/payouts Retrieve payout transactions from your wallets Returns a list of payout (withdrawal) transactions made from the authenticated user's wallets. ``` GET /v1/wallet/payouts ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/payouts' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "amount": "200.00", "currency": "USD", "status": "completed", "recipient": "John Smith", "reference": "PAY-20260401-001", "created_at": "2026-04-01T10:00:00.000000Z" }, { "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "amount": "1500.00", "currency": "BRL", "status": "pending", "recipient": "Maria Santos", "reference": "PAY-20260401-002", "created_at": "2026-04-01T11:30:00.000000Z" } ] } ``` # Create / Update Webhook Source: https://docs.yativo.com/fiat-api-reference/webhooks/create Set or update your webhook endpoint to receive real-time event notifications Set a URL to receive webhook notifications for events in your Yativo account. Yativo sends a `POST` request to your endpoint whenever a matching event occurs and signs every request with an `X-Yativo-Signature` header for verification. ``` POST /business/webhook ``` Requires an `Idempotency-Key` header. To update an existing webhook, send `PUT /business/webhook/{webhook}` with the webhook ID returned from this endpoint. ## Request Body The HTTPS URL of your webhook endpoint. Must be publicly accessible. ## Supported Events | Event | Description | | ------------------------- | ---------------------------------------- | | `deposit.created` | A deposit was initiated | | `deposit.updated` | A deposit status changed | | `deposit.completed` | A deposit was received and credited | | `payout.updated` | A payout status changed | | `payout.completed` | A payout was delivered successfully | | `customer.created` | A new customer was created | | `customer.kyc.approved` | Customer KYC was approved | | `customer.kyc.rejected` | Customer KYC was rejected | | `virtual_account.deposit` | A payment arrived at a virtual account | | `virtual_account.funded` | A virtual account received settled funds | ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/webhook' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "url": "https://your-app.com/webhooks/yativo" }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Webhook configured successfully", "data": { "url": "https://your-app.com/webhooks/yativo", "secret": "whsec_a1b2c3d4e5f6...", "created_at": "2026-04-01T10:00:00.000000Z" } } ``` *** ## Signature Verification Every webhook delivery includes an `X-Yativo-Signature` header — an HMAC SHA256 hex digest of the raw request body signed with your webhook secret. **Algorithm:** ``` X-Yativo-Signature = HMAC-SHA256(webhookSecret, rawRequestBody) → hex ``` Always verify the signature before processing any event. Use **constant-time comparison** to prevent timing attacks — never a plain string equality check. Compute the HMAC over the **raw request body bytes** — not a re-serialized version of parsed JSON. Parsing and re-stringifying can change whitespace or key ordering, causing signature mismatches. ### Verification examples ```javascript Node.js theme={null} const crypto = require('crypto'); app.post('/webhooks/yativo', express.raw({ type: 'application/json' }), (req, res) => { const secret = process.env.YATIVO_WEBHOOK_SECRET; const receivedSignature = req.headers['x-yativo-signature']; const expectedSignature = crypto .createHmac('sha256', secret) .update(req.body) .digest('hex'); if (!crypto.timingSafeEqual( Buffer.from(expectedSignature), Buffer.from(receivedSignature) )) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(req.body); // safe to process res.status(200).send('OK'); }); ``` ```python Python theme={null} import hmac, hashlib, os from flask import Flask, request, abort @app.route('/webhooks/yativo', methods=['POST']) def webhook(): secret = os.environ['YATIVO_WEBHOOK_SECRET'] received = request.headers.get('X-Yativo-Signature', '') expected = hmac.new( secret.encode(), request.data, hashlib.sha256 ).hexdigest() if not hmac.compare_digest(expected, received): abort(401) event = request.get_json() return 'OK', 200 ``` ```php PHP theme={null} $secret = getenv('YATIVO_WEBHOOK_SECRET'); $received = $_SERVER['HTTP_X_YATIVO_SIGNATURE'] ?? ''; $payload = file_get_contents('php://input'); $expected = hash_hmac('sha256', $payload, $secret); if (!hash_equals($expected, $received)) { http_response_code(401); exit('Invalid signature'); } $event = json_decode($payload, true); ``` ```go Go theme={null} func webhookHandler(w http.ResponseWriter, r *http.Request) { secret := []byte(os.Getenv("YATIVO_WEBHOOK_SECRET")) received := r.Header.Get("X-Yativo-Signature") body, _ := io.ReadAll(r.Body) mac := hmac.New(sha256.New, secret) mac.Write(body) expected := hex.EncodeToString(mac.Sum(nil)) if !hmac.Equal([]byte(expected), []byte(received)) { http.Error(w, "Invalid signature", http.StatusUnauthorized) return } w.WriteHeader(http.StatusOK) } ``` ```java Java theme={null} Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256")); byte[] rawHmac = mac.doFinal(rawBody); StringBuilder hex = new StringBuilder(); for (byte b : rawHmac) hex.append(String.format("%02x", b)); String expected = hex.toString(); if (!MessageDigest.isEqual(expected.getBytes(), received.getBytes())) { return ResponseEntity.status(401).body("Invalid signature"); } ``` ```ruby Ruby theme={null} expected = OpenSSL::HMAC.hexdigest('SHA256', secret, payload) unless Rack::Utils.secure_compare(expected, received) halt 401, 'Invalid signature' end ``` ```csharp C# (.NET) theme={null} using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret)); var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(rawBody)); var expected = BitConverter.ToString(hash).Replace("-", "").ToLower(); if (!CryptographicOperations.FixedTimeEquals( Encoding.UTF8.GetBytes(expected), Encoding.UTF8.GetBytes(received) )) return Unauthorized(); ``` # Delete Webhook Source: https://docs.yativo.com/fiat-api-reference/webhooks/delete Remove a registered webhook endpoint Delete a webhook endpoint. Yativo will stop delivering events to this URL immediately. ``` DELETE https://api.yativo.com/api/v1/business/webhook/{webhook_id} ``` ## Path parameters The ID of the webhook to delete. Returned when the webhook was created. ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/business/webhook/wh-01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```javascript Node.js theme={null} const response = await fetch( `https://api.yativo.com/api/v1/business/webhook/${webhookId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` }, } ); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Webhook deleted successfully" } ``` ```json Not found theme={null} { "status": "error", "status_code": 404, "message": "Webhook not found" } ``` # List Webhooks Source: https://docs.yativo.com/fiat-api-reference/webhooks/list Retrieve all configured webhook endpoints for your business account Returns all configured webhook endpoints for your business account. ``` GET /business/webhook ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/webhook' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": "wh_a1b2c3d4-e5f6-7890-abcd-ef1234567890", "url": "https://your-app.com/webhooks/yativo", "events": "general", "created_at": "2026-04-01T10:00:00.000000Z" } ] } ``` # Accept Crypto Payments Source: https://docs.yativo.com/guides/accept-crypto-payments Set up a crypto deposit flow for your application This guide walks you through the full flow for accepting crypto deposits: creating a custodial account, generating wallet addresses per chain, registering webhooks, and crediting user accounts when deposits confirm. Test this entire flow against the Sandbox at `https://crypto-sandbox.yativo.com/api/v1/` before going live. Sandbox deposits are simulated — no real funds are used. ## Overview The deposit flow has four components: 1. **Account** — a logical container for assets belonging to one user or entity 2. **Wallet addresses** — per-chain addresses derived from the account 3. **Webhooks** — real-time notifications when deposits are detected and confirmed 4. **Business logic** — your code credits the user after confirming the deposit Each user or entity in your system maps to a Yativo account. Create one at onboarding time and store the returned `accountId`. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/accounts/create-account \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -d '{ "label": "alice_account", "metadata": { "userId": "usr_01HYZPQR3NMVK8F2GXB7T9D4CE", "email": "alice@example.com" } }' ``` ```typescript TypeScript theme={null} import { YativoCrypto } from "@yativo/crypto-sdk"; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, baseUrl: "https://crypto-api.yativo.com/api/v1/", }); const account = await client.accounts.create({ label: "alice_account", metadata: { userId: "usr_01HYZPQR3NMVK8F2GXB7T9D4CE", email: "alice@example.com", }, }); console.log(account.accountId); // acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y ``` ```python Python theme={null} from yativo_crypto import YativoCrypto client = YativoCrypto( api_key=os.environ["YATIVO_API_KEY"], base_url="https://crypto-api.yativo.com/api/v1/", ) account = client.accounts.create( label="alice_account", metadata={ "userId": "usr_01HYZPQR3NMVK8F2GXB7T9D4CE", "email": "alice@example.com", }, ) print(account.account_id) # acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y ``` **Response:** ```json theme={null} { "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", "label": "alice_account", "status": "active", "metadata": { "userId": "usr_01HYZPQR3NMVK8F2GXB7T9D4CE", "email": "alice@example.com" }, "createdAt": "2026-03-26T10:00:00Z" } ``` Store `accountId` in your database alongside the user record. You will reference it for every wallet and transaction operation. For each blockchain you want to support, add an asset to the account. This returns a deposit address on that chain. ```bash cURL theme={null} # Ethereum (ERC-20 / ETH) curl -X POST https://crypto-api.yativo.com/api/v1/assets/add-asset \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -d '{ "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", "chain": "ethereum", "asset": "USDC" }' ``` ```typescript TypeScript theme={null} const chains = ["ethereum", "polygon", "base", "solana", "tron"]; const wallets = await Promise.all( chains.map((chain) => client.assets.addAsset({ accountId: "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", chain, asset: "USDC", }) ) ); // wallets[0] = { chain: "ethereum", address: "0x742d35Cc6634C0532925a3b8D4C9D5b9a1f4e8Bd", ... } // wallets[1] = { chain: "polygon", address: "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD", ... } // wallets[2] = { chain: "base", address: "0x89D24A6b4CcB1B6fAA2625fE562bDD9a23260359", ... } // wallets[3] = { chain: "solana", address: "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV", ... } // wallets[4] = { chain: "tron", address: "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE", ... } ``` ```python Python theme={null} chains = ["ethereum", "polygon", "base", "solana", "tron"] wallets = [ client.assets.add_asset( account_id="acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", chain=chain, asset="USDC", ) for chain in chains ] ``` **Response (Ethereum example):** ```json theme={null} { "assetId": "ast_01J2KBMNPQ7R4S5T6U7V8W9XEth", "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", "chain": "ethereum", "asset": "USDC", "address": "0x742d35Cc6634C0532925a3b8D4C9D5b9a1f4e8Bd", "balance": "0.000000", "createdAt": "2026-03-26T10:01:00Z" } ``` Register a webhook endpoint to receive `deposit.detected` (immediate, unconfirmed) and `deposit.confirmed` (safe to credit) events. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/webhook/create \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://api.yourapp.com/webhooks/yativo", "events": ["deposit.detected", "deposit.confirmed"], "description": "Crypto deposit notifications" }' ``` ```typescript TypeScript theme={null} const webhook = await client.webhooks.create({ url: "https://api.yourapp.com/webhooks/yativo", events: ["deposit.detected", "deposit.confirmed"], description: "Crypto deposit notifications", }); console.log(webhook.webhookId); // wh_01J2KCMNPQ3R4S5T6U7VWEBHK console.log(webhook.secret); // whsec_a8f3c2e1d4b7... (store this securely!) ``` ```python Python theme={null} webhook = client.webhooks.create( url="https://api.yourapp.com/webhooks/yativo", events=["deposit.detected", "deposit.confirmed"], description="Crypto deposit notifications", ) print(webhook.webhook_id) # wh_01J2KCMNPQ3R4S5T6U7VWEBHK print(webhook.secret) # whsec_a8f3c2e1d4b7... — store securely! ``` **Response:** ```json theme={null} { "webhookId": "wh_01J2KCMNPQ3R4S5T6U7VWEBHK", "url": "https://api.yourapp.com/webhooks/yativo", "events": ["deposit.detected", "deposit.confirmed"], "status": "active", "secret": "whsec_a8f3c2e1d4b7f9e2c5a3b6d8f1e4c7a2b5d8e1f4", "createdAt": "2026-03-26T10:02:00Z" } ``` Store `secret` securely (e.g., in an environment variable). It is only returned once and is used to verify webhook signatures. See [Step 6](#step-6-verify-webhook-signatures) for verification details. Fetch the wallet addresses for an account and present them in your UI. Users send crypto to these addresses. ```typescript TypeScript theme={null} // In your backend — return wallet addresses to your frontend app.get("/api/deposit-addresses/:userId", async (req, res) => { const user = await db.users.findById(req.params.userId); const assets = await client.assets.listByAccount(user.yativoAccountId); const addresses = assets.map((a) => ({ chain: a.chain, asset: a.asset, address: a.address, network: a.networkLabel, // "Ethereum Mainnet", "Polygon", etc. })); res.json({ addresses }); }); ``` ```python Python theme={null} # Flask example @app.route("/api/deposit-addresses/") def get_deposit_addresses(user_id): user = db.users.find_by_id(user_id) assets = client.assets.list_by_account(user.yativo_account_id) addresses = [ { "chain": a.chain, "asset": a.asset, "address": a.address, "network": a.network_label, } for a in assets ] return jsonify({"addresses": addresses}) ``` Show a QR code for each address in your UI — most crypto wallets can scan them directly. When a deposit confirms, your webhook handler receives a `deposit.confirmed` event. Verify the signature (next step), then credit the user. Here is a complete Express.js webhook handler: ```typescript TypeScript (Express webhook handler) theme={null} import express from "express"; import crypto from "crypto"; const app = express(); // Use raw body for signature verification app.use( "/webhooks/yativo", express.raw({ type: "application/json" }), async (req, res) => { // 1. Verify signature immediately const signature = req.headers["x-webhook-signature"] as string; const secret = process.env.YATIVO_WEBHOOK_SECRET!; const expectedSig = crypto .createHmac("sha256", secret) .update(req.body) .digest("hex"); if ( !signature || !crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSig) ) ) { return res.status(401).json({ error: "Invalid signature" }); } // 2. Parse event const event = JSON.parse(req.body.toString()); // 3. Return 200 immediately — process async res.sendStatus(200); // 4. Process asynchronously setImmediate(async () => { try { await processEvent(event); } catch (err) { console.error("Failed to process event", event.eventId, err); } }); } ); async function processEvent(event: any) { // Idempotency: skip already-processed events const alreadyProcessed = await db.events.exists(event.eventId); if (alreadyProcessed) return; switch (event.type) { case "deposit.detected": // Optionally notify user of pending deposit — don't credit yet await notifyUserPendingDeposit(event.data); break; case "deposit.confirmed": const { accountId, amount, asset, chain, txHash } = event.data; // Look up the user by accountId const user = await db.users.findByYativoAccountId(accountId); if (!user) { console.warn("No user found for accountId", accountId); return; } // Credit the user await db.balances.credit(user.id, asset, amount); await db.transactions.record({ userId: user.id, type: "deposit", asset, chain, amount, txHash, yativoEventId: event.eventId, }); await notifyUserDepositConfirmed(user, amount, asset); break; } // Mark event as processed await db.events.markProcessed(event.eventId); } ``` All webhook requests from Yativo include an `X-Webhook-Signature` header containing an HMAC-SHA256 signature of the raw request body. ```typescript TypeScript theme={null} function verifyWebhookSignature( rawBody: Buffer, signatureHeader: string, secret: string ): boolean { const expected = crypto .createHmac("sha256", secret) .update(rawBody) .digest("hex"); // Use timing-safe comparison to prevent timing attacks return crypto.timingSafeEqual( Buffer.from(signatureHeader), Buffer.from(expected) ); } ``` ```python Python theme={null} import hmac import hashlib def verify_webhook_signature(raw_body: bytes, signature_header: str, secret: str) -> bool: expected = hmac.new( secret.encode("utf-8"), raw_body, hashlib.sha256, ).hexdigest() # Use compare_digest to prevent timing attacks return hmac.compare_digest(signature_header, expected) ``` ```php PHP theme={null} function verifyWebhookSignature(string $rawBody, string $signatureHeader, string $secret): bool { $expected = hash_hmac('sha256', $rawBody, $secret); return hash_equals($expected, $signatureHeader); } ``` ## Webhook Payload: `deposit.confirmed` ```json theme={null} { "eventId": "evt_01J2KF3MNPQ7R4S5T6U7VDPST1", "type": "deposit.confirmed", "createdAt": "2026-03-26T10:15:32Z", "data": { "depositId": "dep_01J2KF3MNPQ7R4S5T6U7VDEP42", "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", "assetId": "ast_01J2KBMNPQ7R4S5T6U7V8W9XEth", "chain": "ethereum", "asset": "USDC", "amount": "250.000000", "address": "0x742d35Cc6634C0532925a3b8D4C9D5b9a1f4e8Bd", "txHash": "0x4a7d3f2e1c8b5a9e2f4d7c3b6a1e8d2f5c4b3a7e1d9f2c5b8a4e3d7c1b6a2f", "blockNumber": 19847201, "confirmations": 12, "networkFee": "0.001823", "metadata": { "userId": "usr_01HYZPQR3NMVK8F2GXB7T9D4CE" } } } ``` ## Next Steps * See **[Webhook Integration](/guides/webhook-integration)** for the full webhook reference including all event types and retry policy. * Use **[Send Crypto](/guides/send-crypto)** to move funds back out on behalf of users. # Set Up Agentic Wallets Source: https://docs.yativo.com/guides/agentic-wallets Create a programmable wallet for your AI agent in under 10 minutes This guide walks you through creating an agentic wallet, generating a connector API key, and making your first agent-initiated payment. *** ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/agentic-wallets/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "name": "My AI Agent Wallet" }' ``` ```json Response theme={null} { "success": true, "data": { "wallet_id": "aw_01HX9KZMB3F7VNQP8R2WDGT4E5", "name": "My AI Agent Wallet", "status": "pending_activation", "created_at": "2026-03-25T10:00:00Z" } } ``` Save the `wallet_id` from the response. Request an activation OTP: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/agentic-wallets/aw_.../activation/send-email-otp' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Response theme={null} { "success": true, "message": "OTP sent to your registered email" } ``` Enter the OTP from your email to activate: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/agentic-wallets/aw_.../activation/activate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "email_otp": "123456" }' ``` ```json Response theme={null} { "success": true, "data": { "wallet_id": "aw_01HX9KZMB3F7VNQP8R2WDGT4E5", "status": "active", "address": "0x9F8b2E...a4C7", "chain": "solana", "activated_at": "2026-03-25T10:05:00Z" } } ``` Create an API key for your agent: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/agentic-wallets/aw_.../connectors' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "name": "Production Agent", "per_transaction_limit": 50, "daily_limit": 500, "monthly_limit": 5000 }' ``` ```json Response theme={null} { "success": true, "data": { "connector_id": "conn_01HX9KZMB3F7VNQP8R2WDGT", "name": "Production Agent", "api_key": "yac_e072b3ef7e30fcb420183aa86ddd8452", "per_transaction_limit": 50, "daily_limit": 500, "monthly_limit": 5000, "created_at": "2026-03-25T10:10:00Z" } } ``` Save the `api_key` (starts with `yac_`) — it's shown only once. Deposit USDC to the wallet's on-chain address, or use manual funding: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/agentic-wallets/aw_.../fund' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "amount": 100 }' ``` ```json Response theme={null} { "success": true, "data": { "wallet_id": "aw_01HX9KZMB3F7VNQP8R2WDGT4E5", "funded_amount": 100, "balance": 100, "currency": "USDC" } } ``` Using the connector API key, send a payment: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/agent/transact' \ -H 'Authorization: Bearer yac_your_connector_key' \ -H 'Content-Type: application/json' \ -d '{ "wallet_id": "aw_...", "amount": 5.00, "recipient_address": "0x9F8b...", "service_name": "OpenAI", "payment_reason": "GPT-4 inference" }' ``` ```json Response theme={null} { "success": true, "data": { "transaction_id": "atx_01HX9KZMB3F7VNQP8R2WDGT", "wallet_id": "aw_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 5.00, "recipient_address": "0x9F8b...", "service_name": "OpenAI", "status": "confirmed", "tx_hash": "0xabc123...", "created_at": "2026-03-25T10:15:00Z" } } ``` *** ## Using with the MCP Server For AI agents that support the Model Context Protocol, skip the API calls and use the MCP server: ```bash theme={null} npm install -g @yativo/mcp-server ``` Then configure it in your AI client (e.g., Claude Desktop): ```json theme={null} { "mcpServers": { "yativo-wallet": { "command": "npx", "args": ["-y", "@yativo/mcp-server"], "env": { "YATIVO_API_KEY": "yac_your_connector_key", "YATIVO_WALLET_ID": "aw_your_wallet_id" } } } } ``` Your agent can now say "check my balance" or "send \$5 to 0x..." and it works. *** ## Next Steps Full Agentic Wallets documentation. MCP server setup and tool reference. Test in sandbox first. # Card Issuer Program Source: https://docs.yativo.com/guides/b2b-card-issuer End-to-end integration guide: apply, onboard customers, complete KYC, and issue Visa virtual cards under your brand The Card Issuer Program lets your platform issue Visa virtual cards to your end customers. Yativo handles the card network, compliance, and settlement — your backend drives the entire flow via API. **Two API namespaces — keep them separate.** | Namespace | Base path | Purpose | | ------------- | ----------------------------- | ---------------------------------------------------------------------------- | | Card Issuer | `/v1/card-issuer/*` | Your program: apply, check status, manage customers, fund cards | | Card Customer | `/v1/yativo-card/customers/*` | Individual customer lifecycle: OTP, KYC, card creation, freeze, transactions | The `/v1/customers/*` path is **WaaS** (wallet sub-accounts for crypto deposits/withdrawals). It has nothing to do with card customers. Do not mix them up. *** ## Identity Model ``` Yativo └── You (the Issuer) — authenticated via your API Bearer token └── Your Customers — identified by yativo_card_id, external_customer_id, or email ``` * **You** are a Yativo user who has been approved into the Card Issuer Program. * **Your Customers** are the end users of your platform who get a card. They are never authenticated directly against Yativo — all API calls come from your backend using your token. * `yativo_card_id` is the primary identifier for a card customer. Store it after onboarding. * `external_customer_id` is your own reference ID — pass it at onboarding and use it to look up the customer later without storing Yativo IDs. *** ## Flow Overview ``` Apply → Approved → (Fund Master Wallet) ↓ Onboard Customer → OTP → KYC → Source of Funds → Phone ↓ Card Issued → Fund Card → Active ``` *** ## Step 1 — Check Eligibility Confirm your account has been granted access before applying. ```bash theme={null} GET /v1/card-issuer/eligibility Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "eligible": true, "enrolled": false, "status": null } } ``` If `eligible` is `false`, contact your account manager. This gate is admin-only — there is no API call to change it yourself. *** ## Step 2 — Apply ```bash theme={null} POST /v1/card-issuer/apply Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "funding_structure": "master_wallet", "preferred_chain": "SOL", "iban_enabled": false } ``` | Field | Type | Required | Description | | ------------------- | ------- | -------- | ----------------------------------------------------------------------------- | | `funding_structure` | string | Yes | `master_wallet` or `non_master` (see below) | | `preferred_chain` | string | No | `SOL` (default) or `XDC` — the chain your master wallet will receive funds on | | `iban_enabled` | boolean | No | Enable IBAN for cardholders. Defaults to `false`. | ### Funding Structures | Value | How it works | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `master_wallet` | You maintain a shared balance and push funds to each customer card via the Fund Customer API. Best for platforms that control card top-ups. | | `non_master` | Each customer receives their own deposit address and funds their card directly. Best for self-serve wallets. | ```json Response theme={null} { "success": true, "message": "Application submitted. An admin will review your request.", "data": { "id": "69ecc05a4fc8c9c148ed1a9a", "status": "pending", "funding_structure": "master_wallet", "preferred_chain": "SOL" } } ``` *** ## Step 3 — Check Program Status Applications are reviewed within 1–2 business days. Poll until `status` is `approved`. ```bash theme={null} GET /v1/card-issuer/status Authorization: Bearer YOUR_TOKEN ``` ```json Approved theme={null} { "success": true, "data": { "enrolled": true, "status": "approved", "funding_structure": "master_wallet", "preferred_chain": "SOL", "enabled_chains": ["SOL"], "iban_enabled": false, "card_reissue_enabled": true, "master_wallets": { "sol": { "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", "balance": 0, "last_balance_check": null }, "usdc": { "balance": 0, "last_balance_check": null }, "eur": { "balance": 0, "last_balance_check": null }, "gbp": { "balance": 0, "last_balance_check": null } }, "stats": { "total_cards_issued": 0, "total_funded_amount": 0, "total_fees_paid": 0 }, "limits": { "max_cards": 1000, "daily_funding_limit": 50000, "monthly_funding_limit": 500000 } } } ``` On approval, Yativo provisions your master wallet set: * **SOL deposit address** (`sol.address`) — send USDC on Solana here to top up your USD balance. * **USD balance** — funded automatically when your SOL deposit confirms. * **EUR balance** — funded by swapping from USD. * **GBP balance** — funded by swapping from USD. Balances update in real time. You never interact with the underlying settlement infrastructure directly. *** ## Step 4 — Fund Your Master Wallet *(master\_wallet programs only)* Get your current balances and deposit addresses: ```bash theme={null} GET /v1/card-issuer/master-wallets Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "wallets": { "sol": { "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", "balance": 0, "last_balance_check": null }, "usdc": { "balance": 0 }, "eur": { "balance": 0 }, "gbp": { "balance": 0 } } } } ``` Send USDC on Solana to `sol.address`. Once the deposit confirms, your `usdc` balance increases automatically. Swap to `eur` or `gbp` before funding customers who hold those card currencies. ### Swap Currencies If your customers are in the EU or UK, swap USDC into the correct card currency before funding: ```bash theme={null} POST /v1/card-issuer/master-wallets/swap Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "from_token": "USD", "to_token": "EUR", "amount": 1000 } ``` ```json Response theme={null} { "success": true, "data": { "swap_id": "swap_01HX...", "status": "initiated", "from": { "token": "USD", "amount": 1000 }, "to": { "token": "EUR" }, "estimated_time": "2-10 minutes" } } ``` Card currency is determined by the cardholder's country: **UK** → GBP, **EU** → EUR, **all others** → USD. *** ## Step 5 — Onboard a Customer Start the onboarding flow for each end customer. Only `email` is required. ```bash theme={null} POST /v1/yativo-card/customers/onboard Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "email": "priya@yourapp.com", "external_customer_id": "usr_8821" } ``` ```json Response 201 theme={null} { "success": true, "message": "Customer card onboarding initiated. Verification code sent to customer email.", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "customer_id": "6627f3a2c5d4e100123abcde", "external_customer_id": "usr_8821", "email_masked": "pr***@yourapp.com", "next_step": "verify_otp", "otp_expires_in_seconds": 600 } } ``` Store **`yativo_card_id`** — it is the primary path parameter in every subsequent customer call. It is different from `customer_id`. Do **not** use your own issuer email as a customer email. Each customer must have a unique email address. A 6-digit OTP is sent to the customer's email automatically. *** ## Step 6 — Verify OTP Collect the OTP from your customer and submit it: ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/verify-otp Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "otp": "847291" } ``` ```json Response 200 theme={null} { "success": true, "message": "Email verified successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "flow_status": "otp_verified", "next_step": "kyc_link" } } ``` | Error code | Meaning | Recovery | | ------------------------- | ---------------------------------------------------- | -------------------------------------------------------- | | `OTP_EXPIRED` | 10-minute window passed | Call `resend-otp` | | `OTP_INVALID_OR_EXPIRED` | Wrong or expired code | Check code and retry, or call `resend-otp` | | `OTP_VERIFICATION_FAILED` | Verification service rejected with a specific reason | Inspect `message`, call `resend-otp` | | `OTP_ATTEMPTS_EXCEEDED` | 5 failed attempts | Call `resend-otp` — this resets the counter | | `SESSION_EXPIRED` | Session expired and couldn't auto-refresh | Call `resend-otp` — a new OTP re-establishes the session | Every error response with these codes includes a `data.next_step` field and a `data.action` URL pointing to the exact endpoint to call next. ### Resend OTP ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/resend-otp Authorization: Bearer YOUR_TOKEN ``` *** ## Step 7 — Get KYC Link Generate a verification URL for this customer: ```bash theme={null} GET /v1/yativo-card/customers/{yativoCardId}/kyc-link Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "message": "KYC link retrieved", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "kyc_url": "https://kyc.yativo.com/verify?token=...", "sumsub_sdk_token": "eyJ...", "next_step": "kyc_status" } } ``` Redirect the customer to `kyc_url`, or embed the KYC flow in your app using the Sumsub SDK with `sumsub_sdk_token`. Add `?refresh=true` to generate a new link if the existing one has expired. *** ## Step 8 — Poll KYC Status ```bash theme={null} GET /v1/yativo-card/customers/{yativoCardId}/kyc-status Authorization: Bearer YOUR_TOKEN ``` ```json Approved theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "kyc_status": "approved", "flow_status": "kyc_completed", "terms_accepted": true, "next_step": "create_virtual_card" } } ``` ```json Pending theme={null} { "success": true, "data": { "kyc_status": "pending", "flow_status": "kyc_initiated", "next_step": "kyc_status" } } ``` ```json Rejected theme={null} { "success": true, "data": { "kyc_status": "rejected", "flow_status": "kyc_rejected", "rejection_reason": "Document not readable", "next_step": "retry_kyc" } } ``` Poll every 10 seconds for up to 10 minutes. When `next_step` is `retry_kyc`, fetch a fresh `kyc-link?refresh=true` and redirect the customer. After KYC approval, you **must** call both of these endpoints before creating a card — regardless of whether the background operations appear to have succeeded: **1. Accept terms:** ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/terms ``` Works for both own-account and customer cards — supply the customer's `yativo_card_id` as the path parameter. This is idempotent. Skipping it causes `LEGAL_ACCEPTANCE_REQUIRED` at card creation. **2. Confirm Safe deployment:** ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/safe/deploy ``` Even when the platform auto-deploys the Safe in the background, card creation checks the **local DB state**, not the card network directly. Calling this endpoint syncs the deployment status to the DB. You will typically receive `"already_deployed": true` (meaning the card network already has it — this call just ensures the DB record is updated). Skipping it causes `SAFE_NOT_DEPLOYED` at card creation. Both calls are idempotent. Call them in order after KYC approval, then proceed to Source of Funds. *** ## Step 9 — Source of Funds ### Get questions ```bash theme={null} GET /v1/yativo-card/customers/{yativoCardId}/source-of-funds Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "questions": [ { "question": "EMPLOYMENT_STATUS", "label": "What is your employment status?", "options": ["EMPLOYED", "SELF_EMPLOYED", "UNEMPLOYED", "STUDENT", "RETIRED"] }, { "question": "SOURCE_OF_INCOME", "label": "What is your primary source of income?", "options": ["SALARY", "BUSINESS_INCOME", "INVESTMENT", "PENSION", "OTHER"] } ] } } ``` ### Submit answers ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/source-of-funds Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "answers": [ { "question": "EMPLOYMENT_STATUS", "answer": "EMPLOYED" }, { "question": "SOURCE_OF_INCOME", "answer": "SALARY" } ] } ``` ```json Response theme={null} { "success": true, "data": { "status": "completed", "next_step": "phone_verification" } } ``` *** ## Step 10 — Phone Verification ### Request SMS code ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/phone/request-verification Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "phoneNumber": "+14155552671" } ``` ```json Response theme={null} { "success": true, "message": "Verification code sent" } ``` ### Verify SMS code ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/phone/verify Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "code": "382910" } ``` ```json Response theme={null} { "success": true, "data": { "is_verified": true, "next_step": "create_virtual_card" } } ``` *** ## Step 11 — Create Virtual Card All prerequisites are complete. Issue the card: ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/cards/virtual Authorization: Bearer YOUR_TOKEN ``` ```json Response 201 theme={null} { "success": true, "message": "Virtual card created successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167", "card_type": "virtual", "status": "active", "status_code": 1000, "status_name": "Active", "activated_at": "2026-04-25T14:35:41.418Z", "total_cards": 1, "funding_wallet": { "address": "3vQ7GqN8kKTb2mFCdHrE8TvBcJgR2XpLmWqNzYsKdPh", "network": "solana", "asset": "USDC" } } } ``` To show the customer their full card number and CVV, request a secure view URL (see [Secure Card View](#sensitive-card-data) below) and open it in an iframe or WebView. ### Multiple Cards per Customer A single customer account supports up to **5 active cards** (virtual + physical combined). You can issue additional virtual cards on top of the first one, subject to the limits set on your program. ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/cards/virtual Authorization: Bearer YOUR_TOKEN ``` The response is identical to the first card creation. Each call issues a new independent card on the same customer account. If the customer has reached their limit you will get: ```json 403 Limit reached theme={null} { "success": false, "error_code": "VIRTUAL_CARD_LIMIT_REACHED", "message": "Virtual card limit reached for this customer (max: 1). Contact your account manager to increase the limit." } ``` ### Card Limits Limits work in a three-tier hierarchy: ``` Yativo Admin └── sets program ceiling (e.g. max 3 virtual per customer) └── You (the Issuer) └── can set per-customer override ≤ program ceiling └── Platform hard cap: 5 active cards combined ``` The defaults on a new program are **1 virtual, 1 physical, 2 total** per customer. #### Set per-customer limits (issuer) Override the limit for a specific customer, up to your program's ceiling: ```bash theme={null} PATCH /v1/yativo-card/customers/{yativoCardId}/card-limits Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "max_virtual": 2, "max_physical": 1, "max_total": 3 } ``` All fields are optional — send only the limits you want to change. ```json Response 200 theme={null} { "success": true, "message": "Customer card limits updated", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "card_limits": { "max_virtual": 2, "max_physical": 1, "max_total": 3 }, "program_ceilings": { "max_virtual": 3, "max_physical": 2, "max_total": 5 } } } ``` `program_ceilings` reflects the maximum values your program permits. You cannot set a customer limit above its corresponding ceiling. | Error code | Meaning | | ----------------------- | ---------------------------------------------------------------------- | | `LIMIT_EXCEEDS_PROGRAM` | The value you sent is above your program's ceiling for that limit type | | `NO_CHANGES` | No valid limit fields were provided in the request body | *** ## Step 12 — Fund the Card ### Option A: Push from Master Wallet *(master\_wallet programs)* You can identify the customer by any of: `customer_id`, `card_id`, `external_id`, `email`, or `yativo_card_id`. ```bash theme={null} POST /v1/card-issuer/fund-customer Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "external_id": "usr_8821", "amount": 100, "source_chain": "SOL", "pricing_mode": "receive_x" } ``` ```json Response 200 theme={null} { "success": true, "message": "Funding initiated for customer", "data": { "transfer_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E5", "status": "pending", "source": { "chain": "SOL", "amount": 201.80 }, "destination": { "token": "EUR" }, "pricing_mode": "receive_x", "estimated_amount": "200.00", "estimated_time": "2–5 minutes" } } ``` Save the `transfer_id`. Poll [GET /v1/card-issuer/transfers/:transferId](/api-reference/issuer/transfer-status) until `status` is `completed` (typically 2–5 minutes). **`pricing_mode`:** * `receive_x` — the customer receives exactly `amount`. Yativo deducts slightly more from your master wallet to cover fees. * `send_x` *(default)* — exactly `amount` is debited from your master wallet. The customer receives less after fees. **`TOKEN_MISMATCH` error:** if you fund with the wrong currency for a customer's card region, the API returns this error with the exact token their card requires. Swap your master wallet balance first. ### Option B: Customer Self-Funds via Deposit Address *(non\_master programs)* Get the customer's deposit address: ```bash theme={null} GET /v1/yativo-card/customers/{yativoCardId}/wallet/funding-address Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "address": "3vQ7GqN8kKTb2mFCdHrE8TvBcJgR2XpLmWqNzYsKdPh", "network": "solana", "card_currency": "USDCe", "minimum_deposit": "5.00", "funding_sources": { "usdc_sol": { "address": "3vQ7GqN8kKTb2mFCdHrE8TvBcJgR2XpLmWqNzYsKdPh", "network": "solana", "token": "USDC", "contract": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "bridge_type": "automatic", "bridge_time": "2-5 minutes", "description": "Send USDC on Solana — automatically applied to your card" }, "usdc_xdc": { "address": "0x742d35Cc6634C0532925a3b8D4C9b98E8A1f4bC2", "network": "xdc", "token": "USDC", "contract": "0xfA2958CB79b0491CC627c1557F441eF849Ca8eb1", "bridge_type": "manual", "bridge_time": "15-25 minutes", "description": "No minimum. Hold to earn yield. Fund card on demand.", "balance": { "total": 0, "available": 0, "held": 0 } } }, "auto_bridge": { "enabled": true, "source": "USDC_SOL", "destination": "USDC", "estimated_time": "2-5 minutes", "minimum_trigger_amount": 5, "minimum_trigger_amount_unit": "USDC", "accumulates_below_minimum": true }, "instructions": "Send USDC (SPL) on Solana to this address. Auto-bridge starts once your available balance reaches at least 5.00 USDC." } } ``` *** ## Card Management ### List all customers ```bash theme={null} GET /v1/card-issuer/customers?status=card_created&page=1&limit=20 Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "customers": [ { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "customer_id": "6627f3a2c5d4e100123abcde", "external_customer_id": "usr_8821", "email": "priya@yourapp.com", "flow_status": "card_created", "currency": "USDCe", "cards_count": 1, "created_at": "2026-04-25T10:00:00.000Z" } ], "total": 1, "page": 1, "limit": 20 } } ``` Filter by `flow_status`: `otp_requested`, `otp_verified`, `kyc_initiated`, `kyc_completed`, `card_created`, `active`. ### Look up a customer Find a customer by any identifier: ```bash theme={null} GET /v1/card-issuer/lookup-customer?external_id=usr_8821 Authorization: Bearer YOUR_TOKEN ``` Supported query parameters (pass exactly one): | Param | Description | | ---------------- | ----------------------------------------------------------- | | `yativo_card_id` | Yativo's internal card customer ID | | `customer_id` | MongoDB customer ObjectId (or `yativo_card_id` as fallback) | | `card_id` | Card ID from card creation | | `external_id` | Your reference ID set at onboarding | | `email` | Customer email address | | `id` | MongoDB `_id` of the customer record | ```json Response theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "external_id": "usr_8821", "email": "priya@yourapp.com", "flow_status": "card_created", "currency": "USDCe", "token": "USDC", "safe_deployed": true, "cards_count": 1, "created_at": "2026-04-25T10:00:00.000Z" } } ``` ### Freeze / Unfreeze a Card ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/freeze Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "message": "Card frozen successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167", "is_frozen": true, "frozen_at": "2026-04-25T19:07:14.917Z" } } ``` ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/unfreeze Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "message": "Card unfrozen successfully", "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167", "is_frozen": false, "unfrozen_at": "2026-04-25T19:07:20.065Z" } } ``` ### Get Card Transactions ```bash theme={null} GET /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/transactions?limit=20 Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "transactions": [ { "kind": "Payment", "transaction_type": "Purchase", "merchant_name": "CloudSoft Inc", "merchant_country": "United States", "merchant_country_code": "US", "mcc_code": "5734", "mcc_description": "Software", "mcc_category": "Electronics & Tech", "billing_amount": 13.72, "billing_currency": "USD", "billing_formatted": "$13.72", "transaction_amount": 13.72, "transaction_currency": "USD", "status": "approved", "status_label": "Approved", "is_pending": false, "card_token": "849301752", "authorized_at": "2026-04-22T15:03:31.441Z", "cleared_at": "2026-04-24T15:36:51.331Z" } ] } } ``` ### Spending Limits Get the current spending limit for a customer's card: ```bash theme={null} GET /v1/yativo-card/customers/{yativoCardId}/wallet/limits Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "currency": "USD", "limits": { "daily": { "limit": 7999, "used": 0, "remaining": 7999 }, "monthly": {}, "per_transaction": {} } } } ``` Update the daily spending limit: ```bash theme={null} PUT /v1/yativo-card/customers/{yativoCardId}/wallet/limits Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "dailyLimit": 2500 } ``` ```json Response theme={null} { "success": true, "data": { "current_limit": null, "requested_limit": 2500, "admin_limit": null, "delay_seconds": 180, "note": "Limit changes are processed through a delay relay. Refresh after 3 minutes to see the updated limit.", "gelato_status": "ExecSuccess", "enqueue_task_id": "0xb3f4901cd12347834fe93cc55b6608e1ff81gddd63g9d5771e5b5f161d6f194fe" } } ``` Limit changes go through a Gelato relay with a 3-minute processing delay. The `gelato_status: "ExecSuccess"` confirms the transaction was enqueued. Poll `GET /wallet/limits` after 3 minutes to confirm the new limit is active. *** ## Secure Card View To let a cardholder view their full card details (PAN, CVV, expiry, PIN), your backend requests a **secure view URL** from Yativo. You send that URL to your customer — via your app, an email link, or an in-app iframe. Yativo hosts the page and handles all cryptography internally. Your backend never sees or handles raw card data. ### How it works ``` Your backend → POST view-token → gets secure_view_url Your app → opens URL in iframe / WebView / browser tab Yativo page → renders secure card data page Cardholder → sees PAN, CVV, expiry (and optionally PIN) ``` No SDK integration is required on your side. Yativo handles all the cryptography and secure rendering. ### Request a secure view URL ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/view-token Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "enabled_views": ["data", "pin"], "require_access_code": true, "access_code": "1234", "theme": { "accent_color": "#6366f1", "background_color": "#ffffff", "logo_url": "https://yourapp.com/logo.png", "border_radius": 12 } } ``` | Field | Type | Description | | ------------------------ | ------- | --------------------------------------------------------------------------- | | `enabled_views` | array | Which panels to show: `"data"` (PAN/CVV/expiry), `"pin"`. Defaults to both. | | `require_access_code` | boolean | Require the cardholder to enter a code before the card data unlocks. | | `access_code` | string | The code the cardholder must enter (set by you, shared via your app). | | `theme.accent_color` | string | Hex color for buttons and highlights. | | `theme.background_color` | string | Page background color. | | `theme.panel_color` | string | Card panel background color. | | `theme.text_color` | string | Primary text color. | | `theme.logo_url` | string | Your logo shown at the top of the page. | | `theme.border_radius` | number | Corner radius in px (8–36). | | `theme.font_family` | string | CSS font-family string. | ```json Response theme={null} { "success": true, "data": { "secure_view_url": "https://crypto-api.yativo.com/api/v1/yativo-card/view/eyJhbGci...", "expires_at": "2026-04-25T19:09:00.000Z", "last_four": "4291", "card_type": "virtual", "holder_name": "John Doe", "pin_set": true, "enabled_views": ["data", "pin"], "requires_access_code": true, "usage_notes": [ "Open secure_view_url in a browser, iframe, or WebView hosted on your side", "The hosted page renders card data securely and does not auto-refresh", "Request a fresh view URL whenever the previous one expires" ] } } ``` Open `secure_view_url` in a browser tab, iframe, or mobile WebView. The URL is short-lived. Request a new one each time the customer wants to view their card. The response includes `pin_set` — the last known state from the `physical.card.pin.changed` webhook. Use it in your UI to decide whether to prompt the customer to set their PIN before showing card details. ### Customer PIN setup and change Every card starts with `pin_set: false`. The customer must set a PIN before chip-and-PIN or ATM transactions will work. Use the same view-token endpoint with `enabled_views: ["pin"]` to show the PIN setup page — this also handles PIN **changes**. ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/cards/{cardId}/view-token Authorization: Bearer YOUR_ISSUER_TOKEN Content-Type: application/json { "enabled_views": ["pin"], "theme": { "accent_color": "#6366f1", "logo_url": "https://yourapp.com/logo.png" } } ``` Open the returned `secure_view_url` for your customer in an iframe or WebView. The cardholder enters their 4-digit PIN directly in the hosted page — it never passes through your backend. Once saved, the card network fires a `physical.card.pin.changed` webhook and Yativo updates `pin_set: true` on the card record. `pin_set` is sourced from the webhook, not from a direct card network API lookup. Use it as a UI hint to prompt customers who haven't yet set a PIN — not as a hard access gate. *** ## Deposits View all funding deposits into your issuer program (SOL auto-funding and XDC manual deposits): ```bash theme={null} GET /v1/card-issuer/deposits?page=1&limit=20 Authorization: Bearer YOUR_TOKEN ``` Filter by `status`: `pending`, `auto_funding`, `awaiting_manual`, `funding`, `funded`, `failed`. Filter by `chain`: `SOL`, `XDC`. *** ## Transfers ### All transfers View all funding transfers you have sent to customer cards: ```bash theme={null} GET /v1/card-issuer/transfers?page=1&limit=20 Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "transfers": [ { "transfer_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E5", "source_chain": "SOL", "source_amount": 201.80, "destination_token": "EUR", "destination_amount": 200.00, "status": "completed", "customer_id": "6627f3a2c5d4e100123abcde", "created_at": "2026-04-25T12:00:00.000Z", "completed_at": "2026-04-25T12:08:42.000Z" } ], "total": 1, "page": 1, "limit": 20 } } ``` Supports `status`, `customer_id`, and `chain` query filters. See [List Transfers](/api-reference/issuer/transfers). ### Single transfer or withdrawal status ```bash theme={null} GET /v1/card-issuer/transfers/{transferId} Authorization: Bearer YOUR_TOKEN ``` Accepts either a funding `transfer_id` or a withdrawal's `withdrawal_id` — checks funding transfers first, falls back to withdrawals. The response's `type` field (`"funding"` or `"withdrawal"`) tells you which one matched. See [Get Transfer Status](/api-reference/issuer/transfer-status) for the full response shape and status enum. ### Transfers for a specific customer ```bash theme={null} GET /v1/card-issuer/customers/{customerId}/transfers Authorization: Bearer YOUR_TOKEN ``` `customerId` accepts `yativo_card_id`, `customer_id`, or your own `external_id`. See [List Customer Transfers](/api-reference/issuer/customer-transfers). *** ## Check Progress Anytime ```bash theme={null} GET /v1/yativo-card/customers/{yativoCardId}/progress Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "flow_status": "card_created", "current_step": 5, "progress_percentage": 100, "steps": [ { "step": 1, "name": "Initiate Program", "completed": true }, { "step": 2, "name": "Verify Email", "completed": true }, { "step": 3, "name": "Start KYC", "completed": true }, { "step": 4, "name": "Complete KYC", "completed": true }, { "step": 5, "name": "Create Card", "completed": true } ], "kyc_status": "approved", "card_status": "active" } } ``` *** ## Delete an Incomplete Customer Record If you created a customer by mistake (e.g. wrong email) and the card has not yet been issued: ```bash theme={null} DELETE /v1/card-issuer/customers/{yativoCardId} Authorization: Bearer YOUR_TOKEN ``` This endpoint is blocked once the customer reaches `card_created` or `active` status. *** ## Reset Customer Onboarding If a customer's onboarding is stuck (KYC rejected multiple times, verification loop, wrong details submitted) and you need to start completely fresh, use the reset endpoint. This deletes the Yativo record and allows re-onboarding with a new verification flow. ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/reset Authorization: Bearer YOUR_TOKEN ``` ```json Response 200 theme={null} { "success": true, "message": "Customer onboarding reset. Re-onboard this customer via POST /api/yativo-card/customers/onboard with a different email address.", "data": { "deleted_card_id": "yativo_card_customer_8f9a...abc_1769031332068", "email_masked": "sa***@hotmail.com", "external_customer_id": "usr_8821", "next_step": "POST /api/yativo-card/customers/onboard", "email_warning": "The email address used previously remains registered with the card network and cannot be reused. Use a different email address when re-onboarding this customer." } } ``` **You must use a different email address when re-onboarding.** The previous email remains registered with the card network and cannot be reused for a new account. Attempting to re-onboard with the same email will fail with `EMAIL_ALREADY_REGISTERED`. **When reset is blocked:** As an issuer, you can only reset a customer who has **not yet had a card issued**. Once the customer reaches `card_created` status, this endpoint returns: ```json 400 Card already issued theme={null} { "success": false, "error_code": "CARD_ALREADY_ISSUED", "message": "Cannot reset: a payment card has already been issued for this customer. Contact support." } ``` If you need to reset a customer who already has a card, contact Yativo support — admin-level resets are available for exceptional cases. *** ## Webhook Events Subscribe to webhooks for real-time events. See [Webhook Events](/api-reference/issuer/webhooks) for payload examples, signature verification, and the full event reference. | Event | Trigger | | ------------------------------- | ----------------------------------------------------------------------------------------------- | | `customer.funded` | Funding transfer completed into a customer's card wallet | | `customer.funding.failed` | Funding transfer failed | | `master_wallet.customer_funded` | Master wallet debited for a customer funding (includes `remaining_balance` on direct transfers) | | `master_wallet.deposit` | Funds received into your master wallet | | `master_wallet.swap` | Token swap submitted from your master wallet | | `card.created` | New card issued to a customer | | `card.activated` | Physical card activated | | `card.frozen` | Card frozen | | `card.unfrozen` | Card unfrozen | | `card.voided` | Card permanently voided | | `card.lost` | Card reported lost | | `card.stolen` | Card reported stolen | | `card.cancelled` | Card cancelled | | `transaction.authorized` | Card transaction authorized at point of sale | | `transaction.settled` | Transaction cleared and settled | | `transaction.declined` | Transaction declined | | `transaction.reversed` | Transaction reversed | | `transaction.refund.created` | Refund created | | `customer.balance.updated` | Customer balance changed after a spend, top-up, or authorization | KYC status changes are not delivered as webhooks — poll [Get Customer](/api-reference/issuer/customer) or [Look Up Customer](/api-reference/issuer/lookup-customer) to check `kyc_status` after directing customers through the KYC link. *** *** ## Recovery & Continuation Reference Every operation that can fail returns a `data.next_step` field and a `data.action` URL so you never have to guess what to do. This section documents every failure mode and the exact API call that recovers from it. ### Onboarding State Machine ``` [new customer] │ ▼ POST /customers/onboard otp_requested ──────► resend-otp (OTP expired / too many attempts / session expired) │ ▼ POST /customers/{id}/verify-otp otp_verified │ ▼ GET /customers/{id}/kyc-link kyc_initiated ──────► GET /customers/{id}/kyc-link?refresh=true (link expired) │ ├─► (pending) ── poll kyc-status every 10s │ ├─► kyc_rejected ──► GET /customers/{id}/kyc-link?refresh=true → retry KYC │ └─► kyc_completed │ ▼ POST /v1/yativo-card/{id}/terms (idempotent — always call after KYC) terms_accepted │ ▼ POST /customers/{id}/safe/deploy (idempotent — syncs DB state) safe_deployed │ ▼ GET /customers/{id}/source-of-funds → POST /customers/{id}/source-of-funds source_of_funds_completed │ ▼ POST /customers/{id}/phone/request-verification POST /customers/{id}/phone/verify phone_verified │ ▼ POST /customers/{id}/cards/virtual card_created │ ▼ active (terminal — no further steps) ``` *** ### Handling All Error Codes #### OTP Phase errors | Error code | Cause | Recovery call | | ------------------------- | ------------------------------------------------- | ---------------------------------------------------------------------- | | `OTP_EXPIRED` | 10-min window elapsed | `POST /customers/{id}/resend-otp` | | `OTP_INVALID_OR_EXPIRED` | Wrong or expired code | Retry with correct code, or `POST /customers/{id}/resend-otp` | | `OTP_VERIFICATION_FAILED` | Verification service returned an unexpected error | Inspect `message` field; then `resend-otp` | | `OTP_ATTEMPTS_EXCEEDED` | 5 wrong attempts | `POST /customers/{id}/resend-otp` — **this resets the counter** | | `SESSION_EXPIRED` | JWT expired and SIWE auto-refresh failed | `POST /customers/{id}/resend-otp` — new OTP re-establishes the session | | `JWT_REFRESH_FAILED` | SIWE re-auth failed (rare) | `POST /customers/{id}/resend-otp` | All OTP errors include `data.attempts_remaining`, `data.next_step: "resend_otp"`, and `data.action` in the response body. #### KYC Phase errors | Error code | Cause | Recovery call | | ------------------ | ------------------------------------------------- | ----------------------------------------------------------------------------------- | | `KYC_LINK_FAILED` | Identity verification link could not be generated | Retry `GET /customers/{id}/kyc-link?refresh=true` after a short delay | | `KYC_STATUS_ERROR` | Live status check failed | Retry `GET /customers/{id}/kyc-status` — response falls back to cached status | | `SESSION_EXPIRED` | JWT expired and can't refresh | `GET /customers/{id}/kyc-link?refresh=true` — this forces a SIWE re-auth internally | *** ### Abandoned Onboardings — `resume` Endpoint If a customer starts onboarding but never finishes (OTP not verified, KYC link never opened, KYC in progress for days), call the **resume** endpoint. It inspects the current state, takes the correct action automatically, and tells you exactly what to present to the customer next. ```bash theme={null} POST /v1/yativo-card/customers/{yativoCardId}/resume Authorization: Bearer YOUR_TOKEN ``` **What it does by state:** | `flow_status` | Action taken | `next_step` returned | | -------------------------------------------------- | ----------------------------------------------------- | --------------------- | | `otp_requested` | Resends OTP to customer email, resets attempt counter | `verify_otp` | | `reauth_otp_requested` | Same as above (re-auth OTP pending) | `verify_otp` | | `otp_verified` | Generates a fresh KYC link | `kyc_link` | | `kyc_initiated` | Generates a fresh KYC link | `kyc_link` | | `kyc_rejected` | Generates a fresh KYC link for retry | `retry_kyc` | | `kyc_completed` / `kyc_approved` / `safe_deployed` | No action needed — ready for card creation | `create_virtual_card` | | `card_created` / `active` | Already complete | `none` | ```json Response — OTP phase theme={null} { "success": true, "message": "OTP resent to customer email. Customer should verify to continue.", "data": { "yativo_card_id": "yativo_card_customer_...", "flow_status": "otp_requested", "next_step": "verify_otp", "action_taken": "otp_resent", "email_masked": "sa***@truther.to", "otp_expires_in_seconds": 600, "days_since_created": 6 } } ``` ```json Response — KYC phase theme={null} { "success": true, "message": "KYC was rejected. A new KYC link has been generated for retry.", "data": { "yativo_card_id": "yativo_card_customer_...", "flow_status": "kyc_rejected", "kyc_status": "rejected", "rejection_reason": "Document not readable", "next_step": "retry_kyc", "action_taken": "kyc_link_generated", "kyc_url": "https://kyc.yativo.com/verify?token=...", "sumsub_sdk_token": "eyJ...", "days_since_created": 2 } } ``` Use `days_since_created` to decide how aggressively to pursue a customer. A 1-day abandoned onboarding is worth a simple email nudge; a 30-day one may warrant re-onboarding from scratch. *** ### Polling Strategy For KYC status polling, use an exponential-backoff approach with a hard timeout: ```typescript theme={null} async function waitForKycApproval(yativoCardId: string, token: string): Promise { const maxWait = 15 * 60 * 1000; // 15 minutes const start = Date.now(); let delay = 5_000; // start at 5s while (Date.now() - start < maxWait) { const res = await fetch(`/v1/yativo-card/customers/${yativoCardId}/kyc-status`, { headers: { Authorization: `Bearer ${token}` } }); const body = await res.json(); const status = body.data?.kyc_status; if (status === 'approved') return 'approved'; if (status === 'rejected') return 'rejected'; await new Promise(r => setTimeout(r, delay)); delay = Math.min(delay * 1.5, 30_000); // cap at 30s } return 'timeout'; } ``` When `kyc_status === 'rejected'`, fetch a fresh KYC link and redirect the customer: ```typescript theme={null} if (kycResult === 'rejected') { const linkRes = await fetch( `/v1/yativo-card/customers/${yativoCardId}/kyc-link?refresh=true`, { headers: { Authorization: `Bearer ${token}` } } ); const { data } = await linkRes.json(); redirectCustomer(data.kyc_url); // or embed Sumsub SDK with data.sumsub_sdk_token } ``` *** ### Full `next_step` Reference Every API response in the customer lifecycle includes `data.next_step`. Use it to drive your state machine without hardcoding assumptions about flow order. | `next_step` value | What to do | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | | `verify_otp` | Show OTP input to customer | | `resend_otp` | OTP is unusable — call `resend-otp` then show OTP input | | `kyc_link` | Open `kyc_url` or embed SDK | | `kyc_status` | Start polling `kyc-status` | | `retry_kyc` | KYC rejected — show reason, get new link, redirect customer | | `create_virtual_card` | KYC approved — complete remaining steps (terms, safe deploy, source of funds, phone verification) then call `POST /cards/virtual` | | `none` | Customer is fully active, no further action | | `null` | Intermediate state — call `GET /progress` for full picture | *** ### Common Integration Mistakes **Do not hardcode state transitions.** Always read `next_step` from the response. States can be added between releases. | Mistake | Consequence | Fix | | --------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Using issuer email as customer email | `ISSUER_EMAIL_NOT_ALLOWED` — blocked at onboard | Use the customer's own email address | | Not storing `yativo_card_id` | Can't call any subsequent customer endpoint | Store it immediately after `POST /customers/onboard` | | Treating `OTP_ATTEMPTS_EXCEEDED` as fatal | Customer stuck | Call `resend-otp` — resets the counter | | Not handling `kyc_rejected` | Customer stuck in KYC loop | Detect rejection in `kyc-status`, fetch fresh link, re-direct | | Re-creating customer after OTP failure | Duplicate records | Call `resend-otp` on the existing `yativo_card_id` | | Calling `kyc-link` for `otp_requested` customers | `SESSION_EXPIRED` or wrong step | Ensure OTP is verified before requesting KYC link | | Skipping explicit Safe deploy call after KYC | `SAFE_NOT_DEPLOYED` at card creation | Auto-deploy is async via background job and may not update the DB before card creation — call `POST /customers/{id}/safe/deploy` explicitly to sync DB state | | Card creation fails with `LEGAL_ACCEPTANCE_REQUIRED` | Terms auto-accept failed silently at KYC approval | Call `POST /v1/yativo-card/{yativoCardId}/terms` using the customer's `yativo_card_id` — works for customer cards, idempotent | | Treating `INITIALIZATION_FAILED` as a no-op on first call | Customer never progresses | See below — the record may have been created. Always retry and check for `CUSTOMER_CARD_ALREADY_ACTIVE`. | *** ### Handling `INITIALIZATION_FAILED` on Onboard `POST /customers/onboard` performs several steps internally (wallet generation, SIWE signing, OTP request, DB write). In rare cases — typically a transient database timeout or network issue — the API returns `500 INITIALIZATION_FAILED` even though the customer record **was** successfully created and the OTP email was already sent. **Recovery pattern:** Retry the onboard call with the same email (and `external_customer_id` if you use one). One of two things will happen: 1. **Success (201)** — the first call truly failed end-to-end. A fresh customer record is created. 2. **`CUSTOMER_CARD_ALREADY_ACTIVE` (409)** — the first call partially succeeded. The response includes the `yativo_card_id` and `next_step` so you can pick up exactly where you left off: ```json 409 CUSTOMER_CARD_ALREADY_ACTIVE theme={null} { "success": false, "error_code": "CUSTOMER_CARD_ALREADY_ACTIVE", "data": { "yativo_card_id": "yativo_card_customer_8f1f..._1781875244343", "flow_status": "otp_requested", "next_step": "verify_otp", "external_customer_id": "6126" } } ``` Use the returned `yativo_card_id` to call `POST /customers/{yativoCardId}/verify-otp` (the OTP email was already delivered on the first call). Do **not** treat `CUSTOMER_CARD_ALREADY_ACTIVE` as an error — it is the system telling you the card exists and showing you how to continue. *** ## Quick Reference ### Issuer Program (`/v1/card-issuer/*`) | Action | Method | Path | | ----------------------------- | -------- | ------------------------------------------ | | Check eligibility | `GET` | `/v1/card-issuer/eligibility` | | Apply | `POST` | `/v1/card-issuer/apply` | | Check program status | `GET` | `/v1/card-issuer/status` | | Get master wallet balances | `GET` | `/v1/card-issuer/master-wallets` | | Swap master wallet currencies | `POST` | `/v1/card-issuer/master-wallets/swap` | | List customers | `GET` | `/v1/card-issuer/customers` | | Look up customer | `GET` | `/v1/card-issuer/lookup-customer` | | Fund a customer card | `POST` | `/v1/card-issuer/fund-customer` | | List all transfers | `GET` | `/v1/card-issuer/transfers` | | Get transfer status | `GET` | `/v1/card-issuer/transfers/{transferId}` | | List customer transfers | `GET` | `/v1/card-issuer/customers/{id}/transfers` | | Deposits list | `GET` | `/v1/card-issuer/deposits` | | Delete incomplete customer | `DELETE` | `/v1/card-issuer/customers/{id}` | ### Card Customer Lifecycle (`/v1/yativo-card/customers/*`) | Action | Method | Path | | ----------------------------------- | ------- | ------------------------------------------------------------ | | Onboard customer | `POST` | `/v1/yativo-card/customers/onboard` | | Verify OTP | `POST` | `/v1/yativo-card/customers/{id}/verify-otp` | | Resend OTP | `POST` | `/v1/yativo-card/customers/{id}/resend-otp` | | **Resume stuck onboarding** | `POST` | `/v1/yativo-card/customers/{id}/resume` | | Get KYC link | `GET` | `/v1/yativo-card/customers/{id}/kyc-link` | | Poll KYC status | `GET` | `/v1/yativo-card/customers/{id}/kyc-status` | | **Deploy Safe** (sync DB after KYC) | `POST` | `/v1/yativo-card/customers/{id}/safe/deploy` | | **Accept terms** (after KYC) | `POST` | `/v1/yativo-card/{yativoCardId}/terms` | | Get SoF questions | `GET` | `/v1/yativo-card/customers/{id}/source-of-funds` | | Submit SoF answers | `POST` | `/v1/yativo-card/customers/{id}/source-of-funds` | | Request phone OTP | `POST` | `/v1/yativo-card/customers/{id}/phone/request-verification` | | Verify phone OTP | `POST` | `/v1/yativo-card/customers/{id}/phone/verify` | | Create virtual card | `POST` | `/v1/yativo-card/customers/{id}/cards/virtual` | | **Set per-customer card limits** | `PATCH` | `/v1/yativo-card/customers/{id}/card-limits` | | **Reset customer onboarding** | `POST` | `/v1/yativo-card/customers/{id}/reset` | | Get deposit address | `GET` | `/v1/yativo-card/customers/{id}/wallet/funding-address` | | Check onboarding progress | `GET` | `/v1/yativo-card/customers/{id}/progress` | | Freeze card | `POST` | `/v1/yativo-card/customers/{id}/cards/{cardId}/freeze` | | Unfreeze card | `POST` | `/v1/yativo-card/customers/{id}/cards/{cardId}/unfreeze` | | Void card (virtual only) | `POST` | `/v1/yativo-card/customers/{id}/cards/{cardId}/void` | | Report card lost | `POST` | `/v1/yativo-card/customers/{id}/cards/{cardId}/lost` | | Report card stolen | `POST` | `/v1/yativo-card/customers/{id}/cards/{cardId}/stolen` | | Get transactions | `GET` | `/v1/yativo-card/customers/{id}/cards/{cardId}/transactions` | | Get spending limits | `GET` | `/v1/yativo-card/customers/{id}/wallet/limits` | | Set spending limit | `PUT` | `/v1/yativo-card/customers/{id}/wallet/limits` | | Get secure card view URL | `POST` | `/v1/yativo-card/customers/{id}/cards/{cardId}/view-token` | | Get customer profile | `GET` | `/v1/yativo-card/customers/{id}/profile` | # Card Issuer Webhooks Source: https://docs.yativo.com/guides/card-issuer-webhooks Receive real-time event notifications across the full card issuer lifecycle — from master wallet deposits to card transactions Card issuer webhooks let Yativo push event notifications to your server the moment something happens in your program — a deposit settles, a customer's card is funded, a transaction is authorized, or a card is frozen. This guide covers every step from registering a URL to handling the complete event lifecycle. Card issuer events and general crypto events (deposits, swaps, transactions) are delivered through the same webhook service. Register once at `POST /v1/webhook/create-webhook` and subscribe to any combination of event types. *** ## How It Works Your server exposes a public HTTPS URL. Yativo sends a signed `POST` request to that URL each time an event occurs in your issuer program. Your server verifies the signature, acknowledges receipt with HTTP `200`, and processes the event. ``` Yativo event occurs │ ▼ POST https://your-app.com/webhooks/yativo │ ▼ Verify X-Yativo-Signature header │ ▼ Return HTTP 200 immediately │ ▼ Process event asynchronously ``` *** ## Step 1 — Build Your Webhook Endpoint Your endpoint must: * Accept `POST` requests at a public HTTPS URL * Capture the **raw request body** before JSON-parsing it (required for signature verification) * Return HTTP `2xx` within **30 seconds** * Process event logic asynchronously after returning 200 ```typescript theme={null} import express from "express"; import crypto from "crypto"; const app = express(); // Use express.raw() — not express.json() — so you have the raw body for signature verification app.post( "/webhooks/yativo/card-issuer", express.raw({ type: "application/json" }), async (req, res) => { const signature = req.headers["x-yativo-signature"] as string; const timestamp = req.headers["x-yativo-timestamp"] as string; const secret = process.env.YATIVO_WEBHOOK_SECRET!; if (!verifySignature(req.body, signature, timestamp, secret)) { return res.status(401).json({ error: "Invalid signature" }); } // Acknowledge immediately — Yativo waits up to 30 seconds res.sendStatus(200); // Parse and dispatch asynchronously const event = JSON.parse(req.body.toString()); setImmediate(() => handleCardIssuerEvent(event).catch(console.error)); } ); function verifySignature( rawBody: Buffer, signature: string, timestamp: string, secret: string ): boolean { if (!signature || !timestamp) return false; const signed = `${timestamp}.${rawBody.toString("utf8")}`; const expected = "sha256=" + crypto.createHmac("sha256", secret).update(signed).digest("hex"); try { return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); } catch { return false; } } async function handleCardIssuerEvent(event: any) { // Use event.id as an idempotency key — the same event may be delivered more than once const alreadyProcessed = await db.webhookEvents.findById(event.id); if (alreadyProcessed) return; switch (event.type) { case "master_wallet.deposit": if (event.data.status === "settled") { // withdrawal_id present → this credit is from a card withdrawal settling await handleMasterWalletDeposit(event.data); } break; case "customer.funded": await handleCustomerFunded(event.data); break; case "customer.funding.failed": await handleCustomerFundingFailed(event.data); break; case "transaction.authorized": await handleTransactionAuthorized(event.data); break; case "transaction.settled": await handleTransactionSettled(event.data); break; case "transaction.declined": await handleTransactionDeclined(event.data); break; case "card.frozen": case "card.unfrozen": case "card.voided": await handleCardStatusChange(event.type, event.data); break; default: console.log(`Unhandled event type: ${event.type}`); } await db.webhookEvents.insert({ id: event.id, type: event.type, processedAt: new Date() }); } ``` ```python theme={null} from flask import Flask, request, jsonify import hmac import hashlib import threading import os app = Flask(__name__) @app.route("/webhooks/yativo/card-issuer", methods=["POST"]) def card_issuer_webhook(): raw_body = request.get_data() signature = request.headers.get("X-Yativo-Signature", "") timestamp = request.headers.get("X-Yativo-Timestamp", "") secret = os.environ["YATIVO_WEBHOOK_SECRET"] if not verify_signature(raw_body, signature, timestamp, secret): return jsonify({"error": "Invalid signature"}), 401 event = request.get_json(force=True) # Respond immediately, dispatch in background thread = threading.Thread(target=handle_event, args=(event,)) thread.daemon = True thread.start() return "", 200 def verify_signature(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool: if not signature or not timestamp: return False signed = f"{timestamp}.{raw_body.decode('utf-8')}" expected = "sha256=" + hmac.new( secret.encode("utf-8"), signed.encode("utf-8"), hashlib.sha256 ).hexdigest() return hmac.compare_digest(signature, expected) ``` ```php theme={null} "Invalid signature"]); exit; } // Acknowledge immediately http_response_code(200); echo "OK"; if (function_exists("fastcgi_finish_request")) { fastcgi_finish_request(); } $event = json_decode($rawBody, true); handleEvent($event); function verifySignature(string $rawBody, string $signature, string $timestamp, string $secret): bool { if (empty($signature) || empty($timestamp)) return false; $signed = "{$timestamp}.{$rawBody}"; $expected = "sha256=" . hash_hmac("sha256", $signed, $secret); return hash_equals($expected, $signature); } ``` Always use a timing-safe comparison (`timingSafeEqual`, `hmac.compare_digest`, `hash_equals`). A regular `===` check is vulnerable to timing attacks. *** ## Step 2 — Register Your Webhook Register your endpoint at the unified webhook endpoint. You can subscribe to card issuer events, general crypto events, or any mix. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/webhook/create-webhook' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "url": "https://api.yourapp.com/webhooks/yativo", "events": [ "master_wallet.deposit", "master_wallet.swap", "master_wallet.customer_funded", "master_wallet.withdrawal", "customer.funded", "customer.funding.failed", "customer.balance.updated", "wallet.deposit.confirmed", "card.created", "card.activated", "card.frozen", "card.unfrozen", "card.voided", "card.lost", "card.stolen", "card.cancelled", "card.deactivated", "transaction.authorized", "transaction.settled", "transaction.declined", "transaction.reversed", "transaction.refund.created" ], "description": "Production card issuer webhook" }' ``` ```typescript TypeScript theme={null} const response = await fetch( "https://crypto-api.yativo.com/api/v1/webhook/create-webhook", { method: "POST", headers: { Authorization: `Bearer ${process.env.YATIVO_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://api.yourapp.com/webhooks/yativo", events: ["*"], // Subscribe to all events description: "Production card issuer webhook", }), } ); const { data } = await response.json(); console.log("Webhook ID:", data.webhook_id); console.log("Secret:", data.secret); // Store securely — also retrievable via GET /v1/yativo-card/webhooks/:webhookId ``` ```json Response theme={null} { "status": true, "message": "Webhook created successfully", "data": { "webhook_id": "68241abc2f3d4e5f6a7b8c9d", "url": "https://api.yourapp.com/webhooks/yativo", "events": ["master_wallet.deposit", "customer.funded", "..."], "secret": "whsec_a8f3c2e1d4b7f9e2c5a3b6d8f1e4c7a2b5d8e1f4c7a2b5d8", "created_at": "2026-05-12T14:00:00.000Z" } } ``` The `secret` is included in the creation response and is also retrievable later via `GET /v1/yativo-card/webhooks/:webhookId`. Store it in a secure environment variable or secrets manager (e.g., AWS Secrets Manager, HashiCorp Vault). If you need to invalidate a compromised secret, rotate it via `POST /v1/yativo-card/webhooks/:webhookId/rotate-secret`. Pass `"events": ["*"]` to receive every event type. You can narrow the list later via `PUT /v1/yativo-card/webhooks/:webhookId`. *** ## Step 3 — Verify Signatures Every webhook POST includes four security headers: | Header | Description | | ---------------------- | -------------------------------------------------------- | | `X-Yativo-Signature` | `sha256=` of the signed string | | `X-Yativo-Timestamp` | Unix timestamp (seconds) when the event was dispatched | | `X-Yativo-Event` | The event type (e.g. `customer.funded`) | | `X-Yativo-Delivery-Id` | Unique delivery ID — used to retry individual deliveries | The signature is computed as: ``` HMAC-SHA256(secret, ".") ``` The `` is the exact bytes received — not re-serialized. This is why you must capture the raw body before JSON-parsing. **Replay attack protection:** Also check that the timestamp is within 5 minutes of your server clock. Discard requests that are older. ```typescript theme={null} function verifySignature( rawBody: Buffer, signature: string, timestamp: string, secret: string ): boolean { if (!signature || !timestamp) return false; // Guard against replay attacks const age = Math.abs(Date.now() / 1000 - parseInt(timestamp, 10)); if (age > 300) return false; // older than 5 minutes const signed = `${timestamp}.${rawBody.toString("utf8")}`; const expected = "sha256=" + crypto.createHmac("sha256", secret).update(signed).digest("hex"); try { return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); } catch { return false; } } ``` *** ## The Event Lifecycle The following diagram shows the full lifecycle of a card issuer program, and where webhook events fire at each stage. ### Master wallet deposit → settled When you send funds to your master wallet deposit address, Yativo fires `master_wallet.deposit` events as the deposit progresses. The number of events depends on the deposit path: * **Two-step deposits** (funds routed through an intermediate settlement): a `processing` event fires first when the deposit is detected, followed by a `settled` event when the funds land in your spendable balance. * **One-step deposits** (funds that settle directly): only a single `settled` event fires — there is no preceding `processing` event. ``` You send funds to your deposit address │ ▼ (on detection — two-step deposits only) ┌────────────────────────────────────┐ │ master_wallet.deposit │ │ status: "processing" │ └────────────────────────────────────┘ │ ▼ (once funds are spendable) ┌────────────────────────────────────┐ │ master_wallet.deposit │ │ status: "settled" │ │ settled_amount: 499.75 │ └────────────────────────────────────┘ │ ▼ Master wallet balance updated ``` Always act on `status: "settled"` — this is the authoritative confirmation that funds are available. If you receive only a `settled` event with no prior `processing` event, that is expected for one-step deposit paths. ### Fund customer card When you call `POST /v1/card-issuer/fund-customer`, two events fire in tandem: `master_wallet.customer_funded` (your master wallet was debited) and `customer.funded` (the customer's card wallet was credited). ``` POST /v1/card-issuer/fund-customer │ ▼ ┌────────────────────────────────────┐ │ master_wallet.customer_funded │ │ Your master wallet debited │ └────────────────────────────────────┘ │ ┌────────────────────────────────────┐ │ customer.funded │ │ Customer card wallet credited │ └────────────────────────────────────┘ │ ┌────────────────────────────────────┐ │ customer.balance.updated │ │ New card balance snapshot │ └────────────────────────────────────┘ ``` If the funding transfer fails (e.g. network error or insufficient master wallet balance), only `customer.funding.failed` fires. ### Card transaction lifecycle When your customer uses their card, events fire at each stage of the authorization → settlement cycle. ``` Customer taps card at merchant │ ▼ ┌────────────────────────────────────┐ │ transaction.authorized │ │ Funds reserved (hold placed) │ └────────────────────────────────────┘ │ ┌────────────────────────────────────┐ │ customer.balance.updated │ │ available_balance reduced │ └────────────────────────────────────┘ │ ▼ (merchant batch clearing, typically same day) ┌────────────────────────────────────┐ │ transaction.settled │ │ Hold released, charge finalized │ └────────────────────────────────────┘ │ ┌────────────────────────────────────┐ │ customer.balance.updated │ │ ledger_balance reduced │ └────────────────────────────────────┘ ``` A declined authorization fires `transaction.declined` instead of `transaction.authorized`. A reversal fires `transaction.reversed`. ### Card status changes Card lifecycle events fire whenever a card's status changes — whether triggered by your API, by the customer, or by a compliance action. ``` card.created → Virtual card issued to a customer card.activated → Physical card activated (physical cards only) card.frozen → Spending temporarily paused card.unfrozen → Spending re-enabled (upstream status: "active") card.voided → Card permanently deactivated card.lost → Card reported lost (new card required) card.stolen → Card reported stolen (new card required) card.cancelled → Card cancelled card.deactivated → Card deactivated ``` *** ## Event Reference **Amount fields** — Every monetary amount is provided in two formats: * `amount` (float) — human-readable decimal, e.g. `12.50` * `amount_minor` (integer) — minor currency units (cents), e.g. `1250` Use floats for display. Use minor units for precise arithmetic, storing in integer columns, or comparing amounts without floating-point error. Both are always present when the amount is known; both are `null` when the amount is unavailable. ### Envelope All events share this structure. The `data` object is event-specific. ```json theme={null} { "id": "evt_1747058400000_abc123", "type": "customer.funded", "created_at": "2026-05-12T14:10:00.000Z", "data": { } } ``` | Field | Type | Description | | ------------ | -------- | ---------------------------------------- | | `id` | string | Unique event ID — use as idempotency key | | `type` | string | Event type | | `created_at` | ISO 8601 | When the event was generated | | `data` | object | Event-specific payload (see below) | ### `master_wallet.deposit` Fires when a deposit is detected or settles into your spendable balance. One-step deposits fire only `settled`. Two-step deposits fire `processing` first, then `settled`. All amount fields are provided as both a decimal float and an integer in minor units (cents). For example, `500.00 USD` → `amount: 500.00`, `amount_minor: 50000`. ```json Processing theme={null} { "id": "evt_1747058400000_abc123", "type": "master_wallet.deposit", "created_at": "2026-05-12T14:00:00.000Z", "data": { "settlement_id": "bridge_1745123456_2ea87af00de1", "source_currency": "USDC_SOL", "source_amount": 500.00, "source_amount_minor": 50000, "tx_hash": "5KtP3MzXYZABCDE1234567890abcdef12345678901234567890abcdef1234567", "status": "processing" } } ``` ```json Settled — regular deposit theme={null} { "id": "evt_1747058520000_def456", "type": "master_wallet.deposit", "created_at": "2026-05-12T14:02:00.000Z", "data": { "settlement_id": "bridge_1745123456_2ea87af00de1", "deposit_amount": 499.75, "deposit_amount_minor": 49975, "wallet_balance": 999.50, "wallet_balance_minor": 99950, "currency": "USD", "tx_hash": "0xa8739436c44460738a4147055530e450f8b55694e2448875e72cd25eb29cd21f", "solana_tx_hash": "5KtP3MzXYZABCDE1234567890abcdef12345678901234567890abcdef1234567", "status": "settled" } } ``` ```json Settled — withdrawal credit theme={null} { "id": "evt_1747058520000_ghi012", "type": "master_wallet.deposit", "created_at": "2026-05-12T14:02:00.000Z", "data": { "settlement_id": "6a294844e71b09a046f28103", "withdrawal_id": "cwd_1748012345678_x7k2qp", "yativo_card_id": "yativo_card_customer_...", "deposit_amount": 50.0, "deposit_amount_minor": 5000, "wallet_balance": 550.0, "wallet_balance_minor": 55000, "currency": "USD", "tx_hash": "0xa8739436c44460738a4147055530e450f8b55694e2448875e72cd25eb29cd21f", "solana_tx_hash": null, "status": "settled" } } ``` `master_wallet.deposit` fires for two distinct scenarios: (1) a new deposit credited to your master wallet, and (2) funds returning to your master wallet when a card withdrawal settles. In the withdrawal case the payload includes `withdrawal_id` and `yativo_card_id` so you can correlate it with the originating `card.withdrawal.settled` and `master_wallet.withdrawal` events. When `withdrawal_id` is absent the event is a regular deposit. | Field | Type | Description | | ---------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `source_currency` | string | Currency/chain of the incoming deposit (e.g. `USDC_SOL`, `USDC_XDC`). Present on `processing` events only. | | `source_amount` | float | Amount sent by the depositor, in `source_currency` units. Present on `processing` events. | | `source_amount_minor` | integer | `source_amount` in minor units (cents). | | `deposit_amount` | float | Amount that arrived in your wallet after settlement. Present on `settled` events. | | `deposit_amount_minor` | integer | `deposit_amount` in minor units (cents). | | `wallet_balance` | float \| null | Total wallet balance after this credit. Present on `settled` events. | | `wallet_balance_minor` | integer \| null | `wallet_balance` in minor units (cents). | | `currency` | string | Wallet currency (e.g. `USD`, `EUR`, `GBP`). Present on `settled` events. | | `settlement_id` | string \| null | Internal settlement or bridge transaction reference. | | `tx_hash` | string \| null | On-chain transaction hash of the final settlement. | | `solana_tx_hash` | string \| null | Original Solana deposit transaction signature. Present for `USDC_SOL` deposits; `null` for all other paths including withdrawal credits. | | `withdrawal_id` | string \| null | Present only when this event is a withdrawal credit. Matches the `withdrawal_id` on the corresponding `card.withdrawal.settled` and `master_wallet.withdrawal` events. | | `yativo_card_id` | string \| null | Present only when this event is a withdrawal credit. Identifies the card the funds were withdrawn from. | ### `master_wallet.swap` Fired when a currency swap is submitted from your master wallet (e.g. USD → EUR). ```json theme={null} { "id": "evt_1747058700000_ghi789", "type": "master_wallet.swap", "created_at": "2026-05-12T14:05:00.000Z", "data": { "swap_id": "0x4a1b2c3d...", "from_token": "USD", "to_token": "EUR", "amount": 1000.00, "amount_minor": 100000, "expected_output": 921.50, "expected_output_minor": 92150, "status": "submitted" } } ``` ### `master_wallet.customer_funded` Fired alongside `customer.funded` whenever your master wallet is debited. Includes `remaining_balance` when available and `tx_hash` with the on-chain transaction hash of the funding transfer. ```json theme={null} { "id": "evt_1747059001000_mwf01", "type": "master_wallet.customer_funded", "created_at": "2026-05-12T14:10:00.000Z", "data": { "transfer_id": "tx_1745128800_9fc12ab3e4d5", "customer_id": "69f0bdf29a84752db9cc8ff9", "amount": 50.00, "amount_minor": 5000, "currency": "USD", "tx_hash": "0xa8739436c44460738a4147055530e450f8b55694e2448875e72cd25eb29cd21f", "status": "completed", "remaining_balance": 114.98, "remaining_balance_minor": 11498 } } ``` ### `customer.funded` Fired when a customer's card wallet has been successfully credited. ```json theme={null} { "id": "evt_1747059000000_ghi789", "type": "customer.funded", "created_at": "2026-05-12T14:10:00.000Z", "data": { "transfer_id": "tx_1745128800_9fc12ab3e4d5", "customer_id": "69f0bdf29a84752db9cc8ff9", "amount": 50.00, "amount_minor": 5000, "currency": "USD", "tx_hash": "0xa8739436c44460738a4147055530e450f8b55694e2448875e72cd25eb29cd21f", "status": "completed" } } ``` ### `customer.funding.failed` Fired when a funding transfer to a customer's card wallet fails. ```json theme={null} { "id": "evt_1747059000000_fail01", "type": "customer.funding.failed", "created_at": "2026-05-12T14:10:00.000Z", "data": { "customer_id": "69f0bdf29a84752db9cc8ff9", "yativo_card_id": "yativo_card_customer_8f9a...", "amount": 50.00, "amount_minor": 5000, "currency": "USD" } } ``` ### `wallet.deposit.confirmed` Fired when a customer's account wallet balance increases — i.e. a deposit has arrived. This is the primary event for detecting incoming funds to a customer card wallet. ```json theme={null} { "id": "evt_1747060100000_dep01", "type": "wallet.deposit.confirmed", "created_at": "2026-05-12T14:29:45.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "amount": 50.00, "amount_minor": 5000, "new_balance": 145.50, "new_balance_minor": 14550, "currency": "EUR", "timestamp": "2026-05-12T14:29:45.000Z" } } ``` | Field | Type | Description | | ------------------- | -------------- | ---------------------------------------------- | | `amount` | float | Amount deposited (balance delta) | | `amount_minor` | integer | `amount` in minor units (cents) | | `new_balance` | float | Customer's new total balance after the deposit | | `new_balance_minor` | integer | `new_balance` in minor units (cents) | | `currency` | string \| null | Card currency (`USD`, `EUR`, `GBP`) | A `customer.balance.updated` event fires for the same balance change. `wallet.deposit.confirmed` fires only when the balance increased; `customer.balance.updated` fires for all balance changes including spend and reversal. *** ### `customer.balance.updated` Fired after any card balance change — top-up, purchase authorization, settlement, reversal, or periodic reconciliation. ```json theme={null} { "id": "evt_1747060200000_stu901", "type": "customer.balance.updated", "created_at": "2026-05-12T14:30:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "ledger_balance": 45.23, "ledger_balance_minor": 4523, "available_balance": 38.50, "available_balance_minor": 3850, "pending_balance": 6.73, "pending_balance_minor": 673, "currency": "EUR", "balance_source": "live", "trigger": "funding", "transfer_id": "bridge_1779218694580_c22259aa6951", "tx_hash": "0x3fbd8b6c6a1e2e6f0a1b8f6a5b4c3d2e1f0a1b8f6a5b4c3d2e1f0a1b8f6a5b4c", "timestamp": "2026-05-12T14:30:00.000Z" } } ``` | Field | Type | Description | | ------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `ledger_balance` | float | Total balance in the customer's account wallet | | `ledger_balance_minor` | integer | `ledger_balance` in minor units (cents) | | `available_balance` | float | Spendable balance after pending authorizations | | `available_balance_minor` | integer | `available_balance` in minor units (cents) | | `pending_balance` | float \| null | Held for authorized but not yet settled transactions. `null` when no pending authorizations | | `pending_balance_minor` | integer \| null | `pending_balance` in minor units (cents) | | `currency` | string \| null | `USD`, `EUR`, or `GBP` | | `balance_source` | string \| null | `"reconciliation"` when fired by the background reconciliation job; absent or `null` for live card events | | `trigger` | string \| null | What we determined caused this balance change: `"funding"`, `"withdraw"`, or `"transaction"` (a card purchase). `null` if we couldn't match it to a known operation within a 10-minute window. | | `transfer_id` | string \| null | Our own reference for the underlying operation — matches the `transfer_id` you already received on `customer.funded`/`master_wallet.customer_funded` (funding), the `withdrawal_id` from the withdrawal endpoints (withdrawal), or the transaction reference (card purchase). Use this to reconcile a `customer.balance.updated` event back to the operation that caused it. | | `tx_hash` | string \| null | On-chain hash for the underlying operation, when one exists (funding/withdrawal). `null` for card purchases, which don't have a dedicated on-chain leg at this stage. | `pending_balance` / `pending_balance_minor` are always `null` when `balance_source` is `"reconciliation"` — the reconciliation job reads the on-chain settled balance and cannot determine pending authorizations. Use `available_balance` for spendable funds. A single top-up typically produces **two** `customer.balance.updated` events a couple of minutes apart — the first when the ledger reflects the incoming funds, the second when they become spendable (`available_balance` catches up). Both carry the same `trigger`/`transfer_id`, since both stem from the same underlying operation — use `transfer_id` to recognize them as the same event rather than treating the second as a new, unrelated top-up. `trigger`/`transfer_id`/`tx_hash` are inferred by matching this balance change against our own records of your recent funding/withdrawal/transaction activity for this card, not supplied directly by the card network (which doesn't include a correlator on this event type). If nothing matched within the 10-minute window, all three come back `null`. ### `card.created` Fired when a new virtual card is issued to a customer. `card_id` is the card token identifier. `type` and `status` reflect values from the upstream card provider and may be `null` depending on the event payload received. ```json theme={null} { "id": "evt_1747057800000_abc001", "type": "card.created", "created_at": "2026-05-12T13:50:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "type": null, "status": null, "timestamp": "2026-05-12T13:50:00.000Z" } } ``` ### `card.activated` Fired when a physical card is activated by the cardholder. Virtual cards do not fire this event. ```json theme={null} { "id": "evt_1747057900000_act01", "type": "card.activated", "created_at": "2026-05-12T13:52:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "timestamp": "2026-05-12T13:52:00.000Z" } } ``` ### `card.frozen` / `card.unfrozen` For `card.frozen` the `status` field reflects the upstream frozen status string. For `card.unfrozen` the `status` field is `"active"` — the upstream provider reports the card status returning to active when a freeze is lifted. ```json card.frozen theme={null} { "id": "evt_1747059600000_mno345", "type": "card.frozen", "created_at": "2026-05-12T14:20:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "status": "Frozen", "timestamp": "2026-05-12T14:20:00.000Z" } } ``` ```json card.unfrozen theme={null} { "id": "evt_1747059700000_unf01", "type": "card.unfrozen", "created_at": "2026-05-12T14:21:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "status": "active", "timestamp": "2026-05-12T14:21:00.000Z" } } ``` The `card_id` in webhook events is the card token identifier and may differ from the `card_id` returned by the Get Customer API. Use `yativo_card_id` as the stable cross-reference between events and API responses. ### `card.lost` / `card.stolen` / `card.voided` / `card.cancelled` / `card.deactivated` Same shape as `card.frozen` — the envelope `type` identifies the event and `data.status` reflects the upstream status string for that change. ```json theme={null} { "id": "evt_1747059900000_pqr678", "type": "card.lost", "created_at": "2026-05-12T14:25:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "status": "Lost", "timestamp": "2026-05-12T14:25:00.000Z" } } ``` ### Transaction event field reference All `transaction.*` events share the same `data` shape. Fields are populated from card network data and some may be `null` depending on the transaction type or network. | Field | Type | Notes | | ---------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `yativo_card_id` | string | Stable card identifier — use this as the cross-reference key | | `card_id` | string \| null | Card token from the card network | | `transaction_id` | string \| null | Network transaction ID. Use this as the key for deduplication. Falls back to the webhook event `id` when not provided by the card network. | | `blockchain_tx_hash` | string \| null | Hash of the on-chain settlement transaction that debited the card's wallet. Populated on `transaction.authorized` (we wait for this to be available before dispatching — see note below). May be `null` on other event types where no on-chain leg exists yet (e.g. `transaction.declined`, or a reversal that never settled on-chain). | | `type` | string \| null | Transaction type as reported by the card network (e.g. `"Payment"`, `"Refund"`) | | `amount` | float \| null | Transaction amount as a decimal number, in the merchant's local currency | | `amount_minor` | integer \| null | `amount` in minor units (cents) | | `currency` | string \| null | ISO 4217 alpha-3 currency code of `amount` — the merchant's local currency (e.g. `"EUR"`, `"USD"`, `"BRL"`) | | `billing_amount` | float \| null | The amount actually debited from the card's own settlement currency. **Present on every transaction**, not only foreign-currency ones — on a same-currency purchase it simply equals `amount`. | | `billing_amount_minor` | integer \| null | `billing_amount` in minor units (cents) | | `billing_currency` | string \| null | ISO 4217 alpha-3 currency code of `billing_amount` — the card's own currency. Equals `currency` when the purchase was made in the card's native currency. | | `fx_rate` | float \| null | Local-currency units per 1 unit of billing currency: `fx_rate = amount / billing_amount`. Reads as "1 = " — e.g. `924.3827` means `1 USD = 924.3827 CLP`. Equals `1` on a same-currency purchase. Provided so you don't have to compute it, but if you ever need to derive `billing_amount` yourself: `billing_amount = amount / fx_rate`. | | `merchant` | string \| null | Merchant name — `null` for contactless/tap or when not provided by the network | | `merchant_category` | string \| null | Merchant category code (MCC) | | `merchant_city` | string \| null | Merchant city — `null` when not provided | | `merchant_country` | string \| null | ISO 3166 alpha-2 country code (e.g. `"FR"`, `"BR"`) — `null` when not provided | | `status` | string \| null | Raw status string from the card network — values vary (e.g. `"Approved"`, `"Declined"`) | | `timestamp` | ISO 8601 | When the card network event occurred | `status` and `type` values are passed through directly from the card network and are not normalized. Do not hard-code comparisons against specific strings — check for membership in an expected set and handle unknowns gracefully. ### `transaction.authorized` Fired once per card purchase, when the authorization clears (not at the earlier point-of-sale authorization moment — we intentionally wait for clearing so this event always carries both `transaction_id` and `blockchain_tx_hash` together, rather than firing an incomplete notification first). A `customer.balance.updated` event follows immediately. Use `data.transaction_id` (not `event.id`) as your reconciliation key. If `transaction_id` is `null`, fall back to `event.id`. ```json theme={null} { "id": "evt_1747059300000_jkl012", "type": "transaction.authorized", "created_at": "2026-05-12T14:15:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "544599049", "transaction_id": "tx_9d8e7f6a5b4c3d2e1f", "blockchain_tx_hash": "0xedbca669196b14ddc4b5a8b6fd6c313a1400795cdabe686b3d4b908d8e8279bb", "type": "Payment", "amount": 12.50, "amount_minor": 1250, "currency": "EUR", "billing_amount": 12.50, "billing_amount_minor": 1250, "billing_currency": "EUR", "fx_rate": 1, "merchant": "Starbucks", "merchant_category": "5812", "merchant_city": "Paris", "merchant_country": "FR", "status": "Approved", "timestamp": "2026-05-12T14:15:00.000Z" } } ``` This card settles in EUR and the purchase was also in EUR, so `billing_amount`/`billing_currency` simply match `amount`/`currency` and `fx_rate` is `1` — no conversion took place. See the `transaction.settled` example below for a foreign-currency purchase, where they differ. ### `transaction.settled` Fired when the merchant batch clears and the authorization is finalized. ```json theme={null} { "id": "evt_1747063800000_uvw234", "type": "transaction.settled", "created_at": "2026-05-12T15:30:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "544599049", "transaction_id": "tx_9d8e7f6a5b4c3d2e1f", "blockchain_tx_hash": null, "type": "Payment", "amount": 101, "amount_minor": 10100, "currency": "BRL", "billing_amount": 20.15, "billing_amount_minor": 2015, "billing_currency": "USD", "fx_rate": 5.0124, "merchant": "MERCADOPAGO*STORE", "merchant_category": "7298", "merchant_city": null, "merchant_country": "BR", "status": "Approved", "timestamp": "2026-05-12T15:30:00.000Z" } } ``` This example shows a foreign-currency purchase: a USD-denominated card used at a Brazilian merchant. `amount`/`currency` are the merchant's local currency (BRL, what was charged at the point of sale); `billing_amount`/`billing_currency` are what was actually debited from the card (USD). `fx_rate` (`5.0124`) reads as "1 USD = 5.0124 BRL" — check: `101 / 5.0124 ≈ 20.15`, which matches `billing_amount`. `blockchain_tx_hash` on `transaction.settled` is not guaranteed the way it is on `transaction.authorized` — treat it as best-effort here. `merchant` and `merchant_city` may come back `null` on some networks/transaction stages even when populated on the corresponding `transaction.authorized` event for the same `transaction_id` — treat them as best-effort, not guaranteed on every event. ### `transaction.declined` Fired when a card transaction is declined. ```json theme={null} { "id": "evt_1747059400000_dec01", "type": "transaction.declined", "created_at": "2026-05-12T14:16:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "544599049", "transaction_id": "tx_9d8e7f6a5b4c3d2e1f", "blockchain_tx_hash": null, "type": "Payment", "amount": 200.00, "amount_minor": 20000, "currency": "EUR", "merchant": null, "merchant_category": "5411", "merchant_city": null, "merchant_country": "DE", "status": "Declined", "timestamp": "2026-05-12T14:16:00.000Z" } } ``` ### `transaction.reversed` Fired when an authorization is reversed (e.g. a cancelled hold before settlement). ```json theme={null} { "id": "evt_1747060000000_rev01", "type": "transaction.reversed", "created_at": "2026-05-12T14:26:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "transaction_id": "tx_9d8e7f...", "amount": 12.50, "amount_minor": 1250, "currency": "EUR", "status": "REVERSED", "timestamp": "2026-05-12T14:26:00.000Z" } } ``` ### `transaction.refund.created` Fired when a merchant issues a refund. ```json theme={null} { "id": "evt_1747064000000_ref01", "type": "transaction.refund.created", "created_at": "2026-05-12T15:32:00.000Z", "data": { "yativo_card_id": "yativo_card_customer_8f9a...", "card_id": "card_token_abc123", "transaction_id": "tx_9d8e7f...", "amount": 12.50, "amount_minor": 1250, "currency": "EUR", "status": "REFUNDED", "timestamp": "2026-05-12T15:32:00.000Z" } } ``` *** ## Managing Webhooks ### List all subscriptions ```bash theme={null} GET /v1/yativo-card/webhooks Authorization: Bearer YOUR_TOKEN ``` ### Get one subscription ```bash theme={null} GET /v1/yativo-card/webhooks/:webhookId Authorization: Bearer YOUR_TOKEN ``` ### Update URL, events, or enabled state ```bash theme={null} curl -X PUT 'https://crypto-api.yativo.com/api/v1/yativo-card/webhooks/68241abc...' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "url": "https://api.yourapp.com/webhooks/yativo/v2", "events": ["customer.funded", "transaction.authorized", "transaction.declined"], "enabled": true }' ``` ### Rotate signing secret ```bash theme={null} POST /v1/yativo-card/webhooks/:webhookId/rotate-secret Authorization: Bearer YOUR_TOKEN ``` The response returns the new secret — store it immediately, then update your environment variable. ### Delete a subscription ```bash theme={null} DELETE /v1/yativo-card/webhooks/:webhookId Authorization: Bearer YOUR_TOKEN ``` ### Delivery history ```bash theme={null} # Deliveries for one webhook GET /v1/yativo-card/webhooks/:webhookId/deliveries # All deliveries across webhooks GET /v1/yativo-card/webhooks/deliveries/all ``` ### Retry a failed delivery ```bash theme={null} POST /v1/yativo-card/webhooks/deliveries/:deliveryId/retry Authorization: Bearer YOUR_TOKEN ``` *** ## Retry Policy If your endpoint returns a non-2xx response, times out (> 30 s), or is unreachable, Yativo retries using exponential backoff: | Attempt | Delay after previous attempt | | ----------- | ---------------------------- | | 1 (initial) | — | | 2 | 1 minute | | 3 | 5 minutes | | 4 | 30 minutes | | 5 | 2 hours | | 6 | 12 hours | | 7 | 24 hours | After 7 failed attempts the delivery is marked **permanently failed** — no further automatic retries. Replay it manually via `POST /v1/yativo-card/webhooks/deliveries/:deliveryId/retry`. If your endpoint fails **100 consecutive deliveries**, Yativo automatically disables the subscription to protect your program's event queue. Re-enable it with `PUT /v1/yativo-card/webhooks/:webhookId` and `{ "enabled": true }` after resolving the issue. *** ## Best Practices **Return 200 first, process after.** Yativo waits up to 30 seconds for a response. Enqueue the event to a job queue (BullMQ, Celery, SQS) before returning — don't block on database writes or downstream calls. **Deduplicate with `event.id`.** Yativo deduplicates deliveries server-side so the same upstream event is not queued twice, but network-level retries can still cause your endpoint to receive the same delivery more than once. Store processed event IDs in a database table with a unique constraint and skip duplicates. **Do not return 200 speculatively.** Only acknowledge when you have successfully enqueued the event. If your queue is unavailable, return 500 to trigger a retry. **Handle unknown event types gracefully.** Log and ignore event types you don't recognise rather than throwing an error. Yativo adds new event types over time — unknown types should not break your handler. **Subscribe to the events you need.** Use a focused event list rather than `"*"` in production to reduce noise and make your handler logic explicit. *** ## Idempotent Handler Pattern ```typescript theme={null} async function handleCardIssuerEvent(event: { id: string; type: string; data: any; }) { // 1. Deduplicate const exists = await db.processedEvents.findUnique({ where: { id: event.id } }); if (exists) return; // 2. Process switch (event.type) { case "master_wallet.deposit": if (event.data.status === "settled") { if (event.data.withdrawal_id) { // Withdrawal credit — funds returned from a card withdrawal. // withdrawal_id links this back to the originating card.withdrawal.settled event. await recordWithdrawalCredit(event.data.withdrawal_id, event.data.deposit_amount, event.data.tx_hash); } else { // Regular deposit — new funds arriving from an external source. await updateMasterWalletBalance(event.data.deposit_amount, event.data.currency); } } // Ignore processing events — act only on settled break; case "master_wallet.withdrawal": // Companion to card.withdrawal.settled — confirms master wallet was credited. // Use for master wallet reconciliation; withdrawal_id is the join key. await recordMasterWalletWithdrawalSettled(event.data.withdrawal_id, event.data.tx_hash); break; case "customer.funded": await creditCustomerLedger(event.data.customer_id, event.data.amount, event.data.currency); break; case "customer.funding.failed": await flagFailedFunding(event.data.customer_id, event.data.amount); await notifyOpsTeam(event); break; case "customer.balance.updated": await syncCustomerBalance(event.data.yativo_card_id, { ledger: event.data.ledger_balance, available: event.data.available_balance, pending: event.data.pending_balance, }); break; case "transaction.authorized": await recordPendingTransaction(event.data); break; case "transaction.settled": await finalizeTransaction(event.data.transaction_id); break; case "transaction.declined": await notifyCustomerOfDecline(event.data.yativo_card_id); break; case "card.frozen": case "card.voided": case "card.lost": case "card.stolen": await updateCardStatus(event.data.yativo_card_id, event.data.status); break; } // 3. Mark processed await db.processedEvents.create({ data: { id: event.id, processedAt: new Date() } }); } ``` *** ## Testing Use the sandbox environment to test your webhook handler without real funds: * **Sandbox base URL:** `https://crypto-sandbox.yativo.com/api/v1/` * **Register webhooks** the same way as production — use the same endpoint `POST /v1/webhook/create-webhook` * **Expose your local server** using [ngrok](https://ngrok.com) or [Hookdeck](https://hookdeck.com) during development ```bash theme={null} # Register a sandbox webhook pointing at your local ngrok tunnel curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/webhook/create-webhook' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "url": "https://abc123.ngrok-free.app/webhooks/yativo", "events": ["*"], "description": "Local dev webhook" }' ``` *** ## Related * [Card Issuer Program guide](/guides/b2b-card-issuer) * [Webhook Events API reference](/api-reference/issuer/webhooks) * [Fund Customer API](/api-reference/issuer/fund-customer) * [Funding deposits](/api-reference/issuer/deposits) * [General webhook integration](/guides/webhook-integration) # IBAN Account Setup Source: https://docs.yativo.com/guides/iban-onboarding Get a dedicated IBAN for receiving bank transfers that convert to crypto This guide is coming soon. The standalone IBAN product is currently in sandbox and not yet available for production use. Check back for updates. # Issue Crypto Cards (Own Account) Source: https://docs.yativo.com/guides/issue-crypto-cards Step-by-step guide to onboard yourself, deploy your card wallet, and issue a Visa virtual card on your own Yativo account This guide covers the **own-account** card flow — issuing a Visa virtual card directly on your Yativo developer account. For issuing cards to your end customers under a B2B program, see [B2B Card Issuer Program](/guides/b2b-card-issuer). **Two API namespaces — keep them separate.** | Path prefix | Purpose | | ------------------------------------ | ---------------------------------- | | `/v1/yativo-card/{id}/...` | Own-account card flow (this guide) | | `/v1/yativo-card/customers/{id}/...` | B2B customer card flow | These are different flows with different route prefixes. Mixing them up is the most common integration mistake. *** ## Flow Overview ``` Onboard → Verify OTP → KYC → Source of Funds → Phone → Deploy Wallet → Create Card → Fund ``` Unlike the B2B customer flow, you must **manually trigger wallet deployment** after KYC. B2B customers have their wallets auto-deployed. *** ## Step 1 — Onboard Register your card account with an email address: ```bash theme={null} POST /v1/yativo-card/onboard Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "email": "you@example.com" } ``` ```json Response 201 theme={null} { "success": true, "message": "Card onboarding initiated. Check your email for verification code.", "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "email_masked": "yo***@example.com", "next_step": "verify_otp", "otp_expires_in_seconds": 600 } } ``` Store `yativo_card_id` — it is the path parameter for every subsequent call. Do **not** use an email address that belongs to one of your customers. Each account type must have a unique email. A 6-digit OTP is sent automatically to the email address. *** ## Step 2 — Verify Email OTP ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/verify-otp Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "otp": "847291" } ``` ```json Response 200 theme={null} { "success": true, "message": "Email verified successfully", "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "flow_status": "otp_verified", "next_step": "kyc_link" } } ``` | Error | Meaning | | ------------------------- | ------------------------------------------------------------ | | `OTP_EXPIRED` | 10-minute window passed — resend via `POST /{id}/resend-otp` | | `OTP_VERIFICATION_FAILED` | Wrong code | | `OTP_ATTEMPTS_EXCEEDED` | 5 failed attempts — restart onboarding | ### Resend OTP ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/resend-otp Authorization: Bearer YOUR_TOKEN ``` *** ## Step 3 — Get KYC Link ```bash theme={null} GET /v1/yativo-card/{yativoCardId}/kyc-link Authorization: Bearer YOUR_TOKEN ``` ```json Response 200 theme={null} { "success": true, "message": "KYC link generated. Open the link to complete identity verification.", "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "kyc_type": "sumsub", "kyc_url": "https://kyc.yativo.com/verify?token=...", "sumsub_sdk_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "next_step": "kyc_status", "instructions": "Open the KYC link to upload your government ID and complete liveness check" } } ``` Redirect to `kyc_url`, or embed the verification widget using `sumsub_sdk_token` and the [Sumsub Web SDK](https://docs.sumsub.com/reference/web-sdk-readme). Add `?refresh=true` to force-generate a new link if the old one expired. *** ## Step 4 — Poll KYC Status ```bash theme={null} GET /v1/yativo-card/{yativoCardId}/kyc-status Authorization: Bearer YOUR_TOKEN ``` ```json Approved theme={null} { "success": true, "message": "KYC status retrieved", "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "kyc_status": "approved", "verification_level": 1, "terms_accepted": true, "next_step": "create_safe" } } ``` ```json Pending theme={null} { "success": true, "data": { "kyc_status": "pending", "next_step": null } } ``` ```json Rejected theme={null} { "success": true, "data": { "kyc_status": "rejected", "rejection_reason": "Document not readable", "next_step": null } } ``` Poll every 10 seconds for up to 10 minutes. On rejection, fetch a new `kyc-link` and retry. Terms are auto-accepted when KYC first transitions to `approved`. *** ## Step 5 — Source of Funds ### Get questions ```bash theme={null} GET /v1/yativo-card/{yativoCardId}/source-of-funds Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "status": "questions_retrieved", "questions": [ { "question": "EMPLOYMENT_STATUS", "label": "What is your employment status?", "options": ["EMPLOYED", "SELF_EMPLOYED", "UNEMPLOYED", "STUDENT", "RETIRED"] }, { "question": "SOURCE_OF_INCOME", "label": "What is your primary source of income?", "options": ["SALARY", "BUSINESS_INCOME", "INVESTMENT", "PENSION", "OTHER"] } ], "next_step": "Submit answers using POST /source-of-funds" } } ``` ### Submit answers ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/source-of-funds Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "answers": [ { "question": "EMPLOYMENT_STATUS", "answer": "EMPLOYED" }, { "question": "SOURCE_OF_INCOME", "answer": "SALARY" } ] } ``` ```json Response theme={null} { "success": true, "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "status": "completed", "next_step": "Verify phone number using POST /phone/request-verification" } } ``` *** ## Step 6 — Phone Verification ### Request SMS code ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/phone/request-verification Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "phoneNumber": "+14155552671" } ``` ```json Response theme={null} { "success": true, "message": "Verification code sent" } ``` ### Verify SMS code ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/phone/verify Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "code": "382910" } ``` ```json Response theme={null} { "success": true, "data": { "is_verified": true } } ``` *** ## Step 7 — Deploy Card Wallet This step is **own-account only**. B2B customers managed through the Card Issuer Program have their wallets provisioned automatically after KYC — no manual deployment needed. ### Initiate deployment ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/safe/deploy Authorization: Bearer YOUR_TOKEN ``` ```json Response 202 theme={null} { "success": true, "message": "Safe deployment initiated. Deployment typically takes up to 1 minute.", "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "deployment_accepted": true, "estimated_completion": "~1 minute", "next_step": "monitor_deployment", "monitor_endpoint": "/api/yativo-card/yativo_card_abc123_1769031332068/safe/deploy" } } ``` ### Poll until ready ```bash theme={null} GET /v1/yativo-card/{yativoCardId}/safe/deploy Authorization: Bearer YOUR_TOKEN ``` ```json Ready theme={null} { "success": true, "message": "Safe deployment complete", "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "safe_config": { "address": "0xABCD1234...", "token_symbol": "EUR", "fiat_symbol": "EUR", "account_status": 0, "account_status_meaning": "Ok", "is_deployed": true, "has_no_approvals": false }, "is_ready": true, "next_step": "card_ready" } } ``` ```json In Progress theme={null} { "success": true, "message": "Safe deployment in progress", "data": { "is_ready": false, "next_step": "wait_and_check_again" } } ``` Poll every 5 seconds. Move to card creation once `is_ready` is `true`. *** ## Step 8 — Create Virtual Card ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/cards/virtual Authorization: Bearer YOUR_TOKEN ``` ```json Response 201 theme={null} { "success": true, "message": "Virtual card created successfully", "data": { "yativo_card_id": "yativo_card_abc123_1769031332068", "card_id": "b2dc97ab-03f9-49eb-c72f-95be13815278", "card_type": "virtual", "status": "active", "status_code": 1000, "status_name": "Active", "activated_at": "2026-04-01T12:30:00.000Z", "total_cards": 1, "funding_wallet": { "address": "SoLFundingWalletAddressXXX", "network": "solana", "asset": "USDC" } } } ``` By default, each account can hold 1 virtual card and 1 physical card (2 total). Yativo admins can raise these limits up to a platform hard cap of 5 active cards combined. If you hit the limit, you will receive `VIRTUAL_CARD_LIMIT_REACHED` or `PHYSICAL_CARD_LIMIT_REACHED`. Use [Get Secure Card View URL](/api-reference/cards/customer-secure-view) to securely display the full card number and CVV. *** ## Step 9 — Fund Your Card Get your deposit address: ```bash theme={null} GET /v1/yativo-card/{yativoCardId}/wallet/funding-address Authorization: Bearer YOUR_TOKEN ``` ```json Response theme={null} { "success": true, "data": { "address": "SoLFundingWalletAddressXXX", "network": "solana", "card_currency": "EUR", "supported_tokens": [ { "symbol": "USDC", "name": "USD Coin", "contract": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "decimals": 6, "network": "solana" } ], "funding_sources": { "usdc_sol": { "address": "SoLFundingWalletAddressXXX", "network": "solana", "token": "USDC", "bridge_type": "automatic", "bridge_time": "2-5 minutes", "description": "Send USDC on Solana — automatically applied to your card" }, "usdc_xdc": { "address": "0xXDCFundingWallet...", "network": "xdc", "token": "USDC", "bridge_type": "manual", "bridge_time": "15-25 minutes", "description": "No minimum. Hold to earn yield. Fund card on demand." } }, "auto_bridge": { "enabled": true, "source": "USDC_SOL", "destination": "EUR", "estimated_time": "30 seconds", "minimum_trigger_amount": 5, "minimum_trigger_amount_unit": "USDC", "accumulates_below_minimum": true }, "minimum_deposit": "5.00", "instructions": "Send USDC (SPL) on Solana to this address. Auto-bridge starts once your available balance reaches at least 5.00 USDC; smaller deposits accumulate until the minimum is reached." } } ``` Send USDC to the `usdc_sol.address` on Solana. Processing starts automatically once the available balance reaches `minimum_trigger_amount`. *** ## Card Management ### Freeze / Unfreeze ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/freeze POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/unfreeze Authorization: Bearer YOUR_TOKEN ``` ### View Transactions ```bash theme={null} GET /v1/yativo-card/{yativoCardId}/transactions?limit=20 Authorization: Bearer YOUR_TOKEN ``` ### File a Dispute ```bash theme={null} # Get reason codes first GET /v1/yativo-card/{yativoCardId}/transactions/dispute-reasons Authorization: Bearer YOUR_TOKEN # File dispute POST /v1/yativo-card/{yativoCardId}/transactions/{transactionId}/dispute Authorization: Bearer YOUR_TOKEN Content-Type: application/json { "reason_code": "NOT_AS_DESCRIBED" } ``` ### Void a Card (irreversible, virtual only) ```bash theme={null} POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/void Authorization: Bearer YOUR_TOKEN ``` Permanently cancels a virtual card on the card network. Physical cards cannot be voided — use freeze to block transactions instead. *** ## Quick Reference | Step | Method | Path | | ------------------------ | ------ | ------------------------------------------------- | | Onboard | `POST` | `/v1/yativo-card/onboard` | | Verify OTP | `POST` | `/v1/yativo-card/{id}/verify-otp` | | Resend OTP | `POST` | `/v1/yativo-card/{id}/resend-otp` | | Get KYC link | `GET` | `/v1/yativo-card/{id}/kyc-link` | | Poll KYC status | `GET` | `/v1/yativo-card/{id}/kyc-status` | | Get SoF questions | `GET` | `/v1/yativo-card/{id}/source-of-funds` | | Submit SoF answers | `POST` | `/v1/yativo-card/{id}/source-of-funds` | | Request phone OTP | `POST` | `/v1/yativo-card/{id}/phone/request-verification` | | Verify phone | `POST` | `/v1/yativo-card/{id}/phone/verify` | | Initiate wallet deploy | `POST` | `/v1/yativo-card/{id}/safe/deploy` | | Poll wallet deploy | `GET` | `/v1/yativo-card/{id}/safe/deploy` | | Create virtual card | `POST` | `/v1/yativo-card/{id}/cards/virtual` | | Get deposit address | `GET` | `/v1/yativo-card/{id}/wallet/funding-address` | | Freeze card | `POST` | `/v1/yativo-card/{id}/cards/{cardId}/freeze` | | Unfreeze card | `POST` | `/v1/yativo-card/{id}/cards/{cardId}/unfreeze` | | Void card (virtual only) | `POST` | `/v1/yativo-card/{id}/cards/{cardId}/void` | | View transactions | `GET` | `/v1/yativo-card/{id}/transactions` | # Neobanking Features Source: https://docs.yativo.com/guides/neobanking A complete guide to using Yativo's built-in banking features — virtual accounts, send money, gift cards, transaction history, and monthly statements This guide covers the **Yativo app** banking features available to end users. It is not an API integration guide — all functionality described here is managed through the Yativo interface, no code required. Yativo combines crypto asset management with a full set of neobanking features: receive real money into a virtual account, send funds globally, purchase and redeem gift cards, browse your full transaction history, and receive detailed monthly statements across all your accounts. *** ## Virtual Account Deposits Your Yativo account includes a **virtual account (VA)** — a real bank account number you can share with anyone to receive local currency deposits. When funds arrive, they are credited to your Yativo balance and you receive an email confirmation. ### How it works 1. Open the **Deposit** section of the app. 2. Copy your virtual account number and routing details. 3. Share those details with whoever is sending you money (a client, employer, family member, etc.). 4. The sender transfers using their local bank — no crypto knowledge required on their end. 5. Funds appear in your Yativo balance within the typical settlement window for your region (usually minutes to a few hours). 6. You receive an email notification confirming the amount, currency, and sender name. ### Supported regions Virtual accounts are available in supported countries. Your account details are shown in your local currency and banking format (account number + sort code, IBAN, CLABE, etc.) based on your registered country. Virtual accounts are ideal for receiving freelance payments, cross-border invoices, or regular income without asking senders to learn about crypto. *** ## Send Money The **Send Money** feature lets you transfer funds to recipients in supported countries using your USDC wallet balance. Yativo converts at a competitive rate and delivers via local bank rails (SPEI, PIX, mobile money, and more). ### Single transfer Search for an existing beneficiary or create a new one. Enter the recipient's name, country, bank details, and the payment method for their region. Type the amount you want to send. Select the source currency (your wallet currency) and the destination currency. Yativo shows you the converted amount the recipient will receive before you confirm. Review the transfer details — amount, recipient, rate, and fees — then confirm. Your USDC balance is debited immediately. Open **Transaction History → Fiat Transfers** to see real-time status updates: initiated → processing → completed. Tap any row to open the tracking timeline. ### Bulk transfer Need to pay multiple people at once? Use the **Bulk Transfer** tab: 1. Click **Add Recipient** for each person. 2. Fill in their name, country, currency, amount, and optional note. 3. Click **Send All** — Yativo processes each transfer sequentially and updates the status of each row in real time. Each recipient in a bulk transfer is processed individually. A failure on one row does not cancel the others. Review any failed rows and retry if needed. *** ## Gift Cards Yativo lets you **purchase** gift cards for popular brands across dozens of countries, and **redeem** them directly within the app — all funded from your USDC balance. ### Purchasing a gift card 1. Navigate to **Gift Cards** in the app. 2. Filter by country and/or category (Entertainment, Food & Drink, Shopping, Gaming, etc.). 3. Select a product and choose your denomination. 4. Review the total USDC cost and confirm the purchase. 5. Your redemption code (and PIN, if applicable) appears immediately on screen and is also emailed to you. ### Redeeming a gift card If a gift card can be redeemed directly inside Yativo (e.g., to top up a balance): 1. Go to **Gift Cards → Redeem**. 2. Enter the transaction ID from your purchase or paste your redemption code. 3. Confirm — the value is applied instantly. Check your email after every purchase — the confirmation contains your full redemption code, PIN, expiry date, and redemption instructions in one place. *** ## Transaction History The **Transactions** page gives you a unified view of all activity across your Yativo accounts. ### Crypto transactions The **All Crypto** tab shows every on-chain event on your wallets: deposits, withdrawals, swaps, and gas. Each row displays: * Date and time * Asset and chain * Amount * Transaction hash (truncated) for blockchain verification * Status (Confirmed, Pending, Failed) ### Fiat transfers The **Fiat Transfers** tab covers all send money and payout activity. Click any row to open the **tracking drawer** — a slide-in panel with: * Full transfer details (recipient, amount, destination country) * A live timeline showing each processing step * Current status badge ### Filters and export Use the search bar and status filters to narrow results. Click **Download PDF** to generate a printable statement of the currently visible transactions. *** ## Monthly Statements On the **1st of every month**, Yativo automatically emails you four separate account statements covering the previous calendar month: | Statement | What it covers | | --------------------------- | ----------------------------------------------------------------------- | | **Crypto Wallet Statement** | All on-chain deposits, withdrawals, and swaps across your crypto assets | | **Card Statement** | All card spend, merchant transactions, and top-ups | | **Banking Statement** | Send Money and payout transactions funded from your USDC wallet | | **Gift Card Statement** | All gift card purchases and redemptions | ### What's included Each statement email contains: * A **summary section** — total received, total sent, transaction count for the period * A **full transaction table** — date, type, amount, recipient/merchant, and status for every transaction * A printable, professional layout suitable for your records or accounting Statements are only sent for account types that had activity in the month. If you had no card transactions in a given month, no card statement is sent. ### Statement period Statements cover **the previous full calendar month**. The statement sent on 1 February covers 1 January – 31 January, and so on. ### Opting out Statements are part of Yativo's account notifications. You can manage your notification preferences from the **Settings → Notifications** section of the app. *** ## Summary | Feature | Where to find it | | -------------------------------- | ------------------------------------------- | | Virtual account details | Deposit → Virtual Account | | Send money (single or bulk) | Send Money | | Gift card purchase | Gift Cards → Shop | | Gift card redemption | Gift Cards → Redeem | | Crypto transaction history | Transactions → All Crypto | | Fiat transfer history + tracking | Transactions → Fiat Transfers | | Monthly statements | Delivered by email on the 1st of each month | # Guides Source: https://docs.yativo.com/guides/overview Step-by-step tutorials for building with Yativo Crypto These guides walk you through real-world integration scenarios end-to-end — from setting up wallets to issuing cards to handling webhooks. Each guide is self-contained with complete code examples in TypeScript, Python, and cURL. Every guide in this section can be tested against the Sandbox environment before going live. Use the base URL `https://crypto-sandbox.yativo.com/api/v1/` with sandbox credentials. See the [Sandbox docs](/sandbox/overview) for details. ## Tutorials Create wallets, display deposit addresses to users, and receive real-time deposit notifications via webhooks. The fastest path to accepting crypto in your app. Programmatically send crypto to any external wallet address. Learn about gas estimation, idempotency keys, priority levels, and tracking transaction status. Issue Visa/Mastercard virtual and physical cards funded by USDC. Walk through KYC onboarding, wallet deployment, card creation, and secure card detail retrieval. Apply for the card issuer program and issue cards directly to your own customers. Ideal for fintechs, neobanks, and platforms building branded card products. Get a dedicated IBAN that converts incoming bank transfers (SEPA/SWIFT) to crypto automatically. Complete KYC onboarding and start receiving fiat in minutes. Exchange one crypto asset for another across chains. Get quotes, handle expiry, execute swaps, and monitor swap history with full fee transparency. Receive real-time event notifications for deposits, withdrawals, card transactions, and more. Includes signature verification, retry handling, and full event reference. Go from zero to your first API call in TypeScript, Python, PHP, Java, or React. Install the SDK, authenticate, and create your first wallet in under 5 minutes. ## Where to Start If you are new to Yativo Crypto, we recommend this sequence: 1. **[SDK Quickstart](/guides/sdk-quickstart)** — Install the SDK and authenticate 2. **[Accept Crypto Payments](/guides/accept-crypto-payments)** — Set up wallets and start receiving deposits 3. **[Webhook Integration](/guides/webhook-integration)** — Get real-time event notifications 4. **[Send Crypto](/guides/send-crypto)** — Move funds out programmatically For card-specific use cases, start with **[Issue Crypto-Funded Cards](/guides/issue-crypto-cards)**, and for B2B platform use cases see the **[B2B Card Issuer Program](/guides/b2b-card-issuer)**. # Accept Crypto Payments (Gateway) Source: https://docs.yativo.com/guides/payment-gateway Set up a crypto payment gateway to accept payments from anyone via hosted checkout This guide walks you through setting up the Yativo Crypto Payment Gateway to accept payments. By the end, you'll have a working payment flow: submit a compliance application, create a payment intent, share a link, and receive crypto settled to your Gateway Account. *** Get a Bearer token using your API key: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/auth/token' \ -H 'Content-Type: application/json' \ -d '{ "api_key": "yativo_...", "api_secret": "..." }' ``` ```json Response theme={null} { "success": true, "data": { "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 86400 } } ``` Before creating payment links you must pass a one-time compliance check. Attempting to skip this returns `403 GATEWAY_APPLICATION_REQUIRED`. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/crypto-gateway/apply' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "logo_url": "https://yoursite.com/logo.png", "support_email": "support@yoursite.com", "social_media_url": "https://twitter.com/yourcompany", "business_type": "ecommerce", "expected_volume": "1k_10k", "website_url": "https://yoursite.com", "webhook_url": "https://yoursite.com/webhooks/yativo" }' ``` Poll `GET /crypto-gateway/application` to check approval status. Approval typically takes under 24 hours. Once approved, create a payment intent specifying the amount, a title (shown on the checkout page), and the tokens you accept: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/crypto-gateway/payments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "title": "Pro Plan — Monthly", "description": "1-month access to Pro features", "requested_amount": 49.99, "accepted_assets": ["USDC_SOL", "USDT_POL", "USDC_BASE"], "external_reference": "order_abc123" }' ``` ```json Response theme={null} { "success": true, "data": { "payment_id": "pay_a1b2c3d4e5f6", "title": "Pro Plan — Monthly", "description": "1-month access to Pro features", "requested_amount": 49.99, "status": "awaiting_payment", "checkout_url": "https://crypto-checkout.yativo.com/pay/pay_a1b2c3d4e5f6", "embed_url": "https://crypto-checkout.yativo.com/embed/pay_a1b2c3d4e5f6", "accepted_options": [ { "asset_code": "USDC_SOL", "network": "solana", "deposit_address": "7xKXtg..." }, { "asset_code": "USDT_POL", "network": "polygon", "deposit_address": "0xAbCd..." }, { "asset_code": "USDC_BASE", "network": "base", "deposit_address": "0x1234..." } ], "external_reference": "order_abc123", "payment_window_expires_at": "2026-04-18T13:00:00Z", "monitoring_ends_at": "2026-04-18T13:20:00Z", "created_at": "2026-04-18T12:00:00Z" } } ``` Redirect your customer to the `checkout_url`. Redirect your customer to the `checkout_url`, or embed it in: * An email invoice * A QR code * A "Pay with Crypto" button on your site * A Telegram/Discord bot message The hosted checkout page collects the customer's email, displays the title and description, lets the customer choose a token, shows the deposit address and QR code, and auto-confirms once the on-chain payment lands. Register a webhook to get notified when the payment settles. The `webhook_url` from your application is used automatically; you can also override it per payment. ```json Webhook Payload — gateway.payment.settled theme={null} { "event": "gateway.payment.settled", "data": { "payment_id": "pay_a1b2c3d4e5f6", "title": "Pro Plan — Monthly", "requested_amount": 49.99, "settled_amount": 49.99, "asset_code": "USDC_SOL", "network": "solana", "transaction_hash": "5UxR7Kq...", "status": "paid", "external_reference": "order_abc123", "late_payment": false, "settled_at": "2026-04-18T12:08:00Z" } } ``` When your webhook endpoint receives the `gateway.payment.settled` event, check `status === "paid"` or `"paid_late"` and fulfill the order using your `external_reference`: ```javascript theme={null} app.post('/webhooks/yativo', (req, res) => { const { event, data } = req.body; if (event === 'gateway.payment.settled') { const { payment_id, status, external_reference } = data; if (status === 'paid' || status === 'paid_late') { fulfillOrder(external_reference); } } res.status(200).send('ok'); }); ``` *** ## Payment Status Values | Status | Description | | ------------------------ | ----------------------------------------------------- | | `awaiting_payment` | Waiting for the customer to send funds | | `monitoring_late_window` | Primary window closed; still accepted in grace period | | `paid` | Confirmed on-chain within the primary window | | `paid_late` | Confirmed during the late monitoring window | | `expired` | Monitoring window closed with no payment detected | | `cancelled` | Cancelled by the merchant | *** ## Full Example (TypeScript) ```typescript theme={null} import { YativoCrypto } from '@yativo/crypto-sdk'; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, apiSecret: process.env.YATIVO_API_SECRET!, }); // Create a payment for a customer's order async function createPayment(orderId: string, amount: number) { const payment = await client.gateway.createPayment({ title: `Order #${orderId}`, description: 'Your purchase from Acme Store', requestedAmount: amount, acceptedAssets: ['USDC_SOL', 'USDT_POL', 'USDC_BASE'], externalReference: orderId, }); return payment.checkoutUrl; // Send this to your customer } ``` *** ## Next Steps Full Payment Gateway documentation — analytics, reconciliation, and more. Set up and verify webhooks. # Regional Payout Guide Source: https://docs.yativo.com/guides/regional-payouts Country-by-country guide for sending payments via local rails — SPEI, PIX, ACH, SEPA, and more Each country Yativo supports has specific requirements for payment details, account number formats, and payout method IDs. This guide covers the exact fields needed for each corridor so you can build region-specific flows without trial and error. The general flow is the same for all regions: ``` GET /payment-methods/payout/countries → confirm country is supported GET /payment-methods/payout?country={iso3} → get payment_method_id for the rail GET /beneficiary/form/show/{id} → get required account_details fields POST /beneficiaries → create beneficiary POST /beneficiaries/payment-methods → save bank details POST /sendmoney/quote → lock rate POST /sendmoney → execute ``` *** ## Mexico — SPEI via CLABE **Payment rail:** SPEI (Sistema de Pagos Electrónicos Interbancarios)\ **Key identifier:** CLABE — an 18-digit standardised bank code unique to each Mexican bank account\ **Settlement time:** Same-day, typically within minutes ### Required account details | Field | Format | Example | | ------- | --------- | ---------------------- | | `clabe` | 18 digits | `"012345678901234567"` | The first 3 digits of a CLABE identify the bank, the next 3 the city, and the last is a check digit. Validating the check digit before submission reduces failure rates. ```javascript theme={null} function validateClabe(clabe) { if (!/^\d{18}$/.test(clabe)) return false; const weights = [3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7]; const sum = weights.reduce((acc, w, i) => acc + (parseInt(clabe[i]) * w) % 10, 0); const checkDigit = (10 - (sum % 10)) % 10; return checkDigit === parseInt(clabe[17]); } ``` ### Generate a CLABE for a customer If your platform needs to issue SPEI receive addresses (not just send to them), Yativo can generate valid CLABEs for your customers: ``` GET https://api.yativo.com/api/v1/clabe/generate ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/clabe/generate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ### Full payout example ```bash theme={null} # 1. Get payment method ID for Mexico curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout?country=MEX' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' # → returns id: 30 (SPEI) # 2. Save beneficiary with CLABE curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: pm-mexico-001' \ -d '{ "beneficiary_id": "YOUR_BENEFICIARY_ID", "payment_method_id": 30, "account_details": { "clabe": "012345678901234567" } }' # 3. Get a quote (USD → MXN) curl -X POST 'https://api.yativo.com/api/v1/sendmoney/quote' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: quote-mx-001' \ -d '{ "from_currency": "USD", "to_currency": "MXN", "amount": 500, "beneficiary_payment_method_id": "PM_ID" }' # 4. Execute curl -X POST 'https://api.yativo.com/api/v1/sendmoney' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: send-mx-001' \ -d '{ "quote_id": "QUOTE_ID" }' ``` ### Virtual accounts (receive MXN via SPEI) To receive SPEI payments for a customer, create a virtual account with currency `"MXNBASE"`: ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: va-mx-001' \ -d '{ "customer_id": "CUSTOMER_ID", "currency": "MXNBASE" }' ``` The returned `account_number` is a CLABE your customers can send SPEI transfers to. *** ## Brazil — PIX **Payment rail:** PIX (instant payment system by Banco Central do Brasil)\ **Key identifier:** PIX key — a unique alias for a bank account\ **Settlement time:** 24/7, under 10 seconds ### PIX key types | Type | Field value | Example | | --------------------- | ----------- | ---------------------------------------- | | CPF (tax ID) | `cpf` | `"12345678901"` (11 digits) | | CNPJ (company tax ID) | `cnpj` | `"12345678000190"` (14 digits) | | Phone number | `phone` | `"+5511999999999"` (E.164) | | Email | `email` | `"customer@example.com"` | | EVP (random key) | `evp` | `"e2ee3bd7-a7d7-4a9e-b8a1-abcdef123456"` | ### Required account details | Field | Type | Description | | -------------- | ------ | -------------------------------------------------------- | | `pix_key` | string | The recipient's PIX key value | | `pix_key_type` | string | One of: `"cpf"`, `"cnpj"`, `"phone"`, `"email"`, `"evp"` | ### Example — send to a CPF PIX key ```bash theme={null} # Save beneficiary payment method for Brazil PIX curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: pm-brazil-001' \ -d '{ "beneficiary_id": "YOUR_BENEFICIARY_ID", "payment_method_id": 40, "account_details": { "pix_key": "12345678901", "pix_key_type": "cpf" } }' ``` ### Virtual accounts (receive BRL via PIX) ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: va-br-001' \ -d '{ "customer_id": "CUSTOMER_ID", "currency": "BRL" }' ``` The returned `account_number` is a PIX key (EVP type) that any Brazilian bank account can pay to. For virtual accounts, Yativo issues a KYC-linked endorsement (`brazil`). Customers without this endorsement cannot receive PIX deposits. Check `endorsements` in the KYC status response. *** ## Nigeria — NUBAN bank transfer **Payment rail:** Nigerian NUBAN (Nigeria Uniform Bank Account Number)\ **Settlement time:** Same-day to next business day ### KYC requirements Nigerian customers have **mandatory additional KYC fields** when submitting identity verification: | Field | Requirement | Format | | ----- | --------------------------------- | ----------------- | | `bvn` | Required when `nationality: "NG"` | Exactly 11 digits | | `nin` | Required when `nationality: "NG"` | Exactly 11 digits | Without both `bvn` and `nin`, KYC submission will fail validation for Nigerian nationals. See the [Individual KYC](/fiat-api-reference/kyc/submit-individual) reference. ### Required account details for payouts | Field | Format | Example | | ---------------- | --------------------- | --------------------------------------- | | `account_number` | 10-digit NUBAN | `"0123456789"` | | `bank_code` | 3-digit CBN bank code | `"044"` (Access Bank), `"058"` (GTBank) | | `account_name` | String | `"Jane Doe"` | ### Common Nigerian bank codes | Bank | Code | | ----------------------- | -------- | | Access Bank | `044` | | GTBank (Guaranty Trust) | `058` | | Zenith Bank | `057` | | First Bank | `011` | | UBA | `033` | | Fidelity Bank | `070` | | Sterling Bank | `232` | | Kuda Bank | `090267` | ### Example ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: pm-ng-001' \ -d '{ "beneficiary_id": "YOUR_BENEFICIARY_ID", "payment_method_id": 50, "account_details": { "account_number": "0123456789", "bank_code": "044", "account_name": "Jane Doe" } }' ``` *** ## United States — ACH / Wire **Payment rail:** ACH (Automated Clearing House) or domestic wire\ **Settlement time:** ACH 1–3 business days; Wire same-day ### Required account details | Field | Format | Example | | ---------------- | --------------------------- | -------------- | | `account_number` | Bank account number | `"123456789"` | | `routing_number` | 9-digit ABA routing number | `"021000021"` | | `account_type` | `"checking"` or `"savings"` | `"checking"` | | `account_name` | Name on account | `"Alex Smith"` | ### Virtual accounts (receive USD) ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: va-us-001' \ -d '{ "customer_id": "CUSTOMER_ID", "currency": "USDBASE" }' ``` *** ## Europe — SEPA **Payment rail:** SEPA Credit Transfer (SCT) or SEPA Instant (SCT Inst)\ **Settlement time:** Standard SCT next business day; SCT Inst within 10 seconds ### Required account details | Field | Format | Example | | -------------- | --------------------- | -------------------------- | | `iban` | IBAN (up to 34 chars) | `"DE89370400440532013000"` | | `bic` | BIC/SWIFT code | `"COBADEFFXXX"` | | `account_name` | Account holder name | `"Maria Schmidt"` | ### Virtual accounts (receive EUR via SEPA) ```bash theme={null} # Standard EUR SEPA curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -d '{ "customer_id": "CUSTOMER_ID", "currency": "EURBASE" }' # Germany-specific EUR SEPA (EURDE) curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -d '{ "customer_id": "CUSTOMER_ID", "currency": "EURDE" }' ``` *** ## Chile — Bank Transfer **Payment rail:** Local bank transfer (RUT-based)\ **Settlement time:** Same-day (business hours) ### Required account details | Field | Format | Example | | ---------------- | ------------------------------------------------ | ------------------------------------------- | | `account_number` | Bank account number | `"12345678"` | | `bank_code` | Bank code | `"001"` (BancoEstado), `"009"` (Scotiabank) | | `account_type` | `"checking"` or `"savings"` (corriente / ahorro) | `"checking"` | | `rut` | Chilean RUT number | `"12345678-9"` | *** ## Colombia — Bank Transfer / Nequi / DaviPlata **Payment rail:** Local bank ACH, Nequi, or DaviPlata\ **Settlement time:** Same-day ### Required account details | Field | Format | | ----------------- | ------------------------------------------------------ | | `account_number` | Bank account number | | `bank_code` | Bank code | | `account_type` | `"checking"` or `"savings"` | | `document_type` | `"CC"` (cédula), `"NIT"` (company), `"CE"` (foreigner) | | `document_number` | ID number | *** ## Peru — CCI Bank Transfer **Payment rail:** CCI (Código de Cuenta Interbancario)\ **Settlement time:** 1–2 business days ### Required account details | Field | Format | Example | | ---------------- | ------------ | ----------------------------- | | `account_number` | 20-digit CCI | `"00215601234567891234"` | | `bank_code` | Bank code | `"002"` (BCP), `"011"` (BBVA) | *** ## Argentina — CVU / CBU **Payment rail:** CBU (Clave Bancaria Uniforme) or CVU (Mercado Pago / digital wallets)\ **Settlement time:** Same-day for CVU; 1–2 days for CBU ### Required account details (payouts) | Field | Format | Example | | --------- | ------------------- | -------------------------- | | `cbu_cvu` | 22-digit CBU or CVU | `"0000003100097845599238"` | | `alias` | Optional CBU alias | `"ALIAS.PAGO.CUENTA"` | ### Virtual accounts (receive ARS) — Argentina-specific requirements Argentina virtual accounts require additional customer identity fields that are **not needed for other countries**. The customer must be an Argentine resident. ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: va-ar-001' \ -d '{ "customer_id": "CUSTOMER_ID", "currency": "ARS", "document_id": "A23E4567", "document_type": "CUIT" }' ``` | Field | Required | Description | | --------------- | -------- | --------------------------------------------------------------------------------------------------------------------- | | `currency` | Yes | Must be `"ARS"` | | `document_id` | Yes | Customer's official document number | | `document_type` | Yes | `"CUIT"` (tax ID for companies/self-employed), `"CUIL"` (labour ID for individuals), or `"CDI"` (foreign resident ID) | CUIT is used for companies and self-employed individuals. CUIL is for employees. CDI is for foreign residents without a CUIL. When in doubt for an individual customer, use `CUIL`. *** ## Getting the exact fields for any method Use the form fields endpoint to get the precise required fields dynamically — they may change as rails evolve: ```bash theme={null} # Replace 30 with the payment_method_id from GET /payment-methods/payout?country=... curl -X GET 'https://api.yativo.com/api/v1/beneficiary/form/show/30' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` This returns the exact fields with labels, validation rules, and whether each is required — the authoritative source for building your payment forms. # SDK Quickstart Source: https://docs.yativo.com/guides/sdk-quickstart Get up and running with the Yativo Crypto SDK in minutes This guide takes you from zero to your first successful API call in each of the official Yativo Crypto SDKs. Each example shows install, initialization, authentication, and creating your first wallet. All examples connect to the Sandbox at `https://crypto-sandbox.yativo.com/api/v1/` by default. Switch to `https://crypto-api.yativo.com/api/v1/` when you're ready for production. ## Prerequisites 1. Sign up at [crypto.yativo.com](https://crypto.yativo.com/sign-up) 2. Create an API key in the Dashboard under **Settings → API Keys** 3. Copy the key — it starts with `yvk_` ### Install ```bash theme={null} npm install @yativo/crypto-sdk # or yarn add @yativo/crypto-sdk # or pnpm add @yativo/crypto-sdk ``` ### Initialize ```typescript TypeScript theme={null} import { YativoCrypto } from "@yativo/crypto-sdk"; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, // yvk_sandbox_... baseUrl: "https://crypto-sandbox.yativo.com/api/v1/", // switch to crypto-api for production }); ``` ### Authenticate and make your first call ```typescript TypeScript theme={null} import { YativoCrypto } from "@yativo/crypto-sdk"; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, baseUrl: "https://crypto-sandbox.yativo.com/api/v1/", }); async function main() { // 1. Verify credentials const me = await client.auth.me(); console.log(`Authenticated as: ${me.email}`); console.log(`Organization: ${me.organizationName}`); // 2. Create an account const account = await client.accounts.create({ label: "my_first_account", metadata: { purpose: "quickstart" }, }); console.log(`Account created: ${account.accountId}`); // 3. Add a USDC wallet on Polygon const wallet = await client.assets.addAsset({ accountId: account.accountId, chain: "polygon", asset: "USDC", }); console.log(`Wallet address: ${wallet.address}`); // 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD } main().catch(console.error); ``` ### TypeScript types The SDK ships with full TypeScript types. No additional `@types` package is needed. ```typescript TypeScript theme={null} import type { Account, Asset, Transaction } from "@yativo/crypto-sdk"; async function getAccountWallets(accountId: string): Promise { return client.assets.listByAccount(accountId); } ``` ### Environment setup ```bash .env theme={null} YATIVO_API_KEY=yvk_sandbox_01J2K9MNPQ3R4S5T6U7VAPIKEY ``` ```typescript TypeScript theme={null} // Use dotenv in Node.js import "dotenv/config"; import { YativoCrypto } from "@yativo/crypto-sdk"; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, baseUrl: process.env.YATIVO_BASE_URL ?? "https://crypto-sandbox.yativo.com/api/v1/", }); ``` ### Install ```bash theme={null} pip install yativo-crypto # or with poetry poetry add yativo-crypto # or with uv uv add yativo-crypto ``` ### Initialize ```python Python theme={null} import os from yativo_crypto import YativoCrypto client = YativoCrypto( api_key=os.environ["YATIVO_API_KEY"], base_url="https://crypto-sandbox.yativo.com/api/v1/", ) ``` ### Authenticate and make your first call ```python Python theme={null} import os from yativo_crypto import YativoCrypto client = YativoCrypto( api_key=os.environ["YATIVO_API_KEY"], base_url="https://crypto-sandbox.yativo.com/api/v1/", ) def main(): # 1. Verify credentials me = client.auth.me() print(f"Authenticated as: {me.email}") print(f"Organization: {me.organization_name}") # 2. Create an account account = client.accounts.create( label="my_first_account", metadata={"purpose": "quickstart"}, ) print(f"Account created: {account.account_id}") # 3. Add a USDC wallet on Polygon wallet = client.assets.add_asset( account_id=account.account_id, chain="polygon", asset="USDC", ) print(f"Wallet address: {wallet.address}") # 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD if __name__ == "__main__": main() ``` ### Async support The SDK also supports `asyncio`: ```python Python theme={null} import asyncio from yativo_crypto.async_client import AsyncYativoCrypto async def main(): async with AsyncYativoCrypto(api_key=os.environ["YATIVO_API_KEY"]) as client: account = await client.accounts.create(label="async_account") print(account.account_id) asyncio.run(main()) ``` ### Environment setup ```bash .env theme={null} YATIVO_API_KEY=yvk_sandbox_01J2K9MNPQ3R4S5T6U7VAPIKEY YATIVO_BASE_URL=https://crypto-sandbox.yativo.com/api/ ``` ```python Python theme={null} from dotenv import load_dotenv load_dotenv() import os from yativo_crypto import YativoCrypto client = YativoCrypto( api_key=os.environ["YATIVO_API_KEY"], base_url=os.getenv("YATIVO_BASE_URL", "https://crypto-sandbox.yativo.com/api/v1/"), ) ``` ### Install ```bash theme={null} composer require yativo/crypto-sdk ``` Requires PHP 8.1+ and the `ext-curl` extension. ### Initialize ```php PHP theme={null} auth()->me(); echo "Authenticated as: " . $me->email . PHP_EOL; echo "Organization: " . $me->organizationName . PHP_EOL; // 2. Create an account $account = $client->accounts()->create([ "label" => "my_first_account", "metadata" => ["purpose" => "quickstart"], ]); echo "Account created: " . $account->accountId . PHP_EOL; // 3. Add a USDC wallet on Polygon $wallet = $client->assets()->addAsset([ "accountId" => $account->accountId, "chain" => "polygon", "asset" => "USDC", ]); echo "Wallet address: " . $wallet->address . PHP_EOL; ``` ### Laravel integration ```php PHP theme={null} // config/services.php "yativo" => [ "api_key" => env("YATIVO_API_KEY"), "base_url" => env("YATIVO_BASE_URL", "https://crypto-sandbox.yativo.com/api/v1/"), ], // AppServiceProvider.php use Yativo\Crypto\YativoCrypto; $this->app->singleton(YativoCrypto::class, function ($app) { return new YativoCrypto( apiKey: config("services.yativo.api_key"), baseUrl: config("services.yativo.base_url"), ); }); // In a controller public function __construct(private YativoCrypto $yativo) {} public function createWallet(Request $request): JsonResponse { $account = $this->yativo->accounts()->create([ "label" => "user_" . $request->user()->id, ]); return response()->json(["accountId" => $account->accountId]); } ``` ### Install Add to your `pom.xml`: ```xml Maven (pom.xml) theme={null} com.yativo crypto-sdk 1.4.0 ``` Or with Gradle: ```groovy Gradle (build.gradle) theme={null} implementation 'com.yativo:crypto-sdk:1.4.0' ``` ### Initialize ```java Java theme={null} import com.yativo.crypto.YativoCrypto; import com.yativo.crypto.YativoCryptoConfig; YativoCrypto client = YativoCrypto.builder() .apiKey(System.getenv("YATIVO_API_KEY")) .baseUrl("https://crypto-sandbox.yativo.com/api/v1/") .build(); ``` ### Authenticate and make your first call ```java Java theme={null} import com.yativo.crypto.YativoCrypto; import com.yativo.crypto.models.*; public class QuickstartExample { public static void main(String[] args) { YativoCrypto client = YativoCrypto.builder() .apiKey(System.getenv("YATIVO_API_KEY")) .baseUrl("https://crypto-sandbox.yativo.com/api/v1/") .build(); // 1. Verify credentials AuthMe me = client.auth().me(); System.out.println("Authenticated as: " + me.getEmail()); System.out.println("Organization: " + me.getOrganizationName()); // 2. Create an account CreateAccountRequest accountRequest = CreateAccountRequest.builder() .label("my_first_account") .metadata(Map.of("purpose", "quickstart")) .build(); Account account = client.accounts().create(accountRequest); System.out.println("Account created: " + account.getAccountId()); // 3. Add a USDC wallet on Polygon AddAssetRequest assetRequest = AddAssetRequest.builder() .accountId(account.getAccountId()) .chain("polygon") .asset("USDC") .build(); Asset wallet = client.assets().addAsset(assetRequest); System.out.println("Wallet address: " + wallet.getAddress()); } } ``` ### Spring Boot bean configuration ```java Java theme={null} // YativoConfig.java @Configuration public class YativoConfig { @Value("${yativo.api-key}") private String apiKey; @Value("${yativo.base-url:https://crypto-sandbox.yativo.com/api/v1/}") private String baseUrl; @Bean public YativoCrypto yativoCrypto() { return YativoCrypto.builder() .apiKey(apiKey) .baseUrl(baseUrl) .build(); } } // application.properties // yativo.api-key=${YATIVO_API_KEY} // yativo.base-url=https://crypto-sandbox.yativo.com/api/ ``` ### Install ```bash theme={null} npm install @yativo/crypto-react ``` The React SDK wraps the TypeScript SDK with hooks and context for use in browser-based applications. Never expose your API key in client-side code. The React SDK is designed for use with **ephemeral tokens** or a proxy pattern — your server generates a short-lived session token that the frontend uses for read-only operations like displaying balances and addresses. ### Set up the provider ```tsx React theme={null} // src/main.tsx import { YativoProvider } from "@yativo/crypto-react"; import App from "./App"; export default function Root() { return ( ); } ``` ### Backend: generate a session token ```typescript TypeScript (Express server-side) theme={null} import { YativoCrypto } from "@yativo/crypto-sdk"; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, baseUrl: "https://crypto-sandbox.yativo.com/api/v1/", }); app.post("/api/yativo-token", requireAuth, async (req, res) => { const token = await client.auth.createSessionToken({ userId: req.user.id, accountId: req.user.yativoAccountId, scopes: ["balances:read", "addresses:read"], ttlSeconds: 3600, }); res.json({ token: token.value, expiresAt: token.expiresAt }); }); ``` ### Use hooks in components ```tsx React theme={null} import { useAccount, useAssets, useTransactions, } from "@yativo/crypto-react"; function WalletDashboard({ accountId }: { accountId: string }) { const { data: assets, isLoading } = useAssets(accountId); const { data: transactions } = useTransactions(accountId, { limit: 10 }); if (isLoading) return
Loading wallets...
; return (

Your Wallets

{assets?.map((asset) => (
{asset.asset} on {asset.chain}
Address: {asset.address}
Balance: {asset.balance} {asset.asset}
))}

Recent Transactions

{transactions?.items.map((txn) => (
{txn.type} — {txn.amount} {txn.asset} — {txn.status}
))}
); } ``` ### Display a deposit address with QR code ```tsx React theme={null} import { useDepositAddress } from "@yativo/crypto-react"; import QRCode from "react-qr-code"; function DepositAddress({ accountId, chain, asset }: Props) { const { data: wallet } = useDepositAddress(accountId, chain, asset); if (!wallet) return null; return (

Send {asset} on{" "} {chain} to:

{wallet.address}
); } ```
## Next Steps Create accounts, generate deposit addresses, and handle webhook notifications. Programmatically send funds to external wallets with idempotency. Set up real-time event notifications with signature verification. Issue crypto-funded virtual and physical cards to users. # Send Crypto Source: https://docs.yativo.com/guides/send-crypto Programmatically send crypto to any wallet address This guide covers the full flow for sending crypto from a Yativo account to an external wallet: estimating gas fees, executing the transfer with an idempotency key, and tracking the transaction to completion. Test this flow in the Sandbox at `https://crypto-sandbox.yativo.com/api/v1/`. Sandbox transactions are simulated — no real funds move. Before sending, retrieve the current gas fee estimate for the target chain. This lets you show users an accurate fee breakdown and choose a priority level. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/transactions/get-gas-price \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -d '{ "chainType": "ethereum", "priority": "medium", "token_symbol": "USDC" }' ``` ```typescript TypeScript theme={null} import { YativoCrypto } from "@yativo/crypto-sdk"; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, baseUrl: "https://crypto-api.yativo.com/api/v1/", }); const gasEstimate = await client.transactions.getGasPrice({ chain: "ethereum", asset: "USDC", }); console.log(gasEstimate); /* { chain: "ethereum", slow: { gasPrice: "18.2", estimatedFeeUsd: "0.82", estimatedTimeSeconds: 120 }, medium: { gasPrice: "22.5", estimatedFeeUsd: "1.02", estimatedTimeSeconds: 30 }, fast: { gasPrice: "31.0", estimatedFeeUsd: "1.40", estimatedTimeSeconds: 10 }, nativeAsset: "ETH", updatedAt: "2026-03-26T11:00:00Z" } */ ``` ```python Python theme={null} from yativo_crypto import YativoCrypto client = YativoCrypto( api_key=os.environ["YATIVO_API_KEY"], base_url="https://crypto-api.yativo.com/api/v1/", ) gas_estimate = client.transactions.get_gas_price( chain="ethereum", asset="USDC", ) print(gas_estimate.medium.estimated_fee_usd) # "1.02" ``` **Response:** ```json theme={null} { "chain": "ethereum", "slow": { "gasPrice": "18.2", "estimatedFeeUsd": "0.82", "estimatedTimeSeconds": 120 }, "medium": { "gasPrice": "22.5", "estimatedFeeUsd": "1.02", "estimatedTimeSeconds": 30 }, "fast": { "gasPrice": "31.0", "estimatedFeeUsd": "1.40", "estimatedTimeSeconds": 10 }, "nativeAsset": "ETH", "updatedAt": "2026-03-26T11:00:00Z" } ``` ### Priority levels | Priority | Speed | Use case | | -------- | --------- | ------------------------------------ | | `slow` | 1–3 min | Non-urgent payouts, batch processing | | `medium` | 15–30 sec | Default for most use cases | | `fast` | 5–15 sec | Time-sensitive transactions | Use `POST /transactions/send-funds` to initiate the transfer. Always include an `Idempotency-Key` header to safely retry without double-spending. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/transactions/send-funds \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: payout_01J2KG9MNPQ3R4S5T6UPAY001" \ -d '{ "account": "64b1f9e2a3c4d5e6f7a8b9c0", "assets": "64b1f9e2a3c4d5e6f7a8b9d1", "receiving_address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "amount": 100, "type": "USDC", "chain": "ethereum", "category": "payment", "priority": "medium", "description": "Payout for order #ORD-9821" }' ``` ```typescript TypeScript theme={null} import { v4 as uuidv4 } from "uuid"; // Generate a stable idempotency key tied to your payout record const idempotencyKey = `payout_${payoutRecord.id}`; const transaction = await client.transactions.sendFunds( { account: "64b1f9e2a3c4d5e6f7a8b9c0", assets: "64b1f9e2a3c4d5e6f7a8b9d1", receiving_address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", amount: 100, type: "USDC", chain: "ethereum", category: "payment", priority: "medium", description: "Payout for order #ORD-9821", }, { idempotencyKey } ); console.log(transaction.data.transaction_id); // txn_01HX9KZMB3F7VNQP8R2WDGT4E5 console.log(transaction.data.transaction_hash); // 0x9f3e2d... ``` ```python Python theme={null} transaction = client.transactions.send_funds( account="64b1f9e2a3c4d5e6f7a8b9c0", assets="64b1f9e2a3c4d5e6f7a8b9d1", receiving_address="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", amount=100, type="USDC", chain="ethereum", category="payment", priority="medium", description="Payout for order #ORD-9821", idempotency_key=f"payout_{payout_record.id}", ) print(transaction.data.transaction_id) # txn_01HX9KZMB3F7VNQP8R2WDGT4E5 print(transaction.data.transaction_hash) # 0x9f3e2d... ``` **Response:** ```json theme={null} { "status": true, "message": "Transaction Created Successfully", "data": { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E5", "transaction_hash": "0x9f3e2d1c4b7a5e8f2c9b3d6a1e4c7f2b5d8e1c4a", "gas_tx_hash": null, "platform_fee_tx_hash": null, "gas_amount": "0", "platform_fee": "0.50000000", "gas_funding_markup": "0.12000000", "total_fee": "0.62000000", "fee_breakdown": "N/A" } } ``` ### Idempotency keys An idempotency key is a unique string you attach to a request. If the request fails or times out, you can safely retry with the same key — Yativo will return the original response instead of creating a duplicate transaction. If no key is supplied, no deduplication is applied. **Best practices:** * Derive the key from your internal record ID (e.g., `payout_${payoutId}`) * Keys must be unique per operation — reusing a key for a different transfer will return the original transaction * Keys expire after 24 hours You can poll for the current transaction status using `POST /transactions/get-transactions`, filtering by `transaction_id`. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/transactions/get-transactions \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -d '{ "search": "txn_01J2KH3MNPQ7R4S5T6U7VSND99" }' ``` ```typescript TypeScript theme={null} // Poll with exponential backoff async function waitForTransaction(transactionId: string): Promise { const maxAttempts = 20; let delay = 2000; // start at 2 seconds for (let attempt = 0; attempt < maxAttempts; attempt++) { const result = await client.transactions.getTransactions({ search: transactionId }); const txn = result.data?.[0]; if (!txn) throw new Error('Transaction not found'); if (txn.status === 'completed') return txn; if (txn.status === 'failed') throw new Error(`Transaction failed: ${txn.error_message}`); await new Promise((resolve) => setTimeout(resolve, delay)); delay = Math.min(delay * 1.5, 30000); // cap at 30s } throw new Error('Transaction did not complete within timeout'); } const completed = await waitForTransaction('txn_01J2KH3MNPQ7R4S5T6U7VSND99'); console.log(completed.transaction_hash); // 0x9f3e2d1c4b7a5e8f2c9b3d6a1e4c7f2b5d8e1c4a... ``` ```python Python theme={null} import time def wait_for_transaction(transaction_id: str) -> dict: max_attempts = 20 delay = 2.0 for attempt in range(max_attempts): result = client.transactions.get_transactions(search=transaction_id) txn = result.data[0] if result.data else None if not txn: raise Exception('Transaction not found') if txn.status == 'completed': return txn if txn.status == 'failed': raise Exception(f'Transaction failed: {txn.error_message}') time.sleep(delay) delay = min(delay * 1.5, 30.0) raise TimeoutError('Transaction did not complete within timeout') completed = wait_for_transaction('txn_01J2KH3MNPQ7R4S5T6U7VSND99') print(completed.transaction_hash) ``` **Response (completed):** ```json theme={null} { "status": true, "message": "Transactions fetched successfully", "data": [ { "transaction_id": "txn_01J2KH3MNPQ7R4S5T6U7VSND99", "transaction_hash": "0x9f3e2d1c4b7a5e8f2c9b3d6a1e4c7f2b5d8e1c4a7f6e3d2b1a8c5f4e3d2c1b", "receiving_address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "amount": "100", "type": "USDC", "chain": "ethereum", "status": "completed", "blockchain_status": "confirmed", "block_number": 19847345, "confirmations": 12, "fee_paid": "0.62000000", "fee_currency": "USDC", "category": "payment", "description": "Payout for order #ORD-9821", "createdAt": "2026-03-26T11:05:42.000Z" } ] } ``` ### Transaction statuses | Status | Description | | ----------- | ------------------------------------------------- | | `pending` | Submitted, waiting to be broadcast | | `completed` | Included in a block with sufficient confirmations | | `failed` | Transaction failed (see `error_message`) | Rather than polling, register a webhook for `transaction.{type}.completed` and `transaction.failed` events to receive push notifications when transactions settle. ```typescript TypeScript (webhook handler) theme={null} case "transaction.withdrawal.completed": { const { transactionId, toAddress, amount, asset, txHash } = event.data; await db.payouts.markCompleted(transactionId, { txHash, confirmedAt: event.created_at, }); await notifyUserPayoutSent({ toAddress, amount, asset }); break; } case "transaction.failed": { const { transactionId, failureReason } = event.data; await db.payouts.markFailed(transactionId, failureReason); // Refund or retry logic here break; } ``` ## Common Errors | Error | Cause | Fix | | -------------------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------ | | `Assets required` | `assets` body field missing | Include the asset ObjectId in the request body | | `Receiving address required` | `receiving_address` missing | Include the destination address | | `Valid amount required` | `amount` missing, zero, or negative | Provide a positive numeric amount | | `Insufficient balance` | Asset balance too low | Check balance before sending | | `Withdrawal amount must be greater than total fees` | Amount too small to cover platform fee + gas markup | Increase amount or check fee estimates first | | `Self funding is only available for native token transactions` | `use_self_funding: true` on a token asset | Remove `use_self_funding` for token withdrawals | | `Transaction blocked due to high-risk receiving address` | Chainalysis/Circle screening blocked the address | Do not send to flagged addresses | | `DUPLICATE_REQUEST_IN_PROGRESS` | Same `Idempotency-Key` submitted while first request is still processing | Wait for the first request to complete before retrying | ## Next Steps * See **[Webhook Integration](/guides/webhook-integration)** for the full `transaction.withdrawal.completed` and `transaction.failed` event payloads. * Use **[Swap Tokens](/guides/swap-tokens)** to exchange assets before sending. # Swap Tokens Source: https://docs.yativo.com/guides/swap-tokens Exchange one crypto asset for another across chains This guide covers the full token swap flow: browsing available assets, finding valid swap routes, getting a quote, executing the swap, and monitoring the result. Test swaps in the Sandbox at `https://crypto-sandbox.yativo.com/api/v1/`. Sandbox swaps simulate the full flow with test assets. Retrieve the list of assets supported for swapping. Use this to populate asset selector UI in your app. ```bash cURL theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/swap/assets \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." ``` ```typescript TypeScript theme={null} import { YativoCrypto } from "@yativo/crypto-sdk"; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, baseUrl: "https://crypto-api.yativo.com/api/v1/", }); const assets = await client.swap.getAssets(); // Filter to assets available as swap input const fromAssets = assets.filter((a) => a.canSwapFrom); const toAssets = assets.filter((a) => a.canSwapTo); console.log(fromAssets.map((a) => `${a.symbol} on ${a.chain}`)); // ["USDC on ethereum", "ETH on ethereum", "USDC on polygon", ...] ``` ```python Python theme={null} from yativo_crypto import YativoCrypto client = YativoCrypto( api_key=os.environ["YATIVO_API_KEY"], base_url="https://crypto-api.yativo.com/api/v1/", ) assets = client.swap.get_assets() from_assets = [a for a in assets if a.can_swap_from] ``` **Response (excerpt):** ```json theme={null} [ { "assetId": "eth-usdc", "symbol": "USDC", "name": "USD Coin", "chain": "ethereum", "contractAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "decimals": 6, "canSwapFrom": true, "canSwapTo": true, "logoUrl": "https://assets.yativo.com/tokens/usdc.png" }, { "assetId": "eth-weth", "symbol": "ETH", "name": "Ether", "chain": "ethereum", "contractAddress": null, "decimals": 18, "canSwapFrom": true, "canSwapTo": true, "logoUrl": "https://assets.yativo.com/tokens/eth.png" } ] ``` Retrieve the available routes for a given asset pair. Routes describe the path the swap will take (which DEXes or bridges are involved) and help you select the best option. ```bash cURL theme={null} curl -X GET "https://crypto-api.yativo.com/api/v1/swap/routes?fromAsset=eth-usdc&toAsset=pol-usdc" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." ``` ```typescript TypeScript theme={null} const routes = await client.swap.getRoutes({ fromAsset: "eth-usdc", // USDC on Ethereum toAsset: "pol-usdc", // USDC on Polygon }); routes.forEach((route) => { console.log(`Route: ${route.routeId} via ${route.protocol}`); console.log(` Estimated time: ${route.estimatedTimeSeconds}s`); console.log(` Estimated fee: $${route.estimatedFeeUsd}`); }); ``` ```python Python theme={null} routes = client.swap.get_routes( from_asset="eth-usdc", to_asset="pol-usdc", ) for route in routes: print(f"Route: {route.route_id} via {route.protocol}") print(f" Estimated time: {route.estimated_time_seconds}s") print(f" Estimated fee: ${route.estimated_fee_usd}") ``` **Response:** ```json theme={null} [ { "routeId": "rte_01J2KV3MNPQ7R4S5T6U7VRTE01", "fromAsset": "eth-usdc", "toAsset": "pol-usdc", "protocol": "bridge-standard", "estimatedTimeSeconds": 180, "estimatedFeeUsd": "2.40", "tags": ["cross-chain", "bridge"] }, { "routeId": "rte_01J2KV3MNPQ7R4S5T6U7VRTE02", "fromAsset": "eth-usdc", "toAsset": "pol-usdc", "protocol": "bridge-fast", "estimatedTimeSeconds": 60, "estimatedFeeUsd": "3.10", "tags": ["cross-chain", "fast"] } ] ``` Request a precise quote for a specific amount. Quotes have a short expiry window — execute the swap before the quote expires. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/swap/quote \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -d '{ "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", "fromAsset": "eth-usdc", "toAsset": "pol-usdc", "fromAmount": "500.00", "routeId": "rte_01J2KV3MNPQ7R4S5T6U7VRTE01" }' ``` ```typescript TypeScript theme={null} const quote = await client.swap.getQuote({ accountId: "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", fromAsset: "eth-usdc", toAsset: "pol-usdc", fromAmount: "500.00", routeId: "rte_01J2KV3MNPQ7R4S5T6U7VRTE01", }); console.log(quote.quoteId); // qte_01J2KW3MNPQ7R4S5T6U7VQTE55 console.log(quote.toAmount); // "497.52" (after fees) console.log(quote.exchangeRate); // "0.99504" console.log(quote.expiresAt); // "2026-03-26T14:03:00Z" // Check if quote is still valid const expiresIn = new Date(quote.expiresAt).getTime() - Date.now(); console.log(`Quote expires in ${Math.round(expiresIn / 1000)}s`); ``` ```python Python theme={null} import time from datetime import datetime, timezone quote = client.swap.get_quote( account_id="acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", from_asset="eth-usdc", to_asset="pol-usdc", from_amount="500.00", route_id="rte_01J2KV3MNPQ7R4S5T6U7VRTE01", ) print(quote.quote_id) # qte_01J2KW3MNPQ7R4S5T6U7VQTE55 print(quote.to_amount) # "497.52" print(quote.exchange_rate) # "0.99504" # Check expiry expires_at = datetime.fromisoformat(quote.expires_at.replace("Z", "+00:00")) expires_in = (expires_at - datetime.now(timezone.utc)).total_seconds() print(f"Quote expires in {expires_in:.0f}s") ``` **Response:** ```json theme={null} { "quoteId": "qte_01J2KW3MNPQ7R4S5T6U7VQTE55", "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", "fromAsset": "eth-usdc", "toAsset": "pol-usdc", "fromAmount": "500.00", "toAmount": "497.52", "exchangeRate": "0.99504", "fees": { "protocolFee": "1.25", "networkFee": "1.23", "yativoFee": "0.00", "totalFeeUsd": "2.48" }, "routeId": "rte_01J2KV3MNPQ7R4S5T6U7VRTE01", "protocol": "bridge-standard", "expiresAt": "2026-03-26T14:03:00Z", "createdAt": "2026-03-26T14:00:00Z" } ``` ### Quote expiry handling Quotes are valid for **3 minutes** by default. If a quote expires before execution, request a fresh one. ```typescript TypeScript theme={null} async function getValidQuote(params: QuoteParams): Promise { const BUFFER_MS = 30000; // require at least 30s before expiry let quote = await client.swap.getQuote(params); const expiresIn = new Date(quote.expiresAt).getTime() - Date.now(); if (expiresIn < BUFFER_MS) { // Refresh immediately quote = await client.swap.getQuote(params); } return quote; } ``` Submit the swap using the `quoteId`. The quote must not have expired. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/swap/execute \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: swap_qte55_exec_01" \ -d '{ "quoteId": "qte_01J2KW3MNPQ7R4S5T6U7VQTE55", "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y" }' ``` ```typescript TypeScript theme={null} const swap = await client.swap.execute( { quoteId: "qte_01J2KW3MNPQ7R4S5T6U7VQTE55", accountId: "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", }, { idempotencyKey: "swap_qte55_exec_01" } ); console.log(swap.swapId); // swp_01J2KX3MNPQ7R4S5T6U7VSWP33 console.log(swap.status); // "pending" ``` ```python Python theme={null} swap = client.swap.execute( quote_id="qte_01J2KW3MNPQ7R4S5T6U7VQTE55", account_id="acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", idempotency_key="swap_qte55_exec_01", ) print(swap.swap_id) # swp_01J2KX3MNPQ7R4S5T6U7VSWP33 print(swap.status) # "pending" ``` **Response:** ```json theme={null} { "swapId": "swp_01J2KX3MNPQ7R4S5T6U7VSWP33", "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", "quoteId": "qte_01J2KW3MNPQ7R4S5T6U7VQTE55", "fromAsset": "eth-usdc", "toAsset": "pol-usdc", "fromAmount": "500.00", "expectedToAmount": "497.52", "status": "pending", "initiatedAt": "2026-03-26T14:01:30Z" } ``` Poll the swap history endpoint to monitor status. For master wallet swaps, you can also subscribe to the `master_wallet.swap` webhook event. ```bash cURL theme={null} curl -X GET "https://crypto-api.yativo.com/api/v1/swap/history?accountId=acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y&swapId=swp_01J2KX3MNPQ7R4S5T6U7VSWP33" \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." ``` ```typescript TypeScript theme={null} // Get a specific swap const swapStatus = await client.swap.getHistory({ accountId: "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", swapId: "swp_01J2KX3MNPQ7R4S5T6U7VSWP33", }); console.log(swapStatus.status); // "completed" console.log(swapStatus.actualToAmount); // "497.38" (may differ slightly from quote) console.log(swapStatus.completedAt); // "2026-03-26T14:04:52Z" // List all recent swaps for an account const history = await client.swap.getHistory({ accountId: "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", limit: 20, }); ``` ```python Python theme={null} swap_status = client.swap.get_history( account_id="acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", swap_id="swp_01J2KX3MNPQ7R4S5T6U7VSWP33", ) print(swap_status.status) # "completed" print(swap_status.actual_to_amount) # "497.38" print(swap_status.completed_at) # "2026-03-26T14:04:52Z" ``` **Completed swap response:** ```json theme={null} { "swapId": "swp_01J2KX3MNPQ7R4S5T6U7VSWP33", "accountId": "acc_01J2K9MNPQ3R4S5T6U7V8W9X0Y", "fromAsset": "eth-usdc", "toAsset": "pol-usdc", "fromAmount": "500.00", "expectedToAmount": "497.52", "actualToAmount": "497.38", "exchangeRate": "0.99476", "fees": { "protocolFee": "1.25", "networkFee": "1.37", "yativoFee": "0.00", "totalFeeUsd": "2.62" }, "status": "completed", "txHashSource": "0x1a3c5e7f9b2d4f6a8c0e2g4h6j8k0m2n4p6r8s0t2u4v6w8x", "txHashDestination": "0xabcdef1234567890abcdef1234567890abcdef12", "initiatedAt": "2026-03-26T14:01:30Z", "completedAt": "2026-03-26T14:04:52Z" } ``` ### Swap statuses | Status | Description | | ------------- | ---------------------------------------------------------- | | `pending` | Swap initiated, not yet broadcast | | `in_progress` | On-chain, awaiting destination confirmation | | `completed` | Funds arrived in destination asset | | `failed` | Swap failed — check `failureReason` | | `refunded` | Swap failed after funds were sent; original asset refunded | ## Fee Breakdown Every quote response includes a `fees` object: | Field | Description | | ------------- | --------------------------------------------------- | | `protocolFee` | Fee charged by the underlying protocol (DEX/bridge) | | `networkFee` | Gas costs on source and destination chains | | `yativoFee` | Yativo platform fee (0% on most routes) | | `totalFeeUsd` | Sum of all fees in USD equivalent | The `actualToAmount` in the completed swap may differ slightly from `expectedToAmount` in the quote due to slippage and real-time gas fluctuations. ## Next Steps * **[Send Crypto](/guides/send-crypto)** — Send swapped assets to an external wallet * **[Accept Crypto Payments](/guides/accept-crypto-payments)** — Receive deposits before swapping # Webhook Integration Source: https://docs.yativo.com/guides/webhook-integration Receive real-time events from Yativo Crypto Webhooks let Yativo push real-time event notifications to your server the moment something happens — a deposit confirms, a card transaction clears, a swap completes. This guide covers registering webhooks, verifying signatures, handling events correctly, and understanding the retry policy. Test webhooks against the Sandbox at `https://crypto-sandbox.yativo.com/api/v1/`. Use a tool like [ngrok](https://ngrok.com) or [Hookdeck](https://hookdeck.com) to expose your local server during development. Your webhook handler must: * Accept `POST` requests at a public HTTPS URL * Parse the JSON body and verify the `X-Yativo-Signature` + `X-Yativo-Timestamp` headers before processing * Return `HTTP 200` within **5 seconds** * Process event logic asynchronously after returning 200 ```typescript TypeScript theme={null} import express from "express"; import crypto from "crypto"; const app = express(); // IMPORTANT: Use raw body middleware — not json() — for the webhook route app.post( "/webhooks/yativo", express.json(), async (req, res) => { // Verify signature (see Step 3) const signature = req.headers["x-yativo-signature"] as string; const timestamp = req.headers["x-yativo-timestamp"] as string; const isValid = verifyWebhookSignature(req.body, signature, timestamp, process.env.YATIVO_WEBHOOK_SECRET!); if (!isValid) { return res.status(401).json({ error: "Invalid signature" }); } // Respond immediately res.sendStatus(200); // Process asynchronously setImmediate(() => handleEvent(req.body).catch(console.error)); } ); ``` ```python Python theme={null} from flask import Flask, request, jsonify import hmac import hashlib import json import threading import time app = Flask(__name__) @app.route("/webhooks/yativo", methods=["POST"]) def webhook(): signature = request.headers.get("X-Yativo-Signature", "") timestamp = request.headers.get("X-Yativo-Timestamp", "") payload = request.get_json(force=True) if not verify_webhook_signature(payload, signature, timestamp, os.environ["YATIVO_WEBHOOK_SECRET"]): return jsonify({"error": "Invalid signature"}), 401 # Respond immediately, process in background thread = threading.Thread(target=handle_event, args=(payload,)) thread.daemon = True thread.start() return "", 200 ``` ```php PHP theme={null} "Invalid signature"]); exit; } // Acknowledge immediately http_response_code(200); echo "OK"; // Flush output and continue processing if (function_exists("fastcgi_finish_request")) { fastcgi_finish_request(); } handleEvent($payload); ``` Register your endpoint and select which event types you want to receive. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/webhook/create-webhook \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://api.yourapp.com/webhooks/yativo", "events": [ "deposit.detected", "deposit.confirmed", "transaction.failed", "transaction.authorized", "transaction.settled", "customer.funded" ], "description": "Production webhook" }' ``` ```typescript TypeScript theme={null} import { YativoCrypto } from "@yativo/crypto-sdk"; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, baseUrl: "https://crypto-api.yativo.com/api/v1/", }); const webhook = await client.webhooks.create({ url: "https://api.yourapp.com/webhooks/yativo", events: [ "deposit.detected", "deposit.confirmed", "transaction.failed", "transaction.authorized", "transaction.settled", "customer.funded", ], description: "Production webhook", }); console.log(webhook.data.secret); // whsec_a8f3c2e1d4b7f9e2c5a3b6d8f1e4c7a2 ``` ```python Python theme={null} webhook = client.webhooks.create( url="https://api.yourapp.com/webhooks/yativo", events=[ "deposit.detected", "deposit.confirmed", "transaction.failed", "transaction.authorized", "transaction.settled", "customer.funded", ], description="Production webhook", ) print(webhook["data"]["secret"]) # whsec_a8f3c2e1d4b7f9e2c5a3b6d8f1e4c7a2 ``` **Response:** ```json theme={null} { "status": true, "message": "Webhook created successfully", "data": { "webhook_id": "664abc123def456789000001", "url": "https://api.yourapp.com/webhooks/yativo", "events": ["deposit.detected", "deposit.confirmed", "transaction.failed", "transaction.authorized", "transaction.settled", "customer.funded"], "secret": "whsec_a8f3c2e1d4b7f9e2c5a3b6d8f1e4c7a2b5d8e1f4", "created_at": "2026-03-26T15:00:00Z" } } ``` Store the `secret` securely in an environment variable or secrets manager. It can be retrieved later via `GET /v1/yativo-card/webhooks/:webhookId`, but treat it like a password. Every delivery includes two headers: | Header | Value | | -------------------- | ------------------------ | | `X-Yativo-Signature` | `sha256=` | | `X-Yativo-Timestamp` | Unix timestamp (seconds) | The HMAC is computed over `"${timestamp}.${JSON.stringify(payload)}"`. **Always verify this signature before processing the event.** ```typescript TypeScript theme={null} import crypto from "crypto"; function verifyWebhookSignature( payload: object, signatureHeader: string, timestamp: string, secret: string ): boolean { if (!signatureHeader || !timestamp) return false; // Reject replays older than 5 minutes const ts = parseInt(timestamp, 10); if (Math.abs(Date.now() / 1000 - ts) > 300) return false; const signedPayload = `${timestamp}.${JSON.stringify(payload)}`; const expected = "sha256=" + crypto .createHmac("sha256", secret) .update(signedPayload) .digest("hex"); try { return crypto.timingSafeEqual( Buffer.from(signatureHeader), Buffer.from(expected) ); } catch { return false; } } ``` ```python Python theme={null} import hmac import hashlib import json import time def verify_webhook_signature(payload: dict, signature_header: str, timestamp: str, secret: str) -> bool: if not signature_header or not timestamp: return False # Reject replays older than 5 minutes if abs(time.time() - int(timestamp)) > 300: return False signed_payload = f"{timestamp}.{json.dumps(payload, separators=(',', ':'))}" expected = "sha256=" + hmac.new( secret.encode("utf-8"), signed_payload.encode("utf-8"), hashlib.sha256, ).hexdigest() return hmac.compare_digest(signature_header, expected) ``` ```php PHP theme={null} function verifyWebhookSignature(array $payload, string $signatureHeader, string $timestamp, string $secret): bool { if (empty($signatureHeader) || empty($timestamp)) { return false; } // Reject replays older than 5 minutes if (abs(time() - intval($timestamp)) > 300) { return false; } $signedPayload = $timestamp . '.' . json_encode($payload); $expected = 'sha256=' . hash_hmac('sha256', $signedPayload, $secret); return hash_equals($expected, $signatureHeader); } ``` Always use a timing-safe comparison function (`timingSafeEqual`, `hmac.compare_digest`, `hash_equals`). Using a regular string equality check (`===`) exposes you to timing attacks. The same event may be delivered more than once (see Retry Policy below). Your handler must be idempotent — processing the same event twice should produce the same result as processing it once. ```typescript TypeScript theme={null} async function handleEvent(event: WebhookEvent): Promise { // 1. Check if already processed const processed = await db.webhookEvents.findById(event.id); if (processed) { console.log(`Event ${event.id} already processed — skipping`); return; } // 2. Process the event switch (event.type) { case "deposit.confirmed": await handleDepositConfirmed(event.data); break; case "transaction.failed": await handleTransactionFailed(event.data); break; case "transaction.authorized": await handleCardAuthorized(event.data); break; case "transaction.settled": await handleCardSettled(event.data); break; case "customer.funded": await handleCustomerFunded(event.data); break; default: console.log(`Unhandled event type: ${event.type}`); } // 3. Mark as processed await db.webhookEvents.insert({ id: event.id, type: event.type, processedAt: new Date(), }); } ``` Store processed event IDs in a database table with a unique index on `id`. Use the insert as an upsert or check-then-insert within a transaction to prevent race conditions when events arrive in parallel. Yativo waits up to **5 seconds** for an HTTP 200 response. If your server does not respond in time, the delivery is treated as failed and will be retried. **Pattern:** Respond 200 first, then process. ```typescript TypeScript theme={null} app.post("/webhooks/yativo", express.json(), async (req, res) => { // Signature verification is fast — do it synchronously const sig = req.headers["x-yativo-signature"] as string; const ts = req.headers["x-yativo-timestamp"] as string; if (!verifyWebhookSignature(req.body, sig, ts, secret)) { return res.status(401).send(); } // Acknowledge receipt immediately res.sendStatus(200); // Enqueue for async processing (use a job queue in production) await jobQueue.enqueue("process_webhook_event", req.body); }); ``` In production, use a job queue (e.g., BullMQ, Celery, SQS) rather than `setImmediate` so events survive server restarts. If your endpoint returns a non-2xx status code, times out, or is unreachable, Yativo retries the delivery with exponential backoff: | Attempt | Delay after previous | | ----------- | -------------------- | | 1 (initial) | — | | 2 | 1 minute | | 3 | 5 minutes | | 4 | 30 minutes | | 5 | 2 hours | | 6 | 6 hours | | 7 | 24 hours | After 7 failed attempts, the event is marked as **permanently failed** and no further retries are made. You can manually replay failed deliveries via `POST /v1/yativo-card/webhooks/deliveries/:deliveryId/retry`. Because retries are possible, your handlers must be idempotent (see Step 4). A 200 response stops retries — never return 200 if you have not processed (or enqueued) the event. ## Event Types Reference ### Deposit Events | Event | Description | | ------------------- | ----------------------------------------------------- | | `deposit.detected` | A deposit transaction was seen on-chain (unconfirmed) | | `deposit.confirmed` | Deposit has sufficient confirmations — safe to credit | ### Transaction Events | Event | Description | | ------------------------------ | ----------------------------------------------------------------------------------- | | `transaction.initiated` | Outbound transaction created and queued | | `transaction.submitted` | Transaction broadcast to the network | | `transaction.failed` | Transaction failed; funds returned to account | | `transaction.{type}.completed` | A transaction of the given type completed (e.g. `transaction.withdrawal.completed`) | ### Card Events Card issuer events and general crypto events share the same webhook service. Register at `POST /v1/webhook/create-webhook` and include the relevant card event slugs in your `events` array. | Event | Description | | ------------------------------- | ----------------------------------------------- | | `card.created` | A card was issued | | `card.activated` | A card was activated (physical cards) | | `card.frozen` | A card was frozen | | `card.unfrozen` | A frozen card was re-enabled | | `card.lost` | A card was marked lost | | `card.stolen` | A card was reported stolen | | `card.voided` | A card was voided | | `card.cancelled` | A card was cancelled | | `card.deactivated` | A card was permanently deactivated | | `transaction.authorized` | A card transaction was authorized | | `transaction.declined` | A card transaction was declined | | `transaction.settled` | A card transaction settled | | `transaction.reversed` | A card transaction was reversed | | `transaction.refund.created` | A refund was initiated | | `customer.funded` | A customer's card wallet was credited | | `customer.funding.failed` | A funding transfer failed | | `customer.balance.updated` | A customer's card balance changed | | `master_wallet.deposit` | Funds arrived in the card program master wallet | | `master_wallet.swap` | A swap executed in the master wallet | | `master_wallet.customer_funded` | Master wallet funds allocated to a customer | See [Card Issuer Webhook Events](/api-reference/issuer/webhooks) for full payload examples. ### IBAN Events | Event | Description | | ------------------------ | ------------------------------------------- | | `iban.activated` | IBAN account is active and ready to receive | | `iban.transfer.received` | Incoming bank transfer detected | ### KYC Events | Event | Description | | -------------------- | ----------------------------- | | `kyc.submitted` | A KYC submission was received | | `kyc.approved` | KYC was approved | | `kyc.rejected` | KYC was rejected | | `kyc.pending_review` | KYC is awaiting manual review | ## Webhook Event Envelope All events share a common envelope. The request body is JSON; delivery metadata is carried in HTTP headers. **Request body:** ```json theme={null} { "id": "evt_1716652800_abc123xyz", "type": "deposit.confirmed", "created_at": "2026-03-26T15:30:00Z", "data": { // Event-specific payload } } ``` **Request headers:** | Header | Value | | ---------------------- | ------------------------------------------------- | | `X-Yativo-Signature` | `sha256=` — use this to verify authenticity | | `X-Yativo-Timestamp` | Unix timestamp (seconds) — included in the HMAC | | `X-Yativo-Event` | Event type string (e.g. `deposit.confirmed`) | | `X-Yativo-Delivery-Id` | Unique delivery ID for this attempt | **Body fields:** | Field | Type | Description | | ------------ | -------- | ------------------------------------- | | `id` | string | Unique event ID — use for idempotency | | `type` | string | Event type | | `created_at` | ISO 8601 | When the event was generated | | `data` | object | Event-specific payload | ## Managing Webhooks ```bash theme={null} # List all webhooks GET /v1/yativo-card/webhooks # Get a single webhook (includes secret) GET /v1/yativo-card/webhooks/:webhookId # Update events or URL PUT /v1/yativo-card/webhooks/:webhookId # body: { "events": ["deposit.confirmed", "transaction.failed"], "enabled": true } # Pause delivery without deleting PUT /v1/yativo-card/webhooks/:webhookId # body: { "enabled": false } # Delete a webhook DELETE /v1/yativo-card/webhooks/:webhookId # Rotate the signing secret POST /v1/yativo-card/webhooks/:webhookId/rotate-secret # View delivery history GET /v1/yativo-card/webhooks/:webhookId/deliveries?limit=20&status=failed # Retry a failed delivery POST /v1/yativo-card/webhooks/deliveries/:deliveryId/retry ``` # Sandbox: Agentic Wallets Source: https://docs.yativo.com/sandbox/agentic-wallets Test agentic wallets with simulated agent transactions on testnet ## Agentic Wallets in Sandbox The sandbox agentic wallet system runs on testnet chains. Create wallets, add connectors, and simulate agent transactions without real funds. *** ## Create and Activate a Test Wallet ```bash theme={null} # 1. Create a wallet curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/agentic-wallets/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "name": "Test Agent Wallet" }' # 2. Send activation OTP curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/agentic-wallets/aw_.../activation/send-email-otp' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' # 3. Activate (enter the OTP from your email) curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/agentic-wallets/aw_.../activation/activate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "email_otp": "123456" }' ``` *** ## Simulate Agent Transactions In sandbox, simulate a transaction from an agentic wallet: ```bash theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/sandbox/simulate-agentic-transaction' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "wallet_id": "aw_01abc123" }' ``` This creates a mock transaction with realistic data including service name, payment category, and audit trail fields. *** ## Test the MCP Server Point the MCP server at the sandbox: ```json theme={null} { "mcpServers": { "yativo-wallet": { "command": "npx", "args": ["-y", "@yativo/mcp-server"], "env": { "YATIVO_API_KEY": "yac_sandbox_connector_key", "YATIVO_WALLET_ID": "aw_sandbox_wallet_id", "YATIVO_API_URL": "https://crypto-sandbox.yativo.com/api/v1" } } } } ``` The MCP server works identically against sandbox — all transactions use testnet chains. # Test: Authentication Source: https://docs.yativo.com/sandbox/authentication Get a Bearer token for the sandbox — use the shared key instantly or sign up at the sandbox dashboard for isolated data ## Option A — Shared sandbox key (instant, no sign-up) Use the pre-populated shared sandbox API key to get a token immediately: ```bash theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/auth/token' \ -H 'Content-Type: application/json' \ -d '{ "api_key": "yativo_e072b3ef7e30fcb420183aa86ddd8452abd28a9ac8f5d04d", "api_secret": "df8da4d6b855c7e89bd3b4216dd0a1f4b30de1963c9bff0dcd666b15a0f836a5" }' ``` ```json Response theme={null} { "success": true, "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600 } ``` Pass the `access_token` as `Authorization: Bearer ` on every request. Tokens expire in 60 minutes — call `/auth/token` again with the same key to refresh. **The API key itself never expires.** This is a **shared public sandbox key**. Any developer following these docs can read and write to the shared sandbox account. For private isolated testing, use Option B below. *** ## Option B — Your own sandbox account For isolated sandbox data with your own wallets and transactions: 1. Sign up at [sandbox-crypto.yativo.com](https://sandbox-crypto.yativo.com) — sign-up is **passwordless**, you'll receive a one-time code by email 2. Go to **Settings → API Keys** and create a sandbox API key 3. Use your key with the token endpoint: ```bash theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/auth/token' \ -H 'Content-Type: application/json' \ -d '{ "api_key": "yativo_", "api_secret": "" }' ``` *** ## Using the token Pass the token on every sandbox request: ```bash theme={null} curl 'https://crypto-sandbox.yativo.com/api/v1/accounts/get-accounts' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Refreshing a token Simply call `/auth/token` again with the same API key credentials — there is no separate refresh endpoint: ```bash theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/auth/token' \ -H 'Content-Type: application/json' \ -d '{ "api_key": "yativo_...", "api_secret": "..." }' ``` # Cards in Sandbox Source: https://docs.yativo.com/sandbox/cards Mock responses for Yativo Card endpoints — card features are not available in the sandbox environment ## Important Notice **The Yativo Card feature does NOT have a sandbox environment.** Card endpoints (`/yativo-card/...` and `/card-issuer/...`) are not available at `https://crypto-sandbox.yativo.com/api/v1/`. Calls to card endpoints using the sandbox URL will return an error. To integrate and test card features, you must use the **production environment** (`https://crypto-api.yativo.com/api/v1/`) with real KYC-verified accounts. *** ## Why No Card Sandbox? The Yativo Card operates on live payment infrastructure that cannot be replicated in a testnet environment. Card transactions go through regulated payment networks that require real-world identity verification and live authorization flows. **What this means for your integration:** * You must complete real KYC onboarding to test card endpoints * Use test amounts (e.g., $0.01 or $1.00 top-ups) for initial integration testing in production * Review the mock response examples below to understand the expected data shapes before coding against production *** ## How to Test Cards Study the mock responses in this document to understand the structure of each endpoint response. Write your data models and parsers against these shapes. Build your card integration logic using the mock data as a reference. Your code should be fully written and tested against mocks before going to production. Use the production API to complete card account onboarding with real identity documents. Fund your card wallet with a small amount (e.g., $5–$10 USDC) and verify the full flow works end-to-end. *** ## Mock Responses The following are representative mock responses for each card endpoint. Use these to build and test your integration logic. *** ### POST /yativo-card/onboard — Mock Response ```json theme={null} { "status": "success", "data": { "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "email": "user@example.com", "first_name": "Jane", "last_name": "Doe", "kyc_status": "pending", "created_at": "2026-03-25T10:00:00Z" } } ``` *** ### GET /yativo-card/kyc-status — Mock Responses ```json KYC Pending theme={null} { "status": "success", "data": { "kyc_status": "pending", "kyc_verified_at": null, "rejection_reason": null } } ``` ```json KYC Approved theme={null} { "status": "success", "data": { "kyc_status": "approved", "kyc_verified_at": "2026-03-25T10:15:00Z", "rejection_reason": null } } ``` ```json KYC Rejected theme={null} { "status": "success", "data": { "kyc_status": "rejected", "kyc_verified_at": null, "rejection_reason": "Document quality too low. Please resubmit a clearer image." } } ``` *** ### POST /yativo-card/create-card — Mock Response ```json theme={null} { "status": "success", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "display_name": "Online Shopping", "card_type": "virtual", "status": "active", "last_four": "4242", "spending_limit_amount": 500.00, "spending_limit_frequency": "monthly", "created_at": "2026-03-25T10:30:00Z" } } ``` *** ### GET /yativo-card/list-cards — Mock Response ```json theme={null} { "status": "success", "data": [ { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "display_name": "Online Shopping", "card_type": "virtual", "status": "active", "last_four": "4242", "spending_limit_amount": 500.00, "spending_limit_frequency": "monthly", "created_at": "2026-03-25T10:30:00Z" }, { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4F1", "display_name": "Subscriptions", "card_type": "virtual", "status": "frozen", "last_four": "7891", "spending_limit_amount": 100.00, "spending_limit_frequency": "monthly", "created_at": "2026-03-20T08:00:00Z" } ] } ``` *** ### GET /yativo-card//wallet — Mock Response ```json theme={null} { "status": "success", "data": { "wallet_id": "wlt_01HX9KZMB3F7VNQP8R2WDGT4E5", "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "balance": 250.75, "currency": "USD", "wallet_address": "0x4a9d2f8b3c1e6a7d0f5b8c2e9a4d7f1b3c8e0a2d", "status": "active", "updated_at": "2026-03-25T14:00:00Z" } } ``` *** ### GET /yativo-card//wallet/funding-address — Mock Response ```json theme={null} { "status": "success", "data": { "funding_address": "7dRp9qLmKv3xFjNw4aBcYhUeT8sGkZoP2iMnDuWr5Cx", "chain": "solana", "token": "USDC", "token_contract": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "minimum_deposit": 5.00, "memo_required": false } } ``` *** ### GET /yativo-card//cards//transactions — Mock Response ```json theme={null} { "status": "success", "data": { "transactions": [ { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT901", "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 42.50, "currency": "USD", "merchant_name": "Amazon", "merchant_category": "Online Retail", "status": "completed", "type": "purchase", "created_at": "2026-03-20T15:30:00Z", "settled_at": "2026-03-21T10:00:00Z" }, { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT902", "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 12.99, "currency": "USD", "merchant_name": "Netflix", "merchant_category": "Streaming", "status": "completed", "type": "purchase", "created_at": "2026-03-15T08:00:00Z", "settled_at": "2026-03-16T09:00:00Z" }, { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT903", "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 150.00, "currency": "USD", "merchant_name": "Unknown Merchant", "merchant_category": "Other", "status": "failed", "type": "purchase", "failure_reason": "Spending limit exceeded", "created_at": "2026-03-10T12:00:00Z", "settled_at": null } ], "total": 3, "limit": 20, "offset": 0 } } ``` *** ### POST /yativo-card/cards//freeze — Mock Response ```json theme={null} { "status": "success", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "status": "frozen", "frozen_at": "2026-03-25T11:00:00Z" } } ``` *** ### POST /yativo-card/cards//void — Mock Response ```json theme={null} { "status": "success", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "status": "voided", "voided_at": "2026-03-25T11:10:00Z" } } ``` *** ### POST /yativo-card/customers//cards//view-token — Mock Response ```json theme={null} { "success": true, "data": { "secure_view_url": "https://crypto-sandbox.yativo.com/api/v1/yativo-card/view/eyJhbGciOiJIUzI1NiJ9...", "expires_at": "2026-03-25T10:35:00Z", "last_four": "4242", "card_type": "virtual", "enabled_views": ["data", "pin"], "requires_access_code": false } } ``` *** ### GET /yativo-card//bridges — Mock Response ```json theme={null} { "status": "success", "data": { "bridges": [ { "transfer_id": "tx_01HX9KZMB3F7VNQP8R2WDGT555", "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "source_token": "USDC", "source_chain": "solana", "source_amount": 100.00, "destination_amount": 99.75, "destination_currency": "USD", "deposit_tx_hash": "4xKp9qLmKv3xFjNw4aBcYhUeT8sGkZoP2iMnDuWr5CxABCDEFGHIJKL", "status": "completed", "created_at": "2026-03-25T14:05:00Z", "completed_at": "2026-03-25T14:07:30Z" } ], "total": 1, "limit": 20, "offset": 0 } } ``` *** ## Error Response for Sandbox Calls If you accidentally call a card endpoint against the sandbox URL, you will receive: ```json theme={null} { "status": "error", "message": "Card services are not available in the sandbox environment. Please use the production API at https://crypto-api.yativo.com/api/v1/", "error_code": "FEATURE_NOT_AVAILABLE_IN_SANDBOX" } ``` *** ## Next Steps Complete real KYC onboarding in the production environment. Review the full card feature set before building. # Test: IBAN Source: https://docs.yativo.com/sandbox/iban Test the IBAN onboarding flow in the Yativo Crypto sandbox This feature is coming soon. The standalone IBAN product is currently in sandbox and not yet available for production use. Check back for updates. # Sandbox Environment Source: https://docs.yativo.com/sandbox/overview Test and develop against the Yativo Crypto sandbox — pre-populated with test data and a public API key you can use immediately ## Overview The Yativo Crypto Sandbox is an isolated testing environment that mirrors the production API. All wallets and transactions in sandbox run on **testnets only** — no real funds are ever involved. `https://crypto-sandbox.yativo.com/api/v1/` `https://crypto-api.yativo.com/api/v1/` *** ## Quick Start — Use the Shared Sandbox Account To get started immediately without registering, use the **shared sandbox API key** below. It's public and pre-populated with accounts, wallets, customers, and a webhook so you can explore every endpoint right away. This is a **shared public account** for exploration only. Do not store sensitive data here. For real integration testing, [create your own sandbox account](#create-your-own-sandbox-account) with a private API key. ### Step 1 — Generate a Bearer Token For quick documentation testing, use the **long-lived docs token** (valid 1 year): ```bash theme={null} curl -X GET 'https://crypto-sandbox.yativo.com/api/v1/sandbox/docs-token' ``` This returns a bearer token you can use immediately in the API playground above — no API key or secret needed. ```bash theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/auth/token' \ -H 'Content-Type: application/json' \ -d '{ "api_key": "yativo_e072b3ef7e30fcb420183aa86ddd8452abd28a9ac8f5d04d", "api_secret": "df8da4d6b855c7e89bd3b4216dd0a1f4b30de1963c9bff0dcd666b15a0f836a5" }' ``` You'll get back an `access_token`. The docs token is valid for 1 year; the standard token lasts 60 minutes (call `/auth/token` again to refresh). ### Step 2 — Start calling the API ```bash theme={null} curl -X GET 'https://crypto-sandbox.yativo.com/api/v1/accounts/get-accounts' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` The shared sandbox account is pre-populated with: | Resource | Details | | --------------- | ------------------------------------------------------------------------------------------------------ | | Accounts | 1 account — "Sandbox Main" | | Assets | USDC (SOL testnet) at address `GY1EZGdpiJNyx2BSKq8rfTDRe5K8Bb6Cf2Bn1pdmE2o1` | | Customers | 2 customers — [alice@example.com](mailto:alice@example.com), [bob@example.com](mailto:bob@example.com) | | Webhooks | 1 active webhook | | Agentic Wallets | 1 test wallet with connector | | Payment Gateway | Simulated checkout available | The shared sandbox credentials above can also be used in the **API playground** on every API reference page in these docs. The docs default to the sandbox base URL — just paste your Bearer token and try any endpoint. *** ## Create Your Own Sandbox Account For private integration testing with dedicated credentials: 1. Register at [crypto.yativo.com/sign-up](https://crypto.yativo.com/sign-up) 2. Log in and go to **Developer → API Keys** 3. Create an API key — it works against both sandbox and production (just change the base URL) 4. Use `POST /auth/token` with your credentials against `https://crypto-sandbox.yativo.com/api/v1/` *** ## Sandbox vs Production | Feature | Sandbox | Production | | --------------- | --------------------------------------------------- | --------------------------------------- | | Base URL | `https://crypto-sandbox.yativo.com/api/v1/` | `https://crypto-api.yativo.com/api/v1/` | | API Keys | Same keys work on both | Same | | Wallets | Testnet only — no real value | Mainnet, real funds | | Blockchains | Testnets (Solana Devnet, Sepolia, etc.) | Mainnets | | Swap rates | Simulated | Live market rates | | IBAN | Testnet IBAN (no real banking) | Live EUR IBAN | | Card program | Test-mode card provider with simulated transactions | Live card issuer | | Payment Gateway | Simulated payments via sandbox endpoint | Live on-chain payments | | Agentic Wallets | Testnet wallets with simulated transactions | Real wallets, real funds | | Data | Isolated from production | Live data | All crypto wallets created in sandbox are on **testnet chains**. Addresses generated will never hold real funds. Testnet tokens can be obtained from each chain's faucet. *** ## Supported Testnet Chains | Network | Testnet Used | | --------------- | ------------ | | Solana | Devnet | | Ethereum / Base | Sepolia | | Gnosis | Chiado | | Polygon | Amoy | | BNB Chain | BSC Testnet | *** ## Sandbox Limitations * **Yativo Card KYC**: Uses a test-mode KYC and card provider. Transactions are simulated. * **IBAN bank transfers**: Cannot receive transfers from real banks — testnet only. * **Swap rates**: Simulated, not live market prices. * **Email OTPs**: Delivered to real email addresses, same as production. * **Payment Gateway**: Use the sandbox simulation endpoint to trigger payment confirmation. * **Agentic Wallets**: Testnet chains only. Use the simulation endpoint to generate mock agent transactions. *** ## Sandbox Simulation Endpoints These endpoints are only available in the sandbox environment and let you simulate events that normally require on-chain activity: | Endpoint | Description | | -------------------------------------------- | -------------------------------------- | | `POST /sandbox/simulate-card-spend` | Simulate a card purchase | | `POST /sandbox/generate-card-history` | Generate mock card transaction history | | `POST /sandbox/simulate-gateway-payment` | Mark a gateway payment as paid | | `POST /sandbox/simulate-agentic-transaction` | Create a mock agent transaction | *** ## Environment Variable Pattern We recommend switching environments with a single variable change: ```bash .env.sandbox theme={null} YATIVO_API_KEY=yativo_e072b3ef7e30fcb420183aa86ddd8452abd28a9ac8f5d04d YATIVO_API_SECRET=df8da4d6b855c7e89bd3b4216dd0a1f4b30de1963c9bff0dcd666b15a0f836a5 YATIVO_BASE_URL=https://crypto-sandbox.yativo.com/api ``` ```bash .env.production theme={null} YATIVO_API_KEY=your_production_api_key YATIVO_API_SECRET=your_production_api_secret YATIVO_BASE_URL=https://crypto-api.yativo.com/api ``` Your integration code doesn't change — only the environment variables. # Sandbox: Payment Gateway Source: https://docs.yativo.com/sandbox/payment-gateway Test the crypto payment gateway with simulated payments ## Payment Gateway in Sandbox The sandbox payment gateway works exactly like production, but payments are simulated on testnet chains. You can create payment intents, view the hosted checkout page, and simulate payment confirmation. *** ## Create a Test Payment ```bash theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/crypto-gateway/payments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "amount": 25.00, "currency": "USD", "description": "Test payment" }' ``` The response includes a `checkout_url` you can open in a browser to see the hosted checkout page. *** ## Simulate a Payment In sandbox, you can simulate a successful payment without actually sending on-chain funds: ```bash theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/sandbox/simulate-gateway-payment' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "payment_id": "pi_01abc123" }' ``` This marks the payment as `paid` and triggers any configured webhooks, just as if a real on-chain payment was confirmed. *** ## Test Webhook Flow 1. Create a [webhook](/yativo-crypto/webhooks) listening for `gateway.payment.paid` 2. Create a payment intent 3. Simulate the payment using the endpoint above 4. Your webhook receives the payment confirmation event This lets you test your full checkout integration without any real blockchain transactions. # Test: Swaps Source: https://docs.yativo.com/sandbox/swap Test token swap functionality in the Yativo Crypto sandbox ## Overview Test the full swap lifecycle — getting quotes and executing cross-chain or same-chain token swaps — without spending real funds. **Sandbox base URL:** `https://crypto-sandbox.yativo.com/api/v1/` Swap rates in the sandbox are simulated. They reflect approximate market conditions but are not live market prices. *** ## Step 1 — Get a Swap Quote Request a price quote before executing. The quote includes the expected output amount, rate, and fees. ``` POST https://crypto-sandbox.yativo.com/api/v1/swap/quote ``` Source blockchain: `solana`, `ethereum`, `base`, `polygon`, etc. Source token ticker: `USDC_SOL`, `ETH`, `SOL`, etc. Destination blockchain. Can be the same as `from_chain` for same-chain swaps. Destination token ticker: `USDC_ETH`, `USDC_SOL`, etc. Input amount in the source token's native units, e.g. `"100.00"`. Source wallet address sending the funds. Destination wallet address to receive the swapped funds. ```bash USDC Solana → USDC Ethereum (cross-chain) theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/swap/quote' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "sourceAsset": "USDC_SOL", "destinationAsset": "ETH_Base", "amount": "10" }' ``` ```bash Same-chain swap theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/swap/quote' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "sourceAsset": "USDC_SOL", "destinationAsset": "SOL", "amount": "50" }' ``` ```json Response — Quote theme={null} { "status": "success", "data": { "quote_id": "qte_01HX9KZMB3F7VNQP8R2WDGT4EG", "from_chain": "solana", "from_ticker": "USDC_SOL", "from_amount": "10", "to_chain": "base", "to_ticker": "ETH_Base", "to_amount": "0.00284", "exchange_rate": "0.000284", "fee": "0.05", "fee_ticker": "USDC", "price_impact": "0.01", "quote_valid_until": "2026-03-28T11:02:00Z", "estimated_execution_time_seconds": 120 } } ``` Quotes expire quickly (typically 60–120 seconds). If the quote expires before you execute, request a new one. *** ## Step 2 — Execute the Swap Execute a swap using a previously obtained quote ID. ``` POST https://crypto-sandbox.yativo.com/api/v1/swap/execute ``` The quote ID obtained from `POST /swap/quote`. The asset ID of the source wallet to deduct funds from. Destination wallet address to receive the swapped tokens. ```bash Execute swap theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/swap/execute' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "quote_id": "qte_01HX9KZMB3F7VNQP8R2WDGT4EG", "from_asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4E6", "to_address": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b" }' ``` ```json Swap Initiated theme={null} { "status": "success", "message": "Swap initiated successfully", "data": { "swap_id": "swp_01HX9KZMB3F7VNQP8R2WDGT4EH", "quote_id": "qte_01HX9KZMB3F7VNQP8R2WDGT4EG", "from_chain": "solana", "from_ticker": "USDC_SOL", "to_chain": "base", "to_ticker": "ETH_Base", "from_amount": "10", "to_amount": "0.00284", "status": "pending", "from_tx_hash": "5KgF7hJ2mN4pQ8rT9vX1yC3bA6wD0eG2jL5nP8sU1z4", "created_at": "2026-03-28T11:01:00Z" } } ``` ```json Quote Expired theme={null} { "success": false, "error": "Quote has expired. Please request a new quote." } ``` *** ## Step 3 — Check Swap History Retrieve the history of your swaps. ``` GET https://crypto-sandbox.yativo.com/api/v1/swap/history ``` Max results to return. Defaults to `20`. Records to skip for pagination. Defaults to `0`. Filter by status: `pending`, `completed`, `failed`. ```bash cURL theme={null} curl -X GET 'https://crypto-sandbox.yativo.com/api/v1/swap/history?limit=10&status=completed' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' ``` ```json Response theme={null} { "success": true, "data": [ { "swap_id": "swp_01HX9KZMB3F7VNQP8R2WDGT4EH", "from_ticker": "USDC_SOL", "from_chain": "solana", "from_amount": "10", "to_ticker": "ETH_Base", "to_chain": "base", "to_amount": "0.00284", "status": "completed", "created_at": "2026-03-28T11:01:00Z" } ] } ``` *** ## Swap Status Values | Status | Description | | ------------ | ----------------------------------------------------- | | `pending` | Swap submitted, awaiting processing. | | `processing` | Swap in progress — tokens are being exchanged. | | `completed` | Swap completed. Destination tokens credited. | | `failed` | Swap failed. Source tokens returned (minus gas fees). | *** ## Testing Scenarios Wait 60–120 seconds after getting a quote, then try to execute it. Your application should receive an error and re-request a fresh quote. Request a quote for more than your available balance, then try to execute it. Verify your application handles the `INSUFFICIENT_BALANCE` error. After a swap completes, verify the balance update by calling `POST /assets/get-user-assets`. The source asset balance should decrease and the destination asset balance should increase. # Test: Transactions Source: https://docs.yativo.com/sandbox/transactions Test sending funds, estimating gas fees, and querying transaction history in the sandbox ## Overview Test crypto transactions in the sandbox — send testnet tokens, estimate gas fees, and query transaction history, all without spending real funds. **Sandbox base URL:** `https://crypto-sandbox.yativo.com/api/v1/` The sandbox uses testnet blockchains. Never send real mainnet tokens to sandbox wallet addresses. *** ## Get a Gas Fee Estimate Estimate the gas fee for a transaction before sending. ``` POST https://crypto-sandbox.yativo.com/api/v1/transactions/get-gas-price ``` Blockchain to estimate gas for: `ethereum`, `solana`, `bitcoin`, `polygon`, `bsc`, `base`, `xdc`. Transaction speed: `low`, `medium`, `high`. Defaults to `low`. Optional USD amount, for calculating gas as a percentage. ```bash Solana fee estimate theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/transactions/get-gas-price' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "chainType": "SOL", "priority": "medium" }' ``` ```bash Ethereum fee estimate theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/transactions/get-gas-price' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "chainType": "ETH", "priority": "low" }' ``` ```json Response theme={null} { "success": true, "data": { "estimatedFee": 0.00063, "gasFee": 0.00063, "platformFees": 0, "priority": "low", "chainType": "ETH", "breakdown": { "gas_cost_usd": "0.00063000", "platform_fees_usd": "0.00000000", "total_cost_usd": "0.00063000", "platform_fee_details": [] } } } ``` *** ## Send a Transaction Send testnet tokens from your sandbox wallet to another address. ``` POST https://crypto-sandbox.yativo.com/api/v1/transactions/send-funds ``` The ObjectId of the account that owns the source asset. The ObjectId of the asset (wallet) to send from. Destination blockchain address. Must be a valid testnet address for the specified chain. Amount to send in the token's native units, e.g. `25`. Blockchain network: `solana`, `ethereum`, `base`, etc. Token ticker / short name: `"USDC"`, `"ETH"`, `"SOL"`, etc. Must match the asset record. Transaction category: `"personal"`, `"business"`, `"payment"`, `"other"`, etc. Transaction speed: `"low"`, `"medium"`, `"high"`. Defaults to `"medium"`. Optional human-readable note. Pay gas from the wallet's own native balance. Defaults to `false`. ```bash Send USDC on Solana Devnet theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/transactions/send-funds' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account": "64b1f9e2a3c4d5e6f7a8b9c0", "assets": "64b1f9e2a3c4d5e6f7a8b9d1", "receiving_address": "9xZ7Y4mQkLpR3sVwC8tF2bG6hJ5nM1yK", "amount": 25, "type": "USDC", "chain": "solana", "category": "payment", "priority": "medium" }' ``` ```bash Send ETH on Sepolia theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/transactions/send-funds' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account": "64b1f9e2a3c4d5e6f7a8b9c0", "assets": "64b1f9e2a3c4d5e6f7a8b9d2", "receiving_address": "0x8b5d42Dd7745C1643B36e4F8C5E2b5A8E9f1c456", "amount": 0.001, "type": "ETH", "chain": "base", "category": "personal", "priority": "low", "use_self_funding": true }' ``` ```json Response — Transaction Submitted theme={null} { "status": true, "message": "Transaction Created Successfully", "data": { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E5", "transaction_hash": "5KtMKNmZtEbXq3RrsPkjDqNJVA5rtzEPvR8WBa7kLnZm", "gas_tx_hash": null, "platform_fee_tx_hash": null, "gas_amount": "0", "platform_fee": "0.50000000", "gas_funding_markup": "0.12000000", "total_fee": "0.62000000", "fee_breakdown": "N/A" } } ``` *** ## List Transactions Retrieve a paginated list of all transactions for your sandbox account. ``` POST https://crypto-sandbox.yativo.com/api/v1/transactions/get-transactions ``` Page number. Defaults to `1`. Transactions per page. Defaults to `20`, max `100`. Filter by status: `pending`, `confirmed`, `failed`, `cancelled`. Filter by blockchain: `solana`, `ethereum`, etc. ```bash List recent transactions theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/transactions/get-transactions' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "page": 1, "limit": 20 }' ``` ```bash Filter by chain and status theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/transactions/get-transactions' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "page": 1, "limit": 20, "chain": "solana", "status": "confirmed" }' ``` ```json Response theme={null} { "data": [ { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT100", "type": "send", "chain": "solana", "ticker": "USDC_SOL", "amount": "25.00", "status": "confirmed", "to_address": "9xZ7Y4mQkLpR3sVwC8tF2bG6hJ5nM1yK", "tx_hash": "5KgF7hJ2mN4pQ8rT9vX1yC3bA6wD0eG2jL5nP8sU1z4", "created_at": "2026-03-28T11:00:00Z" } ], "status": true, "message": "Transactions retrieved successfully" } ``` *** ## Transaction Status Values | Status | Description | | ----------- | ------------------------------------------------------------- | | `pending` | Submitted to the blockchain, awaiting confirmation. | | `confirmed` | Confirmed on-chain. | | `failed` | Transaction failed (insufficient gas, invalid address, etc.). | | `cancelled` | Cancelled before broadcast. | *** ## Testing Tips Attempt to send more than your wallet balance. Your application should handle this gracefully. ```bash theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/transactions/send-funds' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "from_asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4E6", "to_address": "9xZ7Y4mQkLpR3sVwC8tF2bG6hJ5nM1yK", "amount": "99999999.00", "chain": "solana", "ticker": "USDC_SOL" }' ``` Send two transactions with the same `idempotency_key`. The second call should return the original transaction rather than creating a duplicate. After submitting a transaction, poll `POST /transactions/get-transactions` filtering by the `transaction_id` until the status changes from `pending` to `confirmed` or `failed`. # Test: Wallets & Assets Source: https://docs.yativo.com/sandbox/wallets Test account creation, wallet (asset) creation, and balance checking in the sandbox ## Overview Use the sandbox to test the full wallet lifecycle — creating accounts, adding crypto assets, and checking balances. All wallet operations in the sandbox use testnet tokens on testnet blockchains. **Sandbox base URL:** `https://crypto-sandbox.yativo.com/api/v1/` You must be authenticated with a sandbox access token before calling these endpoints. See [Sandbox Authentication](/sandbox/authentication) to obtain a token. *** ## Step 1 — Create an Account Accounts are containers for your wallets and assets. ``` POST https://crypto-sandbox.yativo.com/api/v1/accounts/create-account ``` ```bash cURL theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/accounts/create-account' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_name": "Sandbox Main", "account_type": "business" }' ``` ```json Response theme={null} { "status": "success", "message": "Account created successfully", "data": { "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "account_name": "Sandbox Main", "account_type": "business", "created_at": "2026-03-28T10:00:00Z" } } ``` *** ## Step 2 — Add a Wallet (Asset) Add a specific blockchain + token combination to your account. This generates a new wallet address on the sandbox testnet. ``` POST https://crypto-sandbox.yativo.com/api/v1/assets/add-asset ``` The account to add the wallet to. Blockchain network: `solana`, `ethereum`, `bitcoin`, `polygon`, `bsc`, `base`, `xdc`. Token ticker symbol: `USDC_SOL`, `ETH`, `BTC`, `USDC_ETH`, `BNB`, etc. ```bash Add USDC on Solana (Devnet) theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/assets/add-asset' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chain": "solana", "ticker": "USDC_SOL" }' ``` ```bash Add ETH on Base (Sepolia) theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/assets/add-asset' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chain": "base", "ticker": "ETH" }' ``` ```json Response theme={null} { "status": "success", "message": "Asset created successfully", "data": { "asset_id": "ast_01HX9KZMB3F7VNQP8R2WDGT4E6", "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "chain": "solana", "ticker": "USDC_SOL", "wallet_address": "GY1EZGdpiJNyx2BSKq8rfTDRe5K8Bb6Cf2Bn1pdmE2o1", "status": "active", "created_at": "2026-03-28T10:05:00Z" } } ``` The `wallet_address` is your deposit address for this asset on the testnet. Use a testnet faucet to fund it. *** ## Step 3 — List Your Assets Retrieve all wallets and their balances. ``` POST https://crypto-sandbox.yativo.com/api/v1/assets/get-user-assets ``` Filter by a specific account. If omitted, returns all assets across all accounts. ```bash cURL theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/assets/get-user-assets' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5" }' ``` ```json Response theme={null} { "data": [ { "id": "ast_01HX9KZMB3F7VNQP8R2WDGT4E6", "user_id": "usr_01HX9KZMB3F7VNQP8R2WDGT001", "account_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "asset_name": "USD Coin (Solana)", "asset_short_name": "USDC", "ticker_name": "USDC_SOL", "chain": "SOL", "address": "GY1EZGdpiJNyx2BSKq8rfTDRe5K8Bb6Cf2Bn1pdmE2o1", "amount": "0.000000", "token_type": "token" } ], "status": true, "message": "Assets Listed Successfully" } ``` *** ## Step 4 — List Accounts Retrieve all accounts with their asset counts and total values. ``` GET https://crypto-sandbox.yativo.com/api/v1/accounts/get-accounts ``` ```bash cURL theme={null} curl -X GET 'https://crypto-sandbox.yativo.com/api/v1/accounts/get-accounts' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' ``` ```json Response theme={null} { "data": [ { "_id": "acc_01HX9KZMB3F7VNQP8R2WDGT4E5", "account_name": "Sandbox Main", "assets": "2", "account_value": 0, "portfolio": "0.00", "archived": "0", "subaccount": false, "createdAt": "2026-03-28T10:00:00Z" } ], "status": true, "message": "Accounts and assets listed successfully" } ``` *** ## Available Testnet Networks | Network | Testnet Used | Faucet | | --------------- | ------------ | ---------------------------------------------------------------- | | Solana | Devnet | [faucet.solana.com](https://faucet.solana.com) | | Ethereum / Base | Sepolia | [sepoliafaucet.com](https://sepoliafaucet.com) | | Gnosis | Chiado | [faucets.buildwithsygma.com](https://faucets.buildwithsygma.com) | | Polygon | Amoy | Polygon faucet | | BNB Chain | BSC Testnet | BNB testnet faucet | Testnet tokens have no monetary value. Use the faucets above to get free testnet tokens and send them to your wallet `address` to fund your sandbox wallets. *** ## Pre-Populated Shared Sandbox Account The shared sandbox account (accessible via the [public API key](/sandbox/overview)) already has: | Asset | Ticker | Network | Address | | -------- | --------- | ------------- | ---------------------------------------------- | | USD Coin | USDC\_SOL | Solana Devnet | `GY1EZGdpiJNyx2BSKq8rfTDRe5K8Bb6Cf2Bn1pdmE2o1` | # Java / Spring Boot SDK Source: https://docs.yativo.com/sdks/java Complete guide for yativo-crypto-sdk-spring-boot-starter — auto-configuration, service injection, webhook events, and error handling # Java / Spring Boot SDK The `yativo-crypto-sdk-spring-boot-starter` is a Spring Boot auto-configuration library that wires up all Yativo service beans automatically from your `application.yml`. Just add the dependency, set your credentials, and `@Autowired` the service you need. [![Maven Central](https://img.shields.io/maven-central/v/com.yativo/yativo-crypto-sdk-spring-boot-starter?label=Maven%20Central\&color=C71A36)](https://central.sonatype.com/artifact/com.yativo/yativo-crypto-sdk-spring-boot-starter) ## Installation ```xml theme={null} com.yativo yativo-crypto-sdk-spring-boot-starter 1.0.1 ``` ```kotlin theme={null} implementation("com.yativo:yativo-crypto-sdk-spring-boot-starter:1.0.1") ``` ```groovy theme={null} implementation 'com.yativo:yativo-crypto-sdk-spring-boot-starter:1.0.1' ``` **Package:** [`com.yativo:yativo-crypto-sdk-spring-boot-starter`](https://central.sonatype.com/artifact/com.yativo/yativo-crypto-sdk-spring-boot-starter) · **Latest:** `1.0.1` · **Requirements:** Java 11+, Spring Boot 2.7+ or 3.x. *** ## Configuration Add the following to your `application.yml`: ```yaml theme={null} yativo: crypto: api-key: ${YATIVO_API_KEY} api-secret: ${YATIVO_API_SECRET} base-url: https://crypto-api.yativo.com/api/v1/ # optional, this is the default timeout: 30000 # ms, optional webhook: enabled: true path: /webhooks/yativo secret: ${YATIVO_WEBHOOK_SECRET} ``` Or in `application.properties`: ```properties theme={null} yativo.crypto.api-key=${YATIVO_API_KEY} yativo.crypto.api-secret=${YATIVO_API_SECRET} yativo.crypto.base-url=https://crypto-api.yativo.com/api/ yativo.crypto.webhook.enabled=true yativo.crypto.webhook.path=/webhooks/yativo yativo.crypto.webhook.secret=${YATIVO_WEBHOOK_SECRET} ``` All beans are registered as Spring-managed singletons. The starter handles HTTP client setup, token storage, and automatic 401 token refresh for you. *** ## Available Services | Bean / Service | Purpose | | ----------------------- | --------------------------------------- | | `CustomerService` | Manage end-customers | | `WalletService` | Create and query wallets | | `WithdrawalService` | Send funds (withdrawals) | | `TransactionService` | Query transaction history | | `CardService` | Virtual card issuance and management | | `SwapService` | Quote and execute swaps | | `StandaloneIbanService` | Dedicated IBAN accounts | | `GasStationService` | Manage gas station sponsorships | | `AutoForwardingService` | Create and manage auto-forwarding rules | *** ## CustomerService ```java theme={null} import com.yativo.service.CustomerService; import com.yativo.model.Customer; import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; @Service public class OnboardingService { @Autowired private CustomerService customerService; public Customer createCustomer(String customerId, String email, String name) { return customerService.createCustomer(customerId, email, name); } public Customer createCustomerWithPhone(String customerId, String email, String name, String phone) { return customerService.createCustomer(customerId, email, name, phone, null); } public Customer getCustomer(String customerId) { return customerService.getCustomer(customerId); } public List listCustomers(int page, int limit) { return customerService.listCustomers(page, limit); } } ``` *** ## WalletService ```java theme={null} import com.yativo.service.WalletService; import com.yativo.model.Wallet; import com.yativo.model.CreateWalletRequest; import com.yativo.model.BatchCreateWalletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class WalletManagementService { @Autowired private WalletService walletService; public Wallet createWallet(String accountId, String asset, String network) { CreateWalletRequest request = CreateWalletRequest.builder() .accountId(accountId) .asset(asset) .network(network) .build(); return walletService.create(request); } public List batchCreateWallets(String accountId) { BatchCreateWalletRequest request = BatchCreateWalletRequest.builder() .accountId(accountId) .assets(List.of( new AssetNetworkPair("USDC", "SOLANA"), new AssetNetworkPair("XDC", "XDC"), new AssetNetworkPair("ETH", "ETHEREUM") )) .build(); return walletService.batchCreate(request); } public WalletBalance getBalance(String walletId) { return walletService.getBalance(walletId); } public List listWallets(String accountId) { return walletService.list(accountId); } } ``` *** ## WithdrawalService ```java theme={null} import com.yativo.service.WithdrawalService; import com.yativo.model.Transaction; import com.yativo.model.SendFundsRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.UUID; @Service public class PaymentService { @Autowired private WithdrawalService withdrawalService; public Transaction sendFunds(String fromWalletId, String toAddress, String amount, String asset, String network) { SendFundsRequest request = SendFundsRequest.builder() .fromWalletId(fromWalletId) .toAddress(toAddress) .amount(amount) .asset(asset) .network(network) .idempotencyKey(UUID.randomUUID().toString()) .memo("Payment from app") .build(); return withdrawalService.send(request); } public GasFeeEstimate estimateGas(String fromWalletId, String toAddress, String amount, String asset, String network) { return withdrawalService.estimateGas( fromWalletId, toAddress, amount, asset, network ); } } ``` *** ## TransactionService ```java theme={null} import com.yativo.service.TransactionService; import com.yativo.model.Transaction; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; @Service public class TransactionHistoryService { @Autowired private TransactionService transactionService; public List searchTransactions(String accountId) { Map filters = Map.of( "account_id", accountId, "page", 1, "limit", 25, "status", "COMPLETED" ); return transactionService.searchTransactions(filters); } public List getWalletTransactions(String walletAddress) { return transactionService.getWalletTransactions(walletAddress, 1, 25); } public List getCustomerTransactions(String customerId) { return transactionService.getCustomerTransactions(customerId, 1, 25); } public Transaction getTransaction(String transactionId) { return transactionService.getTransaction(transactionId); } } ``` *** ## CardService ```java theme={null} import com.yativo.service.CardService; import com.yativo.model.Card; import com.yativo.model.CardholderRequest; import com.yativo.model.CreateCardRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class CardManagementService { @Autowired private CardService cardService; public Cardholder onboardCardholder(String customerId) { CardholderRequest request = CardholderRequest.builder() .customerId(customerId) .firstName("Ada") .lastName("Lovelace") .dateOfBirth("1990-05-15") .address(Address.builder() .line1("1 Infinite Loop") .city("Cupertino") .state("CA") .zip("95014") .country("US") .build()) .build(); return cardService.onboard(request); } public Card createCard(String cardholderId) { CreateCardRequest request = CreateCardRequest.builder() .cardholderId(cardholderId) .currency("USD") .label("Engineering expenses") .build(); return cardService.create(request); } public CardFundingAddress getFundingAddress(String cardId) { return cardService.getFundingAddress(cardId); } public Page getCardTransactions(String cardId, int page, int limit) { return cardService.getTransactions(cardId, page, limit); } } ``` *** ## SwapService ```java theme={null} import com.yativo.service.SwapService; import com.yativo.model.SwapQuote; import com.yativo.model.SwapResult; import com.yativo.model.SwapQuoteRequest; import com.yativo.model.ExecuteSwapRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class SwapManagementService { @Autowired private SwapService swapService; public SwapQuote getQuote(String fromAsset, String toAsset, String amount, String network) { SwapQuoteRequest request = SwapQuoteRequest.builder() .fromAsset(fromAsset) .toAsset(toAsset) .amount(amount) .network(network) .build(); return swapService.getQuote(request); } public SwapResult executeSwap(String quoteId, String fromWalletId, String toWalletId) { ExecuteSwapRequest request = ExecuteSwapRequest.builder() .quoteId(quoteId) .fromWalletId(fromWalletId) .toWalletId(toWalletId) .build(); return swapService.execute(request); } } ``` *** ## StandaloneIbanService ```java theme={null} import com.yativo.service.StandaloneIbanService; import com.yativo.model.StandaloneIban; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class IbanService { @Autowired private StandaloneIbanService standaloneIbanService; public StandaloneIban createIban(String customerId, String currency, String label) { return standaloneIbanService.create( CreateIbanRequest.builder() .customerId(customerId) .currency(currency) .label(label) .build() ); } } ``` *** ## AutoForwardingService ```java theme={null} import com.yativo.service.AutoForwardingService; import com.yativo.model.AutoForwardingRule; import com.yativo.model.CreateAutoForwardingRequest; import com.yativo.model.UpdateAutoForwardingRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class ForwardingManagementService { @Autowired private AutoForwardingService autoForwardingService; public List listRules() { return autoForwardingService.list(); } public AutoForwardingRule createRule(String sourceWalletId, String destinationAddress, String asset, String network) { CreateAutoForwardingRequest request = CreateAutoForwardingRequest.builder() .sourceWalletId(sourceWalletId) .destinationAddress(destinationAddress) .asset(asset) .network(network) .minAmount("10.00") // optional .build(); return autoForwardingService.create(request); } public AutoForwardingRule updateRule(String ruleId, String newMinAmount) { UpdateAutoForwardingRequest request = UpdateAutoForwardingRequest.builder() .minAmount(newMinAmount) .build(); return autoForwardingService.update(ruleId, request); } public void deleteRule(String ruleId) { autoForwardingService.delete(ruleId); } } ``` *** ## Webhook Event Handling When `yativo.crypto.webhook.enabled=true`, the starter registers an HTTP endpoint at `yativo.crypto.webhook.path` that verifies incoming signatures and publishes `YativoWebhookEvent` instances to the Spring application context. Listen to these events with `@EventListener`: ```java theme={null} import com.yativo.event.YativoWebhookEvent; import com.yativo.event.TransactionCompletedEvent; import com.yativo.event.DepositReceivedEvent; import com.yativo.event.CardTransactionEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component public class YativoEventHandler { private static final Logger log = LoggerFactory.getLogger(YativoEventHandler.class); @EventListener public void onTransactionCompleted(TransactionCompletedEvent event) { log.info("Transaction completed: id={}, amount={} {}", event.getTransactionId(), event.getAmount(), event.getAsset()); // Trigger your business logic here } @EventListener public void onDepositReceived(DepositReceivedEvent event) { log.info("Deposit received: wallet={}, amount={} {}", event.getWalletId(), event.getAmount(), event.getAsset()); } @EventListener public void onCardTransaction(CardTransactionEvent event) { log.info("Card transaction: card={}, amount={}, merchant={}", event.getCardId(), event.getAmount(), event.getMerchantName()); } // Catch-all for any Yativo webhook event @EventListener public void onAnyYativoEvent(YativoWebhookEvent event) { log.debug("Yativo event received: type={}", event.getType()); } } ``` ### Available Event Types | Event Class | Webhook Event Type | | -------------------------------- | ------------------------ | | `TransactionFailedEvent` | `transaction.failed` | | `DepositDetectedEvent` | `deposit.detected` | | `DepositConfirmedEvent` | `deposit.confirmed` | | `CardTransactionAuthorizedEvent` | `transaction.authorized` | | `CardTransactionSettledEvent` | `transaction.settled` | | `CardCreatedEvent` | `card.created` | | `CustomerFundedEvent` | `customer.funded` | *** ## Error Handling ```java theme={null} import com.yativo.exception.YativoApiException; import com.yativo.exception.AuthenticationException; import com.yativo.exception.ValidationException; import com.yativo.exception.RateLimitException; import com.yativo.exception.NotFoundException; @Service public class PaymentService { @Autowired private WithdrawalService withdrawalService; public Transaction sendFundsSafely(SendFundsRequest request) { try { return withdrawalService.send(request); } catch (AuthenticationException e) { log.error("Authentication failed: {}", e.getMessage()); throw new RuntimeException("Yativo auth error", e); } catch (ValidationException e) { log.error("Validation failed: {}", e.getErrors()); throw new IllegalArgumentException("Invalid payment data: " + e.getErrors()); } catch (RateLimitException e) { log.warn("Rate limited. Retry after {}s", e.getRetryAfter()); // Schedule retry via Spring's @Scheduled or a task queue throw new RuntimeException("Rate limited, please retry shortly"); } catch (NotFoundException e) { log.error("Resource not found: {}", e.getResourceId()); throw new RuntimeException("Wallet or address not found"); } catch (YativoApiException e) { log.error("Yativo API error {}: {}", e.getStatusCode(), e.getMessage()); throw new RuntimeException("Yativo API error", e); } } } ``` *** ## Full Spring Boot Application Example ```java theme={null} @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @RestController @RequestMapping("/payments") public class PaymentController { @Autowired private WithdrawalService withdrawalService; @Autowired private WalletService walletService; @PostMapping("/send") public ResponseEntity sendPayment(@RequestBody SendPaymentDto dto) { Transaction tx = withdrawalService.send( SendFundsRequest.builder() .fromWalletId(dto.getWalletId()) .toAddress(dto.getToAddress()) .amount(dto.getAmount()) .asset(dto.getAsset()) .network(dto.getNetwork()) .idempotencyKey(UUID.randomUUID().toString()) .build() ); return ResponseEntity.ok(tx); } @GetMapping("/wallets/{accountId}") public ResponseEntity> getWallets(@PathVariable String accountId) { return ResponseEntity.ok(walletService.list(accountId)); } } ``` # MCP Server Source: https://docs.yativo.com/sdks/mcp Model Context Protocol server for AI agents — manage crypto wallets, send payments, and pay for x402 APIs # @yativo/mcp-server The Yativo MCP Server exposes [Agentic Wallet](/yativo-crypto/agentic-wallets) operations as [Model Context Protocol](https://modelcontextprotocol.io) tools. Any MCP-compatible AI agent (Claude, GPT, custom agents) can manage crypto wallets, send payments, and interact with x402-paywalled APIs through a standardized tool interface. **Package**: [`@yativo/mcp-server`](https://www.npmjs.com/package/@yativo/mcp-server) on npm *** ## Installation ```bash theme={null} npm install -g @yativo/mcp-server ``` Or add it to your project: ```bash theme={null} npm install @yativo/mcp-server ``` *** ## Configuration The MCP server is configured via environment variables: | Variable | Required | Default | Description | | ------------------ | -------- | -------------------------------------- | ---------------------------------------------------------------------- | | `YATIVO_API_KEY` | Yes | — | Connector API key (starts with `yac_`) from your agentic wallet | | `YATIVO_WALLET_ID` | No | — | Default wallet ID (starts with `aw_`). Can be overridden per tool call | | `YATIVO_API_URL` | No | `https://crypto-api.yativo.com/api/v1` | API base URL. Change for sandbox testing | *** ## Setup with Claude Desktop Add to your Claude Desktop config (`claude_desktop_config.json`): ```json theme={null} { "mcpServers": { "yativo-wallet": { "command": "npx", "args": ["-y", "@yativo/mcp-server"], "env": { "YATIVO_API_KEY": "yac_your_connector_api_key", "YATIVO_WALLET_ID": "aw_your_wallet_id" } } } } ``` For sandbox testing, add the sandbox URL: ```json theme={null} { "mcpServers": { "yativo-wallet": { "command": "npx", "args": ["-y", "@yativo/mcp-server"], "env": { "YATIVO_API_KEY": "yac_your_sandbox_connector_key", "YATIVO_WALLET_ID": "aw_your_sandbox_wallet_id", "YATIVO_API_URL": "https://crypto-sandbox.yativo.com/api/v1" } } } } ``` *** ## Available Tools ### `get_balance` Check the balance and address of your agentic wallet. | Parameter | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------- | | `wallet_id` | string | No | Wallet ID (uses `YATIVO_WALLET_ID` default) | **Example prompt**: *"What's my wallet balance?"* *** ### `send_payment` Send a crypto payment with full audit trail fields. | Parameter | Type | Required | Description | | ------------------- | ------ | -------- | -------------------------------------------------------------------- | | `recipient_address` | string | Yes | Destination wallet address | | `amount` | number | Yes | Amount in USD | | `asset` | string | No | Asset to send (default: `USDC`) | | `chain` | string | No | Chain override (e.g., `base`, `ethereum`) | | `service_name` | string | Yes | Name of the service being paid | | `service_url` | string | No | URL of the service | | `payment_reason` | string | Yes | Why this payment is being made | | `payment_category` | string | No | Category: `ai_service`, `subscription`, `purchase`, `transfer`, etc. | | `wallet_id` | string | No | Wallet ID (uses default) | **Example prompt**: *"Send \$5 USDC to 0x9F8b... for the OpenAI API subscription"* *** ### `x402_fetch` Fetch a URL with automatic x402 payment support. If the URL returns HTTP 402 (Payment Required), the wallet auto-pays and retries. | Parameter | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------- | | `url` | string | Yes | URL to fetch | | `method` | string | No | HTTP method (default: `GET`) | | `headers` | object | No | Additional request headers | | `body` | any | No | Request body for POST/PUT/PATCH | | `wallet_id` | string | No | Wallet ID (uses default) | **Example prompt**: *"Fetch the premium data from [https://api.example.com/data](https://api.example.com/data) — pay if it requires x402"* *** ### `get_transactions` Get recent transaction history for the wallet. | Parameter | Type | Required | Description | | ----------- | ------ | -------- | ---------------------------------------- | | `wallet_id` | string | No | Wallet ID (uses default) | | `page` | number | No | Page number (default: 1) | | `limit` | number | No | Results per page (default: 10, max: 100) | **Example prompt**: *"Show me my last 5 transactions"* *** ## Resources The server exposes an MCP resource for wallet information: | Resource URI | Description | | --------------- | --------------------------------------------------------- | | `wallet://info` | JSON snapshot of the default wallet's balance and address | *** ## Running Directly ```bash theme={null} # Set environment variables export YATIVO_API_KEY="yac_your_connector_key" export YATIVO_WALLET_ID="aw_your_wallet_id" # Run the server npx @yativo/mcp-server ``` The server communicates over stdio using the MCP protocol. *** ## Prerequisites Before using the MCP server, you need: 1. A Yativo account with an [agentic wallet](/yativo-crypto/agentic-wallets) 2. An activated wallet with at least one connector 3. The connector's API key (`yac_...`) 4. Funds (USDC) in the wallet See the [Agentic Wallets guide](/yativo-crypto/agentic-wallets) for setup instructions. *** ## Next Steps Create and configure agentic wallets via the API. Learn more about HTTP-native micropayments. For programmatic (non-MCP) integration, use the TypeScript SDK. Test the MCP server against the sandbox environment. # SDK Overview Source: https://docs.yativo.com/sdks/overview Official Yativo Crypto SDKs for TypeScript/Node.js, Python, PHP, Java/Spring Boot, React, and MCP # Yativo Crypto SDKs Yativo provides official SDKs for the most popular languages and frameworks, plus an MCP server for AI agents. Every SDK wraps the same underlying [Yativo Crypto API](https://crypto-api.yativo.com/api/v1/) and provides a consistent, idiomatic interface for your platform. Full-featured SDK for Node.js and browser environments, including a card embed widget. Pythonic SDK with snake\_case methods and structured exception hierarchy. Composer package with static webhook verification helpers. Spring Boot starter with auto-configuration, DI-ready services, and event-driven webhooks. Hooks and pre-built components built on top of the TypeScript SDK. Model Context Protocol server for AI agents — manage agentic wallets via Claude, GPT, or any MCP-compatible agent. *** ## Quick Comparison | Feature | TypeScript | Python | PHP | Java | React | MCP | | -------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------ | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ | | Package manager | npm | pip | Composer | Maven / Gradle | npm | npm | | Package name | [`@yativo/crypto-sdk`](https://www.npmjs.com/package/@yativo/crypto-sdk) | [`yativo-crypto-sdk`](https://pypi.org/project/yativo-crypto-sdk/) | [`yativo/crypto-sdk`](https://packagist.org/packages/yativo/crypto-sdk) | [`com.yativo:yativo-crypto-sdk-spring-boot-starter`](https://central.sonatype.com/artifact/com.yativo/yativo-crypto-sdk-spring-boot-starter) | [`@yativo/crypto-sdk-react`](https://www.npmjs.com/package/@yativo/crypto-sdk-react) | [`@yativo/mcp-server`](https://www.npmjs.com/package/@yativo/mcp-server) | | Latest version | `1.0.3` | `1.0.1` | `1.0.0` | `1.0.1` | `1.0.2` | `1.0.1` | | Min runtime | Node 16 / modern browser | Python 3.8 | PHP 7.4 | Java 11 / Spring Boot 2.7+ | React 17+ | Node 18+ | | Auto token refresh | Yes | Yes | Yes | Yes | Yes | N/A (API key auth) | | Webhook verification | Yes | Yes | Yes (static) | Yes (@EventListener) | Via TypeScript SDK | — | | Card widget / embed | YativoCardEmbed | — | — | — | YativoCardWidget | — | | UI components | — | — | — | — | Yes | — | | Agentic wallets | Via API | Via API | Via API | Via API | Via API | Built-in MCP tools | *** ## Choosing the Right SDK Use the TypeScript SDK when: * Building a **Node.js** backend (Express, Fastify, NestJS, etc.) * Writing a **serverless function** (Vercel, AWS Lambda, Cloudflare Workers) * Embedding the Yativo Card widget directly in a **non-React** frontend * You want full TypeScript type safety across all API resources ```bash theme={null} npm install @yativo/crypto-sdk ``` Use the Python SDK when: * Building a **Django**, **Flask**, or **FastAPI** backend * Running **data pipelines** or **automation scripts** * Integrating Yativo into a **Jupyter notebook** or analytics workflow ```bash theme={null} pip install yativo-crypto-sdk ``` Use the PHP SDK when: * Building a **Laravel**, **Symfony**, or plain PHP application * Your existing stack is PHP and you need a drop-in Composer package ```bash theme={null} composer require yativo/crypto-sdk ``` Use the Java SDK when: * Your application is built on **Spring Boot** * You want **auto-configuration** via `application.yml` with zero boilerplate * You prefer dependency injection and `@Autowired` service beans * You want to handle webhook events via Spring's `@EventListener` ```xml theme={null} com.yativo yativo-crypto-sdk-spring-boot-starter 1.0.1 ``` Use the React SDK when: * Building a **React** single-page application or Next.js app * You want ready-made hooks (`useWallets`, `useBalance`, `useSwap`, etc.) * You need pre-built UI components (`DepositWidget`, `YativoCardWidget`, etc.) * You want authentication state managed for you via `YativoProvider` ```bash theme={null} npm install @yativo/crypto-sdk-react ``` *** ## Common Concepts Across All SDKs All SDKs expose the same logical resources: | Resource | Description | | -------------- | ------------------------------------ | | `auth` | Register, login, OTP verification | | `accounts` | Manage business accounts | | `assets` | Wallets and supported assets | | `transactions` | Send / receive funds | | `webhooks` | Create and verify webhooks | | `apiKeys` | Programmatic API key management | | `customers` | End-customer management | | `analytics` | Volume, fees, and reporting | | `cards` | Virtual card issuance and management | | `swap` | Quote and execute asset swaps | | `iban` | Dedicated IBAN accounts | ### Authentication Modes Every SDK supports two authentication flows: 1. **Email / password** — call `auth.login()` then `auth.verifyOtp()` to obtain a session token; the SDK stores it and auto-refreshes on 401 responses. 2. **API key + secret** — pass `apiKey` and `apiSecret` to the constructor. The SDK exchanges them for a Bearer token automatically; no manual token management required. ### Rate Limiting The Yativo Crypto API enforces **60 requests per minute per endpoint**. All SDKs surface rate-limit errors as dedicated exception types so you can implement back-off logic. *** ## Base URL All SDKs default to the production base URL: ``` https://crypto-api.yativo.com/api/ ``` You can override this in the constructor for staging or local development environments. *** ## Next Steps Complete guide with code examples for every resource. Python-idiomatic examples and exception handling. Composer setup, try/catch patterns, and webhook verification. Spring Boot auto-configuration and service injection. Hooks, components, widgets, and theme customization. Chrome and Firefox extensions for wallet monitoring and notifications. # PHP SDK Source: https://docs.yativo.com/sdks/php Complete guide for yativo/crypto-sdk — Composer installation, all resources, exception handling, and static webhook verification # PHP SDK The `yativo/crypto-sdk` Composer package provides a clean, object-oriented PHP interface to the Yativo Crypto API with automatic token refresh and static webhook signature verification. [![Packagist version](https://img.shields.io/packagist/v/yativo/crypto-sdk?label=Packagist\&color=F28D1A)](https://packagist.org/packages/yativo/crypto-sdk) ## Installation ```bash theme={null} composer require yativo/crypto-sdk ``` **Package:** [`yativo/crypto-sdk`](https://packagist.org/packages/yativo/crypto-sdk) · **Latest:** `1.0.0` · **Requirements:** PHP 7.4 or higher, `ext-json`, Guzzle HTTP 7+. *** ## Quick Start ```php theme={null} 'https://crypto-api.yativo.com/api/v1/', ]); // Register $sdk->auth->register([ 'email' => 'user@example.com', 'password' => 'SecurePass123!', 'first_name' => 'Ada', 'last_name' => 'Lovelace', ]); // Step 1 — Send OTP to the user's email $sdk->auth->login('user@example.com'); // Step 2 — Verify the OTP to complete login // Token is stored and auto-refreshed on 401 $session = $sdk->auth->verifyOTP('123456', 'user@example.com'); echo 'Logged in as: ' . $session['user']['email'] . PHP_EOL; ``` ```php theme={null} getenv('YATIVO_API_KEY'), 'api_secret' => getenv('YATIVO_API_SECRET'), 'base_url' => 'https://crypto-api.yativo.com/api/v1/', ]); // No login needed — requests are signed automatically $wallets = $sdk->assets->list(); print_r($wallets); ``` *** ## Constructor Options ```php theme={null} new \Yativo\YativoSDK([ 'api_key' => 'your_api_key', // optional 'api_secret' => 'your_api_secret', // optional 'base_url' => 'https://crypto-api.yativo.com/api/v1/', 'timeout' => 30, // seconds, default 30 'standalone_iban_enabled' => false, // default false ]); ``` *** ## Authentication (`$sdk->auth`) ### Register ```php theme={null} $user = $sdk->auth->register([ 'email' => 'user@example.com', 'password' => 'SecurePass123!', 'first_name' => 'Ada', 'last_name' => 'Lovelace', 'phone_number' => '+14155552671', // optional ]); ``` ### Login (Passwordless) Login is passwordless. Call `login($email)` to send an OTP, then call `verifyOTP($otp, $email)` to complete authentication. ```php theme={null} // Step 1 — Send OTP $sdk->auth->login('user@example.com'); // Step 2 — Verify OTP to complete auth $session = $sdk->auth->verifyOTP('123456', 'user@example.com'); ``` ### 2FA Setup (Google Authenticator) ```php theme={null} // Get QR code and secret for Google Authenticator setup $details = $sdk->auth->get2faDetails(); // $details['qr_code'] — display as QR image // $details['secret'] — manual entry fallback // Activate 2FA on the account $sdk->auth->enable2fa(); // Verify a TOTP code (use instead of verifyOTP when 2FA is enabled) $session = $sdk->auth->verify2FA('654321', 'user@example.com'); ``` ### Passkey (WebAuthn) Auth ```php theme={null} // Get WebAuthn challenge $options = $sdk->auth->passkeyAuthOptions('user@example.com'); // Verify WebAuthn credential $session = $sdk->auth->passkeyAuthVerify($credential); ``` ### Exchange API Key for Bearer Token ```php theme={null} $tokenResp = $sdk->auth->getToken( getenv('YATIVO_API_KEY'), getenv('YATIVO_API_SECRET') ); ``` *** ## Accounts (`$sdk->accounts`) ```php theme={null} // Create an account $account = $sdk->accounts->create([ 'name' => 'Main Treasury', 'currency' => 'USD', ]); // List accounts $result = $sdk->accounts->list(['page' => 1, 'limit' => 20]); echo 'Total: ' . $result['total'] . PHP_EOL; // Get a single account $account = $sdk->accounts->get('acct_abc123'); ``` *** ## Assets / Wallets (`$sdk->assets`) ### Create a Wallet ```php theme={null} $wallet = $sdk->assets->createWallet([ 'account_id' => 'acct_abc123', 'asset' => 'USDC', 'network' => 'SOLANA', ]); echo 'Deposit address: ' . $wallet['address'] . PHP_EOL; ``` ### Batch Create Wallets ```php theme={null} $wallets = $sdk->assets->batchCreate([ 'account_id' => 'acct_abc123', 'assets' => [ ['asset' => 'USDC', 'network' => 'SOLANA'], ['asset' => 'XDC', 'network' => 'XDC'], ['asset' => 'ETH', 'network' => 'ETHEREUM'], ], ]); ``` ### List Wallets ```php theme={null} $wallets = $sdk->assets->list(['account_id' => 'acct_abc123']); ``` ### Check Balance ```php theme={null} $balance = $sdk->assets->getBalance(['wallet_id' => 'wallet_xyz789']); echo "Balance: {$balance['amount']} {$balance['asset']}" . PHP_EOL; ``` *** ## Transactions (`$sdk->transactions`) ### Send Funds (with Idempotency) ```php theme={null} $tx = $sdk->transactions->send([ 'from_wallet_id' => 'wallet_xyz789', 'to_address' => 'BjhiXKt...', 'amount' => '100.00', 'asset' => 'USDC', 'network' => 'SOLANA', 'idempotency_key' => bin2hex(random_bytes(16)), // prevents double-sends 'memo' => 'Invoice #INV-2026-001', ]); echo "Transaction ID: {$tx['id']}, Status: {$tx['status']}" . PHP_EOL; ``` ### Estimate Gas Fee ```php theme={null} $fee = $sdk->transactions->estimateGas([ 'from_wallet_id' => 'wallet_xyz789', 'to_address' => 'BjhiXKt...', 'amount' => '100.00', 'asset' => 'USDC', 'network' => 'SOLANA', ]); echo "Estimated fee: {$fee['fee']} {$fee['fee_asset']}" . PHP_EOL; ``` ### List Transactions ```php theme={null} $result = $sdk->transactions->list([ 'account_id' => 'acct_abc123', 'page' => 1, 'limit' => 25, 'status' => 'COMPLETED', // optional 'start_date' => '2026-01-01', // optional 'end_date' => '2026-03-31', // optional ]); foreach ($result['transactions'] as $t) { echo "{$t['id']} | {$t['status']} | {$t['amount']}" . PHP_EOL; } ``` ### Get a Transaction ```php theme={null} $tx = $sdk->transactions->get('txn_def456'); ``` *** ## Swap (`$sdk->swap`) ```php theme={null} // Get a swap quote $quote = $sdk->swap->getQuote([ 'from_asset' => 'USDC', 'to_asset' => 'XDC', 'amount' => '500.00', 'network' => 'SOLANA', ]); echo "You receive: {$quote['to_amount']} XDC at rate {$quote['rate']}" . PHP_EOL; // Execute the swap (quote expires after ~30 seconds) $result = $sdk->swap->execute([ 'quote_id' => $quote['id'], 'from_wallet_id' => 'wallet_xyz789', 'to_wallet_id' => 'wallet_xdc001', ]); echo 'Swap status: ' . $result['status'] . PHP_EOL; ``` *** ## Cards (`$sdk->cards`) ### Onboard a Cardholder ```php theme={null} $cardholder = $sdk->cards->onboard([ 'customer_id' => 'cust_111', 'first_name' => 'Ada', 'last_name' => 'Lovelace', 'date_of_birth' => '1990-05-15', 'address' => [ 'line1' => '1 Infinite Loop', 'city' => 'Cupertino', 'state' => 'CA', 'zip' => '95014', 'country' => 'US', ], ]); ``` ### Create a Virtual Card ```php theme={null} $card = $sdk->cards->create([ 'cardholder_id' => $cardholder['id'], 'currency' => 'USD', 'label' => 'Engineering expenses', ]); echo "Card {$card['id']}, last 4: {$card['last4']}" . PHP_EOL; ``` ### Get Card Funding Address ```php theme={null} $funding = $sdk->cards->getFundingAddress(['card_id' => $card['id']]); echo "Fund at: {$funding['address']} on {$funding['network']}" . PHP_EOL; ``` ### Get Card Transactions ```php theme={null} $result = $sdk->cards->getTransactions([ 'card_id' => $card['id'], 'page' => 1, 'limit' => 20, ]); ``` *** ## Webhooks (`$sdk->webhooks`) ### Create a Webhook ```php theme={null} $webhook = $sdk->webhooks->create([ 'url' => 'https://your-app.com/webhooks/yativo', 'events' => ['transaction.completed', 'deposit.received', 'card.transaction'], 'secret' => 'whsec_your_generated_secret', ]); echo 'Webhook ID: ' . $webhook['id'] . PHP_EOL; ``` ### Verify a Webhook Signature (Static Method) ```php theme={null} use Yativo\Auth; // In your webhook controller (Laravel example): public function handle(Request $request): Response { $payload = $request->getContent(); $signature = $request->header('X-Yativo-Signature', ''); if (!Auth::verifySignature($payload, $signature, config('yativo.webhook_secret'))) { abort(401, 'Invalid webhook signature'); } $event = json_decode($payload, true); // Handle event... Log::info('Yativo event', ['type' => $event['type']]); return response()->noContent(); } ``` `Auth::verifySignature()` is a static helper — you do not need an SDK instance to call it. This makes it easy to use in lightweight webhook endpoints that do not initialise the full SDK. ### List / Delete Webhooks ```php theme={null} $webhooks = $sdk->webhooks->list(); $sdk->webhooks->delete('wh_ghi789'); ``` *** ## API Keys (`$sdk->apiKeys`) ```php theme={null} // Create an API key $key = $sdk->apiKeys->create([ 'key_name' => 'Production Server', 'scopes' => ['transactions:read', 'transactions:write', 'wallets:read'], 'expires_in_days' => 90, // optional 'allowed_ips' => ['203.0.113.10'], // optional ]); // Store $key['secret'] securely — shown only once echo 'API Key: ' . $key['key'] . PHP_EOL; echo 'API Secret: ' . $key['secret'] . PHP_EOL; // List API keys $result = $sdk->apiKeys->list(); // Revoke a key (simple DELETE — no 2FA token required) $sdk->apiKeys->revoke('key_jkl012'); ``` *** ## Auto-Forwarding (`$sdk->autoForwarding`) Auto-forwarding rules automatically sweep incoming deposits to a destination address. ```php theme={null} // List all auto-forwarding rules $result = $sdk->autoForwarding->list(); // Create a rule $rule = $sdk->autoForwarding->create([ 'source_wallet_id' => 'wallet_xyz789', 'destination_address' => 'BjhiXKt...', 'asset' => 'USDC', 'network' => 'SOLANA', 'min_amount' => '10.00', // optional — only forward if amount >= this ]); echo 'Rule ID: ' . $rule['id'] . PHP_EOL; // Update a rule $sdk->autoForwarding->update($rule['id'], ['min_amount' => '25.00']); // Delete a rule $sdk->autoForwarding->delete($rule['id']); ``` *** ## Customers (`$sdk->customers`) ```php theme={null} $customer = $sdk->customers->create([ 'external_id' => 'usr_from_your_db', 'email' => 'customer@example.com', 'first_name' => 'Charles', 'last_name' => 'Babbage', 'kyc_level' => 'BASIC', ]); $result = $sdk->customers->list(['page' => 1, 'limit' => 50]); $customer = $sdk->customers->get('cust_abc'); $sdk->customers->update('cust_abc', ['kyc_level' => 'FULL']); ``` *** ## Analytics (`$sdk->analytics`) ```php theme={null} $report = $sdk->analytics->getSummary([ 'account_id' => 'acct_abc123', 'start_date' => '2026-01-01', 'end_date' => '2026-03-31', ]); echo 'Total volume: ' . $report['total_volume'] . PHP_EOL; echo 'Total fees: ' . $report['total_fees'] . PHP_EOL; ``` *** ## IBAN (`$sdk->standaloneIban`) Pass `'standalone_iban_enabled' => true` in the constructor options to unlock this resource. ```php theme={null} $sdk = new YativoSDK([ 'api_key' => getenv('YATIVO_API_KEY'), 'api_secret' => getenv('YATIVO_API_SECRET'), 'standalone_iban_enabled' => true, ]); $iban = $sdk->standaloneIban->create([ 'customer_id' => 'cust_111', 'currency' => 'EUR', 'label' => 'EU Collections', ]); echo "IBAN: {$iban['iban']}, BIC: {$iban['bic']}" . PHP_EOL; $ibans = $sdk->standaloneIban->list(['customer_id' => 'cust_111']); ``` *** ## Exception Handling ```php theme={null} use Yativo\Exceptions\YativoException; use Yativo\Exceptions\AuthenticationException; use Yativo\Exceptions\ValidationException; use Yativo\Exceptions\RateLimitException; use Yativo\Exceptions\NotFoundException; try { $tx = $sdk->transactions->send([ 'from_wallet_id' => 'wallet_xyz789', 'to_address' => 'BjhiXKt...', 'amount' => '100.00', 'asset' => 'USDC', 'network' => 'SOLANA', 'idempotency_key' => bin2hex(random_bytes(16)), ]); } catch (AuthenticationException $e) { // Invalid or expired credentials error_log('Auth failed: ' . $e->getMessage()); } catch (ValidationException $e) { // Server-side validation failed error_log('Validation: ' . json_encode($e->getErrors())); } catch (RateLimitException $e) { // 60 req/min per endpoint exceeded $retryAfter = $e->getRetryAfter(); // seconds error_log("Rate limited. Retry after {$retryAfter}s"); } catch (NotFoundException $e) { error_log('Not found: ' . $e->getResourceId()); } catch (YativoException $e) { error_log("API error {$e->getStatusCode()}: {$e->getMessage()}"); } ``` ### Exception Hierarchy ``` \Yativo\Exceptions\YativoException ├── AuthenticationException (HTTP 401) ├── AuthorizationException (HTTP 403) ├── ValidationException (HTTP 422) — getErrors(): array ├── NotFoundException (HTTP 404) — getResourceId(): string ├── RateLimitException (HTTP 429) — getRetryAfter(): int └── ServerException (HTTP 5xx) ``` *** ## Laravel Service Provider Example ```php theme={null} // config/yativo.php return [ 'api_key' => env('YATIVO_API_KEY'), 'api_secret' => env('YATIVO_API_SECRET'), 'base_url' => env('YATIVO_BASE_URL', 'https://crypto-api.yativo.com/api/v1/'), 'webhook_secret' => env('YATIVO_WEBHOOK_SECRET'), ]; // app/Providers/YativoServiceProvider.php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Yativo\YativoSDK; class YativoServiceProvider extends ServiceProvider { public function register(): void { $this->app->singleton(YativoSDK::class, fn() => new YativoSDK([ 'api_key' => config('yativo.api_key'), 'api_secret' => config('yativo.api_secret'), 'base_url' => config('yativo.base_url'), ])); } } // Usage in a controller use Yativo\YativoSDK; class PaymentController extends Controller { public function __construct(private YativoSDK $yativo) {} public function send(Request $request) { $tx = $this->yativo->transactions->send([ 'from_wallet_id' => $request->wallet_id, 'to_address' => $request->to_address, 'amount' => $request->amount, 'asset' => 'USDC', 'network' => 'SOLANA', 'idempotency_key' => (string) \Str::uuid(), ]); return response()->json($tx); } } ``` # Python SDK Source: https://docs.yativo.com/sdks/python Complete guide for yativo-crypto-sdk — installation, authentication, all resources, and exception handling # Python SDK The `yativo-crypto-sdk` package provides a Pythonic interface to the Yativo Crypto API with snake\_case methods, a structured exception hierarchy, and automatic token refresh on `401` responses. [![PyPI version](https://img.shields.io/pypi/v/yativo-crypto-sdk?label=PyPI\&color=3775A9)](https://pypi.org/project/yativo-crypto-sdk/) [![PyPI downloads](https://img.shields.io/pypi/dm/yativo-crypto-sdk?color=3775A9)](https://pypi.org/project/yativo-crypto-sdk/) ## Installation ```bash theme={null} pip install yativo-crypto-sdk # or with poetry poetry add yativo-crypto-sdk # or with uv uv add yativo-crypto-sdk ``` **Package:** [`yativo-crypto-sdk`](https://pypi.org/project/yativo-crypto-sdk/) · **Latest:** `1.0.1` · **Requirements:** Python 3.8 or higher. *** ## Quick Start ```python theme={null} from yativo import YativoSDK sdk = YativoSDK( base_url="https://crypto-api.yativo.com/api/v1/" ) # Register sdk.auth.register( email="user@example.com", password="SecurePass123!", first_name="Ada", last_name="Lovelace", ) # Step 1 — Send OTP to the user's email sdk.auth.login("user@example.com") # Step 2 — Verify the OTP to complete login # Token is stored and refreshed automatically session = sdk.auth.verify_otp("123456", "user@example.com") print("Logged in as:", session["user"]["email"]) ``` ```python theme={null} import os from yativo import YativoSDK sdk = YativoSDK( api_key=os.environ["YATIVO_API_KEY"], api_secret=os.environ["YATIVO_API_SECRET"], base_url="https://crypto-api.yativo.com/api/v1/", ) # No login needed — every request is signed automatically wallets = sdk.assets.list() print("Wallets:", wallets) ``` *** ## Constructor Parameters ```python theme={null} YativoSDK( api_key: str | None = None, api_secret: str | None = None, base_url: str = "https://crypto-api.yativo.com/api/v1/", timeout: int = 30, # seconds standalone_iban_enabled: bool = False, ) ``` *** ## Authentication (`sdk.auth`) ### Register ```python theme={null} user = sdk.auth.register( email="user@example.com", password="SecurePass123!", first_name="Ada", last_name="Lovelace", phone_number="+14155552671", # optional ) ``` ### Login (Passwordless) Login is passwordless. Call `login(email)` to send an OTP to the user, then call `verify_otp(otp, email)` to complete authentication. ```python theme={null} # Step 1 — Send OTP sdk.auth.login("user@example.com") # Step 2 — Verify OTP to complete auth session = sdk.auth.verify_otp("123456", "user@example.com") ``` ### 2FA Setup (Google Authenticator) ```python theme={null} # Get QR code and secret for Google Authenticator setup details = sdk.auth.get_2fa_details() # details["qr_code"] — display as QR image # details["secret"] — manual entry fallback # Activate 2FA on the account sdk.auth.enable_2fa() # Verify a TOTP code (use instead of verify_otp when 2FA is enabled) session = sdk.auth.verify_2fa("654321", "user@example.com") ``` ### Passkey (WebAuthn) Auth ```python theme={null} # Get WebAuthn challenge options = sdk.auth.passkey_auth_options("user@example.com") # Verify WebAuthn credential session = sdk.auth.passkey_auth_verify(credential) ``` ### Exchange API Key for Bearer Token ```python theme={null} import os token_resp = sdk.auth.get_token( os.environ["YATIVO_API_KEY"], os.environ["YATIVO_API_SECRET"], ) ``` *** ## Accounts (`sdk.accounts`) ```python theme={null} # Create an account account = sdk.accounts.create(name="Main Treasury", currency="USD") # List accounts result = sdk.accounts.list(page=1, limit=20) print(f"Total: {result['total']}, Accounts: {result['accounts']}") # Get a single account account = sdk.accounts.get("acct_abc123") ``` *** ## Assets / Wallets (`sdk.assets`) ### Create a Wallet ```python theme={null} wallet = sdk.assets.create_wallet( account_id="acct_abc123", asset="USDC", network="SOLANA", ) print("Deposit address:", wallet["address"]) ``` ### Batch Create Wallets ```python theme={null} wallets = sdk.assets.batch_create( account_id="acct_abc123", assets=[ {"asset": "USDC", "network": "SOLANA"}, {"asset": "XDC", "network": "XDC"}, {"asset": "ETH", "network": "ETHEREUM"}, ], ) ``` ### List Wallets ```python theme={null} wallets = sdk.assets.list(account_id="acct_abc123") ``` ### Check Balance ```python theme={null} balance = sdk.assets.get_balance(wallet_id="wallet_xyz789") print(f"Balance: {balance['amount']} {balance['asset']}") ``` *** ## Transactions (`sdk.transactions`) ### Send Funds (with Idempotency) ```python theme={null} import uuid tx = sdk.transactions.send( from_wallet_id="wallet_xyz789", to_address="BjhiXKt...", amount="100.00", asset="USDC", network="SOLANA", idempotency_key=str(uuid.uuid4()), # prevents double-sends on retry memo="Invoice #INV-2026-001", ) print(f"Transaction ID: {tx['id']}, Status: {tx['status']}") ``` ### Estimate Gas Fee ```python theme={null} fee = sdk.transactions.estimate_gas( from_wallet_id="wallet_xyz789", to_address="BjhiXKt...", amount="100.00", asset="USDC", network="SOLANA", ) print(f"Estimated fee: {fee['fee']} {fee['fee_asset']}") ``` ### List Transactions ```python theme={null} result = sdk.transactions.list( account_id="acct_abc123", page=1, limit=25, status="COMPLETED", # optional start_date="2026-01-01", # optional end_date="2026-03-31", # optional ) for tx in result["transactions"]: print(tx["id"], tx["status"], tx["amount"]) ``` ### Get a Transaction ```python theme={null} tx = sdk.transactions.get("txn_def456") ``` *** ## Swap (`sdk.swap`) ```python theme={null} # Get a swap quote quote = sdk.swap.get_quote( from_asset="USDC", to_asset="XDC", amount="500.00", network="SOLANA", ) print(f"You receive: {quote['to_amount']} XDC at rate {quote['rate']}") # Execute the swap (quote expires after ~30 seconds) result = sdk.swap.execute( quote_id=quote["id"], from_wallet_id="wallet_xyz789", to_wallet_id="wallet_xdc001", ) print("Swap status:", result["status"]) ``` *** ## Cards (`sdk.cards`) ### Onboard a Cardholder ```python theme={null} cardholder = sdk.cards.onboard( customer_id="cust_111", first_name="Ada", last_name="Lovelace", date_of_birth="1990-05-15", address={ "line1": "1 Infinite Loop", "city": "Cupertino", "state": "CA", "zip": "95014", "country": "US", }, ) ``` ### Create a Virtual Card ```python theme={null} card = sdk.cards.create( cardholder_id=cardholder["id"], currency="USD", label="Engineering expenses", ) print(f"Card {card['id']}, last 4: {card['last4']}") ``` ### Get Card Funding Address ```python theme={null} funding = sdk.cards.get_funding_address(card_id=card["id"]) print(f"Fund this card at: {funding['address']} on {funding['network']}") ``` ### Get Card Transactions ```python theme={null} result = sdk.cards.get_transactions(card_id=card["id"], page=1, limit=20) for t in result["transactions"]: print(t["amount"], t["merchant"], t["status"]) ``` *** ## Webhooks (`sdk.webhooks`) ### Create a Webhook ```python theme={null} webhook = sdk.webhooks.create( url="https://your-app.com/webhooks/yativo", events=["transaction.completed", "deposit.received", "card.transaction"], secret="whsec_your_generated_secret", ) print("Webhook ID:", webhook["id"]) ``` ### Verify a Webhook Signature ```python theme={null} from yativo import Webhooks from flask import Flask, request, abort app = Flask(__name__) @app.post("/webhooks/yativo") def handle_webhook(): signature = request.headers.get("X-Yativo-Signature", "") raw_body = request.get_data() if not Webhooks.verify_signature(raw_body, signature, "whsec_your_secret"): abort(401) event = request.get_json(force=True) print("Event:", event["type"], event["data"]) return "", 200 ``` ### List / Delete Webhooks ```python theme={null} webhooks = sdk.webhooks.list() sdk.webhooks.delete("wh_ghi789") ``` *** ## API Keys (`sdk.api_keys`) ```python theme={null} # Create an API key key = sdk.api_keys.create( key_name="Production Server", scopes=["transactions:read", "transactions:write", "wallets:read"], expires_in_days=90, # optional allowed_ips=["203.0.113.10"], # optional ) # Store key["secret"] securely — shown only once print("API Key:", key["key"]) print("API Secret:", key["secret"]) # List API keys result = sdk.api_keys.list() # Revoke a key (simple DELETE — no 2FA token required) sdk.api_keys.revoke("key_jkl012") ``` *** ## Auto-Forwarding (`sdk.auto_forwarding`) Auto-forwarding rules automatically sweep incoming deposits to a destination address. ```python theme={null} # List all auto-forwarding rules result = sdk.auto_forwarding.list() # Create a rule rule = sdk.auto_forwarding.create( source_wallet_id="wallet_xyz789", destination_address="BjhiXKt...", asset="USDC", network="SOLANA", min_amount="10.00", # optional — only forward if amount >= this ) print("Rule ID:", rule["id"]) # Update a rule sdk.auto_forwarding.update(rule["id"], min_amount="25.00") # Delete a rule sdk.auto_forwarding.delete(rule["id"]) ``` *** ## Customers (`sdk.customers`) ```python theme={null} customer = sdk.customers.create( external_id="usr_from_your_db", email="customer@example.com", first_name="Charles", last_name="Babbage", kyc_level="BASIC", ) result = sdk.customers.list(page=1, limit=50) customer = sdk.customers.get("cust_abc") sdk.customers.update("cust_abc", kyc_level="FULL") ``` *** ## Analytics (`sdk.analytics`) ```python theme={null} report = sdk.analytics.get_summary( account_id="acct_abc123", start_date="2026-01-01", end_date="2026-03-31", ) print("Total volume:", report["total_volume"]) print("Total fees:", report["total_fees"]) ``` *** ## IBAN (`sdk.standalone_iban`) You must pass `standalone_iban_enabled=True` to the constructor to use this resource. ```python theme={null} sdk = YativoSDK( api_key=os.environ["YATIVO_API_KEY"], api_secret=os.environ["YATIVO_API_SECRET"], standalone_iban_enabled=True, ) iban = sdk.standalone_iban.create( customer_id="cust_111", currency="EUR", label="EU Collections", ) print(f"IBAN: {iban['iban']}, BIC: {iban['bic']}") ibans = sdk.standalone_iban.list(customer_id="cust_111") ``` *** ## Exception Handling ```python theme={null} from yativo.exceptions import ( YativoError, AuthenticationError, ValidationError, RateLimitError, NotFoundError, ) try: tx = sdk.transactions.send( from_wallet_id="wallet_xyz789", to_address="BjhiXKt...", amount="100.00", asset="USDC", network="SOLANA", idempotency_key=str(uuid.uuid4()), ) except AuthenticationError as e: # Token expired and could not be refreshed, or invalid API key print(f"Auth failed: {e}") except ValidationError as e: # Request body failed server-side validation print(f"Validation errors: {e.errors}") except RateLimitError as e: # 60 req/min per endpoint exceeded print(f"Rate limited. Retry after {e.retry_after}s") except NotFoundError as e: print(f"Resource not found: {e.resource_id}") except YativoError as e: print(f"API error {e.status_code}: {e}") ``` ### Exception Hierarchy ``` YativoError ├── AuthenticationError (HTTP 401) ├── AuthorizationError (HTTP 403) ├── ValidationError (HTTP 422) — has .errors: list[dict] ├── NotFoundError (HTTP 404) — has .resource_id: str ├── RateLimitError (HTTP 429) — has .retry_after: int └── ServerError (HTTP 5xx) ``` *** ## Async Support The synchronous client is recommended for most use cases. An async variant is available for high-throughput applications running on an event loop (FastAPI, asyncio). ```python theme={null} import asyncio from yativo.async_client import AsyncYativoSDK async def main(): sdk = AsyncYativoSDK( api_key=os.environ["YATIVO_API_KEY"], api_secret=os.environ["YATIVO_API_SECRET"], ) wallets = await sdk.assets.list() print(wallets) asyncio.run(main()) ``` *** ## Django / Flask Integration Example ```python theme={null} # settings.py (Django) or app config (Flask) YATIVO_API_KEY = os.environ["YATIVO_API_KEY"] YATIVO_API_SECRET = os.environ["YATIVO_API_SECRET"] # views.py from django.http import JsonResponse from yativo import YativoSDK from yativo.exceptions import YativoError import uuid sdk = YativoSDK( api_key=settings.YATIVO_API_KEY, api_secret=settings.YATIVO_API_SECRET, ) def send_payment(request): try: tx = sdk.transactions.send( from_wallet_id=request.POST["wallet_id"], to_address=request.POST["to_address"], amount=request.POST["amount"], asset="USDC", network="SOLANA", idempotency_key=str(uuid.uuid4()), ) return JsonResponse({"transaction_id": tx["id"], "status": tx["status"]}) except YativoError as e: return JsonResponse({"error": str(e)}, status=400) ``` # React SDK Source: https://docs.yativo.com/sdks/react Complete guide for @yativo/crypto-sdk-react — provider setup, hooks, pre-built components, widgets, and theme customization # React SDK The `@yativo/crypto-sdk-react` package wraps the TypeScript SDK with React hooks and pre-built components, giving you managed authentication state, data-fetching hooks, and drop-in UI widgets. [![npm version](https://img.shields.io/npm/v/@yativo/crypto-sdk-react?label=npm\&color=CB3837)](https://www.npmjs.com/package/@yativo/crypto-sdk-react) [![npm weekly downloads](https://img.shields.io/npm/dw/@yativo/crypto-sdk-react?color=CB3837)](https://www.npmjs.com/package/@yativo/crypto-sdk-react) ## Installation ```bash theme={null} npm install @yativo/crypto-sdk-react # or yarn add @yativo/crypto-sdk-react ``` **Package:** [`@yativo/crypto-sdk-react`](https://www.npmjs.com/package/@yativo/crypto-sdk-react) · **Latest:** `1.0.2` · **Requirements:** React 17 or higher. The TypeScript SDK (`@yativo/crypto-sdk`) is installed automatically as a peer dependency. *** ## Provider Setup Wrap your application (or the relevant subtree) with `YativoProvider`. This creates the SDK instance and makes it available to all hooks and components below. Never expose `apiSecret` in client-side code. Do not use `NEXT_PUBLIC_YATIVO_API_SECRET` or any environment variable that gets bundled into the browser. For React apps, use passwordless login (`sdk.auth.login` + `sdk.auth.verifyOTP`) for client-side auth — or have your backend exchange API key credentials and return a short-lived access token to the frontend. ```tsx theme={null} // app.tsx (or _app.tsx in Next.js) import { YativoProvider } from "@yativo/crypto-sdk-react"; export default function App({ children }: { children: React.ReactNode }) { return ( {children} ); } ``` *** ## `useYativo()` — Authentication & SDK Access Login is passwordless and happens in two steps: send an OTP with `login(email)`, then verify it with `verifyOTP(otp, email)`. ```tsx theme={null} import { useYativo } from "@yativo/crypto-sdk-react"; function LoginForm() { const { sdk, user, logout } = useYativo(); const [email, setEmail] = React.useState(""); const [otp, setOtp] = React.useState(""); const [step, setStep] = React.useState<"email" | "otp">("email"); const [error, setError] = React.useState(null); async function handleSendOtp(e: React.FormEvent) { e.preventDefault(); try { await sdk.auth.login(email); setStep("otp"); } catch (err: any) { setError(err.message); } } async function handleVerifyOtp(e: React.FormEvent) { e.preventDefault(); try { await sdk.auth.verifyOTP(otp, email); } catch (err: any) { setError(err.message); } } if (user) { return (

Welcome, {user.email}

); } if (step === "otp") { return (
{error &&

{error}

}

Enter the OTP sent to {email}

setOtp(e.target.value)} placeholder="6-digit OTP" />
); } return (
{error &&

{error}

} setEmail(e.target.value)} placeholder="Email" />
); } ``` ### Hook Return Values | Property | Type | Description | | -------- | -------------- | --------------------------------------- | | `sdk` | `YativoSDK` | The underlying TypeScript SDK instance | | `client` | `YativoSDK` | Alias for `sdk` | | `user` | `User \| null` | Currently authenticated user, or `null` | | `logout` | `() => void` | Clear session | *** ## `useWallets()` — Create and List Wallets ```tsx theme={null} import { useWallets } from "@yativo/crypto-sdk-react"; function WalletManager({ accountId }: { accountId: string }) { const { wallets, loading, error, createWallet, refresh } = useWallets(accountId); async function handleCreate() { await createWallet({ asset: "USDC", network: "SOLANA" }); } if (loading) return

Loading wallets...

; if (error) return

Error: {error.message}

; return (
    {wallets.map((w) => (
  • {w.asset} ({w.network}): {w.address}
  • ))}
); } ``` *** ## `useTransactions()` — Send and List Transactions ```tsx theme={null} import { useTransactions } from "@yativo/crypto-sdk-react"; function TransactionHistory({ accountId }: { accountId: string }) { const { transactions, total, loading, error, sendFunds, refresh } = useTransactions({ accountId, limit: 20 }); async function handleSend() { await sendFunds({ fromWalletId: "wallet_xyz789", toAddress: "BjhiXKt...", amount: "50.00", asset: "USDC", network: "SOLANA", }); refresh(); } if (loading) return

Loading transactions...

; return (

Total transactions: {total}

    {transactions.map((tx) => (
  • {tx.amount} {tx.asset} — {tx.status} — {tx.createdAt}
  • ))}
); } ``` *** ## `useBalance()` — Auto-Refreshing Balance Display ```tsx theme={null} import { useBalance } from "@yativo/crypto-sdk-react"; function BalanceDisplay({ assetId }: { assetId: string }) { // Auto-refresh every 30 seconds const { balance, asset, loading, error } = useBalance( assetId, true, // autoRefresh 30000 // interval in ms ); if (loading) return ...; if (error) return Error loading balance; return (
{balance} {asset}
); } ``` *** ## `useCards()` — Card Management ```tsx theme={null} import { useCards } from "@yativo/crypto-sdk-react"; function CardDashboard({ cardholderId }: { cardholderId: string }) { const { cards, loading, createCard, freezeCard, unfreezeCard } = useCards(); async function handleCreateCard() { await createCard({ cardholderId, currency: "USD", label: "Travel expenses", }); } if (loading) return

Loading cards...

; return (
{cards.map((card) => (

•••• {card.last4}

Expires: {card.expiry}

Status: {card.status}

{card.status === "ACTIVE" ? ( ) : ( )}
))}
); } ``` *** ## `useSwap()` — Swap Functionality ```tsx theme={null} import { useSwap } from "@yativo/crypto-sdk-react"; function SwapForm() { const { getQuote, executeSwap, loading, quote, result } = useSwap(); const [amount, setAmount] = React.useState("100"); async function handleQuote() { await getQuote({ fromAsset: "USDC", toAsset: "XDC", amount, network: "SOLANA", }); } async function handleExecute() { if (!quote) return; await executeSwap({ quoteId: quote.id, fromWalletId: "wallet_xyz789", toWalletId: "wallet_xdc001", }); } return (
setAmount(e.target.value)} placeholder="Amount USDC" /> {quote && (

You receive: {quote.toAmount} XDC

Rate: {quote.rate}

Fee: {quote.fee} USDC

)} {result &&

Swap complete! Status: {result.status}

}
); } ``` *** ## `useStandaloneIban()` — IBAN Management ```tsx theme={null} import { useStandaloneIban } from "@yativo/crypto-sdk-react"; function IbanManager({ customerId }: { customerId: string }) { const { ibans, loading, createIban } = useStandaloneIban(); async function handleCreate() { await createIban({ customerId, currency: "EUR", label: "EU Collections", }); } return (
{ibans.map((iban) => (

IBAN: {iban.iban}

BIC: {iban.bic}

))}
); } ``` *** ## `useGasStations()` — Gas Station Management ```tsx theme={null} import { useGasStations } from "@yativo/crypto-sdk-react"; function GasStationDashboard() { const { stations, loading, createStation } = useGasStations(); async function handleCreate() { await createStation({ network: "SOLANA", sponsorType: "ALL_WALLETS", }); } return (
{stations.map((s) => (

Network: {s.network}

Balance: {s.balance}

Status: {s.status}

))}
); } ``` *** ## `useAutoForwarding()` — Auto-Forwarding Rules ```tsx theme={null} import { useAutoForwarding } from "@yativo/crypto-sdk-react"; function AutoForwardingManager() { const { rules, loading, createRule, updateRule, deleteRule } = useAutoForwarding(); async function handleCreate() { await createRule({ sourceWalletId: "wallet_xyz789", destinationAddress: "BjhiXKt...", asset: "USDC", network: "SOLANA", minAmount: "10.00", }); } if (loading) return

Loading rules...

; return (
{rules.map((rule) => (

{rule.asset} on {rule.network} → {rule.destinationAddress}

))}
); } ``` *** ## `DepositWidget` — Embedded Deposit UI The `DepositWidget` renders a complete deposit flow: it displays a QR code, network selector, and deposit address — with real-time confirmation updates. ```tsx theme={null} import { DepositWidget } from "@yativo/crypto-sdk-react"; function DepositPage({ walletId }: { walletId: string }) { return ( { console.log("Deposit confirmed:", deposit.amount, deposit.asset); }} theme={{ primaryColor: "#6366f1", backgroundColor: "#ffffff", borderRadius: "12px", }} /> ); } ``` *** ## `YativoCardWidget` — Embedded Card Display The card widget renders sensitive card details (PAN, CVV, expiry) inside a secure sandboxed iframe. Card data never touches your JavaScript. Your backend requests a `secure_view_url` and passes it to the client — never pass API credentials to client-side components. ```tsx theme={null} import { YativoCardWidget } from "@yativo/crypto-sdk-react"; // secureViewUrl must come from your backend: // const { secure_view_url } = await sdk.cards.getCardViewToken({ yativoCardId, cardId }) function CardViewer({ secureViewUrl }: { secureViewUrl: string }) { return (
console.log("Card widget ready")} onError={(err) => console.error("Widget error:", err)} />
); } ``` *** ## Pre-Built UI Components The React SDK ships utility components styled to match the Yativo design system: ```tsx theme={null} import { YativoButton, YativoCard, YativoInput, YativoLogo, } from "@yativo/crypto-sdk-react"; function ExamplePage() { return ( {}}> Send Funds {}}> Cancel ); } ``` *** ## Theme Customization Pass a `theme` object to `YativoProvider` to apply a global theme to all SDK components and widgets: ```tsx theme={null} {children} ``` Individual components and widgets accept their own `theme` prop which merges with (and overrides) the global theme. *** ## Complete Example — Next.js Dashboard Page ```tsx theme={null} // pages/dashboard.tsx import { useYativo, useWallets, useBalance, useTransactions, DepositWidget, YativoCardWidget, } from "@yativo/crypto-sdk-react"; const ACCOUNT_ID = "acct_abc123"; const WALLET_ID = "wallet_xyz789"; const CARD_ID = "card_mno345"; export default function Dashboard() { const { user, logout } = useYativo(); const { wallets, loading: wLoad } = useWallets(ACCOUNT_ID); const { balance } = useBalance(WALLET_ID, true, 15000); const { transactions } = useTransactions({ accountId: ACCOUNT_ID, limit: 5 }); if (!user) return

Please log in.

; return (

Hello, {user.firstName}

USDC Balance: {balance}

Wallets ({wallets.length})

{wLoad ? (

Loading...

) : ( wallets.map((w) => (

{w.asset} — {w.address}

)) )}

Deposit

alert(`Received ${d.amount} ${d.asset}`)} />

My Card

Recent Transactions

    {transactions.map((tx) => (
  • {tx.amount} {tx.asset} — {tx.status}
  • ))}
); } ``` # TypeScript / Node.js SDK Source: https://docs.yativo.com/sdks/typescript Complete guide for @yativo/crypto-sdk — installation, authentication, all resources, card widget, webhooks, and error handling # TypeScript / Node.js SDK The `@yativo/crypto-sdk` package is the official TypeScript SDK for the Yativo Crypto API. It ships with full TypeScript typings, automatic token refresh, rate-limit handling, and an embeddable card widget. [![npm version](https://img.shields.io/npm/v/@yativo/crypto-sdk?label=npm\&color=CB3837)](https://www.npmjs.com/package/@yativo/crypto-sdk) [![npm weekly downloads](https://img.shields.io/npm/dw/@yativo/crypto-sdk?color=CB3837)](https://www.npmjs.com/package/@yativo/crypto-sdk) ## Installation ```bash theme={null} npm install @yativo/crypto-sdk # or yarn add @yativo/crypto-sdk # or pnpm add @yativo/crypto-sdk ``` **Package:** [`@yativo/crypto-sdk`](https://www.npmjs.com/package/@yativo/crypto-sdk) · **Latest:** `1.0.3` · **Requirements:** Node.js 16+ or a modern browser bundler (Webpack, Vite, esbuild). *** ## Quick Start ```typescript theme={null} import { YativoSDK } from "@yativo/crypto-sdk"; const sdk = new YativoSDK({ baseURL: "https://crypto-api.yativo.com/api/v1/", }); // Register a new user await sdk.auth.register({ email: "user@example.com", password: "SecurePass123!", firstName: "Ada", lastName: "Lovelace", }); // Step 1 — Send OTP to the user's email await sdk.auth.login("user@example.com"); // Step 2 — Verify the OTP to complete login // The SDK stores and auto-refreshes the token const session = await sdk.auth.verifyOTP("123456", "user@example.com"); console.log("Logged in:", session.user.email); ``` ```typescript theme={null} import { YativoSDK } from "@yativo/crypto-sdk"; const sdk = new YativoSDK({ apiKey: process.env.YATIVO_API_KEY, apiSecret: process.env.YATIVO_API_SECRET, baseURL: "https://crypto-api.yativo.com/api/v1/", }); // No login needed — the SDK signs every request automatically const wallets = await sdk.assets.list(); console.log("Wallets:", wallets); ``` *** ## Constructor Options ```typescript theme={null} interface YativoSDKOptions { /** API key for key-based authentication */ apiKey?: string; /** API secret for key-based authentication */ apiSecret?: string; /** Override the base URL (default: https://crypto-api.yativo.com/api/v1/) */ baseURL?: string; /** Request timeout in milliseconds (default: 30000) */ timeout?: number; /** Enable the IBAN feature (must be true to use sdk.standaloneIban) */ standaloneIbanEnabled?: boolean; } ``` *** ## Authentication (`sdk.auth`) ### Register ```typescript theme={null} const user = await sdk.auth.register({ email: "user@example.com", password: "SecurePass123!", firstName: "Ada", lastName: "Lovelace", phoneNumber: "+14155552671", // optional }); ``` ### Login (Passwordless) Login is passwordless. Call `login(email)` to send an OTP to the user, then call `verifyOTP(otp, email)` to complete authentication. The SDK stores the token internally and auto-refreshes on 401. ```typescript theme={null} // Step 1 — Send OTP await sdk.auth.login("user@example.com"); // Step 2 — Verify OTP to complete auth const session = await sdk.auth.verifyOTP("123456", "user@example.com"); // session.accessToken is stored internally; auto-refreshed on 401 ``` ### 2FA Setup (Google Authenticator) ```typescript theme={null} // Get QR code and secret for Google Authenticator setup const details = await sdk.auth.get2faDetails(); // details.qrCode — display this as a QR image // details.secret — manual entry fallback // Activate 2FA on the account await sdk.auth.enable2fa(); // Verify a TOTP code (use instead of verifyOTP when 2FA is enabled) const session = await sdk.auth.verify2FA("654321", "user@example.com"); ``` ### Passkey (WebAuthn) Auth ```typescript theme={null} // Get WebAuthn challenge const options = await sdk.auth.passkeyAuthOptions("user@example.com"); // Verify WebAuthn credential (pass the result from navigator.credentials.get) const session = await sdk.auth.passkeyAuthVerify(credential); ``` ### Exchange API Key for Bearer Token ```typescript theme={null} // Exchange API key + secret for a Bearer token (POST /auth/token) const { token } = await sdk.auth.getToken( process.env.YATIVO_API_KEY!, process.env.YATIVO_API_SECRET! ); ``` *** ## Accounts (`sdk.accounts`) ```typescript theme={null} // Create a new account const account = await sdk.accounts.create({ name: "Main Treasury", currency: "USD", }); // List all accounts const { accounts, total } = await sdk.accounts.list({ page: 1, limit: 20 }); // Get a single account const account = await sdk.accounts.get("acct_abc123"); ``` *** ## Assets / Wallets (`sdk.assets`) ### Create a Wallet ```typescript theme={null} const wallet = await sdk.assets.createWallet({ accountId: "acct_abc123", asset: "USDC", network: "SOLANA", }); console.log("Deposit address:", wallet.address); ``` ### Batch Create Wallets ```typescript theme={null} const wallets = await sdk.assets.batchCreate({ accountId: "acct_abc123", assets: [ { asset: "USDC", network: "SOLANA" }, { asset: "XDC", network: "XDC" }, { asset: "ETH", network: "ETHEREUM" }, ], }); ``` ### List Wallets ```typescript theme={null} const wallets = await sdk.assets.list({ accountId: "acct_abc123" }); ``` ### Check Balance ```typescript theme={null} const balance = await sdk.assets.getBalance({ walletId: "wallet_xyz789", }); console.log(`Balance: ${balance.amount} ${balance.asset}`); ``` *** ## Transactions (`sdk.transactions`) ### Send Funds (with Idempotency) ```typescript theme={null} const tx = await sdk.transactions.send({ fromWalletId: "wallet_xyz789", toAddress: "BjhiXKt...", amount: "100.00", asset: "USDC", network: "SOLANA", idempotencyKey: crypto.randomUUID(), // prevents double-sends on retry memo: "Invoice #INV-2026-001", }); console.log("Transaction ID:", tx.id, "Status:", tx.status); ``` ### Estimate Gas Fee ```typescript theme={null} const fee = await sdk.transactions.estimateGas({ fromWalletId: "wallet_xyz789", toAddress: "BjhiXKt...", amount: "100.00", asset: "USDC", network: "SOLANA", }); console.log(`Estimated fee: ${fee.fee} ${fee.feeAsset}`); ``` ### List Transactions ```typescript theme={null} const { transactions, total } = await sdk.transactions.list({ accountId: "acct_abc123", page: 1, limit: 25, status: "COMPLETED", // optional filter startDate: "2026-01-01", // optional endDate: "2026-03-31", // optional }); ``` ### Get a Transaction ```typescript theme={null} const tx = await sdk.transactions.get("txn_def456"); ``` *** ## Swap (`sdk.swap`) ```typescript theme={null} // Get a swap quote const quote = await sdk.swap.getQuote({ fromAsset: "USDC", toAsset: "XDC", amount: "500.00", network: "SOLANA", }); console.log(`You receive: ${quote.toAmount} XDC, rate: ${quote.rate}`); // Execute the swap (quote expires after ~30 seconds) const result = await sdk.swap.execute({ quoteId: quote.id, fromWalletId: "wallet_xyz789", toWalletId: "wallet_xdc001", }); console.log("Swap status:", result.status); ``` *** ## Cards (`sdk.cards`) ### Onboard a Cardholder ```typescript theme={null} const cardholder = await sdk.cards.onboard({ customerId: "cust_111", firstName: "Ada", lastName: "Lovelace", dateOfBirth: "1990-05-15", address: { line1: "1 Infinite Loop", city: "Cupertino", state: "CA", zip: "95014", country: "US", }, }); ``` ### Create a Virtual Card ```typescript theme={null} const card = await sdk.cards.create({ cardholderId: cardholder.id, currency: "USD", label: "Engineering expenses", }); console.log("Card ID:", card.id, "Last 4:", card.last4); ``` ### Get Card Funding Address ```typescript theme={null} const funding = await sdk.cards.getFundingAddress({ cardId: card.id }); console.log("Fund this card at:", funding.address, "on", funding.network); ``` ### Get Card Transactions ```typescript theme={null} const { transactions } = await sdk.cards.getTransactions({ cardId: card.id, page: 1, limit: 20, }); ``` *** ## Webhooks (`sdk.webhooks`) ### Create a Webhook ```typescript theme={null} const webhook = await sdk.webhooks.create({ url: "https://your-app.com/webhooks/yativo", events: ["transaction.completed", "deposit.received", "card.transaction"], secret: "whsec_your_generated_secret", }); console.log("Webhook ID:", webhook.id); ``` ### Verify a Webhook Signature Use this in your webhook receiver to confirm the payload came from Yativo: ```typescript theme={null} import { Webhooks } from "@yativo/crypto-sdk"; import express from "express"; const app = express(); app.post( "/webhooks/yativo", express.raw({ type: "application/json" }), (req, res) => { const signature = req.headers["x-yativo-signature"] as string; const isValid = Webhooks.verifySignature( req.body, // raw Buffer signature, process.env.YATIVO_WEBHOOK_SECRET! ); if (!isValid) { return res.status(401).send("Invalid signature"); } const event = JSON.parse(req.body.toString()); console.log("Received event:", event.type, event.data); res.sendStatus(200); } ); ``` ### List / Delete Webhooks ```typescript theme={null} const webhooks = await sdk.webhooks.list(); await sdk.webhooks.delete("wh_ghi789"); ``` *** ## API Keys (`sdk.apiKeys`) ```typescript theme={null} // Create an API key const key = await sdk.apiKeys.create({ key_name: "Production Server", scopes: ["transactions:read", "transactions:write", "wallets:read"], expires_in_days: 90, // optional allowed_ips: ["203.0.113.10"], // optional }); // Store key.secret securely — it is shown only once console.log("API Key:", key.key); console.log("API Secret:", key.secret); // List API keys const { keys } = await sdk.apiKeys.list(); // Revoke a key (simple DELETE — no 2FA token required) await sdk.apiKeys.revoke("key_jkl012"); ``` *** ## Auto-Forwarding (`sdk.autoForwarding`) Auto-forwarding rules automatically sweep incoming deposits to a destination address. ```typescript theme={null} // List all auto-forwarding rules const { rules } = await sdk.autoForwarding.list(); // Create a rule const rule = await sdk.autoForwarding.create({ sourceWalletId: "wallet_xyz789", destinationAddress: "BjhiXKt...", asset: "USDC", network: "SOLANA", minAmount: "10.00", // optional — only forward if amount >= this }); console.log("Rule ID:", rule.id); // Update a rule await sdk.autoForwarding.update(rule.id, { minAmount: "25.00" }); // Delete a rule await sdk.autoForwarding.delete(rule.id); ``` *** ## Customers (`sdk.customers`) ```typescript theme={null} const customer = await sdk.customers.create({ externalId: "usr_from_your_db", email: "customer@example.com", firstName: "Charles", lastName: "Babbage", kycLevel: "BASIC", }); const { customers } = await sdk.customers.list({ page: 1, limit: 50 }); const customer = await sdk.customers.get("cust_abc"); await sdk.customers.update("cust_abc", { kycLevel: "FULL" }); ``` *** ## Analytics (`sdk.analytics`) ```typescript theme={null} const report = await sdk.analytics.getSummary({ accountId: "acct_abc123", startDate: "2026-01-01", endDate: "2026-03-31", }); console.log("Total volume:", report.totalVolume); console.log("Total fees:", report.totalFees); ``` *** ## IBAN (`sdk.standaloneIban`) You must set `standaloneIbanEnabled: true` in the constructor to use this resource. Attempting to call these methods without the feature flag will throw a `FeatureNotEnabledError`. ```typescript theme={null} const sdk = new YativoSDK({ apiKey: process.env.YATIVO_API_KEY, apiSecret: process.env.YATIVO_API_SECRET, standaloneIbanEnabled: true, }); const iban = await sdk.standaloneIban.create({ customerId: "cust_111", currency: "EUR", label: "EU Collections", }); console.log("IBAN:", iban.iban, "BIC:", iban.bic); const ibans = await sdk.standaloneIban.list({ customerId: "cust_111" }); ``` *** ## Card Widget — `YativoCardEmbed` The card widget displays sensitive card details (PAN, CVV, expiry) inside a secure sandboxed iframe. Card data never touches your JavaScript. Card data is displayed via a **Yativo-hosted secure page** — your backend requests a URL, your frontend opens it. No SDK widget to mount, no sensitive token to handle client-side. **Step 1 — Request a secure view URL on your server:** ```typescript theme={null} // Server-side only (Node.js / backend route) const view = await sdk.cards.getCardViewToken({ yativoCardId: "yc_abc123", cardId: "card_mno345", enabledViews: ["data", "pin"], theme: { accentColor: "#6366f1", logoUrl: "https://yourapp.com/logo.png", }, }); // Send view.secureViewUrl to your frontend ``` **Step 2 — Open the URL for the cardholder:** ```typescript theme={null} // In your frontend — open in iframe, WebView, or new tab const iframe = document.createElement("iframe"); iframe.src = secureViewUrlFromServer; iframe.width = "420"; iframe.height = "740"; iframe.style.border = "0"; document.getElementById("card-container").appendChild(iframe); ``` ```html theme={null} ``` Always request a fresh URL immediately before showing it. Never cache or reuse a previous `secure_view_url`. See [Get Secure Card View URL](/api-reference/cards/customer-secure-view). *** ## Error Handling ```typescript theme={null} import { YativoError, AuthenticationError, ValidationError, RateLimitError, NotFoundError, } from "@yativo/crypto-sdk"; try { await sdk.transactions.send({ /* ... */ }); } catch (err) { if (err instanceof AuthenticationError) { // Token expired and could not be refreshed, or API key invalid console.error("Auth failed:", err.message); } else if (err instanceof ValidationError) { // Request body failed server-side validation console.error("Validation errors:", err.errors); } else if (err instanceof RateLimitError) { // 60 req/min per endpoint limit exceeded const retryAfter = err.retryAfter; // seconds until the window resets console.warn(`Rate limited. Retry after ${retryAfter}s`); } else if (err instanceof NotFoundError) { console.error("Resource not found:", err.resourceId); } else if (err instanceof YativoError) { // Catch-all for other API errors console.error(`API error ${err.statusCode}:`, err.message); } else { throw err; // unexpected — re-throw } } ``` *** ## Rate Limiting The Yativo Crypto API allows **60 requests per minute per endpoint**. The SDK: 1. Throws `RateLimitError` when a `429` response is received. 2. Exposes `err.retryAfter` (seconds) so you can implement exponential back-off. ```typescript theme={null} import { RateLimitError } from "@yativo/crypto-sdk"; async function sendWithRetry(payload, maxRetries = 3) { for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await sdk.transactions.send(payload); } catch (err) { if (err instanceof RateLimitError && attempt < maxRetries) { const delay = (err.retryAfter ?? Math.pow(2, attempt)) * 1000; await new Promise((r) => setTimeout(r, delay)); } else { throw err; } } } } ``` *** ## TypeScript Interfaces Key types exported from the SDK: ```typescript theme={null} interface Wallet { id: string; accountId: string; asset: string; network: string; address: string; balance: string; createdAt: string; } interface Transaction { id: string; fromWalletId: string; toAddress: string; amount: string; asset: string; network: string; status: "PENDING" | "PROCESSING" | "COMPLETED" | "FAILED"; hash?: string; fee?: string; idempotencyKey?: string; createdAt: string; updatedAt: string; } interface SwapQuote { id: string; fromAsset: string; toAsset: string; fromAmount: string; toAmount: string; rate: string; fee: string; expiresAt: string; } interface Card { id: string; cardholderId: string; last4: string; expiry: string; currency: string; status: "ACTIVE" | "FROZEN" | "TERMINATED"; label?: string; createdAt: string; } ``` # Accounts Source: https://docs.yativo.com/yativo-crypto/accounts Create and manage accounts — containers for wallets and assets ```typescript theme={null} interface Account { account_id: string; account_name: string; account_type: string; user_id: string; created_at: string; updated_at: string; } interface CreateAccountRequest { account_name: string; account_type?: string; } ``` Accounts are the top-level organizational unit in Yativo Crypto. Each account holds a collection of wallets (assets) across one or more blockchains. You can create multiple accounts to separate concerns — for example, a treasury account, a hot wallet account, and a per-customer account. *** ## Create an Account **POST** `/accounts/create-account` A human-readable name for the account. The account type. Common values: `business`, `personal`, `customer`. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/accounts/create-account \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "account_name": "Main Treasury", "account_type": "business" }' ``` ```typescript TypeScript theme={null} const account = await client.accounts.create({ account_name: 'Main Treasury', account_type: 'business', }); ``` ```python Python theme={null} account = client.accounts.create( account_name='Main Treasury', account_type='business', ) ``` ```json Response theme={null} { "id": "acc_01abc123", "account_name": "Main Treasury", "account_type": "business", "status": "active", "created_at": "2026-03-26T10:00:00Z" } ``` *** ## Get All Accounts **GET** `/accounts/get-accounts` Returns all accounts belonging to the authenticated user. ```bash cURL theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/accounts/get-accounts \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```typescript TypeScript theme={null} const accounts = await client.accounts.list(); ``` ```python Python theme={null} accounts = client.accounts.list() ``` ```json Response theme={null} { "accounts": [ { "id": "acc_01abc123", "account_name": "Main Treasury", "account_type": "business", "status": "active", "asset_count": 4, "created_at": "2026-03-26T10:00:00Z" }, { "id": "acc_02def456", "account_name": "Hot Wallet", "account_type": "business", "status": "active", "asset_count": 2, "created_at": "2026-03-20T08:00:00Z" } ] } ``` *** ## Get User Accounts **POST** `/accounts/get-user-accounts` Returns accounts for a specific sub-user or B2B customer. Used when managing accounts on behalf of your customers. The ID of the user or customer whose accounts you want to retrieve. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/accounts/get-user-accounts \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"user_id": "usr_cust_01xyz"}' ``` ```json Response theme={null} { "user_id": "usr_cust_01xyz", "accounts": [ { "id": "acc_cust_01abc", "account_name": "Customer Wallet", "account_type": "customer", "status": "active", "created_at": "2026-03-10T12:00:00Z" } ] } ``` *** ## Create Connections **POST** `/accounts/create-connections` Connect an account to one or more blockchain networks. This initializes address generation for the specified chains on that account. The ID of the account to connect. Array of chain identifiers to connect. See [Supported Chains](/yativo-crypto/supported-chains) for valid values. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/accounts/create-connections \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "account_id": "acc_01abc123", "chains": ["ethereum", "solana", "polygon"] }' ``` ```json Response theme={null} { "account_id": "acc_01abc123", "connections": [ { "chain": "ethereum", "status": "connected", "connected_at": "2026-03-26T10:02:00Z" }, { "chain": "solana", "status": "connected", "connected_at": "2026-03-26T10:02:00Z" }, { "chain": "polygon", "status": "connected", "connected_at": "2026-03-26T10:02:00Z" } ] } ``` *** ## Get Connections **GET** `/accounts/get-connections` Returns blockchain connections for an account. Filter connections by account ID. If omitted, returns connections for all accounts. ```bash cURL theme={null} curl -X GET "https://crypto-api.yativo.com/api/v1/accounts/get-connections?account_id=acc_01abc123" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```json Response theme={null} { "connections": [ { "account_id": "acc_01abc123", "chain": "ethereum", "status": "connected", "connected_at": "2026-03-26T10:02:00Z" }, { "account_id": "acc_01abc123", "chain": "solana", "status": "connected", "connected_at": "2026-03-26T10:02:00Z" } ] } ``` *** ## Account Hierarchy Accounts belong to your platform. Within an account, you add [Assets (wallets)](/yativo-crypto/assets) for specific chains and tokens. For B2B scenarios, use [Customers](/yativo-crypto/customers) to create managed sub-accounts that belong to your end customers. ``` Your Platform ├── Account: Main Treasury │ ├── Asset: ETH (Ethereum) │ ├── Asset: USDC (Ethereum) │ └── Asset: SOL (Solana) └── Account: Customer 001 ├── Asset: USDC_SOL (Solana) └── Asset: USDT_POLYGON (Polygon) ``` *** ## Sandbox Testing Use the sandbox to test this endpoint without real funds: Sandbox URL: `https://crypto-sandbox.yativo.com/api/v1/` ```bash cURL theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/accounts/create-account' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "account_name": "Sandbox Treasury", "account_type": "business" }' ``` ```typescript TypeScript SDK theme={null} const sdk = new YativoSDK({ baseURL: 'https://crypto-sandbox.yativo.com/api/v1/', apiKey: 'YOUR_SANDBOX_API_KEY', apiSecret: 'YOUR_SANDBOX_API_SECRET', }); const account = await sdk.accounts.create({ account_name: 'Sandbox Treasury', account_type: 'business', }); console.log('Account ID:', account.id); ``` # Agentic Wallets Source: https://docs.yativo.com/yativo-crypto/agentic-wallets Programmable wallets for AI agents — send crypto, pay for x402 APIs, and track spending with full audit trails Agentic Wallets give AI agents their own self-custodial crypto wallets. Each wallet is a programmable spending account that AI services can use to send payments, pay for x402 paywalled APIs, and keep an immutable audit trail of every dollar spent. Built for the agentic economy — where AI agents need to pay for services, tools, and data autonomously. *** ## How It Works Create an agentic wallet from the dashboard or via API. Each wallet gets its own on-chain address with USDC funding support. Activate the wallet using email OTP and/or TOTP verification. This ensures only the wallet owner can authorize the wallet for agent use. Generate API keys (connectors) that your AI agent uses to authenticate. Each connector can have its own spending limits and permissions. Deposit USDC into the wallet's on-chain address, or use the manual funding endpoint to top up from your main account. The agent uses its connector API key to send payments, pay for x402 APIs, and check balances — all with per-transaction audit trails. *** ## Key Features Each connector gets a unique API key (`yac_...`) with configurable spending limits. Revoke a connector without affecting the wallet. Built-in support for the x402 payment protocol. Your agent can fetch paywalled APIs and the wallet auto-pays the 402 response. Set per-transaction, daily, and monthly limits at the wallet level and per connector. Enforce budget controls before the agent can overspend. Every transaction records the service name, URL, payment reason, and category. Built for compliance and cost attribution. Configure automatic top-ups when the wallet balance drops below a threshold. Funds are pulled from your main account. Wallets support USDC across multiple chains. Pay services on any supported network. *** ## Wallet Lifecycle ```mermaid theme={null} stateDiagram-v2 [*] --> Created: POST /agentic-wallets/create Created --> Activating: Send OTP Activating --> Active: Verify OTP + Activate Active --> Active: Transact, fund, add connectors Active --> Deactivated: POST /deactivate Deactivated --> [*] ``` | Status | Description | | ------------- | ------------------------------------------------------- | | `created` | Wallet exists but cannot transact until activated | | `activating` | OTP verification in progress | | `active` | Fully operational — agents can transact | | `suspended` | Temporarily halted by admin (e.g., suspicious activity) | | `deactivated` | Permanently disabled by the owner | *** ## Connectors Connectors are API keys tied to a specific wallet. Think of them as "agent credentials" — each AI agent or service integration gets its own connector. | Field | Description | | ----------------------- | --------------------------------------------------------- | | `name` | Human-readable label (e.g., "Production Agent") | | `api_key` | Starts with `yac_` — used by the agent for authentication | | `per_transaction_limit` | Max USD amount per single transaction | | `daily_limit` | Max USD amount per 24-hour period | | `monthly_limit` | Max USD amount per calendar month | | `status` | `active` or `revoked` | You can have multiple connectors per wallet for different agents or environments. *** ## Agent API Once a connector is active, the agent authenticates with its API key and hits the Agent API directly: | Endpoint | Description | | ------------------------- | --------------------------------------- | | `POST /agent/transact` | Send a crypto payment | | `GET /agent/balance` | Check wallet balance | | `GET /agent/transactions` | List recent transactions | | `POST /agent/x402-fetch` | Fetch a URL with automatic x402 payment | ### Send a Payment ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/agent/transact' \ -H 'Authorization: Bearer yac_connector_api_key' \ -H 'Content-Type: application/json' \ -d '{ "wallet_id": "aw_01abc123", "amount": 5.00, "asset": "USDC", "recipient_address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "service_name": "OpenAI API", "service_url": "https://api.openai.com", "payment_reason": "GPT-4 inference for customer support bot", "payment_category": "ai_service" }' ``` ```json Response theme={null} { "success": true, "data": { "transaction_id": "atx_01pqr456", "tx_hash": "0xabc123...", "amount": 5.00, "asset": "USDC", "recipient_address": "0x9F8b...", "chain": "base", "status": "completed", "fee": 0.00, "is_free_transaction": true } } ``` ### x402 Protocol Fetch The x402 protocol enables HTTP-native micropayments. When your agent fetches a URL that returns HTTP 402 (Payment Required), the wallet automatically pays and retries: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/agent/x402-fetch' \ -H 'Authorization: Bearer yac_connector_api_key' \ -H 'Content-Type: application/json' \ -d '{ "wallet_id": "aw_01abc123", "url": "https://api.example.com/premium-data", "method": "GET" }' ``` ```json Response theme={null} { "success": true, "data": { "status": 200, "paid": true, "payment": { "amount_usd": 0.01, "asset": "USDC", "network": "base", "pay_to": "0x..." }, "body": { "premium_data": "..." } } } ``` *** ## Payment Categories Every agent transaction requires a `payment_category` for audit and analytics: | Category | Use Case | | ------------------- | ---------------------------------------------------- | | `ai_service` | Paying for AI model inference, embeddings, etc. | | `prediction_market` | Placing bets or funding prediction contracts | | `legal_escrow` | Escrow payments for legal or contractual obligations | | `subscription` | Recurring service subscriptions | | `purchase` | One-time purchases or API credits | | `transfer` | Wallet-to-wallet transfers | | `settlement` | Settling invoices or outstanding balances | | `other` | Anything not covered above | *** ## Pricing Agentic wallet pricing is tier-based. Check the current pricing: ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/agentic-wallets/pricing' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` Each plan includes a number of free transactions per month. Transactions beyond the free tier incur a small per-transaction fee. *** ## MCP Server Integration For AI agents using the Model Context Protocol, install the [`@yativo/mcp-server`](/sdks/mcp) package. It exposes agentic wallet operations as MCP tools that any MCP-compatible AI agent can call directly. *** ## Next Steps Full endpoint reference for all agentic wallet operations. Connect AI agents via the Model Context Protocol. Test agentic wallets in the sandbox environment. Get notified on agent transaction events. # Analytics Source: https://docs.yativo.com/yativo-crypto/analytics Transaction analytics and dashboard metrics for your platform The Analytics API provides aggregated metrics about your platform's transaction activity and overall account health. Use these endpoints to build internal dashboards, generate reports, or power analytics widgets in your product. ```typescript theme={null} interface TransactionAnalytics { total_volume_usd: string; total_transactions: number; successful_transactions: number; failed_transactions: number; average_transaction_usd: string; volume_by_chain: Record; volume_by_status: Record; period: string; } interface DashboardAnalytics { total_assets: number; total_balance_usd: string; recent_transactions: Transaction[]; wallets_by_chain: Record; } ``` *** ## Transaction Analytics **GET** `/analytics/transaction-analytics` Returns aggregated transaction data — volumes, counts, success rates, and trends over time. ```bash cURL theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/analytics/transaction-analytics \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```json Response theme={null} { "period": "last_30_days", "summary": { "total_transactions": 1842, "total_volume_usd": "2450000.00", "successful_transactions": 1821, "failed_transactions": 21, "success_rate": "98.86%" }, "by_chain": [ { "chain": "ethereum", "transaction_count": 620, "volume_usd": "980000.00" }, { "chain": "solana", "transaction_count": 890, "volume_usd": "1100000.00" }, { "chain": "polygon", "transaction_count": 332, "volume_usd": "370000.00" } ], "by_type": { "deposits": 1020, "withdrawals": 822 }, "daily_volumes": [ { "date": "2026-03-25", "volume_usd": "82000.00", "transaction_count": 61 }, { "date": "2026-03-26", "volume_usd": "95000.00", "transaction_count": 74 } ] } ``` *** ## Dashboard Analytics **GET** `/analytics/dashboard-analytics` Returns a high-level snapshot for dashboard display: current balances, recent activity, customer counts, and key performance indicators. ```bash cURL theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/analytics/dashboard-analytics \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```json Response theme={null} { "account_summary": { "total_assets": 24, "total_balance_usd": "145000.00", "active_customers": 87, "active_cards": 34 }, "recent_activity": { "transactions_today": 74, "volume_today_usd": "95000.00", "deposits_today": 45, "withdrawals_today": 29 }, "top_chains": [ { "chain": "solana", "volume_usd": "52000.00" }, { "chain": "ethereum", "volume_usd": "28000.00" }, { "chain": "polygon", "volume_usd": "15000.00" } ], "gas_station_status": [ { "chain": "solana", "balance_native": "8.5", "balance_usd": "1225.00", "status": "healthy" }, { "chain": "ethereum", "balance_native": "0.12", "balance_usd": "300.00", "status": "low" } ] } ``` *** ## Using Analytics in Your Dashboard Cache analytics responses for 1–5 minutes. These are aggregated metrics that don't need to be fetched on every page load. For real-time transaction status, use webhooks instead. The `gas_station_status` field in the dashboard analytics gives you a quick health check of all your gas stations. Treat `"status": "low"` as an alert to top up before the station runs empty. *** ## Common Use Cases Use `transaction-analytics` with the `by_chain` breakdown to generate per-chain volume reports for your finance team or investors. Combine `dashboard-analytics` (for totals) with `customers/get-customer-transactions` (for per-customer drill-down) to build a full customer activity view. The `gas_station_status` array in dashboard analytics is the fastest way to check gas levels across all chains in a single request. Automate an alert when any station shows `"low"` or `"critical"`. The `daily_volumes` array in transaction analytics gives you the raw data to render charts. Fetch it daily and store it in your own database to build longer historical views. # API Keys Source: https://docs.yativo.com/yativo-crypto/api-keys Manage API credentials for server-to-server Yativo Crypto integrations API keys are the recommended authentication method for Yativo Crypto integrations. They let your server authenticate programmatically without user sessions, and can be scoped to the minimum permissions your integration requires. 2FA must be enabled on your account before you can create API keys. All key management operations require a current TOTP code in the `X-2FA-Token` header. *** ## Crypto-Relevant Permissions | Permission | What It Unlocks | | -------------- | ---------------------------------------------------------------------- | | `read` | Read balances, transaction history, asset info, analytics | | `write` | Create accounts, add wallets, configure gas stations, manage customers | | `transactions` | Initiate sends, execute swaps, fund cards | | `webhooks` | Create and manage webhook subscriptions | For most Yativo Crypto server integrations, you'll want `read`, `write`, and `transactions` at minimum. *** ## Create an API Key **POST** `/apikey/create` Current 6-digit TOTP code from your authenticator app. A descriptive name (e.g., "Crypto Backend — Production"). Array of permission scopes. Days until expiry. Omit for a non-expiring key. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/apikey/create \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "X-2FA-Token: 123456" \ -H "Content-Type: application/json" \ -d '{ "name": "Crypto Backend — Production", "permissions": ["read", "write", "transactions", "webhooks"], "expires_in_days": 365 }' ``` ```json Response theme={null} { "id": "key_01abc123", "name": "Crypto Backend — Production", "api_key": "yvk_live_...", "api_secret": "yvs_live_...", "permissions": ["read", "write", "transactions", "webhooks"], "expires_at": "2027-03-26T10:00:00Z", "created_at": "2026-03-26T10:00:00Z" } ``` The `api_secret` is only shown once. Store it in your secrets manager immediately. *** ## Authenticate with an API Key **Method 1: Exchange for Bearer token (recommended for production)** ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/apikey/token \ -H "Content-Type: application/json" \ -d '{ "api_key": "yvk_live_...", "api_secret": "yvs_live_..." }' ``` Use the returned `access_token` as `Authorization: Bearer {token}` on all subsequent requests. Refresh it before expiry using the same endpoint. **Method 2: Header-based (for simpler integrations)** ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/transactions/send-funds \ -H "X-API-Key: yvk_live_..." \ -H "X-API-Secret: yvs_live_..." \ -H "Content-Type: application/json" \ -d '{ ... }' ``` *** ## Server-to-Server Pattern Here's a complete server-to-server setup using the Bearer token method with auto-refresh: ```typescript theme={null} import { YativoCrypto } from '@yativo/sdk'; // The SDK handles token exchange and refresh automatically const yativo = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, apiSecret: process.env.YATIVO_API_SECRET!, // environment: 'sandbox', // uncomment for sandbox }); // All methods are authenticated automatically const accounts = await yativo.accounts.list(); const balance = await yativo.balance.check({ asset_id: 'asset_01xyz' }); ``` Without the SDK: ```typescript theme={null} class YativoClient { private token: string | null = null; private expiresAt = 0; private baseUrl = 'https://crypto-api.yativo.com/api'; constructor( private apiKey: string, private apiSecret: string ) {} async getHeaders(): Promise> { const token = await this.getToken(); return { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }; } private async getToken(): Promise { if (this.token && Date.now() < this.expiresAt - 60_000) { return this.token; } const res = await fetch(`${this.baseUrl}/apikey/token`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ api_key: this.apiKey, api_secret: this.apiSecret }), }); const { access_token, expires_in } = await res.json(); this.token = access_token; this.expiresAt = Date.now() + expires_in * 1000; return access_token; } } ``` *** ## Key Management | Operation | Endpoint | | ------------------ | ------------------------------------------------------- | | List all keys | `GET /apikey/list` | | Get a key | `GET /apikey/{id}` | | Revoke a key | `POST /apikey/{id}/revoke` (requires `X-2FA-Token`) | | Rotate secret | `POST /apikey/{id}/rotate` (requires `X-2FA-Token`) | | Update permissions | `PUT /apikey/{id}/permissions` (requires `X-2FA-Token`) | For full endpoint documentation, see the [API Keys reference](/yativo/api-keys). *** ## Best Practices for Crypto Integrations Create dedicated API keys for sandbox and production. Never use a production key for testing. A key used only for reading balances and transaction history should only have `read`. Only grant `transactions` to services that actually initiate transfers. Rotate API secrets periodically (e.g., every 90 days) and immediately if you suspect a key has been exposed. The `rotate` endpoint generates a new secret without requiring you to delete and recreate the key. Never hardcode API keys in source code. Use environment variables or a secrets manager and inject at runtime. # Assets & Wallets Source: https://docs.yativo.com/yativo-crypto/assets Add and manage crypto wallets for specific chains and tokens Assets are wallets tied to a specific blockchain and token within an account. Each asset has a unique deposit address and tracks its own balance. You can add individual assets or batch-create many at once. *** ## Get All Supported Assets **GET** `/assets/get-all-assets` Returns the full list of chains and tokens available on the platform. ```bash cURL theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/assets/get-all-assets \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```json Response theme={null} { "data": [ { "asset_name": "Binance Smart Chain", "asset_short_name": "BNB", "chain": "BSC", "chain_id": 56, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/825/large/bnb-icon2_2x.png", "active": true }, { "asset_name": "XDC Network", "asset_short_name": "XDC", "chain": "XDC", "chain_id": 50, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/2912/large/xdc-icon.png", "active": true }, { "asset_name": "Bitcoin", "asset_short_name": "BTC", "chain": "BTC", "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/1/large/bitcoin.png", "active": true }, { "asset_name": "Solana", "asset_short_name": "SOL", "chain": "SOL", "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/4128/large/solana.png", "active": true }, { "asset_name": "Ethereum on Base", "asset_short_name": "ETH", "chain": "Base", "chain_id": 8453, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/279/large/ethereum.png", "active": true }, { "asset_name": "Polygon", "asset_short_name": "POL", "chain": "POL", "chain_id": 137, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/32440/standard/pol.png", "active": true }, { "asset_name": "Optimism", "asset_short_name": "OP", "chain": "OP", "chain_id": 156, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/25244/standard/Token.png", "active": true }, { "asset_name": "Arbitrum", "asset_short_name": "ARB", "chain": "ARB", "chain_id": 84, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/16547/standard/arb.jpg", "active": true }, { "asset_name": "Tron", "asset_short_name": "TRX", "chain": "TRON", "chain_id": 8, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/1094/standard/tron-logo.png", "active": true }, { "asset_name": "Avalanche", "asset_short_name": "AVAX", "chain": "AVAX", "chain_id": 28, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/12559/standard/Avalanche_Circle_RedWhite_Trans.png", "active": true }, { "asset_name": "Tether USD (Polygon)", "asset_short_name": "USDT", "chain": "POL", "chain_id": 137, "network_type": "mainnet", "asset_type": "token", "token_standard": "ERC20", "contract_address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", "decimals": 6, "image": "https://assets.coingecko.com/coins/images/325/large/Tether.png", "active": true }, { "asset_name": "USD Coin (Solana)", "asset_short_name": "USDC", "chain": "SOL", "network_type": "mainnet", "asset_type": "token", "token_standard": "SPL", "contract_address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "decimals": 6, "image": "https://assets.coingecko.com/coins/images/6319/large/USD_Coin_icon.png", "active": true }, { "asset_name": "EURO Coin", "asset_short_name": "EURC", "chain": "SOL", "network_type": "mainnet", "asset_type": "token", "token_standard": "SPL", "contract_address": "HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr", "decimals": 6, "image": "https://assets.coingecko.com/coins/images/26045/large/euro.png", "active": true }, { "asset_name": "TIVO", "asset_short_name": "TIVO", "chain": "XDC", "network_type": "mainnet", "asset_type": "token", "token_standard": "XRC-20", "contract_address": "0x765087A2360F4D1F516De6552970256F9DB64827", "decimals": 18, "image": "https://tivotoken.com/wp-content/uploads/2024/11/Tivo-A2_040739-e1731947639142.png", "active": true }, { "asset_name": "USD Coin (Polygon)", "asset_short_name": "USDC", "chain": "POL", "chain_id": 137, "network_type": "mainnet", "asset_type": "token", "token_standard": "ERC20", "contract_address": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", "decimals": 6, "image": "https://assets.coingecko.com/coins/images/6319/large/USD_Coin_icon.png", "active": true }, { "asset_name": "Tether USD (Solana)", "asset_short_name": "USDT", "chain": "SOL", "network_type": "mainnet", "asset_type": "token", "token_standard": "SPL", "contract_address": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", "decimals": 6, "image": "https://assets.coingecko.com/coins/images/325/large/Tether.png", "active": true }, { "asset_name": "PayPal USD (PYUSD)", "asset_short_name": "PYUSD", "chain": "SOL", "network_type": "mainnet", "asset_type": "token", "token_standard": "SPL", "contract_address": "2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo", "decimals": 6, "image": "https://assets.coingecko.com/coins/images/31212/standard/PYUSD_Token_Logo_2x.png", "active": true }, { "asset_name": "Global Dollar (USDG)", "asset_short_name": "USDG", "chain": "SOL", "network_type": "mainnet", "asset_type": "token", "token_standard": "SPL", "contract_address": "2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH", "decimals": 6, "image": "https://assets.coingecko.com/coins/images/51281/standard/GDN_USDG_Token_200x200.png", "active": true }, { "asset_name": "Bridged USDC (XDC)", "asset_short_name": "USDC", "chain": "XDC", "chain_id": 50, "network_type": "mainnet", "asset_type": "token", "token_standard": "XRC20", "contract_address": "0xfA2958CB79b0491CC627c1557F441eF849Ca8eb1", "decimals": 6, "image": "https://xdcscan.com/token/images/usdc_ofc_32.svg", "active": true }, { "asset_name": "Gnosis Chain (xDAI)", "asset_short_name": "xDAI", "chain": "GNO", "chain_id": 100, "network_type": "mainnet", "asset_type": "native", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/11062/standard/Identity-Primary-DarkBG.png", "active": true }, { "asset_name": "Gnosis", "asset_short_name": "GNO", "chain": "GNO", "network_type": "mainnet", "asset_type": "token", "token_standard": "ERC20", "contract_address": "0x9C58BAcC331c9aa871AFD802DB6228953991E8a0", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/662/standard/logo_square_simple_300px.png", "active": true }, { "asset_name": "USD Coin Bridged (GNO)", "asset_short_name": "USDCe", "chain": "GNO", "chain_id": 100, "network_type": "mainnet", "asset_type": "token", "token_standard": "ERC20", "contract_address": "0x2a22f9c3b484c3629090FeED35F17Ff8F88f76F0", "decimals": 6, "image": "https://assets.coingecko.com/coins/images/6319/standard/usdc.png", "active": true }, { "asset_name": "Pound Sterling Bridged (GNO)", "asset_short_name": "GBPe", "chain": "GNO", "chain_id": 100, "network_type": "mainnet", "asset_type": "token", "token_standard": "ERC20", "contract_address": "0x5Cb9073902F2035222B9749F8fB0c9BFe5527108", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/39004/standard/gbp.png", "active": true }, { "asset_name": "Euro Bridged (GNO)", "asset_short_name": "EURe", "chain": "GNO", "chain_id": 100, "network_type": "mainnet", "asset_type": "token", "token_standard": "ERC20", "contract_address": "0x39b8B6385416f4cA36a20319F70D28621895279D", "decimals": 18, "image": "https://assets.coingecko.com/coins/images/23354/standard/eur.png?1696522569", "active": true } ], "status": true, "message": "Assets Listed Successfully" } ``` *** ## Get Supported Chains **GET** `/assets/get-chains` ```bash cURL theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/assets/get-chains \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` *** ## Add an Asset **POST** `/assets/add-asset` Creates a new wallet (deposit address) for a specific chain and token within an account. The account this wallet belongs to. The blockchain identifier (e.g., `ethereum`, `solana`). See [Supported Chains](/yativo-crypto/supported-chains). The token ticker (e.g., `USDC`, `SOL`). ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/add-asset \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "account_id": "acc_01abc123", "chain": "ethereum", "ticker": "USDC" }' ``` ```typescript TypeScript theme={null} const wallet = await client.assets.add({ account_id: 'acc_01abc123', chain: 'ethereum', ticker: 'USDC', }); console.log('Deposit address:', wallet.address); ``` ```python Python theme={null} wallet = client.assets.add( account_id='acc_01abc123', chain='ethereum', ticker='USDC', ) print('Deposit address:', wallet['address']) ``` ```json Response theme={null} { "id": "asset_01xyz789", "account_id": "acc_01abc123", "chain": "ethereum", "ticker": "USDC", "name": "USD Coin", "address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "balance": "0", "balance_usd": "0", "status": "active", "created_at": "2026-03-26T10:00:00Z" } ``` *** ## Batch Add Assets **POST** `/assets/batch-add-asset` Create multiple wallets in a single request. Useful when onboarding a new account that needs wallets across multiple chains. The account these wallets will belong to. Array of chain identifiers. Array of token tickers. Each ticker is paired with the corresponding chain by index. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/batch-add-asset \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "account_id": "acc_01abc123", "chains": ["ethereum", "solana", "polygon"], "tickers": ["USDC", "USDC_SOL", "USDC_POLYGON"] }' ``` ```json Response theme={null} { "created": [ { "id": "asset_01a", "chain": "ethereum", "ticker": "USDC", "address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1" }, { "id": "asset_02b", "chain": "solana", "ticker": "USDC_SOL", "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" }, { "id": "asset_03c", "chain": "polygon", "ticker": "USDC_POLYGON", "address": "0x8A7c4f2E9B1D3A6C5E0F7B2D4A9C8E1F3B5D7A9" } ] } ``` *** ## Get User Assets **POST** `/assets/get-user-assets` Returns all assets (wallets) for the authenticated user, or filtered by account. Filter assets by account. If omitted, returns all assets across all accounts. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/get-user-assets \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"account_id": "acc_01abc123"}' ``` ```json Response theme={null} { "assets": [ { "id": "asset_01xyz789", "account_id": "acc_01abc123", "chain": "ethereum", "ticker": "USDC", "address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "balance": "500.00", "balance_usd": "500.00", "status": "active" } ] } ``` *** ## Check Balance **POST** `/balance/check` Returns the current balance for a specific asset. The asset ID to check the balance for. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/balance/check \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"asset_id": "asset_01xyz789"}' ``` ```json Response theme={null} { "asset_id": "asset_01xyz789", "chain": "ethereum", "ticker": "USDC", "address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "balance": "500.00", "balance_usd": "500.00", "last_updated": "2026-03-26T10:05:00Z" } ``` *** ## Archive an Asset **POST** `/assets/archive-asset` Deactivates a wallet. The address remains valid for receiving funds, but the asset will no longer appear in active asset lists. The ID of the asset to archive. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/archive-asset \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"asset_id": "asset_01xyz789"}' ``` *** ## Add Customer Asset **POST** `/assets/add-customer-asset` Create a wallet for a specific B2B customer. See [Customers](/yativo-crypto/customers) for context on the customer model. The customer ID to create the wallet for. Blockchain identifier. Token ticker. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/add-customer-asset \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "customer_id": "cust_01abc", "chain": "solana", "ticker": "USDC_SOL" }' ``` *** ## Get Customer Assets **POST** `/assets/get-customer-assets` Returns all wallets for a B2B customer. Filter by customer. If omitted, returns assets for all customers. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/get-customer-assets \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"customer_id": "cust_01abc"}' ``` *** ## Supported Chains & Tickers Reference | Chain | Native | Stablecoins | | -------- | -------------- | -------------------------------- | | Ethereum | `ETH` | `USDC`, `USDT`, `DAI` | | Solana | `SOL` | `USDC_SOL`, `USDT_SOL` | | Bitcoin | `BTC` | — | | Polygon | `POL` | `USDC_POLYGON`, `USDT_POLYGON` | | BSC | `BNB` | `USDC_BSC`, `USDT_BSC` | | Base | `ETH_BASE` | `USDC_BASE` | | Arbitrum | `ETH_ARBITRUM` | `USDC_ARBITRUM`, `USDT_ARBITRUM` | | Optimism | `ETH_OPTIMISM` | `USDC_OPTIMISM`, `USDT_OPTIMISM` | | XDC | `XDC` | `USDC_XDC`, `USDT_XDC` | Deposit addresses are chain-specific. Never send a token to an address on the wrong chain — funds sent to the wrong network cannot be automatically recovered. # Authentication Source: https://docs.yativo.com/yativo-crypto/authentication Sign up at the Yativo Crypto dashboard, then use your API key and secret to authenticate all API calls with a Bearer token ## Step 1 — Create an account Sign up and log in from the Yativo Crypto dashboard. Authentication is **passwordless** — you enter your email and receive a one-time code; no password required. | Environment | Dashboard URL | | ----------- | -------------------------------------------------------------- | | Live | [crypto.yativo.com](https://crypto.yativo.com) | | Sandbox | [sandbox-crypto.yativo.com](https://sandbox-crypto.yativo.com) | Once logged in, go to **Settings → API Keys** to generate your credentials. *** ## Step 2 — Generate an API key From the dashboard (or via `POST /apikey/generate` once you already have a token), create an API key: * Give it a name and assign the **scopes** it needs (e.g. `wallets:read`, `transactions:write`) * Optionally set an expiry and restrict it to specific IP addresses * Copy the **API key** and **API secret** — the secret is shown **only once** Store the API secret securely (e.g. an environment variable or secrets manager). If you lose it, you must rotate the key. *** ## Step 3 — Exchange for a Bearer token All API endpoints require an `Authorization: Bearer ` header. Tokens expire after **60 minutes**; your API key never expires. ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/auth/token \ -H "Content-Type: application/json" \ -d '{ "api_key": "yativo_...", "api_secret": "..." }' ``` ```json Response theme={null} { "success": true, "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600, "expires_at": "2026-03-28T11:00:00.000Z" } ``` For sandbox, use the sandbox base URL: ```bash theme={null} curl -X POST https://crypto-sandbox.yativo.com/api/v1/auth/token \ -H "Content-Type: application/json" \ -d '{ "api_key": "yativo_...", "api_secret": "..." }' ``` *** ## Step 4 — Call the API Pass the access token in every request: ```bash theme={null} curl https://crypto-api.yativo.com/api/v1/accounts/get-accounts \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." ``` *** ## Auto-refresh pattern Tokens expire after 60 minutes. Implement a refresh helper so your integration never hits a 401: ```typescript theme={null} class YativoAuth { private token: string | null = null; private expiresAt: number = 0; constructor( private readonly apiKey: string, private readonly apiSecret: string, private readonly baseURL = 'https://crypto-api.yativo.com/api' ) {} async getToken(): Promise { // Reuse the token if it has more than 60 seconds left if (this.token && Date.now() < this.expiresAt - 60_000) { return this.token; } return this.refresh(); } private async refresh(): Promise { const res = await fetch(`${this.baseURL}/auth/token`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ api_key: this.apiKey, api_secret: this.apiSecret }), }); const { access_token, expires_in } = await res.json(); this.token = access_token; this.expiresAt = Date.now() + expires_in * 1000; return access_token; } } // Usage const auth = new YativoAuth(process.env.YATIVO_API_KEY, process.env.YATIVO_API_SECRET); const token = await auth.getToken(); // automatically refreshes when near expiry ``` The SDKs handle this automatically — see [SDKs](/sdks/overview). *** ## Scopes When generating an API key, assign only the scopes your integration needs: | Scope | Access | | -------------------- | ---------------------------- | | `wallets:read` | List wallets and balances | | `wallets:write` | Create wallets | | `transactions:read` | View transaction history | | `transactions:write` | Send funds | | `cards:read` | View card details | | `cards:write` | Issue and manage cards | | `swap:read` | Get swap quotes | | `swap:write` | Execute swaps | | `webhooks:write` | Create and manage webhooks | | `apikey:write` | Generate and rotate API keys | *** ## Environments | | Live | Sandbox | | -------------- | ---------------------------------------------- | -------------------------------------------------------------- | | Dashboard | [crypto.yativo.com](https://crypto.yativo.com) | [sandbox-crypto.yativo.com](https://sandbox-crypto.yativo.com) | | API base URL | `https://crypto-api.yativo.com/api` | `https://crypto-sandbox.yativo.com/api` | | Token endpoint | `POST /auth/token` | `POST /auth/token` | | Real funds | Yes | No — testnet only | Use separate API keys for live and sandbox. See [Sandbox](/sandbox/overview) for pre-populated test credentials. *** Register and log in via the dashboard only. The API does not expose public sign-up or password-based login endpoints — account creation and access management happen through the Yativo Crypto web interface. # Auto-Forwarding Source: https://docs.yativo.com/yativo-crypto/auto-forwarding Automatically forward incoming deposits to a destination address based on configurable rules Auto-Forwarding lets you create rules that automatically send incoming deposits from one wallet to another address. When crypto lands in a monitored wallet, the forwarding rule triggers and moves the funds to the destination — no manual intervention required. Use cases: treasury sweeping, payment collection, fund aggregation, and automated payouts. *** ## How It Works 1. **Create a rule** — Specify the source asset, destination address, and forwarding conditions 2. **Deposits arrive** — When crypto is deposited to the source wallet, the rule evaluates 3. **Funds forward** — If the deposit matches the rule conditions, funds are automatically sent to the destination *** ## Create a Forwarding Rule ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/auto-forwarding' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "asset_id": "asset_01xyz789", "destination_address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "destination_chain": "ethereum", "min_amount": "10.00", "enabled": true }' ``` ```json Response theme={null} { "success": true, "data": { "rule_id": "af_01abc123", "asset_id": "asset_01xyz789", "destination_address": "0x9F8b...", "destination_chain": "ethereum", "min_amount": "10.00", "enabled": true, "created_at": "2026-03-26T12:00:00Z" } } ``` *** ## Rule Parameters | Parameter | Type | Description | | --------------------- | ------- | ------------------------------------------------------- | | `asset_id` | string | The source wallet asset to monitor for deposits | | `destination_address` | string | Where to forward funds | | `destination_chain` | string | The chain of the destination address | | `min_amount` | string | Minimum deposit amount to trigger forwarding (optional) | | `enabled` | boolean | Whether the rule is active | *** ## List Rules ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/auto-forwarding' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Get Rule Details ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/auto-forwarding/af_01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Update a Rule ```bash theme={null} curl -X PUT 'https://crypto-api.yativo.com/api/v1/auto-forwarding/af_01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "min_amount": "50.00", "enabled": false }' ``` *** ## Delete a Rule ```bash theme={null} curl -X DELETE 'https://crypto-api.yativo.com/api/v1/auto-forwarding/af_01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Trigger Manual Forward Force an immediate forward for a rule, regardless of deposit conditions: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/auto-forwarding/forward' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "rule_id": "af_01abc123" }' ``` *** ## Forwarding Thresholds Yativo applies a minimum value threshold before executing a forward. This ensures the on-chain transfer cost is economical relative to the amount being moved. ### Per-wallet minimum (\$1 USD) Deposits with an equivalent value below \*\*$1 USD** are not forwarded immediately. Instead they accumulate in the source wallet until the cumulative total reaches $1 USD, at which point the entire accumulated balance is forwarded in a single transaction. This is automatic — no configuration is required. Your forwarding rule fires as normal; only the timing changes for sub-threshold deposits. **Example:** A wallet receives three deposits of $0.30 USDC each. The first two are held. After the third, the total ($0.90) is still below $1 and remains accumulated. The next deposit that pushes the total to or past $1 triggers the forward for the full accumulated amount. Your rule's `min_amount` field is evaluated against the transaction amount in token units and is separate from this USD threshold. Both conditions must be satisfied for a forward to execute. ### Cross-wallet batch (\$10 USD) When you have **multiple wallets** accumulating small deposits, forwarding efficiency is improved further by batching across wallets. Once the combined accumulated balance across **all** of your wallets for the same network and token reaches **\$10 USD**, all pending wallets are forwarded together in a single batch — sharing one on-chain gas cost. This means deposits can forward earlier than the per-wallet $1 threshold if the cross-wallet cumulative total reaches $10 first. **Example:** You have five wallets, each holding $2 USDC in accumulated deposits ($10 total). When the fifth wallet's deposit brings the cross-wallet total to \$10, all five wallets forward simultaneously in one batch. ### Threshold summary | Condition | Behaviour | | ---------------------------------------- | ------------------------------------------------------- | | Deposit ≥ \$1 USD | Forward executes immediately per your rule | | Deposit \< $1 USD, wallet total < $1 USD | Accumulated — held until wallet total ≥ \$1 USD | | Wallet total ≥ \$1 USD | Single-wallet batch forward triggered | | Cross-wallet total ≥ \$10 USD | All wallets with pending accumulations forward together | *** ## Webhook Events | Event | Trigger | | --------------------------- | ------------------------------------------------ | | `auto_forwarding.triggered` | A forwarding rule was triggered by a deposit | | `auto_forwarding.completed` | The forwarded transaction was confirmed on-chain | | `auto_forwarding.failed` | The forwarding transaction failed | *** ## Next Steps Full endpoint reference for auto-forwarding. Set up notifications for forwarding events. View forwarded transactions in your transaction history. # Transaction Disputes Source: https://docs.yativo.com/yativo-crypto/cards/disputes File and manage disputes for unauthorized or erroneous card transactions ## Overview If a transaction on your Yativo Card was unauthorized, incorrect, or you did not receive goods or services paid for, you can file a dispute through the API. Disputes require a valid reason code and a description of the issue. Disputes should be filed as soon as possible after identifying a problem. Most card networks require disputes to be submitted within 60–120 days of the transaction date. ```typescript theme={null} interface DisputeReason { code: string; description: string; category: string; } interface CreateDisputeRequest { reason_code: string; description?: string; } interface Dispute { dispute_id: string; transaction_id: string; reason_code: string; status: "submitted" | "under_review" | "resolved" | "rejected"; created_at: string; } ``` *** ## Get Dispute Reason Codes Before submitting a dispute, retrieve the list of valid reason codes for your account type. ``` GET /yativo-card/{yativoCardId}/transactions/dispute-reasons ``` Your Yativo Card account ID. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/transactions/dispute-reasons' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": [ { "reason_code": "UNAUTHORIZED", "description": "Transaction was not authorized by the cardholder" }, { "reason_code": "DUPLICATE", "description": "Transaction was charged more than once for the same purchase" }, { "reason_code": "NOT_RECEIVED", "description": "Goods or services were not received" }, { "reason_code": "NOT_AS_DESCRIBED", "description": "Goods or services were significantly different from what was described" }, { "reason_code": "CANCELLED", "description": "Subscription or service was cancelled but charge still occurred" }, { "reason_code": "INCORRECT_AMOUNT", "description": "Transaction amount was incorrect" }, { "reason_code": "CREDIT_NOT_PROCESSED", "description": "A refund or credit was agreed upon but not posted" } ] } ``` *** ## File a Dispute Submit a dispute for a specific transaction. ``` POST /yativo-card/{yativoCardId}/transactions/{transactionId}/dispute ``` Your Yativo Card account ID. The transaction ID to dispute. Retrieve this from the [transactions endpoint](/yativo-crypto/cards/transactions). A valid dispute reason code from the reasons list (e.g., `"UNAUTHORIZED"`, `"NOT_RECEIVED"`). A detailed description of the dispute. Minimum 20 characters. Include relevant details such as merchant name, transaction date, and what happened. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/transactions/txn_01HX9KZMB3F7VNQP8R2WDGT901/dispute' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "reason_code": "UNAUTHORIZED", "description": "I did not authorize this transaction at Amazon on March 20, 2026 for $42.50. My card was in my possession at the time and I did not make this purchase." }' ``` ```json Success theme={null} { "status": "success", "data": { "dispute_id": "dsp_01HX9KZMB3F7VNQP8R2WDGT999", "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT901", "reason_code": "UNAUTHORIZED", "status": "submitted", "submitted_at": "2026-03-25T16:00:00Z", "expected_resolution_by": "2026-04-24T16:00:00Z" } } ``` *** ## Common Dispute Reason Codes Use this reason code when you see a transaction on your card that you did not make and did not authorize anyone else to make. This typically indicates fraudulent use or card compromise. **What to include in your description:** * Where you were at the time of the transaction * Whether your card was in your possession * Whether you have shared your card details with anyone Use when a merchant has charged you more than once for the same purchase. **What to include:** * The dates of both charges * Order or receipt numbers if available * Any communication with the merchant about the duplicate Use when you paid for goods or services but never received them, and the merchant has not issued a refund. **What to include:** * Expected delivery or service date * Evidence of merchant contact (email threads, support tickets) * Whether tracking shows non-delivery (for physical goods) Use when a subscription, service, or order was cancelled but you were still charged after the cancellation date. **What to include:** * Cancellation date and confirmation number * The charge date relative to the cancellation * Any confirmation emails from the merchant Use when the amount charged differs from the agreed price or invoice. **What to include:** * The amount you expected to be charged * The amount actually charged * Receipts or invoices showing the agreed price *** ## B2B Issuer: Dispute Endpoints If you are operating as a Card Issuer and managing disputes on behalf of your customers, use the B2B dispute endpoints: ### Get Dispute Reasons (B2B) ``` GET /yativo-card/customers/{yativoCardId}/transactions/dispute-reasons ``` ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yc_customer_01HX9KZMB3F7/transactions/dispute-reasons' \ -H 'Authorization: Bearer YOUR_ISSUER_API_KEY' ``` ### File a Dispute (B2B) ``` POST /yativo-card/customers/{yativoCardId}/transactions/{transactionId}/dispute ``` ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yc_customer_01HX9KZMB3F7/transactions/txn_01HX9KZMB3F7VNQP8R2WDGT901/dispute' \ -H 'Authorization: Bearer YOUR_ISSUER_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "reason_code": "NOT_RECEIVED", "description": "Customer reports they did not receive the goods ordered on March 18, 2026. Multiple attempts to contact the merchant have been unsuccessful." }' ``` ```json Success theme={null} { "status": "success", "data": { "dispute_id": "dsp_01HX9KZMB3F7VNQP8R2WDGT888", "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT901", "customer_id": "yc_customer_01HX9KZMB3F7", "reason_code": "NOT_RECEIVED", "status": "submitted", "submitted_at": "2026-03-25T16:30:00Z", "expected_resolution_by": "2026-04-24T16:30:00Z" } } ``` *** ## Dispute Process Timeline | Phase | Typical Duration | Description | | ----------------- | ------------------ | ----------------------------------------------------------- | | Submission | Immediate | Dispute is submitted and acknowledged. | | Review | 3–5 business days | Internal review of the dispute details. | | Chargeback Filing | 5–10 business days | Dispute is escalated to the card network if valid. | | Merchant Response | Up to 30 days | Merchant is given time to respond or accept the chargeback. | | Resolution | 30–90 days total | Final decision is made and any credits are applied. | Providing clear, detailed descriptions and any supporting documentation significantly improves the likelihood of a successful dispute outcome and speeds up the resolution process. Filing a fraudulent dispute is a violation of the cardholder agreement and may result in account suspension. Only submit disputes for genuine issues. # Funding Your Card Source: https://docs.yativo.com/yativo-crypto/cards/funding Deposit crypto to your Yativo Card wallet and convert it to spendable card balance ## Overview The Yativo Card is funded via crypto deposits. USDC on Solana is the primary supported funding method. When you send USDC to your card's funding address, the deposit is automatically detected, processed, and credited to your card balance — no manual action required. ``` USDC (Solana) │ ▼ [Auto-Processing] Card Wallet Balance (spendable) │ ▼ Virtual / Physical Card ``` *** ## Get Wallet Info Retrieve your card wallet details, including current balance. ``` GET /yativo-card/{yativoCardId}/wallet ``` Your Yativo Card account ID. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/wallet' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "wallet_id": "wlt_01HX9KZMB3F7VNQP8R2WDGT4E5", "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "balance": 250.75, "currency": "USD", "wallet_address": "0x4a9d2f8b3c1e6a7d0f5b8c2e9a4d7f1b3c8e0a2d", "status": "active", "updated_at": "2026-03-25T14:00:00Z" } } ``` *** ## Get Funding Address Retrieve the USDC on Solana address you should send funds to. Each card account has a unique, dedicated funding address. ``` GET /yativo-card/{yativoCardId}/wallet/funding-address ``` Your Yativo Card account ID. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/wallet/funding-address' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "funding_address": "7dRp9qLmKv3xFjNw4aBcYhUeT8sGkZoP2iMnDuWr5Cx", "chain": "solana", "token": "USDC", "token_contract": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "minimum_deposit": 5.00, "memo_required": false } } ``` Only send **USDC on Solana** to this address. Sending other tokens or using a different network may result in permanent loss of funds. Always verify the chain and token before submitting a transaction. *** ## How Funding Works Call `GET /yativo-card/{yativoCardId}/wallet/funding-address` to retrieve your unique Solana USDC deposit address. Transfer USDC from your Solana wallet to the funding address. Ensure you are on the **Solana mainnet** and sending **USDC** (not USDT or any other token). Your deposit is detected on-chain automatically. This typically happens within a few seconds to a couple of minutes after the Solana transaction confirms. The detected USDC is automatically processed and converted to your card balance in USD. This conversion is seamless and requires no manual action. Your updated card balance is available immediately after the conversion completes. Use your card for any transaction. *** ## Settlement Times | Funding Method | Typical Settlement Time | | -------------------------- | ------------------------------------------------- | | USDC on Solana | 1–5 minutes after Solana transaction confirmation | | EUR via IBAN bank transfer | 1–2 business days | Settlement times depend on network congestion and conversion processing. During periods of high activity, times may be slightly longer. *** ## Minimum Deposit Amounts | Token | Network | Minimum Deposit | | ----- | ------- | --------------------- | | USDC | Solana | \$5.00 USD equivalent | Deposits below the minimum will not be processed and may be returned or lost. Always check the minimum before sending. *** ## EUR Funding via IBAN If you have activated the IBAN feature on your card account, you can receive EUR bank transfers (SEPA) directly to your card. The received EUR is automatically converted to card balance. See the [Card IBAN documentation](/yativo-crypto/cards/iban) for activation instructions. *** ## Security * Your funding address is static and unique to your account. It does not change after wallet initialization. * Never share your funding address in public forums. * Always double-check the address before sending a large deposit. *** ## Sandbox Testing Use the sandbox to test this endpoint without real funds: Sandbox URL: `https://crypto-sandbox.yativo.com/api/v1/` ```bash cURL theme={null} curl -X GET 'https://crypto-sandbox.yativo.com/api/v1/yativo-card/yc_01SANDBOX_CARD_ID/wallet/funding-address' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' ``` ```typescript TypeScript SDK theme={null} const sdk = new YativoSDK({ baseURL: 'https://crypto-sandbox.yativo.com/api/v1/', apiKey: 'YOUR_SANDBOX_API_KEY', apiSecret: 'YOUR_SANDBOX_API_SECRET', }); const fundingAddress = await sdk.cardWallet.getFundingAddress('yc_01SANDBOX_CARD_ID'); console.log('Send USDC on Solana to:', fundingAddress.data.funding_address); ``` # Card IBAN Source: https://docs.yativo.com/yativo-crypto/cards/iban Activate a dedicated IBAN to receive EUR bank transfers directly to your Yativo Card account ## Overview The Card IBAN feature gives your Yativo Card account a dedicated European bank account number (IBAN). You can share this IBAN with anyone to receive EUR via SEPA bank transfer. Incoming EUR funds are automatically converted and credited to your card balance. This feature is ideal for: * Receiving salary or freelance payments directly to your card * Accepting transfers from European banks without crypto on-ramp friction * Combining EUR bank funding with crypto funding in one unified card balance ```typescript theme={null} interface CardIBANStatus { status: "not_activated" | "pending_kyc" | "kyc_submitted" | "kyc_approved" | "active" | "rejected" | "suspended"; iban?: string; bic?: string; activated_at?: string; } interface ActivateIBANRequest { kyc_method: "platform_sumsub" | "user_sumsub" | "direct_docs"; sumsub_token?: string; // Required for platform_sumsub and user_sumsub } ``` *** ## Activate IBAN Request activation of the IBAN feature for a card account. Activation requires a KYC verification step to comply with European banking regulations. ``` POST /yativo-card/{yativoCardId}/iban/activate ``` Your Yativo Card account ID. The KYC verification method to use. See [KYC Methods](#kyc-methods) below. Accepted values: `platform_sumsub`, `user_sumsub`, `direct_docs`. Required when `kyc_method` is `platform_sumsub` or `user_sumsub`. The Sumsub applicant token generated for the user. ```bash Platform Sumsub KYC theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/iban/activate' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "kyc_method": "platform_sumsub", "sumsub_token": "sumsub_applicant_token_abc123xyz" }' ``` ```bash Direct Docs KYC theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/iban/activate' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "kyc_method": "direct_docs" }' ``` ```json Success theme={null} { "status": "success", "data": { "iban_activation_id": "iban_act_01HX9KZMB3F7VNQP8R2WDGT777", "kyc_method": "platform_sumsub", "status": "pending_kyc", "submitted_at": "2026-03-25T18:00:00Z" } } ``` *** ## Get IBAN Status Check the current status of the IBAN activation and retrieve the IBAN details once activated. ``` GET /yativo-card/{yativoCardId}/iban/status ``` Your Yativo Card account ID. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/iban/status' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Activated theme={null} { "status": "success", "data": { "iban_status": "active", "iban": "DE89370400440532013000", "bic": "SSKMDEMMXXX", "account_holder": "Jane Doe", "bank_name": "Yativo Payments", "currency": "EUR", "activated_at": "2026-03-26T09:00:00Z" } } ``` ```json Pending KYC theme={null} { "status": "success", "data": { "iban_status": "pending_kyc", "iban": null, "message": "KYC verification is in progress. Check back shortly." } } ``` ### IBAN Status Values | Status | Description | | --------------- | -------------------------------------------------------- | | `not_requested` | IBAN activation has not been initiated for this account. | | `pending_kyc` | KYC verification is in progress. | | `kyc_approved` | KYC passed. IBAN is being provisioned. | | `active` | IBAN is active and ready to receive transfers. | | `rejected` | KYC or activation was rejected. Contact support. | | `suspended` | IBAN has been temporarily suspended. | *** ## KYC Methods The IBAN feature requires identity verification due to European banking regulations. Three verification methods are available: **Best for:** Platforms that already run their own identity verification flow and can supply a KYC applicant token to Yativo. Your platform completes identity verification for the user and provides the resulting applicant token to Yativo. Yativo uses this token to retrieve and validate the KYC result on your behalf. **Required field:** `sumsub_token` — the KYC applicant token for the user. **Flow:** 1. Your backend initiates identity verification for the user and obtains an applicant token. 2. The user completes verification on your platform. 3. Pass the token to Yativo's IBAN activation endpoint. 4. Yativo validates the KYC result and provisions the IBAN on approval. **Best for:** Platforms that want to delegate the KYC experience entirely to Yativo. A verification link is generated for the user. The user completes identity verification through the Yativo-hosted flow. **Required field:** `sumsub_token` — the KYC applicant token created for the user. **Flow:** 1. Your platform or Yativo creates an applicant token for the user. 2. The user is redirected to or opens the verification URL. 3. Yativo monitors the result and activates the IBAN upon approval. **Best for:** Scenarios where a direct document review is preferred. The user submits identity documents (passport, national ID, proof of address) directly to Yativo for manual review. **Required fields:** None — documents are submitted through a separate upload flow. **Processing time:** 1–3 business days. *** ## Receiving EUR Transfers Once your IBAN is active, share the IBAN and BIC with the sender. Incoming SEPA transfers will be: 1. Received at the IBAN account. 2. Automatically converted from EUR to USD equivalent. 3. Credited to your card wallet balance. SEPA transfers typically settle within 1 business day. Instant SEPA payments (SEPA Instant) may settle within seconds, depending on the sending bank's capabilities. The IBAN is personal to your account and should not be shared beyond intended senders. Notify Yativo support immediately if you suspect misuse. # Card Issuer Program Source: https://docs.yativo.com/yativo-crypto/cards/issuer-program Issue Yativo Cards to your own customers under your platform — B2B card issuer documentation ## Overview The Yativo Card Issuer Program lets businesses issue virtual and physical payment cards to their own customers under their platform. As an issuer you manage the full card lifecycle — from customer onboarding to card creation, balance funding, and transaction monitoring — through a single API. **Typical use cases:** * Fintech apps offering spending cards to users * Corporate expense management platforms * Digital banking services for underserved markets * Wallets that want to add a card spending layer Access to the Card Issuer Program is by invitation only. Contact your Yativo account manager or [support@yativo.com](mailto:support@yativo.com) to request access. The program section will not appear in your dashboard until your account manager enables it for your account. *** ## How It Works Yativo's team reviews your use case and enables the Card Issuer Program on your account. Nothing is visible in your dashboard until this step is complete. Once eligible, the Card Issuer section appears in your dashboard. Choose your funding structure (`master_wallet` or `non_master`) and an optional IBAN add-on, then submit. Our compliance team reviews and approves the application, typically within 2–5 business days. On approval, your settlement wallets are auto-provisioned. Deposit USDC to your SOL address to top up your USD balance, swap to EUR or GBP as needed, onboard customers, issue cards, and fund them by customer email, ID, or your own external reference. *** ## Funding Structures Choose your funding structure at application time. It cannot be changed after approval. | Structure | Source Chain | Best For | | --------------- | ------------------- | ---------------------------------------------------------------------------------------- | | `master_wallet` | Solana (SOL) or XDC | You hold the source funds and push them to customer cards on demand | | `non_master` | Per-customer | Each customer deposits to their own collateral wallet — you do not hold a shared balance | *** ## Apply for the Program Once your account manager has granted eligibility, submit your application. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/apply' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "funding_structure": "master_wallet", "iban_enabled": false }' ``` | Field | Required | Description | | ------------------- | -------- | -------------------------------------------------------------------------------------------------- | | `funding_structure` | Yes | `master_wallet` or `non_master` | | `iban_enabled` | No | Set to `true` to enable EUR IBAN issuance. Requires additional regulatory review. Default: `false` | ```json Response theme={null} { "success": true, "message": "Application submitted. An admin will review your request.", "data": { "id": "6634abc...", "status": "pending", "funding_structure": "master_wallet", "iban_enabled": false } } ``` *** ## Check Program Status ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/card-issuer/status' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` ```json Response (approved, master_wallet) theme={null} { "success": true, "data": { "enrolled": true, "status": "approved", "funding_structure": "master_wallet", "enabled_chains": ["SOL"], "iban_enabled": false, "card_reissue_enabled": false, "master_wallets": { "sol": { "address": "9gHp7qLmKv3xFjNw4aBcYhUeT8sGkZoP2iMnDuWr5Cx", "balance": 0.012 }, "usdc": { "balance": 5420.00 }, "eur": { "balance": 3100.00 }, "gbp": { "balance": 800.00 } }, "stats": { "total_cards_issued": 47, "total_funded_amount": 12840.00, "total_fees_paid": 12.40 }, "limits": { "max_cards": 1000, "daily_funding_limit": 50000, "monthly_funding_limit": 500000 } } } ``` *** ## Master Wallet & Balances Master wallet issuers (`funding_structure: master_wallet`) have two types of wallets: ### Source wallets (SOL and/or XDC) These are the wallets you deposit USDC into. SOL deposits are settled automatically to your master wallet balance. XDC deposits are settled manually on your own schedule (XDC deposits accrue yield while held). | Chain | Token deposited | Settlement | Time | | ----- | --------------- | ---------- | --------- | | SOL | USDC\_SOL | Automatic | \~2–5 min | | XDC | USDC\_XDC | Manual | \~20 min | ### Settlement wallets These are auto-provisioned on approval. All three currency balances share the same underlying on-chain address. | Balance | Funded by | Used for | | ------- | -------------------------- | ---------------------------- | | USD | USDC deposited via SOL/XDC | Funding cards in USD regions | | EUR | Swap from USD | Funding cards in EUR regions | | GBP | Swap from USD | Funding cards in GBP regions | All three balances are managed internally by Yativo. To move from USD balance to EUR balance, use the swap endpoint below. ### Get master wallet balances ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/card-issuer/master-wallets' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` ```json Response theme={null} { "success": true, "data": { "wallets": { "sol": { "address": "9gHp7qLmKv3xFjNw4aBcYhUeT8sGkZoP2iMnDuWr5Cx", "balance": 0.012 }, "xdc": null, "usdc": { "balance": 5420.00, "last_balance_check": "2026-04-22T09:00:00Z" }, "eur": { "balance": 3100.00, "last_balance_check": "2026-04-22T09:00:00Z" }, "gbp": { "balance": 800.00, "last_balance_check": "2026-04-22T09:00:00Z" } } } } ``` `xdc` is `null` if XDC is not enabled for your program. ### Get funding deposit addresses ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/card-issuer/funding-addresses' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` Returns your SOL and XDC deposit addresses to send USDC to. For `non_master` programs, pass `?customer_id=...` to get the per-customer address. *** ## Swap Between Currency Balances Swap USD ↔ EUR ↔ GBP within your master wallet balances. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/master-wallets/swap' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "from_token": "USDC", "to_token": "EUR", "amount": 1000 }' ``` | Field | Required | Description | | ------------ | -------- | ------------------------------------------------------- | | `from_token` | Yes | `USDC`, `EUR`, or `GBP` | | `to_token` | Yes | `USDC`, `EUR`, or `GBP` (must differ from `from_token`) | | `amount` | Yes | Amount to sell, in the `from_token` currency | ```json Response theme={null} { "success": true, "message": "Swap initiated: 1000 USD → EUR", "data": { "swap_id": "0x7abc...", "status": "submitted", "from_token": "USD", "to_token": "EUR", "amount": 1000, "expected_output": "923.45", "fee_amount": "1.20", "estimated_time": "1-3 minutes" } } ``` *** ## Fund a Customer's Card Transfer from your master wallet to a customer's card wallet. The destination currency is automatically detected from the customer's card region (e.g. UK customers receive GBP, EU customers receive EUR). ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/fund-customer' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "customer_id": "cust_abc123", "amount": 100, "source_chain": "SOL", "pricing_mode": "receive_x" }' ``` | Field | Required | Description | | ------------------- | -------- | -------------------------------------------------------------------------------------------------------------------- | | `customer_id` | One of | Customer's Yativo customer ID | | `card_id` | One of | Card's unique ID | | `external_id` | One of | Your own external reference | | `email` | One of | Customer's email address | | `amount` | Yes | Amount to send (interpretation depends on `pricing_mode`) | | `source_chain` | Yes | `SOL` or `XDC` — which master wallet to send from | | `pricing_mode` | No | `send_x` (default) or `receive_x` — see below | | `destination_token` | No | Override the auto-detected destination token. Must match the customer's card region currency or an error is returned | ### Pricing modes | Mode | You specify | Customer receives | | ----------- | ------------------------------------------- | -------------------------------------------------------------------- | | `send_x` | The amount you send from your master wallet | Less than `amount` (transfer fees deducted) | | `receive_x` | The amount the customer should receive | More than `amount` is sent from your master wallet (you absorb fees) | The currency mismatch check is enforced at the API level. For example, if a customer's card is in a EUR region, you cannot fund them with a USD destination — the API returns `TOKEN_MISMATCH` and tells you the required currency. Swap your USD balance to EUR first, then fund. ```json Response theme={null} { "success": true, "data": { "transfer_id": "tx_1745123456_abc123", "status": "pending", "source": { "chain": "SOL", "amount": 102.50, "wallet": "9gHp7q..." }, "destination": { "token": "EUR" }, "pricing_mode": "receive_x", "estimated_output": "100.00", "estimated_time": "2-5 minutes" } } ``` *** ## Look Up a Customer Find a customer by any of their identifiers. The underlying wallet address is never returned. ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/card-issuer/lookup-customer?email=customer@example.com' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` Query parameters (one required): `customer_id`, `card_id`, `external_id`, or `email`. ```json Response theme={null} { "success": true, "data": { "customer_id": "cust_abc123", "external_id": "user_9821", "email": "customer@example.com", "currency": "GBP", "token": "GBP", "safe_deployed": true, "cards_count": 1, "created_at": "2026-03-15T10:00:00Z" } } ``` *** ## List & Manage Customers ```bash theme={null} # List all customers GET /card-issuer/customers?page=1&limit=20 # List customers filtered by KYC stage GET /card-issuer/customers?status=kyc_approved ``` *** ## Deposit History (XDC) XDC deposits are tracked individually so you can choose when to settle each one. ```bash theme={null} # List deposits curl 'https://crypto-api.yativo.com/api/v1/card-issuer/deposits' \ -H 'Authorization: Bearer YOUR_TOKEN' # Manually trigger settlement for a specific XDC deposit curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/deposits/{depositId}/fund' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "destination_token": "USDC" }' ``` Deposits in `awaiting_manual` status can be manually triggered. SOL deposits are settled automatically. *** ## Funding History ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/card-issuer/funding-history?page=1&limit=20' \ -H 'Authorization: Bearer YOUR_TOKEN' ``` Returns all funding transfers initiated from your master wallet, with status, amounts, and chain details. *** ## Card Reissue When card reissue is enabled for your program (admin-toggled), your customers can request a card reissue from the card management screen. This feature is off by default and is enabled per-program by Yativo's compliance team. Check whether it's enabled: ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/card-issuer/status' \ -H 'Authorization: Bearer YOUR_TOKEN' # → data.card_reissue_enabled: true/false ``` *** ## Rate Limits & Program Limits | Resource | Default | Adjustable | | --------------------- | --------- | ------------------------------------ | | Max customer accounts | 1,000 | Yes — contact your account manager | | Daily funding cap | \$50,000 | Yes — admin-configurable per program | | Monthly funding cap | \$500,000 | Yes — admin-configurable per program | Your current limits are always visible in `GET /card-issuer/status` under `limits`. *** ## PIN Management Every card — virtual and physical — starts with `pin_set: false`. The customer must set a PIN before chip-and-PIN or ATM transactions will work. Online card-not-present transactions do not require a PIN. If a card is active but has no PIN set, the `next_action` field in `GET /v1/card-issuer/customers/{customerId}` will read: > `"Card is active — customer must set card PIN before in-store (PSE) payments will work"` Full guide — PSE-hosted flow, iframe embed, brand theming, `pin_set` monitoring, and webhook confirmation. Full parameter reference for the view-token endpoint. *** ## Webhooks Subscribe to issuer events via `POST /v1/webhook/create-webhook`. See [Webhook Events](/api-reference/issuer/webhooks) for the full event reference, payload examples, and signature verification. Key events to subscribe to: | Event | Description | | ------------------------- | ------------------------------------- | | `customer.funded` | A customer's card wallet was credited | | `customer.funding.failed` | A funding transfer failed | | `master_wallet.deposit` | Funds arrived in your master wallet | | `card.created` | A card was issued to a customer | | `transaction.authorized` | A card transaction was authorized | | `transaction.declined` | A card transaction was declined | *** ## Related * [Card overview](/yativo-crypto/cards/overview) * [Customer onboarding](/yativo-crypto/cards/onboarding) * [Webhook Events](/api-reference/issuer/webhooks) * [Supported chains](/yativo-crypto/supported-chains) # Card Account Onboarding Source: https://docs.yativo.com/yativo-crypto/cards/onboarding Complete the required onboarding steps before creating and using Yativo Cards ```typescript theme={null} interface KYCStatus { status: "pending" | "in_progress" | "pending_review" | "approved" | "rejected" | "expired"; message?: string; } ``` ## Overview Before you can create or use Yativo Cards, every user must complete a four-step onboarding process. This flow verifies identity, establishes acceptance of terms, and initializes the card wallet. Submit name and email to create your card account profile. Identity verification is required by regulation before card issuance. Acknowledge the cardholder terms and conditions. Initialize your card wallet for funding and transactions. *** ## Step 1 — Register Card Account The user's email address. Used for communication and account identification. User's legal first name, as it should appear on the card. User's legal last name. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/onboard' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "email": "user@example.com", "first_name": "Jane", "last_name": "Doe" }' ``` ```json Success theme={null} { "status": "success", "data": { "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "email": "user@example.com", "first_name": "Jane", "last_name": "Doe", "kyc_status": "pending", "created_at": "2026-03-25T10:00:00Z" } } ``` Save the `yativo_card_id` from this response. It is required for all subsequent card operations. *** ## Step 2 — Check KYC Status After registration, KYC verification is initiated. Poll this endpoint to track progress. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/kyc-status' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "kyc_status": "approved", "kyc_verified_at": "2026-03-25T10:15:00Z", "rejection_reason": null } } ``` ### KYC Status Values | Status | Description | | ---------------- | --------------------------------------------------------------------------- | | `pending` | Not yet started, or documents requested. Poll again shortly. | | `in_progress` | Documents submitted — under review. Poll again in a few minutes. | | `pending_review` | Resubmission requested — user must supply additional info via the KYC link. | | `approved` | Identity verified. Proceed to Step 3. | | `rejected` | Verification failed. See `rejection_reason` for details. | | `expired` | KYC session expired — call the KYC link endpoint to restart. | You cannot proceed past this step until the KYC status is `approved`. If the status is `rejected`, contact support to understand next steps. *** ## Step 3 — Accept Terms and Conditions Once KYC is approved, the user must explicitly accept the cardholder terms before a card can be issued. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/accept-terms' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```json Success theme={null} { "status": "success", "data": { "terms_accepted": true, "accepted_at": "2026-03-25T10:20:00Z", "terms_version": "2026-01" } } ``` If you are building on behalf of users in the B2B Issuer Program, ensure your terms of service incorporate the required cardholder agreement language before calling this endpoint on behalf of your customers. *** ## Step 4 — Initialize Card Wallet The final step initializes your card wallet for funding and transactions. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/deploy-safe' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```json Success theme={null} { "status": "success", "data": { "status": "deployed", "initialized_at": "2026-03-25T10:22:00Z" } } ``` Card wallet initialization is a one-time operation per user. Once initialized, your wallet is ready to receive deposits and fund card transactions. *** ## Complete Onboarding Flow (Code Example) The following example shows the full onboarding sequence as a series of API calls: ```bash Step 1: Register theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/onboard' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "email": "user@example.com", "first_name": "Jane", "last_name": "Doe" }' # Save yativo_card_id from response ``` ```bash Step 2: Poll KYC Status theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/kyc-status' \ -H 'Authorization: Bearer YOUR_API_KEY' # Repeat until kyc_status == "approved" ``` ```bash Step 3: Accept Terms theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/accept-terms' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```bash Step 4: Initialize Card Wallet theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/deploy-safe' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{}' ``` *** ## What Happens Next? After successful wallet initialization, you are ready to: Issue a virtual card instantly for online spending. Send USDC on Solana to your card wallet funding address. # Yativo Card Overview Source: https://docs.yativo.com/yativo-crypto/cards/overview Crypto-funded virtual and physical payment cards for individuals and businesses ```typescript theme={null} interface YativoCard { card_id: string; display_name: string; type: "virtual" | "physical"; status: "active" | "frozen" | "voided"; last_four: string; spending_limit_amount: number; spending_limit_frequency: "daily" | "weekly" | "monthly"; created_at: string; } ``` ## What is the Yativo Card? The Yativo Card is a crypto-powered payment card that bridges the gap between your digital assets and everyday spending. Fund your card directly from a crypto wallet — your balance is automatically converted and made available for purchases wherever major payment networks are accepted. Whether you need a virtual card for online purchases or a physical card for in-store transactions, the Yativo Card gives you the flexibility to spend your crypto anywhere in the real world without friction. Instant-issue virtual cards for online and contactless payments. Create, freeze, unfreeze, and void cards programmatically. Order a physical card delivered to your door. Ideal for in-store purchases and ATM withdrawals. Fund your card with USDC on Solana. Deposits are automatically processed and credited to your card balance. Activate a dedicated IBAN to receive EUR bank transfers directly to your card account. Set daily and per-transaction spending limits for your card or your customers' cards. Query full transaction history with filtering by status, date, and card. File disputes for unauthorized or erroneous charges with structured reason codes. Issue cards to your own customers under your brand. Fund customer wallets and manage cards at scale. *** ## How It Works ``` Crypto Wallet (USDC on Solana) │ ▼ Yativo Card Wallet │ ▼ Card Balance (spendable) │ ▼ Virtual / Physical Card │ ▼ Payment Network (online & in-store) ``` 1. **Deposit crypto** — Send USDC on Solana to your Yativo Card funding address. 2. **Auto-convert** — Funds are automatically detected, processed, and credited to your card wallet. 3. **Spend anywhere** — Use your virtual or physical card for purchases worldwide. 4. **Track transactions** — Monitor every transaction in real time via the API. *** ## Key Features Create virtual cards in seconds via API. No waiting, no manual approval. Freeze, unfreeze, void cards, and set spending limits programmatically. Sensitive card data (PAN, CVV) is displayed via a Yativo-hosted secure page — never exposed in plaintext API responses. Accept EUR bank transfers via a dedicated IBAN linked to your card account. Deposit crypto and our automatic conversion layer handles the conversion seamlessly. Structured dispute workflow with reason codes and tracking. *** ## B2B Card Issuer Program The Yativo Card Issuer Program allows businesses to issue cards to their own customers under a white-label arrangement. As an issuer, you can: * **Onboard customers** — Manage KYC and card creation on behalf of your users. * **Fund customer wallets** — Transfer funds from your issuer wallet to customer card accounts. * **Manage cards at scale** — Create, freeze, and void customer cards via API. * **Custom spending controls** — Set per-customer spending limits and restrictions. * **Webhooks** — Subscribe to real-time events for each customer account. The Issuer Program requires separate enrollment. See the [Issuer Program documentation](/yativo-crypto/cards/issuer-program) for how to apply. *** ## Onboarding Requirement Before issuing cards, all users must complete a one-time onboarding flow: 1. Register your card account (name, email) 2. Complete KYC verification 3. Accept the cardholder terms and conditions 4. Initialize your card wallet See the [Onboarding Guide](/yativo-crypto/cards/onboarding) for the complete step-by-step flow. *** ## Supported Regions The Yativo Card is available in supported jurisdictions. Contact [support@yativo.com](mailto:support@yativo.com) for the latest list of supported countries and any regional restrictions that may apply. *** ## Next Steps Complete the card account onboarding flow to get started. Review mock responses and understand the card API before going live. # Physical Cards Source: https://docs.yativo.com/yativo-crypto/cards/physical-cards Order and manage physical payment cards delivered to your address ## Overview Physical Yativo Cards are plastic payment cards delivered to a shipping address. They work anywhere the payment network is accepted — in-store, at ATMs, and for contactless payments. Physical card orders go through a fulfillment process before the card is shipped. Physical card issuance requires a fully onboarded account with KYC approved, terms accepted, and wallet deployed. See the [Onboarding Guide](/yativo-crypto/cards/onboarding). ```typescript theme={null} interface PhysicalCardOrder { order_id: string; status: "pending" | "processing" | "shipped" | "delivered" | "cancelled"; shipping_address: ShippingAddress; tracking_number?: string; estimated_delivery?: string; created_at: string; } interface ShippingAddress { line1: string; line2?: string; city: string; state?: string; postal_code: string; country: string; // ISO 3166-1 alpha-2 } interface CreatePhysicalOrderRequest { shipping_address: ShippingAddress; personalization?: { name_on_card?: string; }; } ``` *** ## Order a Physical Card Submit an order for a physical card. A shipping address is required. ``` POST /yativo-card/{yativoCardId}/cards/physical/order ``` Your Yativo Card account ID. The delivery address for the physical card. Street address line 1. Street address line 2 (apartment, suite, unit, etc.). City name. State or province code. Required for applicable countries. Postal or ZIP code. ISO 3166-1 alpha-2 country code (e.g., `"DE"`, `"GB"`, `"US"`). A label for this card (e.g., "Personal Card"). Defaults to the account holder name. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/physical/order' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "display_name": "Jane'\''s Personal Card", "shipping_address": { "line1": "123 Main Street", "line2": "Apt 4B", "city": "Berlin", "postal_code": "10115", "country": "DE" } }' ``` ```json Success theme={null} { "status": "success", "data": { "order_id": "ord_01HX9KZMB3F7VNQP8R2WDGT4F6", "status": "pending_payment", "display_name": "Jane's Personal Card", "shipping_address": { "line1": "123 Main Street", "line2": "Apt 4B", "city": "Berlin", "postal_code": "10115", "country": "DE" }, "created_at": "2026-03-25T12:00:00Z" } } ``` *** ## Attach Payment to Order After creating an order, submit payment to initiate card fulfillment. ``` POST /yativo-card/{yativoCardId}/cards/physical/order/{orderId}/payment ``` Your Yativo Card account ID. The order ID returned when the order was created. Payment method. Accepted values: `"card_balance"`, `"crypto"`. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/physical/order/ord_01HX9KZMB3F7VNQP8R2WDGT4F6/payment' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "payment_method": "card_balance" }' ``` ```json Success theme={null} { "status": "success", "data": { "order_id": "ord_01HX9KZMB3F7VNQP8R2WDGT4F6", "payment_status": "paid", "order_status": "processing", "amount_charged": 9.99, "currency": "USD" } } ``` *** ## Get Order Status Check the current status of a physical card order. ``` GET /yativo-card/{yativoCardId}/cards/physical/order/{orderId}/status ``` Your Yativo Card account ID. The order ID to check. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/physical/order/ord_01HX9KZMB3F7VNQP8R2WDGT4F6/status' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "order_id": "ord_01HX9KZMB3F7VNQP8R2WDGT4F6", "order_status": "shipped", "tracking_number": "1Z999AA10123456784", "carrier": "DHL", "estimated_delivery": "2026-04-02", "shipped_at": "2026-03-27T08:00:00Z" } } ``` ### Order Status Values | Status | Description | | ----------------- | -------------------------------------------------------------- | | `pending_payment` | Order created, awaiting payment. | | `processing` | Payment received. Card is being manufactured and personalized. | | `shipped` | Card has been dispatched. Tracking number available. | | `delivered` | Card confirmed delivered to the shipping address. | | `cancelled` | Order was cancelled before shipment. | | `failed` | Order could not be fulfilled. Contact support. | *** ## List All Orders Retrieve all physical card orders for a Yativo Card account. ``` GET /yativo-card/{yativoCardId}/cards/physical/orders ``` Your Yativo Card account ID. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/physical/orders' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": [ { "order_id": "ord_01HX9KZMB3F7VNQP8R2WDGT4F6", "order_status": "shipped", "display_name": "Jane's Personal Card", "created_at": "2026-03-25T12:00:00Z", "shipped_at": "2026-03-27T08:00:00Z" } ], "total": 1 } ``` *** ## Cancel an Order Cancel a physical card order. Cancellation is only possible while the order is in `pending_payment` or `processing` status. Once shipped, orders cannot be cancelled. ``` POST /yativo-card/{yativoCardId}/cards/physical/order/{orderId}/cancel ``` Your Yativo Card account ID. The order ID to cancel. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/physical/order/ord_01HX9KZMB3F7VNQP8R2WDGT4F6/cancel' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```json Success theme={null} { "status": "success", "data": { "order_id": "ord_01HX9KZMB3F7VNQP8R2WDGT4F6", "order_status": "cancelled", "cancelled_at": "2026-03-25T13:00:00Z", "refund_status": "pending" } } ``` *** ## Set Physical Card PIN The `pin_set` field in the view-token response tells you whether Yativo has received a `physical.card.pin.changed` webhook for this card. Use it to prompt the cardholder to set a PIN before their first chip-and-PIN or ATM transaction. The same view also handles PIN **changes**. Physical card PINs are set and changed through Yativo's **hosted secure page**, powered by the card network's Partner Secure Elements (PSE) service. The cardholder types their PIN directly inside a sandboxed iframe — your backend never receives or processes the PIN value. **Flow:** 1. Your backend calls `POST /v1/yativo-card/{yativoCardId}/cards/{cardId}/view-token` with `enabled_views: ["pin"]` 2. You receive a `secure_view_url` 3. Open it in an ` ``` The PIN updates the **online PIN** stored by the card network. The chip's offline PIN syncs automatically on the first ATM transaction. Complete flow for virtual and physical cards — PSE iframe, brand theming, `pin_set` monitoring, and webhook confirmation. *** ## Delivery Timeframes Delivery times are estimates and may vary based on destination country and carrier conditions. | Region | Estimated Delivery | | -------------- | ------------------- | | Europe (EU) | 5–10 business days | | United Kingdom | 5–10 business days | | North America | 7–14 business days | | Rest of World | 10–21 business days | After your card is shipped, you will receive a tracking number via the order status endpoint and via email notification. *** ## Physical Card Activation Before a physical card can be activated, a **12.00 USDC** one-time activation fee must be paid. Send 12 USDC (SPL) on Solana to your card wallet address. The fee is detected automatically — once confirmed, you can call the activation endpoint with your activation code. Activation fees are subject to review and may change. The current fee will always be returned in the `402` response if payment is still outstanding. If the fee has not been paid, the activation endpoint returns `HTTP 402` with the payment address: ```json theme={null} { "success": false, "error_code": "ACTIVATION_FEE_REQUIRED", "message": "A 12.00 USDC activation fee is required...", "data": { "fee_amount": "12.00", "fee_currency": "USDC", "payment_address": "SoLFundingWalletAddressXXX", "network": "solana", "fees_subject_to_review": true } } ``` Once the payment is detected your activation call will succeed normally. Set your PIN as soon as your card arrives. Chip-and-PIN and ATM transactions will fail until a PIN is set. Use the [PIN setup flow](#set-physical-card-pin) to let the cardholder set theirs immediately after activation, and use the same flow to change it later. # Secure Card Display Source: https://docs.yativo.com/yativo-crypto/cards/secure-display Display sensitive card details and PIN in a secure hosted iframe — card data and PIN each require a separate view token **Cardholders must set their PIN before card details or PIN reveal can be viewed.** If `pin_set` is `false` and you request `["data"]` or `["pin-view"]`, the API returns a `422 PIN_NOT_SET` error with a ready-to-use `pin_setup_url`. Open that URL so the cardholder can set their PIN, then retry the view-token request. To **set** the PIN, call with `enabled_views: ["pin-set"]` — this always returns **200 OK** and `secure_view_url`, regardless of `pin_set` status. See [Setting a Card PIN](/yativo-crypto/cards/set-pin). Card details (PAN, CVV, expiry) and the card PIN each use **separate view tokens**. You must request the correct `enabled_views` for each use case. Never reuse a token between sessions. ## How it works Sensitive card data is never returned in plain API responses. Instead, Yativo hosts a secure card view page and provides you with a short-lived URL to embed in your application: 1. Your backend calls `POST /yativo-card/{yativoCardId}/cards/{cardId}/view-token` 2. If you request `["data"]` or `["pin-view"]` and `pin_set` is `false`, the API returns `PIN_NOT_SET` and a `pin_setup_url` — direct the cardholder there to set their PIN first. If you request `["pin-set"]`, you always receive a `secure_view_url` regardless of `pin_set` status. 3. Yativo returns a `secure_view_url` — a hosted, tokenized page 4. Your frontend embeds that URL in an ` ``` The hosted page is fully responsive. Recommended dimensions: `420 × 740px` for card details, `420 × 520px` for PIN-only views. *** ## Step 3 — Backend proxy (required) Your frontend must **never** call the Yativo API directly with your credentials. Always proxy the token request through your backend: ```typescript theme={null} import express from 'express'; const app = express(); app.use(express.json()); app.post('/api/card-view-token', async (req, res) => { // 1. Authenticate your own user first const user = await authenticateRequest(req); if (!user) return res.status(401).json({ error: 'Unauthorized' }); const { enabled_views, access_code, theme } = req.body; // 2. Validate enabled_views — only accept known values const VALID_VIEWS = ['data', 'pin-view', 'pin-set']; if (enabled_views && !enabled_views.every(v => VALID_VIEWS.includes(v))) { return res.status(400).json({ error: 'Invalid enabled_views' }); } // 3. Look up this user's card IDs from your own database const { yativoCardId, cardId } = await getUserCardIds(user.id); // 4. Call Yativo from your backend — credentials never leave the server const response = await fetch( `https://crypto-api.yativo.com/api/v1/yativo-card/${yativoCardId}/cards/${cardId}/view-token`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.YATIVO_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ ...(enabled_views ? { enabled_views } : {}), ...(access_code ? { access_code } : {}), ...(theme ? { theme } : {}), }), } ); const payload = await response.json(); // PIN not yet set — return the setup URL so your frontend can redirect the cardholder if (!response.ok && payload.error_code === 'PIN_NOT_SET') { return res.status(422).json({ error_code: 'PIN_NOT_SET', message: payload.message, pin_setup_url: payload.data?.pin_setup_url, }); } if (!response.ok) { return res.status(502).json({ error: 'Failed to get view token' }); } // Return only the URL — do not cache it res.json(payload.data); }); ``` ```typescript theme={null} import { YativoSDK } from '@yativo/crypto-sdk'; const sdk = new YativoSDK({ baseURL: 'https://crypto-api.yativo.com/api/v1/', apiKey: process.env.YATIVO_API_KEY!, apiSecret: process.env.YATIVO_API_SECRET!, }); // In your backend route handler: const result = await sdk.cards.getViewToken( 'yc_01HX9KZMB3F7VNQP8R2WDGT4E5', // yativoCardId 'card_01HX9KZMB3F7VNQP8R2WDGT4E5', // cardId { enabled_views: ['data', 'pin-view', 'pin-set'], theme: { accent_color: '#813AE3', border_radius: 16, }, } ); // Send result.data.secure_view_url to your frontend return res.json({ url: result.data.secure_view_url }); ``` ```html theme={null}
```
```tsx theme={null} import { useEffect, useRef, useState } from 'react'; interface CardViewProps { enabledViews?: ('data' | 'pin-view' | 'pin-set')[]; height?: number; } export function SecureCardDisplay({ enabledViews = ['data', 'pin'], height = 740 }: CardViewProps) { const [url, setUrl] = useState(null); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; async function fetchToken() { try { const res = await fetch('/api/card-view-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled_views: enabledViews }), }); if (!res.ok) throw new Error('Failed to fetch token'); const data = await res.json(); if (!cancelled) setUrl(data.secure_view_url); } catch (err) { if (!cancelled) setError('Could not load card view. Please try again.'); } } fetchToken(); return () => { cancelled = true; }; }, [enabledViews.join(',')]); if (error) return

{error}

; if (!url) return
Loading...
; return ( ``` Recommended iframe dimensions: `420 × 520px` for PIN-only. Use `420 × 740px` if showing card details and PIN together. *** ## Checking PIN status `pin_set` is updated when Yativo receives the `physical.card.pin.changed` webhook from the card network. It is **not** sourced from a direct API lookup — treat it as the last known state. You can read it from: **Per-card**, in `GET /v1/card-issuer/customers/{customerId}`: ```json theme={null} { "card_id": "afeb85fe-02f8-48da-b61e-84ad02704167", "card_type": "virtual", "status": "active", "pin_set": false } ``` **Per-customer** top-level (true only when every card has a PIN): ```json theme={null} { "cards_count": 2, "pin_set": false, "next_action": "Card is active — customer must set card PIN before in-store (PSE) payments will work" } ``` **On the view-token response** — `data.pin_set` is returned every time you call the view-token endpoint. To list all customers who still need to set a PIN: ```bash theme={null} GET /v1/card-issuer/customers?status=card_created ``` Then filter the results by `pin_set: false`. `pin_set` reflects the last state received via webhook and may lag if a webhook was delayed. If a cardholder reports unexpected `PIN_NOT_SET` errors after completing PIN setup, they can retry — the server will re-evaluate when the webhook catches up. *** ## Webhook confirmation Subscribe to `physical.card.pin.changed` on your webhook endpoint. Yativo updates `pin_set: true` automatically when this event arrives — no polling needed. ```json Payload example theme={null} { "event": "physical.card.pin.changed", "data": { "cardToken": "afeb85fe-02f8-48da-b61e-84ad02704167", "yativo_card_id": "yativo_card_customer_8f9a..._1769031332068" } } ``` *** ## Notes | Detail | Value | | ----------------------------- | ---------------------------------------------------------------------------- | | Works for | Virtual and physical cards | | PIN format | Exactly 4 digits (`0000`–`9999`) | | Initial setup & change | Same `enabled_views: ["pin-set"]` flow for both | | PIN never touches your server | Entered directly in the Yativo-hosted iframe | | Brand customisation | Pass `theme` in the token request — applies to the hosted PIN page | | Confirmation | `physical.card.pin.changed` webhook → `pin_set: true` | | `pin_set` source | Webhook only — not from a direct card network API lookup | | Online vs chip PIN | PSE updates the online PIN. The chip syncs on first ATM use (physical cards) | # Spending Limits Source: https://docs.yativo.com/yativo-crypto/cards/spending-limits Configure daily and per-card spending limits on Yativo Card accounts ## Overview Spending limits protect against overspending and add an extra layer of control over card usage. You can set a daily limit on your overall card wallet, which applies as a cap across all cards within the account. Card-level limits can also be set at card creation time. Card-level spending limits (set during card creation) are independent of wallet-level daily limits. Both apply simultaneously — the more restrictive limit takes precedence. ```typescript theme={null} interface SpendingLimits { daily_limit: number; weekly_limit?: number; monthly_limit?: number; currency: string; current_daily_spend: number; reset_at: string; } interface SetSpendingLimitRequest { daily_limit: number; } ``` *** ## Get Current Spending Limits Retrieve the current spending limits configured for a card wallet. ``` GET /yativo-card/{yativoCardId}/wallet/limits ``` Your Yativo Card account ID. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/wallet/limits' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "daily_limit": 500.00, "daily_spent": 42.50, "daily_remaining": 457.50, "currency": "USD", "limit_reset_at": "2026-03-26T00:00:00Z" } } ``` *** ## Set Daily Spending Limit Update the daily spending limit for a card wallet. The new limit applies immediately. ``` PUT /yativo-card/{yativoCardId}/wallet/limits ``` Your Yativo Card account ID. The maximum amount that can be spent across all cards in a single calendar day (in USD). Set to `0` or `null` to remove the daily limit. ```bash cURL theme={null} curl -X PUT 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/wallet/limits' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "daily_limit": 1000.00 }' ``` ```json Success theme={null} { "status": "success", "data": { "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "daily_limit": 1000.00, "currency": "USD", "updated_at": "2026-03-25T17:00:00Z" } } ``` *** ## Remove Daily Limit To remove the daily spending limit entirely, set `daily_limit` to `null`: ```bash cURL theme={null} curl -X PUT 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/wallet/limits' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "daily_limit": null }' ``` ```json Success theme={null} { "status": "success", "data": { "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "daily_limit": null, "currency": "USD", "updated_at": "2026-03-25T17:05:00Z" } } ``` Removing spending limits increases risk exposure. Only remove limits if you have other controls in place, such as low card balances or card-level limits. *** ## B2B Issuer: Customer Spending Limits If you are a Card Issuer, you can view and set spending limits for your customers' card accounts using the B2B endpoints. ### Get Customer Limits ``` GET /yativo-card/customers/{yativoCardId}/wallet/limits ``` The customer's Yativo Card account ID. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yc_customer_01HX9KZMB3F7/wallet/limits' \ -H 'Authorization: Bearer YOUR_ISSUER_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "customer_id": "yc_customer_01HX9KZMB3F7", "daily_limit": 250.00, "daily_spent": 0.00, "daily_remaining": 250.00, "currency": "USD", "limit_reset_at": "2026-03-26T00:00:00Z" } } ``` ### Set Customer Limits ``` PUT /yativo-card/customers/{yativoCardId}/wallet/limits ``` The customer's Yativo Card account ID. The new daily limit for the customer's account. ```bash cURL theme={null} curl -X PUT 'https://crypto-api.yativo.com/api/v1/yativo-card/customers/yc_customer_01HX9KZMB3F7/wallet/limits' \ -H 'Authorization: Bearer YOUR_ISSUER_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "daily_limit": 500.00 }' ``` ```json Success theme={null} { "status": "success", "data": { "customer_id": "yc_customer_01HX9KZMB3F7", "daily_limit": 500.00, "currency": "USD", "updated_at": "2026-03-25T17:10:00Z" } } ``` *** ## Limit Types Summary | Limit Type | Endpoint | Scope | | -------------------------- | ----------------------------------------------- | ------------------------------ | | Daily wallet limit | `PUT /yativo-card/{id}/wallet/limits` | All cards in the account | | Card spending limit | Set via `create-card` | Per card, per frequency period | | Customer daily limit (B2B) | `PUT /yativo-card/customers/{id}/wallet/limits` | All cards under a customer | For B2B issuers managing corporate or consumer card programs, setting conservative daily limits at the customer level is recommended as a risk management best practice. Customers can request limit increases through your platform, and you can raise them via API. # Card Transactions Source: https://docs.yativo.com/yativo-crypto/cards/transactions Query and filter transaction history for your Yativo Cards ## Overview The Yativo Card API provides full transaction history for both individual cards and the overall account. You can filter transactions by status, date range, and paginate results for large histories. ```typescript theme={null} interface CardTransaction { transaction_id: string; card_id: string; type: "purchase" | "refund" | "reversal" | "atm_withdrawal"; amount: number; currency: string; merchant_name?: string; merchant_category?: string; status: "pending" | "completed" | "failed" | "reversed"; created_at: string; } interface CardTransactionListParams { limit?: number; offset?: number; status?: "pending" | "completed" | "failed" | "reversed"; from_date?: string; // ISO 8601 to_date?: string; // ISO 8601 } ``` *** ## Get Transactions for a Specific Card Retrieve transactions for a single card, with optional filters. ``` GET /yativo-card/{yativoCardId}/cards/{cardId}/transactions ``` Your Yativo Card account ID. The card ID to retrieve transactions for. Number of results to return per page. Default: `20`. Max: `100`. Number of results to skip (for pagination). Default: `0`. Filter by transaction status. Accepted values: `pending`, `completed`, `failed`, `reversed`. Start of the date range (ISO 8601 format). Example: `2026-01-01T00:00:00Z`. End of the date range (ISO 8601 format). Example: `2026-03-31T23:59:59Z`. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/card_01HX9KZMB3F7VNQP8R2WDGT4E5/transactions?limit=20&offset=0&status=completed&from_date=2026-03-01T00:00:00Z' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "transactions": [ { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT901", "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 42.50, "currency": "USD", "merchant_name": "Amazon", "merchant_category": "Online Retail", "status": "completed", "type": "purchase", "created_at": "2026-03-20T15:30:00Z", "settled_at": "2026-03-21T10:00:00Z" }, { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT902", "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 12.99, "currency": "USD", "merchant_name": "Netflix", "merchant_category": "Streaming", "status": "completed", "type": "purchase", "created_at": "2026-03-15T08:00:00Z", "settled_at": "2026-03-16T09:00:00Z" } ], "total": 2, "limit": 20, "offset": 0 } } ``` *** ## Get All Account Transactions Retrieve transactions across all cards in the account. Useful for generating account-level reports. ``` GET /yativo-card/{yativoCardId}/transactions ``` Your Yativo Card account ID. Number of results per page. Default: `20`. Max: `100`. Offset for pagination. Default: `0`. Filter by transaction status: `pending`, `completed`, `failed`, `reversed`. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/transactions?limit=50&offset=0&status=completed' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "transactions": [ { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT901", "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "card_display_name": "Online Shopping", "amount": 42.50, "currency": "USD", "merchant_name": "Amazon", "merchant_category": "Online Retail", "status": "completed", "type": "purchase", "created_at": "2026-03-20T15:30:00Z", "settled_at": "2026-03-21T10:00:00Z" } ], "total": 1, "limit": 50, "offset": 0 } } ``` *** ## Transaction Status Values | Status | Description | | ----------- | ----------------------------------------------------------------------------------- | | `pending` | Transaction has been authorized but not yet settled. Funds are reserved. | | `completed` | Transaction has settled successfully. Funds have been deducted. | | `failed` | Transaction was declined or failed to process. No funds were deducted. | | `reversed` | Transaction was reversed or refunded. Funds have been returned to the card balance. | *** ## Transaction Types | Type | Description | | ---------------- | ---------------------------------------------------------- | | `purchase` | A standard card purchase at a merchant. | | `refund` | A merchant-initiated refund to the card. | | `atm_withdrawal` | A cash withdrawal at an ATM (physical cards only). | | `fee` | A fee charged to the card (e.g., foreign transaction fee). | | `authorization` | A pre-authorization hold placed by a merchant. | *** ## Pagination Use `limit` and `offset` for paginating through large transaction histories: ```bash Page 1 theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/transactions?limit=20&offset=0' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```bash Page 2 theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/transactions?limit=20&offset=20' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```bash Page 3 theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/transactions?limit=20&offset=40' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` The `total` field in the response indicates the total number of matching transactions, allowing you to calculate the number of pages: `pages = ceil(total / limit)`. *** ## Filtering by Date Range To export transactions for a specific month: ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/transactions?from_date=2026-03-01T00:00:00Z&to_date=2026-03-31T23:59:59Z' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` If you need to file a dispute on a transaction, see the [Disputes documentation](/yativo-crypto/cards/disputes). The `transaction_id` from the transaction list is used when submitting a dispute. *** ## Sandbox Testing Replace `YOUR_SANDBOX_TOKEN` with a token obtained by authenticating against `https://crypto-sandbox.yativo.com/api/v1/`. See [Sandbox Overview](/sandbox/overview). Card transactions in the sandbox environment return mock data. ```bash cURL (Sandbox) theme={null} curl -X GET 'https://crypto-sandbox.yativo.com/api/v1/yativo-card/yc_sandbox_example/cards/card_sandbox_example/transactions?limit=20&offset=0&status=completed' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' ``` ```typescript TypeScript SDK (Sandbox) theme={null} import { YativoSDK } from '@yativo/crypto-sdk'; const sdk = new YativoSDK({ baseURL: 'https://crypto-sandbox.yativo.com/api/v1/', apiKey: 'YOUR_SANDBOX_API_KEY', apiSecret: 'YOUR_SANDBOX_API_SECRET', }); // Fetch transactions for a specific card (returns mock data in sandbox) const transactions = await sdk.cards.getTransactions('yc_sandbox_example', 'card_sandbox_example', { limit: 20, offset: 0, status: 'completed', }); console.log('Transactions:', transactions.data.transactions); ``` # Virtual Cards Source: https://docs.yativo.com/yativo-crypto/cards/virtual-cards Create and manage virtual payment cards for online and contactless spending ## Overview Virtual cards are instantly issued, digital-only payment cards. Use them for online purchases, subscriptions, and contactless payments. You can create multiple virtual cards, set custom spending limits, and freeze or void them at any time. Before creating a card, you must complete the [onboarding flow](/yativo-crypto/cards/onboarding) including KYC approval, terms acceptance, and wallet deployment. ```typescript theme={null} interface Card { card_id: string; yativo_card_id: string; display_name: string; type: "virtual" | "physical"; status: "active" | "frozen" | "voided"; last_four: string; expiry_month: number; expiry_year: number; spending_limit_amount: number; spending_limit_frequency: "daily" | "weekly" | "monthly"; created_at: string; } interface CreateCardRequest { card_type?: "virtual" | "physical"; display_name?: string; spending_limit_amount?: number; spending_limit_frequency?: "daily" | "weekly" | "monthly"; } interface CardViewTokenResponse { secure_view_url: string; url: string; expires_at: string; last_four: string; card_type: string; holder_name: string; enabled_views: string[]; requires_access_code: boolean; } ``` *** ## List Cards Retrieve all cards associated with the authenticated account. ``` GET /yativo-card/list-cards ``` ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/list-cards' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": [ { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "display_name": "Online Shopping", "card_type": "virtual", "status": "active", "last_four": "4242", "spending_limit_amount": 500.00, "spending_limit_frequency": "monthly", "created_at": "2026-03-25T10:30:00Z" } ] } ``` *** ## Create Virtual Card Issue a new virtual card. Specify a display name and optional spending limit. ``` POST /yativo-card/create-card ``` Must be `"virtual"` for virtual card creation. A human-readable label for the card (e.g., "Monthly Subscriptions", "Travel Expenses"). Maximum amount the card can spend per period. Omit to set no limit. The reset frequency for the spending limit. Accepted values: `daily`, `weekly`, `monthly`, `yearly`, `per_authorization`. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/create-card' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "card_type": "virtual", "display_name": "Online Shopping", "spending_limit_amount": 500.00, "spending_limit_frequency": "monthly" }' ``` ```json Success theme={null} { "status": "success", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "display_name": "Online Shopping", "card_type": "virtual", "status": "active", "last_four": "4242", "spending_limit_amount": 500.00, "spending_limit_frequency": "monthly", "created_at": "2026-03-25T10:30:00Z" } } ``` *** ## View Card Details and PIN (Secure hosted page) Sensitive card data — the full card number (PAN), CVV, expiry, and PIN — is never returned in API responses. To display it, your backend requests a **secure view URL** from Yativo. You open that URL for the cardholder in an iframe, WebView, or browser tab. Yativo hosts the page and handles all the cryptography internally — no SDK integration required on your side. **How it works:** 1. Your backend calls `POST /yativo-card/{yativoCardId}/cards/{cardId}/view-token` 2. You receive a `secure_view_url` 3. Open the URL for the cardholder (iframe, WebView, new tab) 4. Yativo's hosted page displays PAN, CVV, expiry and/or PIN securely ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/cards/card_01HX9KZMB3F7VNQP8R2WDGT4E5/view-token' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "enabled_views": ["data", "pin"], "theme": { "accent_color": "#6366f1", "logo_url": "https://yourapp.com/logo.png" } }' ``` ```json Response theme={null} { "success": true, "data": { "secure_view_url": "https://crypto-api.yativo.com/api/v1/yativo-card/view/eyJhbGci...", "expires_at": "2026-03-26T12:01:00Z", "last_four": "4242", "enabled_views": ["data", "pin"], "requires_access_code": false } } ``` Always request a fresh URL immediately before showing card details. Never cache or reuse a previous `secure_view_url`. Backend proxy pattern, iframe embedding, access code flow, theming options, React/Vue/Vanilla JS examples, and CSP requirements. *** ## Set Card PIN The `pin_set` field in the view-token response tells you whether Yativo has received a `physical.card.pin.changed` webhook for this card. Use it to decide whether to prompt the cardholder to set their PIN — the same `enabled_views: ["pin"]` view also handles PIN **changes**. Card PINs are set and changed through Yativo's **hosted secure page** — the cardholder types their PIN directly inside a sandboxed iframe. The PIN never touches your backend. **How to show the PIN-setup page:** 1. Call `POST /yativo-card/{yativoCardId}/cards/{cardId}/view-token` with `enabled_views: ["pin"]` 2. Open the returned `secure_view_url` in an ` ``` Complete flow for virtual and physical cards — PSE iframe, brand theming, `pin_set` monitoring, and webhook confirmation. *** ## Freeze a Card Temporarily suspend a card. All transactions on a frozen card will be declined until unfrozen. ``` POST /yativo-card/cards/{cardId}/freeze ``` The card ID to freeze. ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/cards/card_01HX9KZMB3F7VNQP8R2WDGT4E5/freeze' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```json Success theme={null} { "status": "success", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "status": "frozen", "frozen_at": "2026-03-25T11:00:00Z" } } ``` *** ## Unfreeze a Card Re-activate a frozen card. ``` POST /yativo-card/cards/{cardId}/unfreeze ``` ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/cards/card_01HX9KZMB3F7VNQP8R2WDGT4E5/unfreeze' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```json Success theme={null} { "status": "success", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "status": "active", "unfrozen_at": "2026-03-25T11:05:00Z" } } ``` *** ## Void a Card Permanently cancel a card. This action is irreversible. A voided card cannot be reactivated. ``` POST /yativo-card/cards/{cardId}/void ``` ```bash cURL theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/yativo-card/cards/card_01HX9KZMB3F7VNQP8R2WDGT4E5/void' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{}' ``` ```json Success theme={null} { "status": "success", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "status": "voided", "voided_at": "2026-03-25T11:10:00Z" } } ``` Voiding a card is permanent. If you only need to temporarily stop spending, use [freeze](#freeze-a-card) instead. *** ## Get User Profile Retrieve the card account profile for a given Yativo Card ID. ``` GET /yativo-card/{yativoCardId}/profile ``` The Yativo Card account ID. ```bash cURL theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/yc_01HX9KZMB3F7VNQP8R2WDGT4E5/profile' \ -H 'Authorization: Bearer YOUR_API_KEY' ``` ```json Success theme={null} { "status": "success", "data": { "yativo_card_id": "yc_01HX9KZMB3F7VNQP8R2WDGT4E5", "email": "user@example.com", "first_name": "Jane", "last_name": "Doe", "kyc_status": "approved", "terms_accepted": true, "wallet_deployed": true, "created_at": "2026-03-25T10:00:00Z" } } ``` *** ## Card Status Reference | Status | Description | | --------- | ------------------------------------------------------------- | | `active` | Card is in good standing and can be used for transactions. | | `frozen` | Card is temporarily suspended. Transactions will be declined. | | `voided` | Card has been permanently cancelled. Cannot be reactivated. | | `pending` | Card is being provisioned. Usually resolves within seconds. | *** ## Sandbox Testing Replace `YOUR_SANDBOX_TOKEN` with a token obtained by authenticating against `https://crypto-sandbox.yativo.com/api/v1/`. See [Sandbox Overview](/sandbox/overview). ### Create a Virtual Card (Sandbox) ```bash cURL (Sandbox) theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/yativo-card/create-card' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "card_type": "virtual", "display_name": "Sandbox Test Card", "spending_limit_amount": 100.00, "spending_limit_frequency": "monthly" }' ``` ```typescript TypeScript SDK (Sandbox) theme={null} import { YativoSDK } from '@yativo/crypto-sdk'; const sdk = new YativoSDK({ baseURL: 'https://crypto-sandbox.yativo.com/api/v1/', apiKey: 'YOUR_SANDBOX_API_KEY', apiSecret: 'YOUR_SANDBOX_API_SECRET', }); const card = await sdk.cards.create({ card_type: 'virtual', display_name: 'Sandbox Test Card', spending_limit_amount: 100.00, spending_limit_frequency: 'monthly', }); console.log('Card ID:', card.data.card_id); ``` ### List Cards (Sandbox) ```bash cURL (Sandbox) theme={null} curl -X GET 'https://crypto-sandbox.yativo.com/api/v1/yativo-card/list-cards' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' ``` ```typescript TypeScript SDK (Sandbox) theme={null} import { YativoSDK } from '@yativo/crypto-sdk'; const sdk = new YativoSDK({ baseURL: 'https://crypto-sandbox.yativo.com/api/v1/', apiKey: 'YOUR_SANDBOX_API_KEY', apiSecret: 'YOUR_SANDBOX_API_SECRET', }); const cards = await sdk.cards.list(); console.log('Cards:', cards.data); ``` # Card Withdrawal Source: https://docs.yativo.com/yativo-crypto/cards/withdrawal Pull funds from a customer's card account back to your master wallet — on-chain USDC settlement in approximately 3 minutes Card withdrawal is only available for issuers using the **master wallet** funding structure. The funds are settled on-chain directly to your issuer master wallet. ## How it works A card withdrawal moves USDC from a customer's card account (their on-chain Safe) back to your issuer master wallet in a single API call: 1. You call `POST /api/card-issuer/withdraw-from-card` with a customer identifier and amount 2. Yativo fetches EIP-712 typed data from the card network, signs it server-side using the card's EOA, and submits the transaction 3. A delay relay holds the transaction for **\~3 minutes** — the card is temporarily frozen during this window 4. Once the delay elapses the transfer executes on-chain and your master wallet is credited 5. Three webhooks fire: `card.withdrawal.settled` (customer-scoped), `master_wallet.withdrawal` (issuer-scoped), and `master_wallet.deposit` (master wallet balance credited) *** ## API ``` POST /api/card-issuer/withdraw-from-card ``` **Authentication:** Bearer token (your issuer API key) Identifies the customer's card. Accepts any of: * `yativo_card_id` — e.g. `yativo_card_customer_...` * `external_id` — the ID you assigned during onboarding * `customer_id` — the Yativo internal customer ObjectId * `email` — only valid when the customer has exactly one card; returns `422` if ambiguous Amount to withdraw in display units (e.g. `1`, `25.50`). Must be positive and not exceed the card's available balance. ```bash Withdraw $1 theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/card-issuer/withdraw-from-card' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "id": "yativo_card_customer_abc123...", "amount": 1 }' ``` ```json 200 Initiated theme={null} { "success": true, "data": { "withdrawal_id": "cwd_1748012345678_x7k2qp", "yativo_card_id": "yativo_card_customer_...", "amount": 1.00, "amount_minor": 100, "currency": "USD", "status": "initiated", "message": "Withdrawal initiated. Funds will arrive in your master wallet shortly.", "estimated_settlement_at": "2026-05-23T14:35:00.000Z" } } ``` ```json 400 Insufficient balance theme={null} { "success": false, "error": "INSUFFICIENT_BALANCE", "message": "Available balance is $0.50. Requested $1.00." } ``` ```json 422 Ambiguous customer theme={null} { "success": false, "error": "AMBIGUOUS_CUSTOMER", "message": "Multiple cards found for this email. Use yativo_card_id instead." } ``` *** ## Timing | Stage | Time | | ---------------------------------- | ---------------------------- | | API response (withdrawal accepted) | Immediate | | Card frozen (delay relay active) | Immediately after submission | | On-chain settlement | \~3 minutes after submission | | Card unfrozen | After settlement confirms | | Webhooks delivered | After settlement confirms | The 3-minute delay is enforced by the card network's on-chain delay relay module and cannot be shortened. *** ## Webhooks Subscribe to these events to track withdrawal lifecycle: ### `card.withdrawal.settled` Fires when the withdrawal confirms on-chain. Scoped to the customer's card account. ```json theme={null} { "type": "card.withdrawal.settled", "data": { "withdrawal_id": "wth_01HXABCDEF...", "yativo_card_id": "yativo_card_customer_...", "amount": 1.00, "amount_minor": 100, "currency": "USD", "card_balance": 10.87, "card_balance_minor": 1087, "tx_hash": "0xabc123...", "status": "settled", "settled_at": "2026-05-28T13:10:45.000Z" } } ``` `card_balance` and `card_balance_minor` are present when the settlement notification arrives directly from the card network. They are absent when settlement is confirmed via the on-chain fallback path — handle both shapes defensively. ### `master_wallet.withdrawal` Fires at the same time as `card.withdrawal.settled`. Scoped to your issuer master wallet — confirms your wallet has been credited. ```json theme={null} { "type": "master_wallet.withdrawal", "data": { "withdrawal_id": "wth_01HXABCDEF...", "yativo_card_id": "yativo_card_customer_...", "amount": 1.00, "amount_minor": 100, "currency": "USD", "destination_address": "0x920abe21a7eb39DF5f5A42AE97F4Cd061d5AdD9b", "tx_hash": "0xabc123...", "status": "settled", "settled_at": "2026-05-28T13:10:45.000Z" } } ``` ### `master_wallet.deposit` Also fires when the withdrawal settles — the master wallet balance increase from the returned funds is treated as a deposit credit. This event carries the on-chain `tx_hash` and includes `withdrawal_id` and `yativo_card_id` so you can correlate it back to the originating withdrawal. You will receive **both** `master_wallet.withdrawal` and `master_wallet.deposit` for each settled withdrawal. `master_wallet.withdrawal` is the semantic event for a withdrawal completing. `master_wallet.deposit` reflects the master wallet balance increasing and is the event that carries the confirmed on-chain transaction hash. Use `withdrawal_id` to join them. ```json theme={null} { "type": "master_wallet.deposit", "data": { "settlement_id": "6a294844e71b09a046f28103", "withdrawal_id": "wth_01HXABCDEF...", "yativo_card_id": "yativo_card_customer_...", "deposit_amount": 1.00, "deposit_amount_minor": 100, "wallet_balance": 101.00, "wallet_balance_minor": 10100, "currency": "USD", "tx_hash": "0xabc123...", "solana_tx_hash": null, "status": "settled" } } ``` ### `card.withdrawal.failed` Fires if the on-chain transaction is rejected. No funds are moved. ```json theme={null} { "type": "card.withdrawal.failed", "data": { "withdrawal_id": "wth_01HXABCDEF...", "yativo_card_id": "yativo_card_customer_...", "amount": 1.00, "amount_minor": 100, "currency": "USD", "reason": "Transaction reverted", "status": "failed" } } ``` ### `customer.balance.updated` Fires when the card balance changes — including after a withdrawal settles. ```json theme={null} { "type": "customer.balance.updated", "data": { "yativo_card_id": "yativo_card_customer_...", "ledger_balance": 10.87, "ledger_balance_minor": 1087, "available_balance": 10.87, "available_balance_minor": 1087, "pending_balance": 0, "pending_balance_minor": 0, "currency": "USD", "timestamp": "2026-05-28T13:10:45.000Z" } } ``` Subscribe to all five events to handle the full lifecycle: ```json theme={null} { "events": [ "card.withdrawal.settled", "card.withdrawal.failed", "master_wallet.withdrawal", "master_wallet.deposit", "customer.balance.updated" ] } ``` *** ## Notes * **Card is frozen during processing.** From submission until on-chain confirmation (\~3 min), the card cannot be used for purchases. * **Settlement is on-chain and irreversible.** Once submitted the transaction cannot be cancelled. Verify the amount and customer before calling the endpoint. * **Master wallet receives USDC on Gnosis Chain.** The credited token matches the customer's card denomination. For USD cards this is USDC (`0x2a22f9c3b484c3629090FeED35F17Ff8F88f76F0`). * **`amount_minor` is in cents** (1 USD = 100 minor units), regardless of the on-chain token decimals. *** Move funds from your master wallet to a customer card. View card spending and transaction history. # Compliance Screener Source: https://docs.yativo.com/yativo-crypto/compliance-screener Screen blockchain addresses against sanctions, fraud, and risk databases before transacting The Compliance Screener checks blockchain addresses against sanctions lists, known fraud databases, and risk scoring services. Use it before processing transactions to flag high-risk addresses and maintain regulatory compliance. The screener is available as a **public API** — no authentication required. *** ## Check an Address ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/screener/check' \ -H 'Content-Type: application/json' \ -d '{ "address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4" }' ``` ```json Response theme={null} { "success": true, "data": { "address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "risk_level": "low", "flagged": false, "checks": { "sanctions": false, "fraud": false, "darknet": false, "mixer": false }, "checked_at": "2026-04-01T12:00:00Z" } } ``` *** ## Risk Levels | Level | Description | | ---------- | --------------------------------------------------------------------- | | `low` | Address has no known risk indicators | | `medium` | Address has some indirect exposure to flagged entities | | `high` | Address is directly associated with sanctioned or fraudulent activity | | `critical` | Address is on an active sanctions list — **do not transact** | *** ## Batch Check Screen multiple addresses in a single request: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/screener/batch-check' \ -H 'Content-Type: application/json' \ -d '{ "addresses": [ "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" ] }' ``` ```json Response theme={null} { "success": true, "data": { "results": [ { "address": "0x9F8b...", "risk_level": "low", "flagged": false }, { "address": "0x742d...", "risk_level": "low", "flagged": false }, { "address": "7xKXt...", "risk_level": "low", "flagged": false } ], "checked_at": "2026-04-01T12:00:00Z" } } ``` *** ## Service Info Get the screener's current capabilities and usage information: ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/screener/info' ``` *** ## Health Check ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/screener/health' ``` *** ## Integration Pattern Screen addresses before sending funds or accepting deposits: ```typescript theme={null} // Before sending funds const screen = await fetch('https://crypto-api.yativo.com/api/v1/screener/check', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address: recipientAddress }), }); const { data } = await screen.json(); if (data.risk_level === 'critical' || data.risk_level === 'high') { throw new Error(`Address ${recipientAddress} is flagged: ${data.risk_level}`); } // Safe to proceed with the transaction ``` *** ## Next Steps Full endpoint reference for the screener. Send funds after screening the recipient. # Customers Source: https://docs.yativo.com/yativo-crypto/customers Create and manage B2B sub-accounts for your end customers The Customers API lets you create managed accounts for your own business customers. Each customer gets their own wallets and transaction history under your platform umbrella — you retain full programmatic control while keeping each customer's data isolated. This is the foundation of a B2B crypto-as-a-service product: you use the Yativo API on the backend, and your customers interact with your interface. **These are WaaS (wallet) customers — not card customers.** If you are issuing crypto cards, your card holders are managed separately via the [Card Issuer API](/api-reference/issuer/customers). The two systems use different customer records and different endpoints. A customer enabled for cards is created through the card onboarding flow; a customer here is created with a single API call and gets crypto wallets immediately. ```typescript theme={null} interface Customer { customer_id: string; email: string; name?: string; phone?: string; metadata?: Record; status: "active" | "suspended"; created_at: string; } interface CreateCustomerRequest { email: string; name?: string; phone?: string; metadata?: Record; } ``` *** ## Create a Customer **POST** `/customers/create-customer` Customer's email address. Used as the unique identifier for the customer. Full name of the customer or business. Customer's phone number. Arbitrary key-value pairs for storing your own reference data (e.g., your internal customer ID, account tier, etc.). ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/customers/create-customer \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "email": "customer@example.com", "name": "Acme Corp", "phone": "+14155551234", "metadata": { "internal_id": "cust-8821", "plan": "enterprise" } }' ``` ```typescript TypeScript theme={null} const customer = await client.customers.create({ email: 'customer@example.com', name: 'Acme Corp', phone: '+14155551234', metadata: { internal_id: 'cust-8821', plan: 'enterprise', }, }); console.log('Customer ID:', customer.id); ``` ```python Python theme={null} customer = client.customers.create( email='customer@example.com', name='Acme Corp', phone='+14155551234', metadata={ 'internal_id': 'cust-8821', 'plan': 'enterprise', }, ) print('Customer ID:', customer['id']) ``` ```json Response theme={null} { "id": "cust_01abc123", "email": "customer@example.com", "name": "Acme Corp", "phone": "+14155551234", "metadata": { "internal_id": "cust-8821", "plan": "enterprise" }, "status": "active", "created_at": "2026-03-26T10:00:00Z" } ``` *** ## Get Customers **POST** `/customers/get-customers` Returns all customers under your platform account. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/customers/get-customers \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```json Response theme={null} { "customers": [ { "id": "cust_01abc123", "email": "customer@example.com", "name": "Acme Corp", "status": "active", "created_at": "2026-03-26T10:00:00Z" }, { "id": "cust_02def456", "email": "another@example.com", "name": "Beta Inc", "status": "active", "created_at": "2026-03-20T08:00:00Z" } ], "total": 2 } ``` *** ## Get Customer Transactions **POST** `/customers/get-customer-transactions` Returns the full transaction history for a specific customer. The ID of the customer to retrieve transactions for. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/customers/get-customer-transactions \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"customer_id": "cust_01abc123"}' ``` ```json Response theme={null} { "customer_id": "cust_01abc123", "transactions": [ { "transaction_id": "txn_01pqr456", "type": "withdrawal", "status": "completed", "amount": "100.00", "ticker": "USDC", "chain": "ethereum", "to_address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "completed_at": "2026-03-26T10:07:30Z" }, { "transaction_id": "txn_02stu789", "type": "deposit", "status": "completed", "amount": "500.00", "ticker": "USDC", "chain": "ethereum", "from_address": "0x1A2B3C4D5E6F7A8B9C0D1E2F3A4B5C6D7E8F9A0B", "completed_at": "2026-03-25T14:30:00Z" } ], "total": 2 } ``` *** ## Customer Wallets After creating a customer, add wallets using the Assets API with the customer-specific endpoints: ```bash theme={null} # Add a wallet for a customer curl -X POST https://crypto-api.yativo.com/api/v1/assets/add-customer-asset \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "customer_id": "cust_01abc123", "chain": "solana", "ticker": "USDC_SOL" }' # Get all wallets for a customer curl -X POST https://crypto-api.yativo.com/api/v1/assets/get-customer-assets \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"customer_id": "cust_01abc123"}' ``` See the [Assets](/yativo-crypto/assets) page for full documentation on these endpoints. *** ## Customer Data Model ``` Your Platform Account ├── Customer: Acme Corp (cust_01abc123) │ ├── Wallet: USDC on Ethereum │ ├── Wallet: USDC_SOL on Solana │ └── Transaction history └── Customer: Beta Inc (cust_02def456) └── Wallet: USDT on Polygon ``` Customer data is isolated — one customer's wallets and transactions are never accessible from another customer's context. Your platform account has visibility across all customers. *** Store your internal customer ID in the `metadata.internal_id` field when creating customers. This makes it easy to cross-reference Yativo customer IDs with your own database. *** ## Sandbox Testing Replace `YOUR_SANDBOX_TOKEN` with a token obtained by authenticating against `https://crypto-sandbox.yativo.com/api/v1/`. See [Sandbox Overview](/sandbox/overview). ### Create a Customer (Sandbox) ```bash cURL (Sandbox) theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/customers/create-customer' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "email": "sandbox-customer@example.com", "name": "Sandbox Test Corp", "phone": "+14155550100", "metadata": { "internal_id": "sandbox-cust-001", "plan": "test" } }' ``` ```typescript TypeScript SDK (Sandbox) theme={null} import { YativoSDK } from '@yativo/crypto-sdk'; const sdk = new YativoSDK({ baseURL: 'https://crypto-sandbox.yativo.com/api/v1/', apiKey: 'YOUR_SANDBOX_API_KEY', apiSecret: 'YOUR_SANDBOX_API_SECRET', }); const customer = await sdk.customers.create({ email: 'sandbox-customer@example.com', name: 'Sandbox Test Corp', phone: '+14155550100', metadata: { internal_id: 'sandbox-cust-001', plan: 'test', }, }); console.log('Customer ID:', customer.customer_id); ``` ### List Customers (Sandbox) ```bash cURL (Sandbox) theme={null} curl -X POST 'https://crypto-sandbox.yativo.com/api/v1/customers/get-customers' \ -H 'Authorization: Bearer YOUR_SANDBOX_TOKEN' ``` ```typescript TypeScript SDK (Sandbox) theme={null} import { YativoSDK } from '@yativo/crypto-sdk'; const sdk = new YativoSDK({ baseURL: 'https://crypto-sandbox.yativo.com/api/v1/', apiKey: 'YOUR_SANDBOX_API_KEY', apiSecret: 'YOUR_SANDBOX_API_SECRET', }); const { customers } = await sdk.customers.list(); console.log('Total customers:', customers.length); ``` # Errors Source: https://docs.yativo.com/yativo-crypto/errors HTTP error codes, error message patterns, and how to handle each The Yativo Crypto API uses standard HTTP status codes and returns structured JSON error responses. All errors follow the same shape: ```json theme={null} { "error": "error_code", "message": "Human-readable description of what went wrong", "details": { } // Optional: additional context } ``` *** ## HTTP Status Codes ### 400 — Bad Request The request was malformed or failed validation. Check the `details` field for which fields are invalid. ```json theme={null} { "error": "validation_error", "message": "Request validation failed", "details": { "amount": "Must be a positive decimal number", "chain": "Unsupported chain identifier" } } ``` **How to handle:** Fix the request before retrying. Do not retry 400 errors without modifying the request. *** ### 401 — Unauthorized The request is missing authentication credentials, or the provided credentials are invalid or expired. ```json theme={null} { "error": "unauthorized", "message": "Invalid or expired access token" } ``` **How to handle:** * If using a Bearer token, refresh it via `POST /apikey/token` or `GET /authentication/refresh-token` * If using API key headers, verify your `X-API-Key` and `X-API-Secret` are correct *** ### 403 — Forbidden The request is authenticated, but the API key or user does not have permission to perform the requested action. ```json theme={null} { "error": "forbidden", "message": "API key does not have the 'transactions' permission" } ``` **How to handle:** Check which permissions your API key has (`GET /apikey/{id}`). If needed, update permissions via `PUT /apikey/{id}/permissions` (requires 2FA). *** ### 404 — Not Found The requested resource does not exist, or is not accessible from your account. ```json theme={null} { "error": "not_found", "message": "Asset with ID 'asset_01xyz' not found" } ``` **How to handle:** Verify the ID is correct. If you just created the resource, allow a moment for propagation and retry. *** ### 409 — Conflict A duplicate operation was attempted. Most commonly seen with idempotency key conflicts. ```json theme={null} { "error": "conflict", "message": "A transaction with this idempotency key already exists", "details": { "existing_transaction_id": "txn_01pqr456", "idempotency_key": "idem_7f3a9b2c1e4d" } } ``` **How to handle:** If the `details` include an `existing_transaction_id`, that transaction is the canonical result — use it rather than creating a new one. This is the intended idempotency behavior. *** ### 422 — Unprocessable Entity The request is syntactically valid but semantically invalid — for example, trying to send more than your wallet balance. ```json theme={null} { "error": "insufficient_balance", "message": "Wallet balance (400.00 USDC) is less than the requested amount (1000.00 USDC)", "details": { "available_balance": "400.00", "requested_amount": "1000.00", "ticker": "USDC" } } ``` Common 422 error codes: | Error Code | Cause | | ---------------------- | ------------------------------------------------------------ | | `insufficient_balance` | Wallet balance is too low for the requested transfer | | `invalid_address` | The `to_address` is not a valid address for the target chain | | `unsupported_token` | The chain/ticker combination is not supported | | `quote_expired` | A swap quote has passed its `expires_at` timestamp | | `gas_station_empty` | The gas station for this chain has no native tokens | | `card_not_active` | The target card is not in an active state | | `iban_not_activated` | The IBAN account has not completed activation | **How to handle:** Read the `error_code` and `details` to determine the specific issue. These errors require business logic changes (top up wallet, get a fresh quote, etc.) — not just a retry. *** ### 429 — Too Many Requests Your request rate has exceeded the limit for your plan. ```json theme={null} { "error": "rate_limit_exceeded", "message": "Too many requests. Please wait before retrying.", "retry_after": 12 } ``` **How to handle:** Wait `retry_after` seconds before retrying. Implement exponential backoff for sustained high-volume use. See [Rate Limits](/yativo/rate-limits) for details. *** ### 500 — Internal Server Error An unexpected error occurred on Yativo's servers. ```json theme={null} { "error": "internal_error", "message": "An unexpected error occurred. Please try again or contact support.", "request_id": "req_01abc123" } ``` **How to handle:** Retry with exponential backoff. If the error persists, open a support ticket with the `request_id` value — it allows the Yativo team to trace the exact request in their logs. *** ## Error Handling Pattern ```typescript theme={null} async function callYativo(url: string, body: object): Promise { const res = await fetch(url, { method: 'POST', headers: { 'Authorization': `Bearer ${await getToken()}`, 'Content-Type': 'application/json', }, body: JSON.stringify(body), }); if (res.ok) return res.json(); const error = await res.json(); switch (res.status) { case 400: throw new ValidationError(error.message, error.details); case 401: await refreshToken(); return callYativo(url, body); // retry once case 403: throw new PermissionError(error.message); case 404: throw new NotFoundError(error.message); case 409: // Idempotent — return the existing resource return error.details; case 422: throw new BusinessError(error.error, error.message, error.details); case 429: await sleep(error.retry_after * 1000); return callYativo(url, body); case 500: throw new ServerError(error.message, error.request_id); default: throw new Error(`Unexpected status ${res.status}: ${error.message}`); } } ``` *** ## Idempotency The `POST /transactions/send-funds` endpoint automatically generates a unique idempotency key for each request. If a network failure causes you to retry a send-funds call, you may receive a `409 Conflict` response. This is not an error condition — it means the original transaction was already created. Use the `existing_transaction_id` from the 409 response body to track that transaction. To override the auto-generated key with your own, include `"idempotency_key": "your-unique-key"` in the request body. Keys must be unique per operation type. # Gas Station Source: https://docs.yativo.com/yativo-crypto/gas-station Pre-fund native token reserves to cover network fees on behalf of your users The Gas Station solves one of the most common UX friction points in crypto applications: requiring users to hold native tokens just to pay network fees. Without a Gas Station, a user who holds USDC on Solana still needs SOL to pay for the transaction fee. With a Gas Station, your platform pre-funds SOL (or ETH, BNB, etc.) and covers fees on behalf of your users — they only need to hold the token they actually want to send. *** ## How It Works 1. You add a gas station asset for a specific chain (e.g., SOL for Solana) 2. You fund the gas station wallet with native tokens 3. When a user initiates a transaction on that chain, the platform draws from the gas station to pay the network fee automatically 4. You monitor the gas station balance and top it up as needed The Gas Station covers **network fees only**. Transaction amounts are still drawn from the user's wallet. *** ## Add a Gas Station Asset **POST** `/assets/add-station-asset` Creates a gas station wallet for a specific chain. The ticker must be the chain's native token. The blockchain to create a gas station for (e.g., `solana`, `ethereum`). The native gas token for that chain. Must match the chain's native currency. | Chain | Required Ticker | | -------- | --------------- | | Ethereum | `ETH` | | Solana | `SOL` | | Polygon | `POL` | | BSC | `BNB` | | Base | `ETH_BASE` | | Arbitrum | `ETH_ARBITRUM` | | Optimism | `ETH_OPTIMISM` | | XDC | `XDC` | ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/add-station-asset \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "chain": "solana", "ticker": "SOL" }' ``` ```typescript TypeScript theme={null} const gasStation = await client.assets.addStation({ chain: 'solana', ticker: 'SOL', }); console.log('Gas station address:', gasStation.address); ``` ```python Python theme={null} gas_station = client.assets.add_station( chain='solana', ticker='SOL', ) print('Gas station address:', gas_station['address']) ``` ```json Response theme={null} { "id": "station_01abc123", "chain": "solana", "ticker": "SOL", "address": "GasStationXxKXtg2CW87d97TXJSDpbD5jBkheTqA83TZ", "balance": "0", "status": "active", "created_at": "2026-03-26T10:00:00Z" } ``` Send SOL to the `address` to fund the gas station. *** ## Get Gas Station Assets **POST** `/assets/get-station-assets` Returns all gas station wallets and their current balances. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/get-station-assets \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```typescript TypeScript theme={null} const stations = await client.assets.getStations(); ``` ```json Response theme={null} { "station_assets": [ { "id": "station_01abc123", "chain": "solana", "ticker": "SOL", "address": "GasStationXxKXtg2CW87d97TXJSDpbD5jBkheTqA83TZ", "balance": "5.2", "balance_usd": "750.40", "status": "active" }, { "id": "station_02def456", "chain": "ethereum", "ticker": "ETH", "address": "0xGasStationAddr...", "balance": "0.05", "balance_usd": "125.00", "status": "active" } ] } ``` *** ## Monitoring & Top-Up If the gas station runs out of native tokens, transactions on that chain will fail with an insufficient gas error. Monitor your gas station balance and set up top-up procedures before going to production. Set up a [webhook](/yativo-crypto/webhooks) for the `gas.low` event to get notified when a gas station balance drops below the configured threshold: ```json Webhook payload (gas.low) theme={null} { "id": "evt_01abc", "type": "gas.low", "created_at": "2026-03-26T11:00:00Z", "data": { "station_id": "station_01abc123", "chain": "solana", "ticker": "SOL", "balance": "0.5", "balance_usd": "72.00", "threshold": "1.0" } } ``` *** ## Best Practices When launching, fund each gas station with enough native tokens to cover several hundred transactions. Monitor actual consumption in the first week to calibrate your top-up schedule. Wire the `gas.low` webhook to an automated top-up system. Don't rely on manual monitoring in production. Each chain requires its own gas station. If you support 5 chains, you need 5 gas station wallets. On Ethereum and other congested networks, gas prices can spike dramatically. Keep a larger buffer on high-usage chains to survive short-term price spikes. # IBAN Account Source: https://docs.yativo.com/yativo-crypto/iban Get a dedicated IBAN for receiving EUR bank transfers that settle directly to your crypto wallet This feature is coming soon. The standalone IBAN product is currently in sandbox and not yet available for production use. Check back for updates. # Yativo Crypto Source: https://docs.yativo.com/yativo-crypto/introduction Multi-chain crypto infrastructure for businesses — wallets, cards, payments, IBAN, agentic AI wallets, and more Yativo Crypto is the crypto infrastructure division of Yativo. It gives businesses and developers a complete stack for building crypto-powered financial products: multi-chain wallet management, crypto-funded debit cards, IBAN accounts, cross-chain token swaps, a crypto payment gateway, agentic wallets for AI agents, and a B2B customer layer for managing your own users. Everything is accessible via a single REST API with SDK support for TypeScript, Python, PHP, Java, React, and an MCP server for AI agents. *** ## What You Can Build * **Crypto wallets as a service** — Generate deposit addresses on multiple chains for your users, track balances, and move funds programmatically * **Crypto-funded payment cards** — Issue virtual and physical debit cards that spend directly from crypto balances * **Crypto payment gateway** — Accept crypto payments with a hosted checkout page — no frontend integration needed * **IBAN accounts** — Assign European bank account numbers to crypto wallets for fiat on/off-ramp flows * **Token swap** — Let users swap between tokens and chains without leaving your product * **Agentic wallets for AI** — Give AI agents their own wallets to send payments, pay for x402 APIs, and maintain audit trails * **Auto-forwarding** — Automatically sweep deposits to a destination address based on configurable rules * **B2B sub-accounts** — Manage wallets and cards for your own business customers under a single Yativo account *** ## Key Features Generate and manage wallet addresses across 9+ blockchains from a single API. Automatic deposit detection with webhook notifications. Issue virtual and physical Visa debit cards funded from crypto balances. Full KYC onboarding, spending limits, and dispute management. Accept crypto payments with hosted checkout. Create a payment intent, share a link, get paid. Multi-chain support. Programmable wallets for AI agents with spending limits, connectors, x402 protocol support, and full audit trails. European IBAN accounts linked to crypto wallets. Receive EUR transfers directly into a wallet-backed bank account. Cross-chain and same-chain token swaps with real-time quotes and slippage control. Automatically sweep incoming deposits to a destination address. Configure rules, thresholds, and destinations. Screen blockchain addresses against sanctions lists and risk databases before transacting. Pre-fund a gas station to cover network fees on behalf of your users. Create and manage sub-accounts for your business customers with their own wallets and cards. Single view of all transaction types with PDF/CSV export support and fee analytics. Model Context Protocol server for AI agents. Install [`@yativo/mcp-server`](https://www.npmjs.com/package/@yativo/mcp-server) from npm. Get notified instantly on deposits, withdrawals, swaps, card transactions, and more. Manage your plan tier with rate limits, wallet quotas, and feature access. A full-featured sandbox environment for testing your integration without touching real funds. *** ## Supported Chains Yativo Crypto supports 9 blockchains at launch, including Ethereum, Solana, Bitcoin, Polygon, BSC, Base, Arbitrum, Optimism, and XDC. See the [Supported Chains](/yativo-crypto/supported-chains) page for the full list of networks and tokens. *** ## API Base URL | Environment | Base URL | | ----------- | ------------------------------------------- | | Production | `https://crypto-api.yativo.com/api/v1/` | | Sandbox | `https://crypto-sandbox.yativo.com/api/v1/` | *** ## Getting Started The [Quickstart](/yativo-crypto/quickstart) walks you through account creation, API key generation, and your first wallet and transaction in under 10 minutes. Install one of the official SDKs for faster integration. The [TypeScript SDK](/sdks/typescript) and [Python SDK](/sdks/python) are the most feature-complete. Use the [Sandbox environment](/sandbox/overview) to simulate the full transaction lifecycle before going live. # Payment Gateway Source: https://docs.yativo.com/yativo-crypto/payment-gateway Accept stablecoin payments on 9 chains — hosted checkout or pure API, with built-in compliance gating, underpayment reconciliation, and direct wallet settlement The Crypto Payment Gateway lets you accept USDC and USDT on any supported chain. Use the **hosted checkout** (share a link, no frontend work) or the **API** to embed payments directly into your flow. Funds settle into a dedicated **Gateway Account** that Yativo creates and manages for you — withdraw manually or enable [Auto-Forwarding](/yativo-crypto/auto-forwarding) for automatic payouts. *** ## How It Works Before creating payment links, submit a one-time compliance application via `POST /crypto-gateway/apply`. Provide your business type, expected volume, logo, support email, and social media URL. Yativo reviews and approves your account — this typically takes under 24 hours. Call `POST /crypto-gateway/payments` with the amount, title, accepted assets, and an optional description of what the customer is paying for. Your logo, support email, and webhook URL are pulled automatically from your approved application. On the hosted checkout page, the customer first provides their email (used for the on-chain receipt). They then pick from your enabled payment methods and get a deposit address and QR code. Yativo monitors the deposit address. Once confirmed on-chain the payment moves to `paid` and the checkout page auto-refreshes. The net amount (after fees) is credited to your **Gateway Account** — a dedicated Yativo wallet Yativo creates for you. The relevant token wallet is auto-provisioned when you first create a payment intent for that asset. A webhook fires so your backend can fulfil the order. *** ## Key Features Share a URL — no frontend code required. The checkout page collects the customer's email, handles asset selection, shows the description of what they're paying for, and auto-confirms once the on-chain payment lands. Fully programmable. Create links, poll status, and receive webhooks from your backend or SDK integration. Accept USDC and USDT on 9 chains in a single payment link. Customers only see the options you enable. Funds settle into a dedicated Gateway Account automatically provisioned for each merchant. Wallets for each accepted token are created automatically on your first payment intent for that asset. If a customer sends less than required, they can file an underpayment report from the expired checkout page. You verify the on-chain balance and choose to reverse, reconcile, or settle at the paid amount. Track settlement rates, late payments, expired links, preferred tokens, and average checkout-to-confirmed timing — per-merchant and platform-wide. *** ## Compliance Gate Before your first payment link, you must submit a Gateway Application. This is a one-time step. ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/crypto-gateway/apply' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "logo_url": "https://yoursite.com/logo.png", "support_email": "support@yoursite.com", "social_media_url": "https://twitter.com/yourcompany", "business_type": "ecommerce", "expected_volume": "1k_10k", "website_url": "https://yoursite.com", "webhook_url": "https://yoursite.com/webhooks/yativo" }' ``` | Field | Required | Description | | ------------------ | -------- | ---------------------------------------------------------------------------------------------- | | `logo_url` | Yes | HTTPS URL to your brand logo — shown on all checkout pages | | `support_email` | Yes | Customer-facing support email — included in expired checkout links | | `social_media_url` | Yes | Company social media URL for identity verification | | `business_type` | Yes | One of: `ecommerce` `saas` `marketplace` `freelance` `ngo` `gaming` `travel` `finance` `other` | | `expected_volume` | Yes | One of: `under_1k` `1k_10k` `10k_50k` `50k_250k` `over_250k` | | `website_url` | No | Your business website | | `webhook_url` | No | Default webhook for all payment events | Once submitted, your application enters `pending` status. Attempting to create payment links before approval returns a `403` with `error_code: GATEWAY_APPLICATION_REQUIRED`. ```bash theme={null} # Check your application status curl 'https://crypto-api.yativo.com/api/v1/crypto-gateway/application' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Supported Payment Assets | `asset_code` | Token | Network | Standard | | ------------ | ----- | --------- | -------- | | `USDC_SOL` | USDC | Solana | SPL | | `USDT_SOL` | USDT | Solana | SPL | | `USDC_POL` | USDC | Polygon | ERC-20 | | `USDT_POL` | USDT | Polygon | ERC-20 | | `USDC_BASE` | USDC | Base | ERC-20 | | `USDT_BASE` | USDT | Base | ERC-20 | | `USDC_ARB` | USDC | Arbitrum | ERC-20 | | `USDT_ARB` | USDT | Arbitrum | ERC-20 | | `USDC_OP` | USDC | Optimism | ERC-20 | | `USDT_OP` | USDT | Optimism | ERC-20 | | `USDC_AVAX` | USDC | Avalanche | ERC-20 | | `USDT_AVAX` | USDT | Avalanche | ERC-20 | | `USDT_TRON` | USDT | TRON | TRC-20 | USDC on TRON is not supported — Circle deprecated it. Use `USDT_TRON` instead. *** ## Create a Payment Link ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/crypto-gateway/payments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "title": "Invoice #1234", "description": "Pro Plan subscription — April 2026", "requested_amount": 49.99, "accepted_assets": ["USDC_SOL", "USDT_POL", "USDC_BASE"], "customer_email": "alice@example.com", "external_reference": "order_abc123" }' ``` `logo_url`, `support_email`, and `webhook_url` are **not** passed here — they are read automatically from your approved Gateway Application. | Field | Required | Description | | ------------------------ | -------- | ------------------------------------------------------------------------------------------------- | | `title` | Yes | Displayed as the payment title on the checkout page | | `requested_amount` | Yes | Amount in USD (USDC/USDT = 1:1 with USD) | | `accepted_assets` | Yes\* | Array of `asset_code` values — customer picks one | | `asset_code` + `network` | Yes\* | Legacy single-asset format — use `accepted_assets` instead | | `description` | No | Description of the goods or service — shown on checkout and on the receipt email (max 1000 chars) | | `customer_email` | No | Pre-fills the email field on checkout; skips the email collection step | | `external_reference` | No | Your own order ID — echoed back on webhooks | \*One of `accepted_assets` or `asset_code` + `network` is required. ```json Response theme={null} { "success": true, "data": { "payment_id": "pay_a1b2c3d4e5f6", "title": "Invoice #1234", "description": "Pro Plan subscription — April 2026", "requested_amount": 49.99, "status": "awaiting_payment", "checkout_url": "https://crypto-checkout.yativo.com/pay/pay_a1b2c3d4e5f6", "embed_url": "https://crypto-checkout.yativo.com/embed/pay_a1b2c3d4e5f6", "accepted_options": [ { "asset_code": "USDC_SOL", "network": "solana", "deposit_address": "7xKXtg..." }, { "asset_code": "USDT_POL", "network": "polygon", "deposit_address": "0xAbCd..." }, { "asset_code": "USDC_BASE", "network": "base", "deposit_address": "0x1234..." } ], "payment_window_expires_at": "2026-04-18T13:00:00Z", "monitoring_ends_at": "2026-04-18T13:20:00Z" } } ``` Share the `checkout_url` with your customer. Each option has its own pre-provisioned deposit address. *** ## Hosted Checkout Flow The checkout page at `checkout_url`: 1. If multiple assets are accepted, the customer picks one 2. The customer enters their email (skipped if `customer_email` was passed at creation) 3. The payment title and description (if set) are displayed 4. The deposit address and QR code are revealed 5. The customer sends the **exact** asset, on the **exact** network, for the **exact** amount shown 6. The page polls for status and auto-transitions to a success screen once detected on-chain If the payment window expires before funds arrive, the customer sees an expired state with a "I already sent crypto — report it" button that opens the [underpayment report form](#underpayment-reconciliation). *** ## Gateway Account & Settlement When you create your first payment intent, Yativo automatically creates a **Gateway Account** for you. All settlement wallets for your payment intents live inside this account — one wallet per accepted token (e.g. a `USDC_SOL` wallet, a `USDT_POL` wallet, etc.). Gateway Accounts are automatically provisioned by the platform. You cannot create a manual account named "gateway" — that name is reserved. All gateway settlement is tracked separately from your regular Yativo wallets for clean accounting and audit. **Settlement flow:** 1. Customer pays on-chain → deposit received at a platform pool wallet 2. Platform verifies the on-chain transaction amount 3. Net amount (after fees) is credited to your Gateway Account wallet for that token 4. Webhook fires: `gateway.payment.settled` 5. If [Auto-Forwarding](/yativo-crypto/auto-forwarding) is configured on that wallet, funds sweep to your external address automatically **Settlement rules:** | Scenario | Outcome | | ----------------------------------------------- | --------------------------------------------- | | Exact or over-payment within the primary window | `paid` — credited in full | | Payment arrives in the late monitoring window | `paid_late` — same credit rules | | Underpayment (received \< requested) | Settlement rejected — use reconciliation flow | | Payment arrives after monitoring window | Rejected unless admin force-settles | *** ## Underpayment Reconciliation If a customer paid but the amount was short and the window expired, both sides can resolve it without a support ticket. ### Customer side On the expired checkout, the customer clicks **"I already sent crypto — report it"** and submits their sending wallet address, how much they sent, and an optional note. ```bash theme={null} # Public endpoint — no auth required curl -X POST 'https://crypto-api.yativo.com/api/v1/crypto-gateway/pay/pay_a1b2c3d4e5f6/report-underpayment' \ -H 'Content-Type: application/json' \ -d '{ "customer_sending_wallet": "7xKXtgMK...", "reported_amount": 45.00, "customer_email": "alice@example.com", "customer_note": "I accidentally sent USDT instead of USDC." }' ``` ### Merchant side ```bash theme={null} # List reports GET /crypto-gateway/reconciliation?status=pending # Verify the on-chain balance at the gateway wallet POST /crypto-gateway/reconciliation/:reportId/verify # Escalate wrong-token or wrong-network cases to Yativo ops POST /crypto-gateway/reconciliation/:reportId/escalate-recovery # Reverse: queue a refund (verified amount minus admin-configured fee) POST /crypto-gateway/reconciliation/:reportId/reverse # Reconcile: create a new payment link for the shortfall POST /crypto-gateway/reconciliation/:reportId/reconcile # Settle as paid: revise original requested amount to verified amount and settle POST /crypto-gateway/reconciliation/:reportId/settle-as-paid ``` | Status | Description | | ------------------ | --------------------------------------------------------- | | `pending` | Submitted by customer — awaiting merchant verification | | `verified` | On-chain balance confirmed — merchant chooses next action | | `reversing` | Refund queued — ops processing the on-chain transfer | | `reversed` | Refund sent on-chain | | `reconciled` | Reconciliatory payment intent created | | `settled_adjusted` | Original intent settled at revised requested amount | | `dismissed` | Dismissed by merchant or admin | *** ## Check Payment Status This endpoint is **public** — no auth required. ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/crypto-gateway/pay/pay_a1b2c3d4e5f6/status' ``` ```json Response theme={null} { "success": true, "data": { "payment_id": "pay_a1b2c3d4e5f6", "status": "paid", "requested_amount": 49.99, "settled_amount": 49.99, "asset_code": "USDC_SOL", "network": "solana", "transaction_hash": "5K3p...", "late_payment": false, "payment_window_expires_at": "2026-04-18T13:00:00Z" } } ``` *** ## Payment Statuses | Status | Description | | ------------------------ | -------------------------------------------------------------- | | `awaiting_payment` | Link created — waiting for the customer to send funds | | `monitoring_late_window` | Primary window closed; still accepted for a short grace period | | `paid` | Confirmed on-chain within the primary window | | `paid_late` | Confirmed in the late monitoring window | | `expired` | Monitoring window closed with no full payment detected | | `cancelled` | Cancelled by the merchant | *** ## List Payments ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/crypto-gateway/payments' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` Returns the 10 most recent payment intents with status, amounts, accepted options, settlement info, and any reconciliation details. *** ## Gateway Overview ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/crypto-gateway/overview' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` Returns totals for pending, paid, and paid-late payments, plus your Gateway Account wallet balance for each settled asset. *** ## Analytics Track payment performance metrics for your gateway. Useful for understanding customer behaviour, tuning monitoring windows, and measuring settlement health. ```bash theme={null} curl 'https://crypto-api.yativo.com/api/v1/crypto-gateway/analytics/me' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Response theme={null} { "success": true, "data": { "payment_intents_created": 142, "payments_settled": 128, "payments_late": 9, "payments_expired": 5, "customer_claimed_paid_clicks": 130, "late_rate_pct": 7.0, "expired_rate_pct": 3.5, "total_volume_usd": 6384.50, "avg_seconds_window_to_settled": 210.0, "avg_seconds_claimed_to_settled": 180.0, "avg_seconds_late_by": 95.0, "preferred_tokens": [ { "token": "USDC", "chain": "SOL", "settlement_count": 88, "volume_usd": 4400.00 }, { "token": "USDT", "chain": "POL", "settlement_count": 25, "volume_usd": 1250.00 } ] } } ``` | Field | Description | | -------------------------------- | --------------------------------------------------------------------------- | | `avg_seconds_window_to_settled` | Average seconds from payment window open to settlement | | `avg_seconds_claimed_to_settled` | Average seconds from customer clicking "I've Paid" to on-chain confirmation | | `avg_seconds_late_by` | For late payments — how far past the primary window they arrived (seconds) | Use `avg_seconds_late_by` to decide whether to widen your primary payment window. A high `late_rate_pct` with a low `avg_seconds_late_by` (e.g. \< 120 s) indicates customers are consistently on time but the window is slightly too tight. *** ## Webhook Events | Event | Trigger | | --------------------------------------------- | -------------------------------------------------------- | | `gateway.payment_intent.created` | Payment link created | | `gateway.payment.customer_confirmed` | Customer clicked "I've Made This Payment" | | `gateway.payment.settled` | Payment confirmed on-chain and merchant balance credited | | `gateway.payment.paid_late` | Settled during the late monitoring window | | `gateway.payment.expired` | Monitoring window closed without full payment | | `gateway.underpayment.reported` | Customer filed an underpayment report | | `gateway.underpayment.recovery_escalated` | Merchant escalated the report to Yativo ops | | `gateway.underpayment.reversal_queued` | Merchant approved a refund | | `gateway.underpayment.reconciliation_created` | Merchant created a reconciliatory payment link | | `gateway.underpayment.settled_as_paid` | Merchant settled original intent at revised paid amount | *** ## Next Steps Sweep settled funds to an external wallet automatically. Full webhook reference and signature verification. All chains and tokens available on the platform. How wallet addresses are screened on the checkout page. # Quickstart Source: https://docs.yativo.com/yativo-crypto/quickstart Create a wallet and send your first crypto transaction in minutes This guide takes you from zero to a completed on-chain transaction using the Yativo Crypto API. Each step includes examples in cURL, TypeScript, and Python. Before starting, make sure you have a Yativo account with 2FA enabled and an API key with `read`, `write`, and `transactions` permissions. See the [main Quickstart](/yativo/quickstart) if you haven't done this yet. *** Exchange your API credentials for a Bearer token: ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/apikey/token \ -H "Content-Type: application/json" \ -d '{ "api_key": "yvk_live_...", "api_secret": "yvs_live_..." }' ``` ```typescript theme={null} import { YativoCrypto } from '@yativo/sdk'; const client = new YativoCrypto({ apiKey: process.env.YATIVO_API_KEY!, apiSecret: process.env.YATIVO_API_SECRET!, }); // The SDK handles token exchange automatically ``` ```python theme={null} from yativo import YativoCrypto client = YativoCrypto( api_key=os.environ['YATIVO_API_KEY'], api_secret=os.environ['YATIVO_API_SECRET'], ) # The SDK handles token exchange automatically ``` Save the `access_token` — you'll use it as `Authorization: Bearer {token}` in all subsequent requests. Accounts are containers that hold wallets and assets. Create one for your business or for a specific use case: ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/accounts/create-account \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "account_name": "Main Treasury", "account_type": "business" }' ``` ```typescript theme={null} const account = await client.accounts.create({ account_name: 'Main Treasury', account_type: 'business', }); console.log('Account ID:', account.id); ``` ```python theme={null} account = client.accounts.create( account_name='Main Treasury', account_type='business', ) print('Account ID:', account['id']) ``` ```json Response theme={null} { "id": "acc_01abc123", "account_name": "Main Treasury", "account_type": "business", "created_at": "2026-03-26T10:00:00Z" } ``` Save the `id` — you'll need it to add assets. Add a wallet for a specific chain and token to your account: ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/assets/add-asset \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "account_id": "acc_01abc123", "chain": "solana", "ticker": "USDC_SOL" }' ``` ```typescript theme={null} const wallet = await client.assets.add({ account_id: account.id, chain: 'solana', ticker: 'USDC_SOL', }); console.log('Deposit address:', wallet.address); ``` ```python theme={null} wallet = client.assets.add( account_id=account['id'], chain='solana', ticker='USDC_SOL', ) print('Deposit address:', wallet['address']) ``` ```json Response theme={null} { "id": "asset_01xyz789", "account_id": "acc_01abc123", "chain": "solana", "ticker": "USDC_SOL", "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", "balance": "0", "created_at": "2026-03-26T10:01:00Z" } ``` The `address` is your deposit address. Share it with anyone who needs to send funds to this wallet. After funding the wallet (or for an existing asset), check the current balance: ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/balance/check \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{"asset_id": "asset_01xyz789"}' ``` ```typescript theme={null} const balance = await client.balance.check({ asset_id: wallet.id }); console.log('Balance:', balance.balance, balance.ticker); ``` ```python theme={null} balance = client.balance.check(asset_id=wallet['id']) print(f"Balance: {balance['balance']} {balance['ticker']}") ``` ```json Response theme={null} { "asset_id": "asset_01xyz789", "chain": "solana", "ticker": "USDC_SOL", "balance": "100.00", "balance_usd": "100.00", "last_updated": "2026-03-26T10:05:00Z" } ``` Send crypto from your wallet to an external address: ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/transactions/send-funds \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "account": "64b1f9e2a3c4d5e6f7a8b9c0", "assets": "64b1f9e2a3c4d5e6f7a8b9d1", "receiving_address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", "amount": 10, "type": "USDC", "chain": "solana", "category": "payment", "priority": "medium" }' ``` ```typescript theme={null} const tx = await client.transactions.send({ account: wallet.accountId, assets: wallet.id, receiving_address: '9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM', amount: 10, type: 'USDC', chain: 'solana', category: 'payment', priority: 'medium', }); console.log('Transaction ID:', tx.data._id); console.log('Status:', tx.data.status); ``` ```python theme={null} tx = client.transactions.send( account=wallet['account_id'], assets=wallet['id'], receiving_address='9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM', amount=10, type='USDC', chain='solana', category='payment', priority='medium', ) print('Transaction ID:', tx['data']['_id']) print('Status:', tx['data']['status']) ``` ```json Response theme={null} { "status": true, "message": "Transaction Created Successfully", "data": { "_id": "64c2a1f3b4d5e6f7a8b9c0d1", "account": "64b1f9e2a3c4d5e6f7a8b9c0", "assets": "64b1f9e2a3c4d5e6f7a8b9d1", "receiving_address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", "amount": 10, "type": "USDC", "chain": "solana", "category": "payment", "status": "pending", "created_at": "2026-03-26T10:06:00Z" } } ``` The transaction starts as `pending` and moves to `completed` once confirmed on-chain. Set up a [webhook](/yativo-crypto/webhooks) to get notified when it completes. *** ## What's Next Get notified in real time when deposits arrive or transactions complete. See all supported blockchains and tokens. Issue debit cards funded from crypto balances. Test your integration safely without real funds. # Subscriptions & Plans Source: https://docs.yativo.com/yativo-crypto/subscriptions Manage subscription tiers, subscribe to plans, and handle billing automatically The Subscriptions API lets you manage your Yativo account subscription tier. Different tiers unlock higher rate limits, more features, and lower fees. *** ## How It Works 1. **View available plans** — `GET /subscription/plans` returns all pricing tiers 2. **Subscribe** — `POST /subscription/subscribe` to upgrade or change your tier 3. **Manage** — Toggle auto-renewal, view payment history, or cancel *** ## List Plans ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/subscription/plans' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Response theme={null} { "success": true, "data": { "tiers": [ { "id": "tier_free", "name": "Free", "price_usd": 0, "billing_period": "monthly", "features": { "rate_limit": 60, "wallets": 5, "api_keys": 2, "webhooks": 3 } }, { "id": "tier_pro", "name": "Pro", "price_usd": 49, "billing_period": "monthly", "features": { "rate_limit": 300, "wallets": 50, "api_keys": 10, "webhooks": 20 } }, { "id": "tier_enterprise", "name": "Enterprise", "price_usd": 299, "billing_period": "monthly", "features": { "rate_limit": 1000, "wallets": "unlimited", "api_keys": "unlimited", "webhooks": "unlimited" } } ] } } ``` *** ## Get Current Subscription ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/subscription/current' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Response theme={null} { "success": true, "data": { "tier_id": "tier_pro", "tier_name": "Pro", "status": "active", "auto_renew": true, "current_period_start": "2026-03-01T00:00:00Z", "current_period_end": "2026-04-01T00:00:00Z" } } ``` *** ## Subscribe to a Plan ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/subscription/subscribe' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "tier_id": "tier_pro" }' ``` *** ## Toggle Auto-Renewal ```bash theme={null} curl -X PUT 'https://crypto-api.yativo.com/api/v1/subscription/auto-renew' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "auto_renew": false }' ``` *** ## Cancel Subscription ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/subscription/cancel' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` Cancellation takes effect at the end of the current billing period. You retain access to your current tier's features until then. *** ## Payment History ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/subscription/history' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` Returns a list of past subscription payments with amounts, dates, and receipt details. *** ## Next Steps Manage the API keys included in your plan. Track your usage against plan limits. # Supported Chains Source: https://docs.yativo.com/yativo-crypto/supported-chains Blockchains and tokens supported by the Yativo Crypto API Yativo Crypto supports the following blockchains and tokens. Each chain has a set of native and token assets you can use when creating wallets and initiating transactions. *** ## Supported Networks | Chain | Network | Chain ID / Identifier | Native Gas Token | | ------------------- | ------- | --------------------- | ---------------- | | Binance Smart Chain | Mainnet | `BSC` (56) | BNB | | XDC Network | Mainnet | `XDC` (50) | XDC | | Bitcoin | Mainnet | `BTC` | BTC | | Solana | Mainnet | `SOL` | SOL | | Polygon | Mainnet | `POL` (137) | POL | | Base | Mainnet | `Base` (8453) | ETH | | Optimism | Mainnet | `OP` (10) | ETH | | Arbitrum | Mainnet | `ARB` (42161) | ETH | | Tron | Mainnet | `TRON` | TRX | | Avalanche | Mainnet | `AVAX` (43114) | AVAX | | Gnosis Chain (xDAI) | Mainnet | `GNO` (100) | xDAI | *** ## Supported Tokens by Chain ### Binance Smart Chain (BSC) | Ticker | Token | Type | | ------ | ------------ | ------ | | BNB | Binance Coin | Native | ### XDC Network | Ticker | Token | Type | | --------- | -------------- | ------ | | XDC | XDC | Native | | USDC\_XDC | USD Coin (XDC) | XRC20 | | TIVO\_XDC | TIVO | XRC-20 | ### Bitcoin | Ticker | Token | Type | | ------ | ------- | ------ | | BTC | Bitcoin | Native | ### Solana | Ticker | Token | Type | | ---------- | ----------------- | ------ | | SOL | Solana | Native | | USDC\_SOL | USD Coin (Solana) | SPL | | USDT\_SOL | Tether (Solana) | SPL | | EURC\_SOL | EURO Coin | SPL | | PYUSD\_SOL | PayPal USD | SPL | | USDG\_SOL | Global Dollar | SPL | ### Polygon | Ticker | Token | Type | | --------- | ------------------ | ------ | | POL | Polygon | Native | | USDC\_POL | USD Coin (Polygon) | ERC-20 | | USDT\_POL | Tether (Polygon) | ERC-20 | ### Base | Ticker | Token | Type | | ---------- | ---------------- | ------ | | ETH\_Base | Ethereum on Base | Native | | USDC\_BASE | USD Coin (Base) | ERC-20 | | USDT\_BASE | Tether (Base) | ERC-20 | | EURC\_BASE | EURC (Base) | ERC-20 | ### Optimism | Ticker | Token | Type | | -------- | -------------------- | ------------------- | | ETH\_OP | Ethereum on Optimism | Native (L2 gas) | | OP | Optimism | ERC-20 (governance) | | USDC\_OP | USD Coin (Optimism) | ERC-20 | | USDT\_OP | Tether (Optimism) | ERC-20 | ### Arbitrum | Ticker | Token | Type | | --------- | -------------------- | ------------------- | | ETH\_ARB | Ethereum on Arbitrum | Native (L2 gas) | | ARB | Arbitrum | ERC-20 (governance) | | USDC\_ARB | USD Coin (Arbitrum) | ERC-20 | | USDT\_ARB | Tether (Arbitrum) | ERC-20 | ### Tron | Ticker | Token | Type | | ---------- | ------------- | ------ | | TRX | Tron | Native | | USDT\_TRON | Tether (Tron) | TRC-20 | USDC on TRON is not supported. Circle deprecated USDC on TRON — use `USDT_TRON` instead. ### Avalanche | Ticker | Token | Type | | ---------- | -------------------- | ------ | | AVAX | Avalanche | Native | | USDC\_AVAX | USD Coin (Avalanche) | ERC-20 | | USDT\_AVAX | Tether (Avalanche) | ERC-20 | | EURC\_AVAX | EURC (Avalanche) | ERC-20 | ### Gnosis Chain (xDAI) | Ticker | Token | Type | | ---------- | ---------------------------- | ------ | | xDAI | Gnosis Chain | Native | | GNO | Gnosis | ERC-20 | | USDCe\_GNO | USD Coin Bridged (GNO) | ERC-20 | | GBPe\_GNO | Pound Sterling Bridged (GNO) | ERC-20 | | EURe\_GNO | Euro Bridged (GNO) | ERC-20 | ### Chiado Testnet | Ticker | Token | Type | | ------------ | ----------------------------- | ------ | | EURe\_CHIADO | Euro e-money (Chiado Testnet) | ERC-20 | *** ## Gas Tokens Every transaction on an EVM-compatible chain requires the native gas token to pay for network fees. Make sure your wallets (or your [Gas Station](/yativo-crypto/gas-station)) hold sufficient native token for the chain you're using. | Chain | Gas Token | Notes | | ------------------- | --------- | ------------------------------------------------------------------- | | Binance Smart Chain | BNB | Low gas costs | | XDC Network | XDC | Very low gas costs | | Bitcoin | BTC | Fee is included in the transaction amount; set priority accordingly | | Solana | SOL | Flat, very low fees per transaction | | Polygon | POL | Low gas costs, fast finality | | Base | ETH | L2 — gas costs are a fraction of Ethereum mainnet | | Optimism | OP | L2 — significantly cheaper than Ethereum mainnet | | Arbitrum | ARB | L2 — significantly cheaper than Ethereum mainnet | | Tron | TRX | Low gas costs | | Avalanche | AVAX | Low gas costs | | Gnosis Chain (xDAI) | xDAI | Very low gas costs | Use the [Gas Station](/yativo-crypto/gas-station) to pre-fund native token reserves. This lets the platform cover gas fees on behalf of your users so they only need to hold the token they want to transfer. *** ## Fetching Supported Assets via API You can also retrieve the current list of supported chains and assets programmatically: ```bash theme={null} # Get all supported assets curl -X GET https://crypto-api.yativo.com/api/v1/assets/get-all-assets \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" # Get supported chains curl -X GET https://crypto-api.yativo.com/api/v1/assets/get-chains \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` Use these endpoints to dynamically populate chain and token selectors in your UI rather than hardcoding values. # Token Swap Source: https://docs.yativo.com/yativo-crypto/swap Cross-chain and same-chain token swaps with real-time quotes The Swap API lets your users exchange tokens within and across chains. Get a quote, review the rate and fees, then execute when ready. Quotes are time-limited, so execute promptly after receiving one. *** ## Get Swappable Assets **GET** `/swap/assets` Returns all tokens that can be used as swap sources or destinations. ```bash cURL theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/swap/assets \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```json Response theme={null} { "assets": [ { "chain": "ethereum", "ticker": "USDC", "name": "USD Coin" }, { "chain": "solana", "ticker": "USDC_SOL", "name": "USD Coin (Solana)" }, { "chain": "ethereum", "ticker": "ETH", "name": "Ether" }, { "chain": "solana", "ticker": "SOL", "name": "Solana" } ] } ``` *** ## Get Available Routes **GET** `/swap/routes` Returns all valid swap routes — which chain/token pairs can be swapped into which other pairs. ```bash cURL theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/swap/routes \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` *** ## Get a Quote **POST** `/swap/quote` Request a swap quote. Returns the expected output amount, exchange rate, slippage, and fees. The source chain (e.g., `ethereum`). The token to swap from (e.g., `USDC`). The destination chain (e.g., `solana`). The token to swap to (e.g., `USDC_SOL`). Amount to swap, as a decimal string. The sender's address on the source chain. The recipient's address on the destination chain. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/swap/quote \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "from_chain": "ethereum", "from_ticker": "USDC", "to_chain": "solana", "to_ticker": "USDC_SOL", "amount": "500", "from_address": "0x742d35Cc6634C0532925a3b8D4C9C2A5Ef8C2B1", "to_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" }' ``` ```typescript TypeScript theme={null} const quote = await client.swap.quote({ from_chain: 'ethereum', from_ticker: 'USDC', to_chain: 'solana', to_ticker: 'USDC_SOL', amount: '500', from_address: '0x742d35Cc...', to_address: '7xKXtg2CW87d...', }); console.log('Quote ID:', quote.quote_id); console.log('You receive:', quote.to_amount, quote.to_ticker); ``` ```python Python theme={null} quote = client.swap.quote( from_chain='ethereum', from_ticker='USDC', to_chain='solana', to_ticker='USDC_SOL', amount='500', from_address='0x742d35Cc...', to_address='7xKXtg2CW87d...', ) print(f"You receive: {quote['to_amount']} {quote['to_ticker']}") ``` ```json Response theme={null} { "quote_id": "quote_01abc123", "from_chain": "ethereum", "from_ticker": "USDC", "from_amount": "500", "to_chain": "solana", "to_ticker": "USDC_SOL", "to_amount": "498.75", "exchange_rate": "0.9975", "price_impact": "0.05%", "fee_usd": "1.25", "estimated_time_seconds": 120, "expires_at": "2026-03-26T10:11:00Z" } ``` Quotes expire after a short window (typically a few minutes). Execute the swap before `expires_at`. *** ## Execute a Swap **POST** `/swap/execute` Executes a previously quoted swap. The quote ID from the `/swap/quote` response. The asset (wallet) ID to debit the source tokens from. The destination address to receive the swapped tokens. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/swap/execute \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "quote_id": "quote_01abc123", "from_asset_id": "asset_01xyz789", "to_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU" }' ``` ```typescript TypeScript theme={null} const swap = await client.swap.execute({ quote_id: quote.quote_id, from_asset_id: 'asset_01xyz789', to_address: '7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU', }); console.log('Swap ID:', swap.swap_id); console.log('Status:', swap.status); ``` ```json Response theme={null} { "swap_id": "swap_01def456", "quote_id": "quote_01abc123", "status": "processing", "from_chain": "ethereum", "from_ticker": "USDC", "from_amount": "500", "to_chain": "solana", "to_ticker": "USDC_SOL", "expected_to_amount": "498.75", "from_tx_hash": "0xabc123...", "created_at": "2026-03-26T10:06:00Z" } ``` *** ## Swap History **GET** `/swap/history` Returns a list of past swaps. Number of results to return. Defaults to 20. Offset for pagination. Defaults to 0. Filter by status: `processing`, `completed`, `failed`. ```bash cURL theme={null} curl -X GET "https://crypto-api.yativo.com/api/v1/swap/history?limit=20&offset=0&status=completed" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ```json Response theme={null} { "swaps": [ { "swap_id": "swap_01def456", "status": "completed", "from_chain": "ethereum", "from_ticker": "USDC", "from_amount": "500", "to_chain": "solana", "to_ticker": "USDC_SOL", "to_amount": "498.71", "completed_at": "2026-03-26T10:08:20Z" } ], "total": 1, "limit": 20, "offset": 0 } ``` *** ## Swap Statuses | Status | Description | | ------------ | ------------------------------------------------ | | `processing` | Swap initiated, source transaction broadcast | | `completed` | Swap fully settled, destination tokens delivered | | `failed` | Swap failed; source funds are returned | Subscribe to `["*"]` or the `master_wallet.swap` webhook event to get real-time notifications on swap status changes instead of polling the history endpoint. # Transactions Source: https://docs.yativo.com/yativo-crypto/transactions Send crypto, check gas prices, and track transaction status The Transactions API handles all outbound fund movements. You can estimate fees before sending, initiate transfers, and track status through to on-chain confirmation. *** ## Get Gas Price Estimate **POST** `/transactions/get-gas-price` Returns an estimated network fee for a transaction before committing to it. The blockchain to estimate fees for (e.g. `"ethereum"`, `"solana"`, `"polygon"`). Fee priority: `"low"`, `"medium"`, or `"high"`. Defaults to `"low"`. Estimated transaction value in USD. Used to calculate proportional fees on some chains. Asset ObjectId for context-aware fee estimation. Token symbol for context-aware fee estimation (e.g. `"USDC"`). ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/transactions/get-gas-price \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "chainType": "ethereum", "priority": "medium", "amount_usd": "500" }' ``` ```json Response theme={null} { "success": true, "data": { "estimatedFee": 0.00127, "gasFee": 0.00127, "platformFees": 0, "estimatedFeeUSD": 3.18, "nativeToken": "ETH", "chain": "ETH", "inputChain": "ETHEREUM", "priority": "medium", "breakdown": { "gas_cost_usd": "3.18000000", "platform_fees_usd": "0.00000000", "total_cost_usd": "3.18000000", "platform_fee_details": [] } } } ``` *** ## Send Funds **POST** `/transactions/send-funds` Initiates an outbound crypto transfer. An idempotency key is automatically generated to prevent duplicate transactions. The MongoDB ObjectId of the **account** that owns the source asset. The MongoDB ObjectId of the **asset** (wallet) to send from. The recipient's blockchain address. Amount to send, in the token's native units (e.g. `100` for 100 USDC). Token ticker / short name (e.g. `"ETH"`, `"USDC"`, `"SOL"`). Must match the asset record. Blockchain network (e.g. `"ethereum"`, `"solana"`, `"polygon"`). Transaction category: `"personal"`, `"business"`, `"payment"`, `"auto-forward"`, `"other"`, etc. Gas priority: `"low"`, `"medium"`, `"high"`. Defaults to `"medium"`. Optional human-readable note. Pay gas from the wallet's own native balance. Only for native token assets. Defaults to `false`. ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/transactions/send-funds \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "account": "64b1f9e2a3c4d5e6f7a8b9c0", "assets": "64b1f9e2a3c4d5e6f7a8b9d1", "receiving_address": "0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4", "amount": 100, "type": "USDC", "chain": "ethereum", "category": "payment", "priority": "medium" }' ``` ```typescript TypeScript theme={null} const tx = await client.transactions.sendFunds({ account: '64b1f9e2a3c4d5e6f7a8b9c0', assets: '64b1f9e2a3c4d5e6f7a8b9d1', receiving_address: '0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4', amount: 100, type: 'USDC', chain: 'ethereum', category: 'payment', priority: 'medium', }); ``` ```python Python theme={null} tx = client.transactions.send_funds( account='64b1f9e2a3c4d5e6f7a8b9c0', assets='64b1f9e2a3c4d5e6f7a8b9d1', receiving_address='0x9F8b3A2c1E4D7F6B5A4C3D2E1F0A9B8C7D6E5F4', amount=100, type='USDC', chain='ethereum', category='payment', priority='medium', ) ``` ```json Response theme={null} { "status": true, "message": "Transaction Created Successfully", "data": { "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E5", "transaction_hash": "0x9f3e2d1c4b7a5e8f2c9b3d6a1e4c7f2b5d8e1c4a", "gas_tx_hash": null, "platform_fee_tx_hash": null, "gas_amount": "0", "platform_fee": "0.50000000", "gas_funding_markup": "0.12000000", "total_fee": "0.62000000", "fee_breakdown": "N/A" } } ``` ### Idempotency Supply an `Idempotency-Key` header to prevent duplicate transactions on retry. If the same key is submitted again by the same user, the original response is returned instead of creating a new transaction. Without a key, no deduplication is applied. Keys expire after 24 hours. Double-check `receiving_address` before sending. Blockchain transactions are irreversible — funds sent to the wrong address cannot be recovered. *** ## List Transactions **POST** `/transactions/get-transactions` Returns up to 100 transactions for the authenticated user, sorted by most recent. Use the filter parameters to narrow results. Search by `transaction_id` or `transaction_hash` (case-insensitive substring match). Filter by status: `pending`, `completed`, `failed`. Filter by asset ObjectId or asset name substring. Filter by transaction `type` field (e.g. `"USDC"`, `"ETH"`). Filter by blockchain (e.g. `"ethereum"`, `"solana"`). ```bash cURL theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/transactions/get-transactions \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "status_filter": "completed", "chain_filter": "ethereum" }' ``` ```json Response theme={null} { "status": true, "message": "Transactions fetched successfully", "data": [ { "_id": "64b1f9e2a3c4d5e6f7a8b9e0", "transaction_id": "txn_01HX9KZMB3F7VNQP8R2WDGT4E5", "transaction_hash": "0x9f3e2d1c4b7a5e8f2c9b3d6a1e4c7f2b5d8e1c4a", "receiving_address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "amount": "100", "type": "USDC", "chain": "ethereum", "status": "completed", "blockchain_status": "confirmed", "confirmations": 12, "block_number": 19847345, "fee_paid": "0.62000000", "fee_currency": "USDC", "platform_fee_tx_hash": null, "category": "payment", "description": "Payout for order #ORD-9821", "is_autoforward": false, "createdAt": "2026-03-26T10:06:00.000Z" } ] } ``` *** ## Transaction Statuses | Status | Description | | ----------- | ----------------------------------------------------------------------- | | `pending` | Transaction created, waiting to be broadcast to the network | | `completed` | Confirmed on-chain with sufficient block confirmations | | `failed` | Transaction failed (insufficient funds, invalid address, network error) | The `blockchain_status` field tracks on-chain state separately: | blockchain\_status | Description | | ------------------ | --------------------------------------------- | | `pending` | Not yet broadcast | | `confirmed` | Included in a block with enough confirmations | ## Priority Levels | Priority | Speed | Fee | | -------- | --------------------------------------------- | -------- | | `slow` | Slower confirmation, may take several minutes | Lowest | | `medium` | Standard confirmation time | Standard | | `fast` | Prioritized for faster inclusion | Highest | ## Gas Funding for Token Withdrawals When withdrawing token assets (USDC, USDT, etc.) the sending wallet needs native currency for gas. Yativo handles this automatically: * **User Gas Station configured** — gas is funded from the user's own gas station wallet * **No user Gas Station** — the platform Gas Station is used as a fallback * **`use_self_funding: true`** — only valid for native token assets (ETH, SOL, etc.); gas is deducted from the wallet's own balance without a markup In both gas station cases, a **20% service markup** on the estimated gas cost is deducted from your withdrawal amount and returned as `gas_funding_markup` in the response. Ensure `amount` is larger than `platform_fee + gas_funding_markup`. The API returns a `400` if the amount cannot cover total fees. Use webhooks to track transaction status changes in real time instead of polling. See [Webhooks](/yativo-crypto/webhooks) for the `transaction.{type}.completed` and `transaction.failed` event payloads. # Unified Transactions Source: https://docs.yativo.com/yativo-crypto/unified-transactions A single view of all transaction types with PDF/CSV export support The Unified Transaction system aggregates all transaction types — deposits, withdrawals, swaps, card transactions, IBAN transfers, gateway payments, auto-forwarding, and agentic wallet transactions — into a single queryable ledger. You can also export transaction history as PDF or CSV files. *** ## Why Unified Transactions Instead of querying separate endpoints for each transaction type, the unified system gives you: * **One endpoint** to list all transactions regardless of type * **Consistent schema** across deposits, withdrawals, swaps, card spends, IBAN transfers, and more * **Export** to PDF (branded) or CSV for accounting and compliance * **Fee tracking** with per-transaction fee breakdowns * **Analytics** with aggregated volume, fee totals, and type distribution *** ## List Unified Transactions ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/unified-transactions/list?page=1&limit=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Response theme={null} { "success": true, "data": { "transactions": [ { "transaction_id": "utx_01abc123", "type": "deposit", "status": "completed", "amount": "500.00", "asset": "USDC", "chain": "solana", "from_address": "7xKXtg2CW87d...", "to_address": "GY1EZGdpiJNyx...", "tx_hash": "5xYz...", "fee_amount": "0.00", "created_at": "2026-03-26T10:00:00Z" }, { "transaction_id": "utx_02def456", "type": "card_transaction", "status": "completed", "amount": "25.99", "asset": "EUR", "merchant_name": "Amazon", "card_last_four": "4242", "created_at": "2026-03-26T11:00:00Z" } ], "pagination": { "page": 1, "limit": 20, "total": 150 } } } ``` *** ## Transaction Types | Type | Description | | --------------------- | -------------------------------------- | | `deposit` | Incoming crypto deposit | | `withdrawal` | Outbound crypto transfer | | `swap` | Token swap (cross-chain or same-chain) | | `fee` | Platform fee deduction | | `auto_forwarding` | Automatically forwarded deposit | | `card_transaction` | Yativo Card spend at a merchant | | `iban_transfer` | IBAN bank transfer (EUR) | | `gateway_payment` | Crypto payment gateway receipt | | `agentic_transaction` | AI agent wallet transaction | *** ## Get Transaction Details ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/unified-transactions/utx_01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Calculate Fees Preview the fees for a transaction before executing: ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/unified-transactions/calculate-fees' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "type": "withdrawal", "amount": "100.00", "chain": "ethereum" }' ``` *** ## Analytics Get aggregated transaction analytics with fee breakdowns: ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/unified-transactions/analytics-with-fees' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Export Transactions Export your transaction history as a branded PDF report or a CSV spreadsheet. ### Request an Export ```bash theme={null} curl -X POST 'https://crypto-api.yativo.com/api/v1/unified-transactions/export' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "format": "pdf", "date_from": "2026-03-01", "date_to": "2026-03-31", "types": ["deposit", "withdrawal", "swap"] }' ``` ```json Response theme={null} { "success": true, "data": { "export_id": "exp_01abc123", "format": "pdf", "status": "processing", "created_at": "2026-04-01T12:00:00Z" } } ``` ### List Exports ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/unified-transactions/export/list' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ### Download an Export ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/unified-transactions/export/exp_01abc123/download' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ --output transactions.pdf ``` Export files are available for **24 hours** after generation. *** ## Next Steps Full endpoint reference for unified transactions. Get notified on transaction events. Dashboard-level transaction analytics. # Webhooks Source: https://docs.yativo.com/yativo-crypto/webhooks Real-time event notifications for crypto deposits, withdrawals, swaps, cards, and more Yativo Crypto fires webhook events for every significant state change across wallets, transactions, cards, IBAN accounts, and system events. Configure webhooks once and your server stays in sync without polling. For webhook management (creating, updating, deleting webhook endpoints), see the [Webhook Management](/yativo/webhooks) docs. This page covers the crypto-specific event types and their payloads. ```typescript theme={null} interface Webhook { webhook_id: string; url: string; events: string[]; // ["*"] for all events secret: string; // only returned at create time or GET single enabled: boolean; description?: string; last_success_at?: string; last_failure_at?: string; consecutive_failures: number; created_at: string; updated_at: string; } interface CreateWebhookRequest { url: string; // required — must be HTTPS events?: string[]; // default ["*"] — all events description?: string; } type WebhookEventType = // Deposits | "deposit.detected" | "deposit.confirmed" // Transactions | "transaction.initiated" | "transaction.submitted" | "transaction.failed" // IBAN | "iban.activated" | "iban.transfer.received" // KYC | "kyc.submitted" | "kyc.approved" | "kyc.rejected" | "kyc.pending_review" // Card lifecycle | "card.created" | "card.activated" | "card.frozen" | "card.unfrozen" | "card.voided" | "card.lost" | "card.stolen" | "card.cancelled" | "card.deactivated" // Card transactions | "transaction.authorized" | "transaction.declined" | "transaction.settled" | "transaction.reversed" | "transaction.refund.created" // Customer & master wallet funding | "customer.funded" | "customer.funding.failed" | "customer.balance.updated" | "master_wallet.deposit" | "master_wallet.swap" | "master_wallet.customer_funded"; ``` *** ## Crypto Event Types ### Deposit Events | Event | Fired When | | ------------------- | ----------------------------------------------------------------- | | `deposit.detected` | An inbound transaction is detected on-chain (unconfirmed) | | `deposit.confirmed` | An inbound transaction has reached sufficient block confirmations | ### Transaction Events | Event | Fired When | | ------------------------------ | ----------------------------------------------------------------------------------- | | `transaction.initiated` | An outbound transaction has been created and queued | | `transaction.submitted` | A transaction has been broadcast to the blockchain | | `transaction.failed` | A transaction failed for any reason | | `transaction.{type}.completed` | A transaction of the given type completed (e.g. `transaction.withdrawal.completed`) | ### Card Events | Event | Fired When | | ------------------------------- | ----------------------------------------------------- | | `card.created` | A new card has been issued | | `card.activated` | A card has been activated and is ready to use | | `card.frozen` | A card has been temporarily frozen | | `card.unfrozen` | A frozen card has been re-enabled | | `card.voided` | A card has been voided | | `card.lost` | A card has been marked as lost | | `card.stolen` | A card has been reported stolen | | `card.cancelled` | A card has been cancelled | | `card.deactivated` | A card has been permanently deactivated | | `transaction.authorized` | A card transaction has been authorized | | `transaction.declined` | A card transaction was declined | | `transaction.settled` | A card transaction has settled | | `transaction.reversed` | A card transaction has been reversed | | `transaction.refund.created` | A refund has been initiated for a card transaction | | `customer.funded` | A card customer's balance has been topped up | | `customer.funding.failed` | A funding transfer to a customer's card wallet failed | | `customer.balance.updated` | A card customer's balance has changed | | `master_wallet.deposit` | A deposit arrived in the card program master wallet | | `master_wallet.swap` | A swap executed in the card program master wallet | | `master_wallet.customer_funded` | Master wallet funds allocated to a customer | ### IBAN Events | Event | Fired When | | ------------------------ | ---------------------------------------------------------------- | | `iban.activated` | An IBAN account has been activated and is ready to receive funds | | `iban.transfer.received` | A SEPA transfer has been received into the IBAN account | ### KYC Events | Event | Fired When | | -------------------- | ------------------------------------------ | | `kyc.submitted` | A KYC submission has been received | | `kyc.approved` | A KYC check has been approved | | `kyc.rejected` | A KYC check has been rejected | | `kyc.pending_review` | A KYC submission is awaiting manual review | *** ## Webhook Payload Examples All payloads share the same envelope structure: ```json theme={null} { "id": "evt_01abc123", "type": "", "created_at": "2026-03-26T10:05:00Z", "data": { ... } } ``` ### deposit.confirmed ```json theme={null} { "id": "evt_01abc123", "type": "deposit.confirmed", "created_at": "2026-03-26T10:05:00Z", "data": { "asset_id": "asset_01xyz789", "account_id": "acc_01abc123", "chain": "solana", "ticker": "USDC_SOL", "amount": "250.00", "from_address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", "to_address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU", "tx_hash": "5KtP3jNHGXi8YmD2L9sRZVAoWqFcBe4TrKlUvJpMxNy", "confirmations": 1, "new_balance": "750.00" } } ``` ### transaction.failed ```json theme={null} { "id": "evt_03ghi789", "type": "transaction.failed", "created_at": "2026-03-26T10:10:00Z", "data": { "transaction_id": "txn_02stu789", "chain": "ethereum", "ticker": "USDC", "amount": "1000.00", "error_code": "insufficient_balance", "error_message": "Wallet balance (400.00 USDC) is less than requested amount (1000.00 USDC)" } } ``` ### transaction.settled ```json theme={null} { "id": "evt_05mno345", "type": "transaction.settled", "created_at": "2026-03-26T11:00:00Z", "data": { "card_id": "card_01abc", "transaction_id": "card_txn_01xyz", "merchant_name": "Amazon", "merchant_category": "Shopping", "amount": "49.99", "currency": "USD", "status": "settled", "new_balance": "450.01" } } ``` ### iban.transfer.received ```json theme={null} { "id": "evt_06pqr678", "type": "iban.transfer.received", "created_at": "2026-03-26T12:00:00Z", "data": { "iban_id": "iban_01abc", "iban_number": "DE89370400440532013000", "amount": "1000.00", "currency": "EUR", "sender_name": "John Smith", "sender_iban": "GB29NWBK60161331926819", "reference": "Invoice #INV-2026-042", "received_at": "2026-03-26T12:00:00Z" } } ``` ### gas.low ```json theme={null} { "id": "evt_07stu901", "type": "gas.low", "created_at": "2026-03-26T11:00:00Z", "data": { "station_id": "station_01abc123", "chain": "ethereum", "ticker": "ETH", "balance": "0.08", "balance_usd": "200.00", "threshold": "0.10" } } ``` *** ## Signature Verification Every webhook delivery is signed with a timestamp to prevent replay attacks. Two headers are sent: | Header | Value | | -------------------- | ------------------------ | | `X-Yativo-Signature` | `sha256=` | | `X-Yativo-Timestamp` | Unix timestamp (seconds) | The HMAC is computed over `"${timestamp}.${JSON.stringify(payload)}"`: ```typescript theme={null} import crypto from 'crypto'; function verifyWebhookSignature( payload: object, signature: string, // value of X-Yativo-Signature header timestamp: string, // value of X-Yativo-Timestamp header secret: string // your webhook secret (starts with whsec_) ): boolean { // Reject if timestamp is more than 5 minutes old const ts = parseInt(timestamp, 10); if (Math.abs(Date.now() / 1000 - ts) > 300) return false; const signedPayload = `${timestamp}.${JSON.stringify(payload)}`; const expected = 'sha256=' + crypto .createHmac('sha256', secret) .update(signedPayload) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); } ``` See the [Webhook Integration guide](/guides/webhook-integration) for Python and PHP examples. *** ## Setting Up Webhooks All events — deposits, swaps, card lifecycle, card transactions, customer funding — are delivered through a single webhook service. Register once at `POST /v1/webhook/create-webhook` and subscribe to any combination of event types. The HTTPS endpoint to receive events. Event slugs to subscribe to. Pass `["*"]` (or omit) to receive all events. Optional label for this subscription. ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/webhook/create-webhook \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-server.com/webhooks/yativo", "events": ["deposit.confirmed", "transaction.authorized", "transaction.settled", "card.created"], "description": "Production webhook" }' ``` ```json Response theme={null} { "status": true, "message": "Webhook created successfully", "data": { "webhook_id": "664abc123def456789000001", "url": "https://your-server.com/webhooks/yativo", "events": ["deposit.confirmed", "transaction.authorized", "transaction.settled", "card.created"], "secret": "whsec_abc123def456...", "created_at": "2026-03-26T10:00:00.000Z" } } ``` Store the `secret` securely. It is also retrievable later via `GET /v1/yativo-card/webhooks/:webhookId`. Use it to verify `X-Yativo-Signature` on every delivery. #### List card webhooks **GET** `/yativo-card/webhooks` ```bash theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/yativo-card/webhooks \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` #### Get a card webhook (includes secret) **GET** `/yativo-card/webhooks/:webhookId` ```bash theme={null} curl -X GET https://crypto-api.yativo.com/api/v1/yativo-card/webhooks/664abc123def456789000001 \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` #### Update a card webhook **PUT** `/yativo-card/webhooks/:webhookId` ```bash theme={null} curl -X PUT https://crypto-api.yativo.com/api/v1/yativo-card/webhooks/664abc123def456789000001 \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "events": ["*"], "enabled": true }' ``` Set `"enabled": false` to pause delivery without deleting the subscription. #### Delete a card webhook **DELETE** `/yativo-card/webhooks/:webhookId` ```bash theme={null} curl -X DELETE https://crypto-api.yativo.com/api/v1/yativo-card/webhooks/664abc123def456789000001 \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` #### Rotate the signing secret **POST** `/yativo-card/webhooks/:webhookId/rotate-secret` Generates a new secret and invalidates the old one immediately. ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/yativo-card/webhooks/664abc123def456789000001/rotate-secret \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` #### Delivery history **GET** `/yativo-card/webhooks/:webhookId/deliveries` Query params: `limit`, `offset`, `status`, `eventType` ```bash theme={null} curl -X GET 'https://crypto-api.yativo.com/api/v1/yativo-card/webhooks/664abc123def456789000001/deliveries?limit=20&status=failed' \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` **GET** `/yativo-card/webhooks/deliveries/all` — All deliveries across all subscriptions. #### Retry a failed delivery **POST** `/yativo-card/webhooks/deliveries/:deliveryId/retry` ```bash theme={null} curl -X POST https://crypto-api.yativo.com/api/v1/yativo-card/webhooks/deliveries/664abc000000000000000099/retry \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` # Accept Payments Source: https://docs.yativo.com/yativo-fiat/accept-payments Receive deposits and payments from customers via local payment methods and virtual accounts To receive money, create virtual accounts for your customers. Customers pay into their assigned virtual account using local payment rails (bank transfer, PIX, SPEI, SEPA, etc.). You receive a webhook notification when funds arrive. Customers must have KYC approved (`is_va_approved: true`) before you can issue them a virtual account. *** ## Step 1: Get Supported Pay-in Countries Retrieve the list of countries where Yativo supports incoming payments: ``` GET /payment-methods/payin/countries ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payin/countries' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": [ { "country": "Brazil", "iso3": "BRA", "iso2": "BR" }, { "country": "Mexico", "iso3": "MEX", "iso2": "MX" }, { "country": "Chile", "iso3": "CHL", "iso2": "CL" } ] } ``` *** ## Step 2: Get Supported Currencies for a Country Once you know the destination country, retrieve which currencies are available for deposits: ``` GET /payment-methods/payin/currency?country={countryCode} ``` ISO 3166-1 alpha-2 country code (e.g. `BR`, `MX`, `CL`). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payin/currency?country=BR' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Step 3: Create a Virtual Account for a Customer Issue a local bank account number to your customer for a specific currency: ``` POST /business/virtual-account/create ``` The ID of the KYC-approved customer to issue the account to. Currency for the virtual account. Supported values: `USDBASE`, `EURBASE`, `EURDE`, `MXN`, `MXNBASE`, `MXNUSD`, `BRL`. ```bash Brazil (PIX / BRL) theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "BRL" }' ``` ```bash Mexico (SPEI / MXN) theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "MXNBASE" }' ``` ```bash USD (ACH / Wire) theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "USDBASE" }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Virtual account creation in progress", "data": { "account_id": "va_xxxxxx", "account_number": "9900123456", "account_type": "savings", "currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "created_at": "2026-04-01T10:00:00Z" } } ``` *** ## Step 4: List Virtual Accounts Retrieve all virtual accounts, with optional filters: ``` GET /business/virtual-account ``` Filter by currency code (e.g. `BRL`, `USD`). Filter by account status. From date (ISO 8601). Search query (account number, customer name, etc.). Results per page. Page number. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account?currency=BRL&per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Step 5: Get Virtual Account Transaction History Retrieve payment history for a specific virtual account: ``` POST /business/virtual-account/history/{account_number} ``` The account number (not the account ID). Filter by customer. Filter by payment status. From date (ISO 8601). To date (ISO 8601). Page number. Results per page. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/history/9900123456?start_date=2026-04-01&end_date=2026-04-30' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": [ { "amount": 1000, "currency": "BRL", "status": "completed", "credited_amount": 950, "transaction_id": "TXNMP2HK81BHJ", "sender_name": "John Smith", "account_number": "9900123456", "transaction_fees": 50 } ] } ``` *** ## Alternative: Gateway-Based Deposits (Quote Flow) For payment gateways that involve a hosted checkout (rather than a push to a standing account number), use the two-step quote flow. ### Step 1: Quote the deposit Call `POST /exchange-rate` with `method_type: "payin"` and the gateway's `method_id` to lock the exchange rate and get a `quote_id`: ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/exchange-rate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "from_currency": "BRL", "to_currency": "USD", "method_id": 15, "method_type": "payin", "amount": 1000 }' ``` ### Step 2: Initiate the deposit Pass the `quote_id` to lock the rate, plus a `redirect_url` for after the customer completes payment on the hosted page: ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/deposits/new' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: deposit-001' \ -d '{ "gateway": 15, "quote_id": "QUOTE_ID_FROM_STEP_1", "currency": "USD", "redirect_url": "https://your-app.com/deposit/complete" }' ``` The response contains a `checkout_url` — redirect the customer there to complete the payment. Once done they return to your `redirect_url` and you receive a `deposit.completed` webhook. Use virtual accounts (Step 3 above) for recurring or standing deposit addresses. Use the gateway quote flow when the customer initiates a one-time payment on a specific date and you want to lock the rate before they pay. *** ## Alternative: Crypto Deposits To accept cryptocurrency deposits, retrieve your crypto wallet addresses: ``` GET /crypto/get-wallets ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/crypto/get-wallets' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Webhooks for Deposit Notifications Configure a webhook endpoint to be notified in real-time when a deposit arrives. See the [Webhooks](/yativo-fiat/webhooks) guide for setup. Key events for deposits: | Event | Triggered when | | ------------------------- | ----------------------------------------------------- | | `virtual_account.deposit` | Payment arrives at a customer's virtual account | | `deposit.created` | A new deposit is initiated | | `deposit.updated` | A deposit status changes (e.g. `pending` → `success`) | Example `virtual_account.deposit` payload: ```json theme={null} { "event.type": "virtual_account.deposit", "payload": { "amount": 1000, "currency": "BRL", "status": "completed", "credited_amount": 950, "transaction_id": "TXNMP2HK81BHJ", "customer": { "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "customer_name": "Jane Doe" } } } ``` Respond with a `2xx` status within 10 seconds to acknowledge receipt. Failed deliveries are retried automatically. # Accounts & Wallets Source: https://docs.yativo.com/yativo-fiat/accounts Understand how wallets and virtual accounts work in the Yativo fiat platform The Yativo fiat platform uses two types of account structures: **wallets** (your business's multi-currency balances) and **virtual accounts** (deposit addresses assigned to your customers). *** ## Your Business Wallets Your Yativo account comes with one or more currency wallets. Wallets hold your settlement balances and are the source of funds for payouts. You can create additional wallets for different currencies as needed. | Endpoint | Description | | --------------------------- | ------------------------------------------------ | | `GET /wallet/balance` | Returns balances for all your active wallets | | `GET /wallet/balance/total` | Returns the aggregate balance across all wallets | | `POST /wallet/create` | Create a new currency wallet | See the [Wallets](/yativo-fiat/wallets) guide for full documentation including request and response examples. *** ## Customer Virtual Accounts Virtual accounts are bank accounts assigned to a specific customer. When a third party sends funds to a virtual account number, the deposit is credited to the corresponding customer and a `virtual_account.deposit` webhook fires. | Endpoint | Description | | -------------------------------------------------------------- | -------------------------------------- | | `POST /business/virtual-account/create` | Issue a virtual account for a customer | | `GET /business/virtual-account` | List all virtual accounts | | `GET /business/virtual-account/show/{id}` | Get a single virtual account | | `DELETE /business/virtual-account/delete-virtual-account/{id}` | Delete a virtual account | | `POST /business/virtual-account/history/{account_number}` | Get transaction history for an account | See the [Virtual Accounts](/yativo-fiat/virtual-accounts) guide for the full walkthrough. *** ## Wallet vs. Virtual Account | | Wallet | Virtual Account | | -------------- | -------------------------------------- | ------------------------------------------------- | | **Owner** | Your business | An end customer | | **Purpose** | Hold settlement balances, fund payouts | Receive deposits on behalf of a customer | | **Currency** | USD, EUR, and others | Local currency (BRL, CLP, MXN, etc.) | | **Created by** | Dashboard or `POST /wallet/create` | `POST /business/virtual-account/create` | | **Funded by** | Payins, topped up | Customer or third party sending to account number | *** ## Supported Currencies To retrieve all currencies supported by the platform: ``` GET /currencies/all ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/currencies/all' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Next Steps * [Wallets](/yativo-fiat/wallets) — manage your business wallet balances and payouts * [Virtual Accounts](/yativo-fiat/virtual-accounts) — issue accounts to customers for receiving deposits * [Deposits](/yativo-fiat/deposits) — track and process incoming payments # Currencies & Assets Source: https://docs.yativo.com/yativo-fiat/assets Discover supported currencies, exchange rates, and payment corridors Yativo supports a growing list of fiat currencies across payment corridors in Latin America, North America, Europe, and Africa. Use the endpoints on this page to discover what's available before building your integration. *** ## Supported Currencies Returns all currencies available on the platform. ``` GET /currencies/all ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/currencies/all' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "code": "USD", "name": "US Dollar", "symbol": "$" }, { "code": "EUR", "name": "Euro", "symbol": "€" }, { "code": "BRL", "name": "Brazilian Real", "symbol": "R$" }, { "code": "MXN", "name": "Mexican Peso", "symbol": "$" }, { "code": "CLP", "name": "Chilean Peso", "symbol": "$" }, { "code": "PEN", "name": "Peruvian Sol", "symbol": "S/" }, { "code": "COP", "name": "Colombian Peso", "symbol": "$" }, { "code": "ARS", "name": "Argentine Peso", "symbol": "$" }, { "code": "NGN", "name": "Nigerian Naira", "symbol": "₦" } ] } ``` *** ## Payout Countries Returns the list of countries where outbound payments are supported: ``` GET /payment-methods/payout/countries ``` ``` GET /payment-methods/payout?country={iso3} ``` Use the second endpoint with a country's ISO 3166-1 alpha-3 code to see the specific payment rails available (SPEI, PIX, bank transfer, etc.) and their required form fields. See [Send Money](/yativo-fiat/send-money) for the full flow. *** ## Payin Countries Returns the list of countries where incoming deposits are supported: ``` GET /payment-methods/payin/countries ``` ``` GET /payment-methods/payin/currency?country={iso2} ``` Use the second endpoint to retrieve payin-specific currencies and gateways for a country. See [Accept Payments](/yativo-fiat/accept-payments) for the full deposit flow. *** ## Exchange Rates Get a live exchange rate with fee breakdown: ``` POST /exchange-rate ``` ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/exchange-rate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "from_currency": "USD", "to_currency": "BRL", "amount": 1000 }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "from_currency": "USD", "to_currency": "BRL", "rate": "4.9820", "amount": "1000.00", "payout_data": { "total_transaction_fee_in_from_currency": "15.00", "total_transaction_fee_in_to_currency": "74.73", "customer_sent_amount": "1000.00", "customer_receive_amount": "4907.27", "customer_total_amount_due": "1015.00" } } } ``` This endpoint is rate-limited to 30 requests per minute. To lock in a rate for payment execution, use `POST /sendmoney/quote` — see [Exchange Rates](/yativo-fiat/exchange-rates) for a full comparison. *** ## Verification Locations Returns countries where Yativo supports customer KYC/KYB onboarding: ``` GET /auth/verification-locations ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/auth/verification-locations' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Next Steps * [Exchange Rates](/yativo-fiat/exchange-rates) — live rates and locked quotes * [Accept Payments](/yativo-fiat/accept-payments) — deposit flows by country * [Send Money](/yativo-fiat/send-money) — payout flows by country # Authentication Source: https://docs.yativo.com/yativo-fiat/authentication Sign up at app.yativo.com and authenticate with your API credentials ## Get Started Create your Yativo account at [app.yativo.com](https://app.yativo.com). The dashboard uses **passwordless authentication** — enter your email, receive a 5-digit OTP, and you're in. Google OAuth is also supported. After signing up, complete the **Business KYC** onboarding to unlock API access. This includes submitting your company details, uploading documents, and verifying UBOs (Ultimate Beneficial Owners). Once approved, retrieve your **Account ID** and generate your **App Secret** from the **Developer** section of the dashboard (Developer → API Key). *** ## Environments | Environment | Base URL | | ----------- | -------------------------------- | | Production | `https://api.yativo.com/api/v1` | | Sandbox | `https://smtp.yativo.com/api/v1` | Use the sandbox environment for development and testing. No real funds are moved in sandbox. *** ## Generate a Bearer Token All API requests require a Bearer token. For **server-to-server / programmatic API access**, authenticate with your Account ID and App Secret: ``` POST /auth/login ``` Your Account ID from the Yativo dashboard (Settings → Account). Your App Secret generated from Developer → API Key. Treat this like a password. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/auth/login' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "your_account_id", "app_secret": "your_app_secret" }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ account_id: process.env.YATIVO_ACCOUNT_ID, app_secret: process.env.YATIVO_APP_SECRET, }), }); const { data } = await response.json(); const token = data.access_token; ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...", "token_type": "bearer", "expires_in": 600 } } ``` Tokens expire in **600 seconds** (10 minutes). Refresh before expiry to maintain uninterrupted API access. *** ## Get Your API Keys 1. Log in to [app.yativo.com](https://app.yativo.com) 2. Go to **Developer → API Key** 3. Click **Generate Secret** 4. Enter your 4-digit **transaction PIN** when prompted 5. Copy and securely store your **App Secret** — it is shown only once Your **Account ID** is displayed in the same section. It looks like: ``` Account ID: acct_01HXAB3F7VNQP8R2WDGT4E5 App Secret: yat_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ123456789 ``` The App Secret is displayed only once. If you lose it, generate a new one — this invalidates the previous secret. You can also programmatically generate a new secret after verifying your PIN: ``` GET /generate-secret ``` *** ## Using the Bearer Token Include the token in the `Authorization` header for all subsequent requests: ``` Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9... ``` ```bash theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/balance' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Refresh Token Refresh an expiring token without re-authenticating with your credentials: ``` GET /auth/refresh-token ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/auth/refresh-token' \ -H 'Authorization: Bearer YOUR_CURRENT_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...", "expires_in": 600 } } ``` *** ## Idempotency All `POST`, `PUT`, and `PATCH` requests require an `Idempotency-Key` header. This ensures safe retries without risk of duplicate operations. ``` Idempotency-Key: ``` Use a UUID or any unique identifier you generate per request. On retry, Yativo returns the original response without re-processing. ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_TOKEN' \ -H 'Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000' \ -H 'Content-Type: application/json' \ -d '{ ... }' ``` *** ## Two-Factor Authentication (2FA) 2FA is optional but strongly recommended for your dashboard account. Enable it under **Developer → Security → 2FA**. To set up 2FA programmatically: 1. **Generate a 2FA secret** — `POST /generate-2fa-secret` → returns a secret to add to your authenticator app 2. **Enable 2FA** — `POST /enable-2fa` → activates 2FA on your account 3. **Verify a 2FA code** — `POST /verify-2fa` with `{ "otp": "6-digit" }` → returns your app secret after 2FA confirmation *** ## Security Best Practices * Store `account_id` and `app_secret` in environment variables or a secrets manager — never hardcode them or commit to source control. * Rotate your `app_secret` immediately if you suspect it has been compromised. * Use the sandbox environment (`https://smtp.yativo.com/api/v1`) for all development and testing. * Enable 2FA on your dashboard account. * Use short-lived tokens and refresh them proactively before expiry (before 600 seconds). # Beneficiaries Source: https://docs.yativo.com/yativo-fiat/beneficiaries Store and manage recipient profiles for recurring payouts Beneficiaries are saved recipient profiles. Create them once, attach their bank details as a payment method, and reference them by ID in every transfer — no need to re-enter account details for each payment. ```typescript theme={null} interface Beneficiary { beneficiary_id: string; name: string; email: string; type: "individual" | "business"; country: string; // ISO 3166-1 alpha-3 created_at: string; } interface CreateBeneficiaryRequest { name: string; // Full name or legal business name email: string; type: "individual" | "business"; country: string; // ISO 3166-1 alpha-3 } interface BeneficiaryPaymentMethod { id: string; beneficiary_id: string; payment_method_id: number; account_details: Record; created_at: string; } interface PayoutMethod { id: number; method_name: string; country: string; currency: string; base_currency: string; } ``` *** ## List beneficiaries ``` GET /beneficiaries/list ``` Results per page (default: 15). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/beneficiaries/list' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "beneficiary_id": "ben-7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "name": "Maria Gonzalez", "email": "maria.gonzalez@example.com", "type": "individual", "country": "CHL", "created_at": "2026-04-02T10:00:00.000000Z" }, { "beneficiary_id": "ben-8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e", "name": "Tech Solutions SA", "email": "payments@techsolutions.mx", "type": "business", "country": "MEX", "created_at": "2026-03-20T09:00:00.000000Z" } ], "pagination": { "total": 18, "per_page": 15, "current_page": 1, "last_page": 2 } } ``` *** ## Create beneficiary Create a beneficiary profile. Bank account details are saved separately via the payment methods endpoint below. ``` POST /beneficiaries ``` Recipient's full name (individual) or legal business name. Recipient's email address. `"individual"` or `"business"`. Destination country in ISO 3166-1 alpha-3 format (e.g. `CHL`, `MEX`, `BRA`). ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: create-beneficiary-001' \ -d '{ "name": "Maria Gonzalez", "email": "maria.gonzalez@example.com", "type": "individual", "country": "CHL" }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Beneficiary created successfully", "data": { "beneficiary_id": "ben-7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "name": "Maria Gonzalez", "email": "maria.gonzalez@example.com", "type": "individual", "country": "CHL", "created_at": "2026-04-02T10:00:00.000000Z" } } ``` *** ## Supported payout countries ``` GET /payment-methods/payout/countries ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout/countries' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": [ { "name": "Chile", "code": "CHL" }, { "name": "Mexico", "code": "MEX" }, { "name": "Brazil", "code": "BRA" } ] } ``` *** ## Payout methods by country Returns available payment rails and their integer IDs for a destination country. The `id` from this response is used as `payment_method_id` in subsequent steps. ``` GET /payment-methods/payout?country={iso3} ``` Destination country in ISO 3166-1 alpha-3 format (e.g. `CHL`, `MEX`, `BRA`). ```bash Mexico theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout?country=MEX' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success (Mexico) theme={null} { "status": "success", "data": [ { "id": 30, "method_name": "SPEI", "country": "MEX", "currency": "MXN", "base_currency": "MXN" } ] } ``` *** ## Payment method form fields Retrieve the exact bank detail fields required for a payment method before saving them. ``` GET /beneficiary/form/show/{payment_method_id} ``` The integer payment method ID from the `/payment-methods/payout` response. ```bash SPEI (Mexico, id=30) theme={null} curl -X GET 'https://api.yativo.com/api/v1/beneficiary/form/show/30' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Save payment method Attach bank account details to a beneficiary. Use the form fields returned above to know exactly which keys are required. ``` POST /beneficiaries/payment-methods ``` The beneficiary to attach the payment method to. The integer payment method ID from `/payment-methods/payout`. Key-value pairs of the required fields for this payment method (returned by `GET /beneficiary/form/show/{id}`). ```bash Mexico SPEI theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: save-pm-001' \ -d '{ "beneficiary_id": "ben-7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "payment_method_id": 30, "account_details": { "clabe": "012345678901234567" } }' ``` ```bash Chile bank transfer theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: save-pm-002' \ -d '{ "beneficiary_id": "ben-7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "payment_method_id": 21, "account_details": { "account_number": "12345678", "bank_code": "001", "account_type": "checking" } }' ``` *** ## List payment methods ``` GET /beneficiaries/payment-methods/all ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/beneficiaries/payment-methods/all' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Update payment method ``` PUT /beneficiaries/payment-methods/update/{id} ``` The payment method record ID. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/beneficiaries/payment-methods/update/pm-3a4b5c6d' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: update-pm-001' \ -d '{ "account_details": { "clabe": "018345678901234567" } }' ``` *** ## Delete payment method ``` DELETE /beneficiaries/payment-methods/delete/{id} ``` The payment method record ID. ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/beneficiaries/payment-methods/delete/pm-3a4b5c6d' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` # Customers Source: https://docs.yativo.com/yativo-fiat/customers Create and manage end-customer profiles Customers are end-users of your platform. Once created, customers can be assigned virtual accounts, attached to payins/payouts, and verified through KYC/KYB. ```typescript theme={null} interface Customer { customer_id: string; customer_name: string; customer_email: string; customer_phone: string; customer_country: string; // ISO 3166-1 alpha-3 (e.g. "USA", "BRA") customer_status: "active" | "inactive"; customer_kyc_status: "not_started" | "pending" | "approved" | "rejected" | null; customer_kyc_reject_reason: string | null; created_at: string; kyc_verified_date?: string; } interface CreateCustomerRequest { customer_name: string; customer_email: string; customer_phone: string; // E.164 format (e.g. "+5511999999999") customer_country: string; // ISO 3166-1 alpha-3 customer_type?: "individual" | "business"; // defaults to "individual" } ``` *** ## Create customer ``` POST /customer ``` Customer's full name. Customer's email address. Customer's phone number in E.164 format (e.g. `"+5511999999999"`). Customer's country — ISO 3166-1 **alpha-3** code (e.g. `"BRA"`, `"USA"`, `"MEX"`). `"individual"` (default) or `"business"`. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "customer_name": "Jane Doe", "customer_email": "jane@example.com", "customer_phone": "+5511999999999", "customer_country": "BRA", "customer_type": "individual" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "customer_id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "customer_name": "Jane Doe", "customer_email": "jane@example.com", "customer_phone": "+5511999999999", "customer_country": "BRA", "customer_status": "active", "created_at": "2026-03-26T10:00:00.000000Z" } } ``` *** ## Get customer Retrieve a single customer's profile. By default only the core profile fields are returned. Use the `include` query parameter to embed related data in the same response. ``` GET /customer/{customer_id} ``` The customer ID (UUID). Comma-separated list of relations to embed. Accepted values: `deposits`, `payouts`, `virtualaccounts`, `virtual_cards`, `crypto_wallets`. Pass `all` to include every relation at once. **Examples** * `?include=all` * `?include=deposits,payouts` * `?include=virtualaccounts,virtual_cards` ```bash All relations theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx?include=all' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Specific relations theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx?include=deposits,virtualaccounts' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Profile only (no include) theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success (?include=all) theme={null} { "status": "success", "status_code": 200, "message": "Customer retrieved successfully", "data": { "customer_id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "customer_name": "Jane Doe", "customer_email": "jane@example.com", "customer_phone": "+5511999999999", "customer_country": "BRA", "customer_status": "active", "customer_kyc_status": "approved", "customer_kyc_reject_reason": null, "created_at": "2026-03-26T10:00:00.000000Z", "kyc_verified_date": "2026-03-26T12:00:00.000000Z", "customer_deposit": [ { "transaction_id": "txn_xxxxxx", "transaction_amount": "500.00", "transaction_currency": "BRL", "transaction_status": "Complete", "transaction_purpose": "Top-up", "created_at": "2026-03-27T08:00:00.000000Z" } ], "customer_payouts": [ { "transaction_id": "txn_yyyyyy", "transaction_amount": "200.00", "transaction_currency": "BRL", "transaction_payout_details": { "status": "Complete" }, "created_at": "2026-03-28T09:00:00.000000Z" } ], "customer_virtualaccounts": [ { "account_id": "va_xxxxxx", "currency": "BRL", "account_number": "BRLPIX0000000000000000000000000000000000", "customer_id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx" } ], "customer_virtual_cards": [], "customer_crypto_wallets": [] } } ``` ```json Profile only (no include param) theme={null} { "status": "success", "status_code": 200, "message": "Customer retrieved successfully", "data": { "customer_id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "customer_name": "Jane Doe", "customer_email": "jane@example.com", "customer_phone": "+5511999999999", "customer_country": "BRA", "customer_status": "active", "customer_kyc_status": "approved", "customer_kyc_reject_reason": null, "created_at": "2026-03-26T10:00:00.000000Z", "kyc_verified_date": "2026-03-26T12:00:00.000000Z" } } ``` The `include` parameter is **additive** — fields not included in the request are simply omitted from the response rather than returning empty arrays. *** ## List all customers ``` GET /customer ``` Supports filtering by `kyc_status`, `country`, `email`, and pagination via `page` / `per_page`. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer?page=1&per_page=15' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Records retrieved successfully", "data": [ { "customer_id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "customer_name": "Jane Doe", "customer_email": "jane@example.com", "customer_phone": "+5511999999999", "customer_country": "BRA", "customer_status": "active", "customer_kyc_status": "approved", "created_at": "2026-03-26T10:00:00.000000Z" } ], "pagination": { "total": 142, "per_page": 15, "current_page": 1, "last_page": 10 } } ``` *** ## Update customer Update mutable fields on a customer record. Only include the fields you want to change. ``` PUT /customer/{customer_id} ``` ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/customer/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: update-customer-001' \ -d '{ "customer_phone": "+5511988887777" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Customer updated successfully", "data": { "customer_id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "customer_name": "Jane Doe", "customer_phone": "+5511988887777", "updated_at": "2026-04-02T14:00:00.000000Z" } } ``` *** ## Delete customer ``` DELETE /customer/{customer_id} ``` ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/customer/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Customer deleted successfully" } ``` *** ## Check KYC status ``` GET /customer/kyc/{customer_id} ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/kyc/xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "first_name": "Jane", "last_name": "Doe", "status": "approved", "kyc_rejection_reasons": [], "kyc_requirements_due": [], "bio_data": { "customer_id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx", "customer_name": "Jane Doe", "customer_kyc_status": "approved", "kyc_verified_date": "2026-03-26T12:00:00.000000Z" }, "kyc_link": "https://checkout.yativo.com/kyc/update-biodata/xxxxx-xxxxx-xxx-xxxx-xxxx", "is_va_approved": true } } ``` Once `is_va_approved` is `true`, the customer can be issued virtual accounts. See the [KYC/KYB](/yativo-fiat/kyc) page for submitting identity verification. # Deposits (Payins) Source: https://docs.yativo.com/yativo-fiat/deposits Accept incoming payments from customers via local payment rails A payin creates a payment link your customer uses to send funds. First discover the right payment gateway for the destination currency, then create the payin — optionally locking an exchange rate with a [quote](/yativo-fiat/exchange-rate) first. ```typescript theme={null} interface PayinGateway { id: number; method_name: string; country: string; // ISO 3166-1 alpha-3 currency: string; base_currency: string; } interface CreatePayinRequest { gateway: number; // ID from /payment-methods/payin currency: string; // currency of the deposit amount?: number; // required if no quote_id quote_id?: string; // from /exchange-rate (locks rate for 5 mins) customer_id?: string; // attach to a specific customer redirect_url?: string; // redirect after payment } interface PayinResponse { id: string; deposit_url: string; // send this to your customer amount: number; currency: string; gateway: string; status: "pending" | "success" | "failed"; receive_amount: string; customer_id?: string; created_at: string; } ``` *** ## Step 1 — Find your gateway ID ### Supported payin countries Returns countries available for receiving payments (ISO 3166-1 **alpha-3** codes). ``` GET /payment-methods/payin/countries ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payin/countries' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "iso3": "BRA", "name": "brazil" }, { "iso3": "CHL", "name": "chile" }, { "iso3": "MEX", "name": "mexico" }, { "iso3": "COL", "name": "colombia" }, { "iso3": "PER", "name": "peru" } ] } ``` ### Gateway ID by country and currency ``` GET /payment-methods/payin?country={iso3}¤cy={code} ``` Country ISO 3166-1 alpha-3 code (e.g. `CHL`, `BRA`, `MEX`). Currency code (e.g. `CLP`, `BRL`, `MXN`). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payin?country=CHL¤cy=CLP' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": 22, "method_name": "Bank Transfer", "country": "CHL", "currency": "CLP", "base_currency": "CLP" }, { "id": 23, "method_name": "Bank Transfer", "country": "CHL", "currency": "CLP", "base_currency": "USD" } ] } ``` Note the `id` — this is your `gateway` value in the payin request. *** ## Step 2 — Create a payin ``` POST /wallet/deposits/new ``` Gateway ID from Step 1. Currency of the deposit (e.g. `"CLP"`, `"BRL"`, `"MXN"`). Quote ID from [`/exchange-rate`](/yativo-fiat/exchange-rate). Locks the rate for 5 minutes. **Recommended** — amount is taken from the quote. Amount to collect. Required if `quote_id` is not provided. Uses current market rate. Attach this deposit to a specific customer wallet. URL to redirect the customer after payment is completed. ```bash With quote ID (recommended) theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/deposits/new' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "gateway": 22, "currency": "CLP", "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "customer_id": "xxxxxx-xxxx-xxxx-xxxxxx", "redirect_url": "https://yourapp.com/payment/success" }' ``` ```bash Without quote ID (market rate) theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/deposits/new' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "gateway": 22, "amount": 10000, "currency": "CLP" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "deposit_url": "https://checkout.yativo.com/process-payin/b3150e03-xxxx-4de3-a0ff-xxxxxxxxxx/paynow", "deposit_data": { "currency": "CLP", "deposit_currency": "USD", "amount": 10000, "gateway": 22, "receive_amount": 9, "customer_id": "948a039f-9883-xxxx-88a6-xxxxxxxxx", "id": "b3150e03-d27e-4de3-a0ff-16ebeb55683c", "created_at": "2026-03-18T15:52:43.000000Z" }, "payment_info": { "send_amount": "10000 CLP", "receive_amount": "9 USD", "exchange_rate": "1 USD = 936.0336 CLP", "transaction_fee": "1236.03 CLP", "payment_method": "Bank Transfer", "estimate_delivery_time": "6 Minute(s)", "total_amount_due": "10000 CLP" } } } ``` Send `deposit_url` to your customer — they complete payment through Yativo's hosted checkout. *** ## List deposits ``` GET /wallet/deposits/ ``` Filter by `gateway`, `currency`, `start_date`, or `end_date` as query parameters. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/deposits/?currency=CLP&start_date=2026-03-01&end_date=2026-03-31' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Records retrieved successfully", "data": [ { "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx", "amount": 10000, "gateway": "22", "currency": "CLP", "status": "success", "deposit_currency": "USD", "receive_amount": "9.36", "customer_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx", "created_at": "2026-03-15T10:00:00.000000Z" } ], "pagination": { "total": 7, "per_page": 10, "current_page": 1, "last_page": 1 } } ``` *** ## Stablecoin funding Fund your Yativo USD balance using stablecoins (USDC or EURC on Solana) to use for payouts or fee payments. ### Generate a deposit wallet address ``` POST /crypto/create-wallet ``` `"USDC_SOL"` or `"EURC_SOL"`. Pass a customer ID to generate a deposit address for a specific customer's account. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/crypto/create-wallet' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "currency": "USDC_SOL" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "coin_name": "USDC_SOL", "wallet_address": "7TzXXXXXXXXXXXXX", "wallet_network": "SOL", "wallet_status": "active", "wallet_balance": "0" } } ``` ### Retrieve your deposit wallet addresses ``` GET /crypto/get-wallets ``` ### Deposit history ``` GET /crypto/deposit-histories ``` For a specific wallet address: ``` GET /crypto/wallet/deposit/histories/{wallet_address} ``` *** ## Recommended workflow ``` # Option A: With locked rate (recommended) 1. POST /exchange-rate → get quote_id (rate locked 5 minutes) 2. POST /wallet/deposits/new → create payin using quote_id # Option B: Market rate 1. POST /wallet/deposits/new → create payin with amount directly ``` # Developer Tools Source: https://docs.yativo.com/yativo-fiat/developer API keys, transaction PIN, 2FA, event logs, and request logs The Developer section of your Yativo dashboard provides all the tools you need to manage API access, audit usage, and secure your integration. *** ## API Keys Your API credentials consist of: * **Account ID** — found in Dashboard → Settings → Account * **App Secret** — generated in Dashboard → Developer → API Key ### Generate App Secret A 4-digit transaction PIN is required before generating a new App Secret. ``` GET /generate-secret ``` ```bash cURL theme={null} # First verify your PIN curl -X POST 'https://api.yativo.com/api/v1/pin/verify' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "pin": "1234" }' # Then generate a new secret curl -X GET 'https://api.yativo.com/api/v1/generate-secret' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": { "app_secret": "yat_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ123456789" } } ``` Generating a new secret invalidates your previous App Secret immediately. Update all systems that use the old secret before regenerating. *** ## Transaction PIN The 4-digit transaction PIN is required for sensitive operations: generating a new App Secret, initiating large transfers, and certain administrative actions. ### Set or Update PIN ``` POST /pin/update ``` Your new 4-digit numeric PIN. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/pin/update' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "pin": "5678" }' ``` ### Verify PIN ``` POST /pin/verify ``` Your current 4-digit PIN. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/pin/verify' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "pin": "5678" }' ``` *** ## Two-Factor Authentication (2FA) Enable 2FA on your dashboard account for additional security (Dashboard → Developer → Security → 2FA). ### Step 1: Generate a 2FA Secret ``` POST /generate-2fa-secret ``` Returns a secret to enter into your authenticator app (Google Authenticator, Authy, etc.): ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/generate-2fa-secret' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Idempotency-Key: unique-key-here' ``` ### Step 2: Enable 2FA ``` POST /enable-2fa ``` After scanning the QR code in your authenticator app: ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/enable-2fa' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Idempotency-Key: unique-key-here' ``` ### Step 3: Verify a 2FA Code ``` POST /verify-2fa ``` The 6-digit OTP from your authenticator app. ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/verify-2fa' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "otp": "123456" }' ``` *** ## Webhooks Configure and manage webhook endpoints for real-time event notifications. See the [Webhooks](/yativo-fiat/webhooks) guide for full details. * `GET /business/webhook` — get current webhook configuration * `POST /business/webhook` — set webhook URL * `PUT /business/webhook/{webhook_id}` — update webhook URL *** ## API Request Logs Audit every API call made against your account: ``` GET /business/logs/all ``` Filter by HTTP status code (e.g. `200`, `400`, `500`). Filter by HTTP method: `GET`, `POST`, `PUT`, `DELETE`. Page number. Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/logs/all?method=POST&status=400&per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Events View all events sent to your webhook endpoint and inspect individual event payloads. ### List All Events ``` GET /business/events/all ``` Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/events/all?per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ### Get Single Event ``` GET /business/events/show/{id} ``` The event ID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/events/show/evt_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` # Exchange Rates & Quotes Source: https://docs.yativo.com/yativo-fiat/exchange-rates Generate locked quotes for payouts and deposits, or fetch live rates for display The `POST /exchange-rate` endpoint is the single source for pricing any transaction on Yativo. It returns a `quote_id` valid for 5 minutes — use this ID in the execution step to guarantee the rate and fee shown to your customer. There are two modes: | Mode | When to use | | ------------------------------------ | ------------------------------------------------------------------ | | **With `method_id` + `method_type`** | Quote a specific payment method — returns exact fees for that rail | | **Without `method_id`** | Generic FX rate for display only | ```typescript theme={null} interface ExchangeRateRequest { from_currency: string; // source currency (ISO 4217) to_currency: string; // target currency (ISO 4217) amount: number; // amount in source currency method_id?: number; // payment method ID (from /payment-methods/payout or /payin) method_type?: "payout" | "payin"; // required when method_id is provided } interface Quote { quote_id: string; // valid for 5 minutes — use in /wallet/payout or /wallet/deposits/new from_currency: string; to_currency: string; rate: string; amount: string; payout_data: { total_transaction_fee_in_from_currency: string; total_transaction_fee_in_to_currency: string; customer_sent_amount: string; customer_receive_amount: string; customer_total_amount_due: string; // total deducted from wallet }; calculator: { amount_due: number; exchange_rate: number; fee_breakdown: { float: { wallet_currency: number; payout_currency: number }; fixed: { wallet_currency: number; payout_currency: number }; total: number; }; PayoutMethod?: { // present when method_id was provided id: number; method_name: string; country: string; currency: string; base_currency: string; }; }; } ``` *** ## Generate a Quote ``` POST /exchange-rate ``` Source currency (ISO 4217), e.g. `"USD"`, `"EUR"`. Target currency (ISO 4217), e.g. `"USD"`, `"CLP"`, `"BRL"`, `"MXN"`. Amount in the source currency. Payment method ID from `GET /payment-methods/payout` or `GET /payment-methods/payin`. Scopes the quote to the exact fees for that rail — required for checkout flows where you will execute at the quoted price. `"payout"` for sends/withdrawals or `"payin"` for deposits. Required when `method_id` is provided. ```bash Payout quote (USD → USD via PayPal, method 21) theme={null} curl -X POST 'https://api.yativo.com/api/v1/exchange-rate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "from_currency": "USD", "to_currency": "USD", "method_id": 21, "method_type": "payout", "amount": 406 }' ``` ```bash FX display only (no method) theme={null} curl -X POST 'https://api.yativo.com/api/v1/exchange-rate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "from_currency": "USD", "to_currency": "MXN", "amount": 200 }' ``` ```javascript Node.js theme={null} const res = await fetch('https://api.yativo.com/api/v1/exchange-rate', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ from_currency: 'USD', to_currency: 'USD', method_id: 21, method_type: 'payout', amount: 406, }), }); const { data } = await res.json(); // Show data.payout_data to customer, then use data.quote_id in /wallet/payout ``` ```json With method_id theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "from_currency": "USD", "to_currency": "USD", "rate": "1.00000000", "amount": "406.00000000", "payout_data": { "total_transaction_fee_in_from_currency": "11.15000000", "total_transaction_fee_in_to_currency": "11.15", "customer_sent_amount": "406.00", "customer_receive_amount": "406.00", "customer_total_amount_due": "417.15" }, "calculator": { "total_fee": { "wallet_currency": 11.15, "payout_currency": 11.15, "usd": 11.15 }, "amount_due": 417.15, "exchange_rate": 1, "fee_breakdown": { "float": { "wallet_currency": 10.15, "payout_currency": 10.15 }, "fixed": { "wallet_currency": 1, "payout_currency": 1 }, "total": 11.15 }, "PayoutMethod": { "id": 21, "method_name": "PayPal", "country": "PER", "currency": "USD", "base_currency": "USD" } } } } ``` Quotes expire after **5 minutes**. Execute the transaction within this window — after expiry the `quote_id` is rejected and a new quote is required. *** ## Execute the Quote Use the `quote_id` in the appropriate execution endpoint: ### For payouts ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: payout-001' \ -d '{ "debit_wallet": "USD", "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "amount": 406, "payment_method_id": 21 }' ``` ### For deposits (payin) ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/deposits/new' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: deposit-001' \ -d '{ "gateway": 20, "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "currency": "USD", "redirect_url": "https://your-app.com/deposit/complete" }' ``` *** ## Get a Locked Quote for Send Money For sending money specifically (rather than wallet payouts), use the dedicated send money quote endpoint which also returns a `quote_id`: ``` POST /sendmoney/quote ``` ```bash USD → MXN theme={null} curl -X POST 'https://api.yativo.com/api/v1/sendmoney/quote' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: quote-001' \ -d '{ "from_currency": "USD", "to_currency": "MXN", "amount": 200, "beneficiary_payment_method_id": "pm-3a4b5c6d-7e8f-9a0b" }' ``` *** ## Complete Quote Workflow ``` 1. GET /payment-methods/payout?country=... → get method_id (e.g. 21) 2. POST /exchange-rate → quote with method_id + method_type → shows exact fees to customer → returns quote_id (5-min window) 3. POST /wallet/payout (or /deposits/new) → execute with quote_id 4. GET /transaction/tracking/{id} → monitor status ``` *** ## Fee Breakdown The `calculator.fee_breakdown` object contains two fee components: | Component | Description | | --------- | --------------------------------------------------------- | | `float` | Percentage-based fee — scales with amount | | `fixed` | Flat fee — charged regardless of amount | | `total` | Sum of float + fixed in both wallet and payout currencies | Always display `payout_data.customer_total_amount_due` to the customer — this is the exact amount that will be debited from their wallet. *** ## Rate Limits The exchange rate endpoint is limited to **30 requests per minute** per API key. Cache quotes client-side for display rather than calling on every user keystroke. # Gift Cards Source: https://docs.yativo.com/yativo-fiat/gift-cards Purchase and redeem digital gift cards from hundreds of global brands Yativo's gift card API lets you purchase digital gift cards across hundreds of brands globally — ideal for rewards programs, employee incentives, or customer cashback products. The cost is deducted from your USD wallet at purchase time. *** ## List Gift Card Categories Browse available gift card categories to help filter the product catalog. ``` GET https://api.yativo.com/api/v1/giftcards/categories ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/giftcards/categories' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Categories fetched successfully", "data": [ { "id": 1, "name": "Entertainment" }, { "id": 2, "name": "Gaming" }, { "id": 3, "name": "Shopping" }, { "id": 4, "name": "Food & Dining" }, { "id": 5, "name": "Travel" } ] } ``` *** ## List Available Gift Cards Browse all purchasable gift card products. Filter by country or category. ``` GET https://api.yativo.com/api/v1/giftcards ``` Filter by ISO 3166-1 alpha-2 country code (e.g. `US`, `BR`, `MX`, `NG`). Filter by category ID from the categories endpoint. ```bash All US gift cards theme={null} curl -X GET 'https://api.yativo.com/api/v1/giftcards?country=US' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Gaming cards theme={null} curl -X GET 'https://api.yativo.com/api/v1/giftcards?category_id=2' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Operators retrieved successfully", "data": [ { "id": 1, "name": "Amazon US", "brand": "Amazon", "country": "US", "currency": "USD", "min_amount": 1, "max_amount": 500, "fixed_amounts": [10, 25, 50, 100], "category": "Shopping" }, { "id": 2, "name": "Netflix US", "brand": "Netflix", "country": "US", "currency": "USD", "min_amount": 15, "max_amount": 100, "fixed_amounts": [15, 25, 50, 100], "category": "Entertainment" } ] } ``` *** ## Purchase a Gift Card Purchase a gift card for a specific product. The amount is debited from your USD wallet. ``` POST https://api.yativo.com/api/v1/giftcards ``` Requires `Idempotency-Key` header. The cost is charged to your wallet at purchase time — purchases are non-refundable. The gift card product ID from the list endpoint. Face value of the gift card in its native currency. Must be within the product's `min_amount` and `max_amount` range, or match one of its `fixed_amounts`. Number of cards to purchase (default: 1). Email address to deliver the gift card code to. Optional — if omitted, the code is returned in the API response only. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/giftcards' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: giftcard-amazon-001' \ -d '{ "product_id": 1, "amount": 50, "quantity": 1, "recipient_email": "jane@example.com" }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/giftcards', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `gc-${Date.now()}`, }, body: JSON.stringify({ product_id: 1, amount: 50, quantity: 1, recipient_email: 'jane@example.com', }), }); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Giftcard request submitted successfully", "data": { "transaction_id": "gc-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "product_name": "Amazon US", "amount": 50, "currency": "USD", "status": "completed", "created_at": "2026-06-01T10:00:00.000000Z" } } ``` ```json Insufficient balance theme={null} { "status": "error", "status_code": 402, "message": "Insufficient wallet balance" } ``` ```json Validation error theme={null} { "status": "error", "status_code": 422, "message": "Validation Error", "data": { "product_id": ["The product id field is required."], "amount": ["The amount field is required."] } } ``` *** ## Redeem / Get Card Instructions Retrieve the redemption instructions and gift card code for a completed gift card purchase. ``` GET https://api.yativo.com/api/v1/giftcards/redeem/{transactionId} ``` The `transaction_id` returned from the purchase endpoint. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/giftcards/redeem/gc-a1b2c3d4-e5f6-7890-abcd-ef1234567890' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Giftcard instruction retrieved successfully", "data": { "transaction_id": "gc-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "product_name": "Amazon US", "redemption_code": "AMZN-XXXX-XXXX-XXXX", "pin": "1234", "instructions": "Visit amazon.com/redeem and enter your gift card code.", "expiry_date": "2028-06-01" } } ``` Gift card redemption codes are sensitive. Treat them like cash — display them only to the intended recipient and do not log them in your application. # Welcome to Yativo Fiat Source: https://docs.yativo.com/yativo-fiat/introduction Cross-border payments, virtual accounts, and financial infrastructure for businesses Yativo Fiat is a cross-border payment infrastructure platform for businesses. Send money globally, receive deposits via local payment rails, issue virtual accounts to your customers, manage KYC/KYB compliance, and access multiple payment networks — all through a single unified API. *** ## What You Can Build Issue virtual accounts so customers can pay via local bank transfer, PIX, SPEI, SEPA, and more. Receive webhook notifications when funds arrive. Send cross-border payments to beneficiaries via local bank transfers, SPEI, ACH, SEPA, and LATAM rails. Lock exchange rates with quotes before executing. Issue dedicated local bank account numbers per customer for automatic payment matching and reconciliation. Issue prepaid virtual Visa/Mastercard cards to your customers for online spending, funded from your wallet balance. Manage multi-currency wallet balances. Hold USD, EUR, BRL, CLP, MXN, COP, PEN, ARS and more. Create and manage customer profiles. Submit KYC/KYB for compliance and unlock features like virtual accounts and virtual cards. *** ## How It Works Sign up at [app.yativo.com](https://app.yativo.com). Authentication is passwordless — enter your email, receive a 5-digit OTP, and you're in. Submit your company details, upload required documents, and verify your UBOs (Ultimate Beneficial Owners). This unlocks full API access. Go to **Developer → API Key** in your dashboard. Generate your App Secret (PIN verification required). Note your Account ID. Call `POST /auth/login` with your Account ID and App Secret to get a Bearer token (valid 10 minutes). Use this token in all API requests. Create customers, issue virtual accounts, send money, and receive payments — all via the API. *** ## Supported Regions & Payment Rails | Region | Countries | Rails | | ------------- | -------------------------------- | -------------------- | | Latin America | Brazil | PIX | | Latin America | Mexico | SPEI | | Latin America | Chile, Peru, Colombia, Argentina | Local bank transfer | | North America | United States | ACH, Wire | | Europe | Eurozone | SEPA Credit Transfer | Contact your integration team for additional corridors not listed here. *** ## Key Concepts | Concept | Description | | -------------------- | --------------------------------------------------------------------------------------------- | | **Customers** | End users your business serves. Must pass KYC before receiving virtual accounts or cards. | | **Virtual Accounts** | Local bank account numbers assigned to a customer for receiving funds on specific rails. | | **Beneficiaries** | Recipients for outbound payments. Save their bank details for reuse. | | **Wallets** | Your multi-currency balance pools. Fund payouts from your wallet. | | **Quotes** | Rate-locked exchange calculations valid for 5 minutes. Use quote IDs when executing payments. | | **Webhooks** | Real-time event notifications sent to your server (e.g. deposit completed, KYC approved). | *** ## Environments | Environment | URL | | ------------------ | ---------------------------------------- | | **Dashboard** | [app.yativo.com](https://app.yativo.com) | | **Production API** | `https://api.yativo.com/api/v1` | | **Sandbox API** | `https://smtp.yativo.com/api/v1` | *** ## Next Steps Get your first payment working in under 10 minutes. Learn how to authenticate and secure your API calls. # IP Allowlisting Source: https://docs.yativo.com/yativo-fiat/ip-allowlist Restrict API access to a specific set of trusted IP addresses IP allowlisting lets you lock down your Yativo API integration so that only requests originating from your approved server IPs are accepted. Any API call from an unregistered IP returns `403 Forbidden`. This is a strongly recommended security control for production integrations — particularly for payout and wallet operations. IP allowlisting is enforced at the API level. Once you add any IP address, requests from all other IPs will be rejected. Only add IPs after you have confirmed your server's outbound IP address. *** ## List Allowlisted IPs ``` GET https://api.yativo.com/api/v1/ip ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/ip' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": "ip-a1b2c3", "ip_address": "203.0.113.10", "label": "Production server", "created_at": "2026-04-01T10:00:00.000000Z" } ] } ``` *** ## Add IP Address ``` POST https://api.yativo.com/api/v1/ip ``` Requires `Idempotency-Key` header. The IPv4 address to allowlist (e.g. `"203.0.113.10"`). CIDR ranges are not supported — add individual IPs. A descriptive label for this IP (e.g. `"Production server"`, `"CI/CD runner"`). ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/ip' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: add-ip-001' \ -d '{ "ip_address": "203.0.113.10", "label": "Production server" }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/ip', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `add-ip-${Date.now()}`, }, body: JSON.stringify({ ip_address: '203.0.113.10', label: 'Production server', }), }); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "IP addresses whitelisted and added to firewall." } ``` *** ## Update IP Address ``` PUT https://api.yativo.com/api/v1/ip/{id} ``` The IP record ID to update. The new IP address to replace the existing one. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/ip/ip-a1b2c3' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: update-ip-001' \ -d '{ "ip_address": "203.0.113.20" }' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "IP addresses updated and added to firewall." } ``` *** ## Remove IP Address ``` DELETE https://api.yativo.com/api/v1/ip/{id} ``` Removing all IPs effectively disables allowlisting — all IPs will be permitted again. If you want to maintain the restriction, always keep at least one IP in the list. The IP record ID to remove. ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/ip/ip-a1b2c3' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "IP address removed from whitelist and firewall." } ``` ```json Not found theme={null} { "status": "error", "status_code": 400, "message": "IP address not found" } ``` # KYC / KYB Verification Source: https://docs.yativo.com/yativo-fiat/kyc Verify individual customers (KYC) and business customers (KYB) to unlock virtual accounts and payment rails Yativo requires identity verification before customers can access payment services such as virtual accounts, send money, and payment rails. Individual users go through **KYC** (Know Your Customer) and businesses go through **KYB** (Know Your Business). ## Environments | Environment | Base URL | | -------------- | -------------------------------- | | Production API | `https://api.yativo.com/api/v1` | | Sandbox API | `https://smtp.yativo.com/api/v1` | | KYC Platform | `https://kyc.yativo.com` | KYC and KYB submissions are sent to **`https://kyc.yativo.com`**, not the main API base URL. All other endpoints (status check, update) use the standard base URL. Include `Authorization: Bearer {token}` in every request. *** ## Integration approaches | Approach | Best for | Effort | | ----------------------- | ------------------------------- | ------ | | **Hosted KYC/KYB link** | Quick integration, iframe embed | Low | | **API submission** | Programmatic flow, native UI | High | **Hosted URLs:** * Individual: `https://kyc.yativo.com/individual/{customer_id}` * Business: `https://kyc.yativo.com/business/{customer_id}` *** ## Verification flow Call `POST /customer` to create a customer record and receive a `customer_id`. Use `POST /storage/upload` to upload files and receive back a hosted URL. Pass those URLs in the KYC payload. Alternatively, embed files as base64-encoded strings. POST to `https://kyc.yativo.com/api/individual-kyc/submit` or `https://kyc.yativo.com/api/business-kyc/submit`. Check `GET /customer/kyc/{customer_id}` or listen for the `kyc.status_updated` webhook event. When `status` is `"approved"` and `is_va_approved` is `true`, service endorsements are activated and payment rails become available. *** ## Upload documents Before submitting KYC, upload any document files you will reference. Files must be PDF, JPG, JPEG, PNG, HEIC, or TIF and must not exceed **5 MB** each. ``` POST /storage/upload ``` Send the file as `multipart/form-data` with the field name `document`. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/storage/upload' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -F 'document=@/path/to/passport_front.jpg' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "url": "https://storage.yativo.com/documents/abc123/passport_front.jpg" } } ``` Use the returned `url` value in the `selfie_image`, `image_front_file`, `proof_of_address_file`, and similar fields below. *** ## Individual KYC ### Submit ``` POST https://kyc.yativo.com/api/individual-kyc/submit ``` This is a five-step data model submitted in one payload. All required fields must be present in a single request. #### Step 1 — Personal details | Field | Type | Required | Notes | | -------------- | ------------------ | -------- | ------------------------------------------------------------------------ | | `customer_id` | string | ✓ | UUID from `POST /customer` | | `first_name` | string | ✓ | Max 1024 chars | | `last_name` | string | ✓ | Max 1024 chars | | `middle_name` | string | | Optional | | `email` | string | ✓ | Valid email address | | `calling_code` | string | ✓ | Dial code, e.g. `"+1"`, `"+234"`. Must match `^\+\d{1,4}$` | | `phone` | string | ✓ | Digits only, 8–15 characters | | `birth_date` | string | ✓ | `YYYY-MM-DD`, must be before today | | `nationality` | string | ✓ | ISO 3166-1 alpha-2, e.g. `"US"`, `"NG"`, `"BR"` | | `gender` | string | ✓ | `"male"` or `"female"` | | `taxId` | string | ✓ | Tax identification number, max 100 chars | | `selfie_image` | file URL or base64 | ✓ | Selfie photo. PDF/JPG/JPEG/PNG/HEIC/TIF, max 5 MB | | `bvn` | string | NG only | 11-digit Bank Verification Number. Required when `nationality` is `"NG"` | | `nin` | string | NG only | 11-digit National ID Number. Required when `nationality` is `"NG"` | #### Step 2 — Residential address | Field | Type | Required | Notes | | ------------------------------------------- | ------------------ | -------- | ---------------------------------------------------------------------- | | `residential_address.street_line_1` | string | ✓ | Max 256 chars | | `residential_address.street_line_2` | string | | Optional | | `residential_address.city` | string | ✓ | Max 256 chars | | `residential_address.state` | string | ✓ | Accepts `"US-CA"` or `"CA"` — both are valid | | `residential_address.postal_code` | string | ✓ | Validated per country | | `residential_address.country` | string | ✓ | ISO 3166-1 alpha-2 | | `residential_address.proof_of_address_file` | file URL or base64 | ✓ | Utility bill, bank statement, etc. PDF/JPG/JPEG/PNG/HEIC/TIF, max 5 MB | #### Step 3 — Identifying information At least one government-issued ID document is required. | Field | Type | Required | Notes | | --------------------------------------------- | ------------------ | -------- | ----------------------------------------------- | | `identifying_information[*].type` | string | ✓ | See [ID types by country](#id-types-by-country) | | `identifying_information[*].issuing_country` | string | ✓ | ISO 3166-1 alpha-2 | | `identifying_information[*].number` | string | ✓ | Document number | | `identifying_information[*].date_issued` | string | ✓ | `YYYY-MM-DD`, must be before today | | `identifying_information[*].expiration_date` | string | ✓ | `YYYY-MM-DD`, must be after today | | `identifying_information[*].image_front_file` | file URL or base64 | ✓ | PDF/JPG/JPEG/PNG, max 5 MB | | `identifying_information[*].image_back_file` | file URL or base64 | | Required for cards with a back side | #### Step 4 — Risk and purpose | Field | Type | Required | Notes | | ------------------------------- | ------- | --------------------------------- | ----------------------------------------------------------- | | `employment_status` | string | ✓ | See [enum values](#employment_status) | | `most_recent_occupation_code` | string | ✓ | 6-digit code from `GET /auth/occupation-codes` | | `expected_monthly_payments_usd` | string | ✓ | See [enum values](#expected_monthly_payments_usd) | | `source_of_funds` | string | ✓ | See [enum values](#source_of_funds) | | `account_purpose` | string | ✓ | See [enum values](#account_purpose) | | `account_purpose_other` | string | If `account_purpose` is `"other"` | Description of the purpose | | `acting_as_intermediary` | boolean | | Whether the customer acts as intermediary for third parties | #### Step 5 — Supporting documents | Field | Type | Required | Notes | | ---------------------------- | ------------------ | -------- | -------------------------- | | `uploaded_documents[*].type` | string | ✓ | Document type identifier | | `uploaded_documents[*].file` | file URL or base64 | ✓ | PDF/JPG/JPEG/PNG, max 5 MB | *** ### KYC example request ```bash cURL theme={null} curl -X POST 'https://kyc.yativo.com/api/individual-kyc/submit' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: kyc-ind-2026-001' \ -d '{ "customer_id": "c586066b-0f29-468f-b775-15483871a202", "first_name": "Alex", "last_name": "Smith", "email": "alex.smith@example.com", "calling_code": "+1", "phone": "5551234567", "gender": "male", "birth_date": "1990-01-15", "nationality": "US", "taxId": "998-88-7766", "selfie_image": "https://storage.yativo.com/documents/abc/selfie.jpg", "residential_address": { "street_line_1": "123 Maple Street", "city": "Austin", "state": "TX", "postal_code": "78701", "country": "US", "proof_of_address_file": "https://storage.yativo.com/documents/abc/utility-bill.pdf" }, "identifying_information": [ { "type": "passport", "issuing_country": "US", "number": "P12345678", "date_issued": "2019-06-01", "expiration_date": "2029-06-01", "image_front_file": "https://storage.yativo.com/documents/abc/passport-front.jpg" } ], "employment_status": "employed", "most_recent_occupation_code": "151252", "expected_monthly_payments_usd": "0_4999", "source_of_funds": "salary", "account_purpose": "receive_salary", "acting_as_intermediary": false, "uploaded_documents": [ { "type": "bank_statement", "file": "https://storage.yativo.com/documents/abc/bank-statement.pdf" } ] }' ``` ```javascript Node.js theme={null} const response = await fetch('https://kyc.yativo.com/api/individual-kyc/submit', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `kyc-${customerId}-${Date.now()}`, }, body: JSON.stringify({ customer_id: customerId, first_name: 'Alex', last_name: 'Smith', email: 'alex.smith@example.com', calling_code: '+1', phone: '5551234567', gender: 'male', birth_date: '1990-01-15', nationality: 'US', taxId: '998-88-7766', selfie_image: selfieUrl, // URL from /storage/upload residential_address: { street_line_1: '123 Maple Street', city: 'Austin', state: 'TX', postal_code: '78701', country: 'US', proof_of_address_file: addressProofUrl, }, identifying_information: [{ type: 'passport', issuing_country: 'US', number: 'P12345678', date_issued: '2019-06-01', expiration_date: '2029-06-01', image_front_file: passportFrontUrl, }], employment_status: 'employed', most_recent_occupation_code: '151252', expected_monthly_payments_usd: '0_4999', source_of_funds: 'salary', account_purpose: 'receive_salary', acting_as_intermediary: false, uploaded_documents: [{ type: 'bank_statement', file: statementUrl }], }), }); ``` ```json Success theme={null} { "success": true, "message": "KYC submission received successfully", "errors": { "submission": { "id": "sub_8f3b2a1c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "type": "individual", "status": "submitted", "customer_id": "c586066b-0f29-468f-b775-15483871a202", "first_name": "Alex", "last_name": "Smith", "email": "alex.smith@example.com", "endorsements": [ { "service": "base", "status": "pending", "link": "https://kyc.yativo.com/endorsement/base/c586066b-0f29-468f-b775-15483871a202" } ], "created_at": "2026-06-01T10:00:00.000000Z" } } } ``` *** ## Business KYB ### Submit ``` POST https://kyc.yativo.com/api/business-kyc/submit ``` #### Step 1 — Business basics | Field | Type | Required | Notes | | ---------------------- | ------- | -------- | ------------------------------------------------------------------------------------ | | `customer_id` | string | ✓ | UUID from `POST /customer` (must be `customer_type: "business"`) | | `business_legal_name` | string | ✓ | Official registered legal name, max 255 chars | | `business_trade_name` | string | ✓ | Trade / DBA name, max 255 chars | | `business_description` | string | ✓ | What the business does, max 1000 chars | | `email` | string | ✓ | Business contact email | | `business_type` | string | ✓ | `cooperative`, `corporation`, `llc`, `partnership`, `sole_prop`, `trust`, or `other` | | `registration_number` | string | ✓ | Government registration / incorporation number, max 100 chars | | `incorporation_date` | string | ✓ | `YYYY-MM-DD`, must be before today | | `tax_id` | string | | Business tax ID, max 100 chars | | `phone_calling_code` | string | | Must match `^\+[1-9]\d{0,3}$` | | `phone_number` | string | | Digits only, 7–15 characters | | `business_industry` | string | | Industry category | | `primary_website` | string | | Full URL | | `is_dao` | boolean | | Whether the business is a DAO | | `statement_descriptor` | string | | How the name appears on statements, max 22 chars | #### Step 2 — Addresses Both `registered_address` and `physical_address` use the same structure: | Field | Type | Required | Notes | | ----------------------- | ------------------ | -------- | ------------------------------------------------- | | `street_line_1` | string | ✓ | Max 255 chars | | `street_line_2` | string | | Optional | | `city` | string | ✓ | Max 100 chars | | `state` | string | ✓ | Accepts `"US-CA"` or `"CA"` | | `postal_code` | string | ✓ | Validated per country | | `country` | string | ✓ | ISO 3166-1 alpha-2 | | `proof_of_address_file` | file URL or base64 | | Optional for registered, recommended for physical | #### Step 3 — Associated persons At least one person is required. Include all UBOs, directors, and authorized signers. | Field | Type | Required | Notes | | ----------------------------- | ------- | -------- | ------------------------------------------------------ | | `first_name` | string | ✓ | Max 100 chars | | `last_name` | string | ✓ | Max 100 chars | | `birth_date` | string | ✓ | `YYYY-MM-DD`, before today | | `nationality` | string | ✓ | ISO 3166-1 alpha-2 | | `email` | string | ✓ | Personal email | | `phone` | string | | Optional | | `title` | string | | E.g. `"CEO"`, `"Director"` | | `ownership_percentage` | number | ✓ | 0–100 | | `relationship_established_at` | string | | `YYYY-MM-DD`, must not be in the future | | `residential_address` | object | ✓ | Same structure as Step 2 | | `identifying_information` | array | ✓ | ID documents (same structure as individual KYC Step 3) | | `has_ownership` | boolean | | Has ownership stake | | `has_control` | boolean | | Has operational control | | `is_signer` | boolean | | Authorized signer | | `is_director` | boolean | | Director | #### Step 4 — Risk and purpose | Field | Type | Required | Notes | | ------------------------------------- | ------- | -------------------------------------- | --------------------------------------------------------------------------------------- | | `account_purpose` | string | ✓ | See [enum values](#account_purpose) | | `account_purpose_other` | string | If `account_purpose` is `"other"` | | | `source_of_funds` | string | ✓ | See [enum values](#source_of_funds) | | `high_risk_activities` | array | ✓ | See [enum values](#high_risk_activities-kyb). Use `["none_of_the_above"]` if none apply | | `high_risk_activities_explanation` | string | If any high-risk activities listed | | | `conducts_money_services` | boolean | | | | `conducts_money_services_description` | string | If `conducts_money_services` is `true` | | | `compliance_screening_explanation` | string | If `conducts_money_services` is `true` | | | `estimated_annual_revenue_usd` | string | | | | `expected_monthly_payments_usd` | number | | Expected monthly volume in USD | | `operates_in_prohibited_countries` | string | | `"yes"` or `"no"` | | `ownership_threshold` | integer | | UBO reporting threshold (5–25) | | `has_material_intermediary_ownership` | boolean | | | #### Step 5 — Regulated activity | Field | Type | Notes | | --------------------------------------------------------- | ------ | ------------------ | | `regulated_activity.regulated_activities_description` | string | Optional | | `regulated_activity.primary_regulatory_authority_country` | string | ISO 3166-1 alpha-2 | | `regulated_activity.primary_regulatory_authority_name` | string | | | `regulated_activity.license_number` | string | | #### Step 6 — Business documents At least one document is required. | Field | Type | Required | Notes | | -------------------------- | ------------------ | -------- | --------------------------------------------------------------------------------------------------- | | `documents[*].purpose` | string | ✓ | `"business_registration"`, `"tax_documents"`, `"compliance_documents"`, or `"financial_statements"` | | `documents[*].description` | string | ✓ | Human-readable description | | `documents[*].file` | file URL or base64 | | File attachment | #### Step 7 — Business identifying information (optional) Business-level ID documents (e.g. business licence). | Field | Type | Notes | | -------------------------------------------- | ------------------ | ------------------------- | | `identifying_information[*].type` | string | | | `identifying_information[*].issuing_country` | string | ISO 3166-1 alpha-2 | | `identifying_information[*].number` | string | | | `identifying_information[*].description` | string | | | `identifying_information[*].expiration` | string | `YYYY-MM-DD`, after today | | `identifying_information[*].image_front` | file URL or base64 | | | `identifying_information[*].image_back` | file URL or base64 | | *** ### KYB example request ```bash cURL theme={null} curl -X POST 'https://kyc.yativo.com/api/business-kyc/submit' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: kyb-acme-2026-001' \ -d '{ "customer_id": "d47f8a2b-1c3e-4f5a-9b8c-7d6e5f4a3b2c", "business_legal_name": "Acme Payments LLC", "business_trade_name": "Acme Pay", "business_description": "International payment processing for SMEs", "email": "compliance@acmepay.com", "business_type": "llc", "registration_number": "LLC-2018-00987", "incorporation_date": "2018-03-12", "tax_id": "47-1234567", "phone_calling_code": "+1", "phone_number": "3055551234", "primary_website": "https://acmepay.com", "registered_address": { "street_line_1": "100 Brickell Ave", "city": "Miami", "state": "FL", "postal_code": "33131", "country": "US" }, "physical_address": { "street_line_1": "100 Brickell Ave", "city": "Miami", "state": "FL", "postal_code": "33131", "country": "US", "proof_of_address_file": "https://storage.yativo.com/documents/abc/lease.pdf" }, "associated_persons": [ { "first_name": "Jane", "last_name": "Doe", "birth_date": "1978-07-22", "nationality": "US", "email": "jane.doe@acmepay.com", "title": "CEO", "ownership_percentage": 60, "relationship_established_at": "2018-03-12", "residential_address": { "street_line_1": "456 Coral Way", "city": "Miami", "state": "FL", "postal_code": "33133", "country": "US" }, "identifying_information": [ { "type": "passport", "issuing_country": "US", "number": "P87654321", "date_issued": "2020-01-10", "expiration_date": "2030-01-10", "image_front_file": "https://storage.yativo.com/documents/abc/jane-passport.jpg" } ], "has_ownership": true, "has_control": true, "is_signer": true, "is_director": true } ], "account_purpose": "business_transactions", "source_of_funds": "business_income", "high_risk_activities": ["none_of_the_above"], "conducts_money_services": false, "regulated_activity": {}, "documents": [ { "purpose": "business_registration", "description": "Certificate of Incorporation", "file": "https://storage.yativo.com/documents/abc/certificate.pdf" }, { "purpose": "tax_documents", "description": "EIN confirmation letter", "file": "https://storage.yativo.com/documents/abc/ein.pdf" } ] }' ``` ```json Success theme={null} { "success": true, "message": "Business KYC submission received successfully", "business_data": { "customer_id": "d47f8a2b-1c3e-4f5a-9b8c-7d6e5f4a3b2c", "type": "business", "business_legal_name": "Acme Payments LLC", "status": "submitted", "created_at": "2026-06-01T10:00:00.000000Z" } } ``` *** ## Check KYC / KYB status ``` GET /customer/kyc/{customer_id} ``` The customer UUID. ### Status values | Status | Description | | --------------- | -------------------------------------- | | `not_started` | No submission has been made | | `submitted` | Received, awaiting review | | `manual_review` | Under manual compliance review | | `approved` | Customer is fully verified | | `rejected` | Rejected — see `kyc_rejection_reasons` | | `under_review` | Additional review in progress | Check both `status === "approved"` **and** `is_va_approved === true` before enabling payment features for a customer. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/kyc/c586066b-0f29-468f-b775-15483871a202' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Approved theme={null} { "status": "success", "status_code": 200, "data": { "first_name": "Alex", "last_name": "Smith", "status": "approved", "kyc_rejection_reasons": [], "kyc_requirements_due": [], "bio_data": { "customer_kyc_status": "approved", "kyc_verified_date": "2026-06-01T12:00:00.000000Z" }, "kyc_link": "https://kyc.yativo.com/individual/c586066b-0f29-468f-b775-15483871a202", "is_va_approved": true } } ``` ```json Rejected theme={null} { "status": "success", "status_code": 200, "data": { "first_name": "Alex", "last_name": "Smith", "status": "rejected", "kyc_rejection_reasons": [ "Selfie image does not clearly show the customer's face", "Document expiration date is invalid" ], "kyc_requirements_due": ["selfie_image", "identifying_information"], "bio_data": { "customer_kyc_status": "rejected", "kyc_verified_date": null }, "kyc_link": "https://kyc.yativo.com/individual/c586066b-0f29-468f-b775-15483871a202", "is_va_approved": false } } ``` *** ## Update a KYC submission Use this endpoint to correct information or provide missing documents after a rejection. ``` PUT /customer/kyc/update ``` Send only the fields you need to correct. `customer_id` is always required. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/customer/kyc/update' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: kyc-update-2026-002' \ -d '{ "customer_id": "c586066b-0f29-468f-b775-15483871a202", "selfie_image": "https://storage.yativo.com/documents/abc/selfie-v2.jpg", "identifying_information": [ { "type": "passport", "issuing_country": "US", "number": "P12345678", "date_issued": "2019-06-01", "expiration_date": "2029-06-01", "image_front_file": "https://storage.yativo.com/documents/abc/passport-front-hd.jpg" } ] }' ``` *** ## Service endorsements After approval, customers receive service endorsements that unlock specific payment rails. | Service | Description | | -------------- | --------------------------------- | | `base` | USD base payment access | | `sepa` | European SEPA transfers | | `spei` | Mexico SPEI transfers | | `brazil` | Brazilian payment rails | | `eurde` | EUR/DE virtual accounts | | `usd_latam` | USD Latin America transfers | | `eur_latam` | EUR Latin America transfers | | `virtual_card` | Virtual card issuance | | `asian` | Asian region payments | | `native` | Native payment rails | | `cobo_pobo` | Collection / payment-on-behalf-of | ### Endorsement statuses | Status | Description | | -------------- | ----------------------------- | | `not_started` | Not yet initiated | | `pending` | Awaiting review | | `approved` | Active for this customer | | `rejected` | Rejected | | `declined` | Customer declined | | `under_review` | Additional review in progress | ### Regenerate an endorsement link If an endorsement link has expired, regenerate it and share the new URL with the customer: ``` GET https://kyc.yativo.com/api/kyc/regenerate/{customer_id}/{service} ``` ```bash cURL theme={null} curl -X GET 'https://kyc.yativo.com/api/kyc/regenerate/c586066b-0f29-468f-b775-15483871a202/sepa' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "success": true, "message": "Endorsement link regenerated successfully", "data": { "service": "sepa", "customer_id": "c586066b-0f29-468f-b775-15483871a202", "link": "https://kyc.yativo.com/endorsement/sepa/c586066b-0f29-468f-b775-15483871a202?token=abc123" } } ``` *** ## Reference lookups ### Occupation codes Get the full list of valid occupation codes for `most_recent_occupation_code`: ``` GET /auth/occupation-codes ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/auth/occupation-codes' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "status": "success", "status_code": 200, "data": [ { "display_name": "Software developer", "code": "151252" }, { "display_name": "Accountant and auditor", "code": "132011" }, { "display_name": "Financial manager", "code": "113031" }, { "display_name": "Registered nurse", "code": "291141" } ] } ``` ### Supported countries Get the list of countries supported for customer registration and verification: ``` GET /auth/verification-locations ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/auth/verification-locations' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json theme={null} { "status": "success", "status_code": 200, "data": [ { "country": "United States", "code": "US" }, { "country": "Brazil", "code": "BR" }, { "country": "Nigeria", "code": "NG" }, { "country": "Mexico", "code": "MX" }, { "country": "Colombia", "code": "CO" } ] } ``` *** ## Enum reference values ### `employment_status` | API value | Description | | --------------- | ------------- | | `employed` | Employed | | `exempt` | Exempt | | `homemaker` | Homemaker | | `retired` | Retired | | `self_employed` | Self-Employed | | `student` | Student | | `unemployed` | Unemployed | ### `expected_monthly_payments_usd` | API value | Range | | ------------- | ----------------- | | `0_4999` | Less than \$5,000 | | `5000_9999` | $5,000 – $9,999 | | `10000_49999` | $10,000 – $49,999 | | `50000_plus` | \$50,000 or more | ### `source_of_funds` | API value | Description | | ---------------------------- | ----------------------------- | | `business_income` | Business Income | | `company_funds` | Company Funds | | `ecommerce_reseller` | Ecommerce Reseller | | `gambling_proceeds` | Gambling Proceeds | | `gifts` | Gifts | | `government_benefits` | Government Benefits | | `inheritance` | Inheritance | | `investments_loans` | Investments / Loans | | `pension_retirement` | Pension / Retirement | | `salary` | Salary | | `sale_of_assets_real_estate` | Sale of Assets or Real Estate | | `savings` | Savings | | `someone_elses_funds` | Someone Else's Funds | ### `account_purpose` | API value | Description | | -------------------------------------- | ---------------------------------------- | | `business_transactions` | Business Transactions | | `charitable_donations` | Charitable Donations | | `ecommerce_retail_payments` | Ecommerce / Retail Payments | | `investment_purposes` | Investment Purposes | | `operating_a_company` | Operating a Company | | `other` | Other (requires `account_purpose_other`) | | `payments_to_friends_or_family_abroad` | Payments to Friends or Family Abroad | | `personal_or_living_expenses` | Personal / Living Expenses | | `protect_wealth` | Protect Wealth | | `purchase_goods_and_services` | Purchase Goods and Services | | `receive_payment_for_freelancing` | Receive Payment for Freelancing | | `receive_salary` | Receive Salary | ### `high_risk_activities` (KYB) | API value | Description | | ----------------------------------------------------------- | ----------------------------------------- | | `adult_entertainment` | Adult entertainment | | `gambling` | Gambling | | `hold_client_funds` | Holding client funds | | `investment_services` | Investment services | | `lending_banking` | Lending or banking | | `marijuana_or_related_services` | Marijuana-related services | | `money_services` | Money services | | `operate_foreign_exchange_virtual_currencies_brokerage_otc` | Foreign exchange / crypto brokerage / OTC | | `pharmaceuticals` | Pharmaceuticals | | `precious_metals_precious_stones_jewelry` | Precious metals / stones / jewelry | | `safe_deposit_box_rentals` | Safe deposit box rentals | | `weapons_firearms_and_explosives` | Weapons / firearms / explosives | | `none_of_the_above` | None of the above | ### `business_type` (KYB) `cooperative`, `corporation`, `llc`, `partnership`, `sole_prop`, `trust`, `other` *** ## ID types by country The accepted `type` values under `identifying_information` depend on the issuing country. Common types available globally: | Type | Description | | ------------- | -------------------------- | | `passport` | Passport | | `national_id` | National ID card | | `other` | Other government-issued ID | Countries also accept country-specific types, for example: | Country | Extra types available | | --------------------- | --------------------- | | `NG` (Nigeria) | `tin`, `nin`, `bvn` | | `US` (United States) | `ssn`, `itin` | | `BR` (Brazil) | `cpf` | | `GB` (United Kingdom) | `nino`, `utr` | | `IN` (India) | `pan` | | `MX` (Mexico) | `rfc`, `curp`, `ine` | | `DE` (Germany) | `steuer_id` | | `AE` (UAE) | `emirates_id` | Use `GET /auth/verification-locations` to check which countries are supported, and consult the full ID type reference in the API reference section. *** ## Webhooks Configure your webhook endpoint in the Yativo dashboard to receive status updates automatically. ### Events | Event | Description | | ------------------------- | --------------------------------------------- | | `kyc.status_updated` | KYC/KYB verification status changed | | `kyc.endorsement_updated` | A specific service endorsement status changed | ### Payload example ```json theme={null} { "event": "kyc.status_updated", "data": { "customer_id": "c586066b-0f29-468f-b775-15483871a202", "status": "approved", "type": "individual", "endorsements": ["base", "sepa"], "rejection_reasons": [], "updated_at": "2026-06-01T15:00:00.000000Z" } } ``` *** ## Error handling ```json theme={null} { "status": "failed", "status_code": 422, "message": "Request failed", "data": { "email": ["The email field is required."], "nationality": ["The nationality must be 2 characters."], "identifying_information": ["The identifying information field is required."] } } ``` ### Common errors and fixes | Error | Fix | | -------------------------------------------- | --------------------------------------------------------- | | `customer_id does not exist` | Create the customer first with `POST /customer` | | `nationality must be 2 characters` | Use ISO 3166-1 alpha-2 (e.g. `"US"`, `"NG"`) | | `birth_date must be a date before today` | Ensure the date is in the past | | `expiration_date must be a date after today` | ID document must not be expired | | `bvn is required` | Required for Nigerian nationals — exactly 11 digits | | `nin is required` | Required for Nigerian nationals — exactly 11 digits | | `calling_code is invalid` | Must be `+` followed by 1–4 digits, e.g. `"+1"`, `"+234"` | | `identifying_information is required` | At least one ID document must be included | | `documents is required` | KYB requires at least one business document | *** ## Implementation notes * KYC review typically completes within **24 hours**. Complex cases may take longer. * Use `Idempotency-Key` on all POST and PUT requests to prevent duplicate submissions. * Files can be passed as hosted URLs (from `POST /storage/upload`) or base64-encoded strings — both are accepted. * For Nigerian customers (`nationality: "NG"`), `bvn` and `nin` are mandatory regardless of which ID type is provided. * The `state` field accepts both `"US-CA"` and `"CA"` — the API normalizes both forms. * Access tokens expire in 600 seconds. Implement token refresh before making KYC submissions in long-running flows. # KYC/KYB Frontend Integration Guide Source: https://docs.yativo.com/yativo-fiat/kyc-frontend-guide Step-by-step guide for integrating Yativo identity verification into web and mobile applications This guide walks you through integrating Yativo KYC (individual) and KYB (business) verification into your application. You can choose a hosted approach for quick integration or a fully custom API integration for maximum control. ## Integration approaches | Approach | Best For | Effort | Customization | | ---------------------- | -------------------------- | ------ | ------------- | | Hosted KYC/KYB Link | Quick launch, iframe embed | Low | Limited | | Custom API Integration | Full control, native UI | High | Full | *** ## Option A: Hosted links (recommended) The simplest integration. You create a customer, then redirect them to Yativo's hosted verification flow at `https://kyc.yativo.com`. ### Step 1: Get an access token ```javascript theme={null} async function getAuthToken() { const response = await fetch('https://api.yativo.com/api/v1/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ account_id: process.env.YATIVO_ACCOUNT_ID, app_secret: process.env.YATIVO_APP_SECRET, }), }); const data = await response.json(); // Token expires in 600 seconds — cache and refresh as needed return data.data.access_token; } ``` ### Step 2: Create a customer ```javascript theme={null} async function createCustomer(token, customerData) { const response = await fetch('https://api.yativo.com/api/v1/customer', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `create-customer-${customerData.email}-${Date.now()}`, }, body: JSON.stringify({ customer_name: customerData.name, customer_email: customerData.email, customer_phone: customerData.phone, customer_country: customerData.country, // ISO 3166-1 alpha-2, e.g. "US" customer_type: 'individual', // or 'business' }), }); const data = await response.json(); return data.data.customer_id; } ``` ### Step 3: Redirect to hosted KYC ```javascript theme={null} function redirectToKYC(customerId) { // Redirect individual customers window.location.href = `https://kyc.yativo.com/individual/${customerId}`; } function redirectToKYB(customerId) { // Redirect business customers window.location.href = `https://kyc.yativo.com/business/${customerId}`; } ``` ### Embedding in an iframe If you prefer to embed verification within your application instead of a full redirect: ```html theme={null} ``` The `allow="camera; microphone"` attribute is required for document capture and selfie steps to work correctly in the iframe. ### Step 4: Poll for verification status After the customer completes the hosted flow, poll the status endpoint to detect when verification is complete. ```javascript theme={null} function pollKycStatus(token, customerId, onComplete) { const intervalId = setInterval(async () => { try { const response = await fetch( `https://api.yativo.com/api/v1/customer/kyc/${customerId}`, { headers: { 'Authorization': `Bearer ${token}` } } ); const data = await response.json(); const status = data.data?.status; if (status === 'approved') { clearInterval(intervalId); onComplete({ success: true, status, isVaApproved: data.data.is_va_approved }); } else if (status === 'rejected') { clearInterval(intervalId); onComplete({ success: false, status, reasons: data.data.kyc_rejection_reasons, }); } } catch (err) { console.error('Error polling KYC status:', err); } }, 5000); // Poll every 5 seconds // Return cleanup function return () => clearInterval(intervalId); } // Usage const stopPolling = pollKycStatus(token, customerId, (result) => { if (result.success) { console.log('Customer verified! VA approved:', result.isVaApproved); } else { console.log('Verification rejected. Reasons:', result.reasons); } }); ``` Instead of polling, consider using [webhooks](/yativo-fiat/webhooks) to receive real-time notifications when KYC status changes. *** ## Option B: Custom API integration Build your own multi-step form that collects customer data and submits it directly to the KYC API. ### Step 1: Collect personal information ```jsx theme={null} import { useState } from 'react'; function PersonalInfoStep({ onNext }) { const [form, setForm] = useState({ first_name: '', last_name: '', email: '', phone: '', calling_code: '+1', gender: '', birth_date: '', nationality: '', taxId: '', // Nigerian nationals only bvn: '', nin: '', }); const handleChange = (field) => (e) => setForm((prev) => ({ ...prev, [field]: e.target.value })); const isNigerian = form.nationality === 'NG'; return (
{ e.preventDefault(); onNext(form); }}> {/* Gender accepts only "male" or "female" */} {isNigerian && ( <> )}
); } ``` When `nationality` is `"NG"`, both `bvn` and `nin` (each exactly 11 digits) are required by the API. Show these fields conditionally based on the selected nationality. ### Step 2: Upload files via Yativo storage Before submitting the KYC form, upload document images using Yativo's storage endpoint. This keeps payloads small and avoids base64 encoding large files. ```javascript theme={null} /** * Upload a file to Yativo storage and return a hosted URL * to pass into the KYC payload. */ async function uploadDocument(token, file) { const formData = new FormData(); formData.append('document', file); // field name must be "document" const response = await fetch('https://api.yativo.com/api/v1/storage/upload', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, // Do NOT set Content-Type — let the browser set it with the boundary }, body: formData, }); if (!response.ok) { const err = await response.json(); throw new Error(err.message || 'File upload failed'); } const data = await response.json(); return data.data.url; // Pass this URL in the KYC payload } ``` You can also pass files as base64-encoded strings inline, but the hosted URL approach is recommended for files over \~500 KB. ```javascript theme={null} function fileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); // Returns data URL (base64) reader.onerror = reject; reader.readAsDataURL(file); }); } ``` ### Step 3: Collect residential address ```jsx theme={null} function AddressStep({ token, onNext }) { const [address, setAddress] = useState({ street_line_1: '', city: '', state: '', postal_code: '', country: '', }); const [proofFile, setProofFile] = useState(null); const [uploading, setUploading] = useState(false); const handleFileChange = async (e) => { const file = e.target.files[0]; if (!file) return; setUploading(true); try { const url = await uploadDocument(token, file); setProofFile(url); } finally { setUploading(false); } }; const handleSubmit = (e) => { e.preventDefault(); onNext({ ...address, proof_of_address_file: proofFile }); }; return (
setAddress((a) => ({ ...a, street_line_1: e.target.value }))} required /> setAddress((a) => ({ ...a, city: e.target.value }))} required /> setAddress((a) => ({ ...a, state: e.target.value }))} required /> setAddress((a) => ({ ...a, postal_code: e.target.value }))} required />
); } ``` ### Step 4: Collect ID document ```jsx theme={null} function IdDocumentStep({ token, onNext }) { const [doc, setDoc] = useState({ type: 'passport', issuing_country: '', number: '', date_issued: '', expiration_date: '', image_front_file: null, image_back_file: null, }); const handleFileUpload = (field) => async (e) => { const file = e.target.files[0]; if (!file) return; const url = await uploadDocument(token, file); setDoc((d) => ({ ...d, [field]: url })); }; const needsBack = doc.type !== 'passport'; return (
{ e.preventDefault(); onNext([doc]); }}> setDoc((d) => ({ ...d, number: e.target.value }))} required /> {needsBack && ( )}
); } ``` ### Step 5: Collect financial information The values sent to the API are snake\_case identifiers, not display labels. Use the exact values below — the API will reject any other values. ```jsx theme={null} function FinancialInfoStep({ onNext }) { const [financial, setFinancial] = useState({ employment_status: '', most_recent_occupation_code: '', source_of_funds: '', account_purpose: '', account_purpose_other: '', expected_monthly_payments_usd: '', acting_as_intermediary: false, }); const showOtherPurpose = financial.account_purpose === 'other'; return (
{ e.preventDefault(); onNext(financial); }}> {showOtherPurpose && ( setFinancial((f) => ({ ...f, account_purpose_other: e.target.value }))} required /> )}
); } ``` ### Step 6: Submit to the KYC API ```javascript theme={null} async function submitKYC(token, customerId, formData) { const payload = { customer_id: customerId, // Personal info ...formData.personal, // Residential address (including proof_of_address_file URL) residential_address: formData.address, // ID documents (array of document objects with uploaded URLs) identifying_information: formData.documents, // Financial & purpose ...formData.financial, // Selfie image URL from storage upload selfie_image: formData.selfieUrl, // Supporting documents uploaded_documents: formData.supportingDocs, }; // Remove account_purpose_other unless account_purpose is "other" if (payload.account_purpose !== 'other') { delete payload.account_purpose_other; } const response = await fetch('https://kyc.yativo.com/api/individual-kyc/submit', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `kyc-${customerId}-${Date.now()}`, }, body: JSON.stringify(payload), }); if (!response.ok) { const error = await response.json(); throw new Error(error.message || 'KYC submission failed'); } return response.json(); } ``` The KYC submission endpoint is at `https://kyc.yativo.com`, not the main API. The `Authorization` bearer token is the same one issued by `POST /auth/login`. *** ## Status polling (TypeScript) ```typescript theme={null} type KycStatus = 'not_started' | 'submitted' | 'manual_review' | 'approved' | 'rejected' | 'under_review'; interface KycStatusResult { status: KycStatus; isVaApproved: boolean; rejectionReasons: string[]; kycLink: string; } function pollKycStatus( token: string, customerId: string, onStatusChange: (result: KycStatusResult) => void, intervalMs = 5000 ): () => void { const intervalId = setInterval(async () => { const response = await fetch( `https://api.yativo.com/api/v1/customer/kyc/${customerId}`, { headers: { Authorization: `Bearer ${token}` } } ); const { data } = await response.json(); const result: KycStatusResult = { status: data.status, isVaApproved: data.is_va_approved, rejectionReasons: data.kyc_rejection_reasons ?? [], kycLink: data.kyc_link, }; onStatusChange(result); if (data.status === 'approved' || data.status === 'rejected') { clearInterval(intervalId); } }, intervalMs); return () => clearInterval(intervalId); } ``` *** ## Webhooks (recommended over polling) Instead of polling, register a webhook to receive real-time notifications: ```javascript theme={null} // Register webhook await fetch('https://api.yativo.com/api/v1/webhook', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': 'webhook-kyc-events', }, body: JSON.stringify({ url: 'https://your-app.com/webhooks/yativo', events: [ 'customer.kyc.approved', 'customer.kyc.rejected', ], }), }); ``` Then in your webhook handler: ```javascript theme={null} // Express.js example app.post('/webhooks/yativo', (req, res) => { const { event, data } = req.body; if (event === 'customer.kyc.approved') { const { customer_id } = data; // Activate customer account, send welcome email, etc. activateCustomer(customer_id); } if (event === 'customer.kyc.rejected') { const { customer_id, rejection_reasons } = data; // Notify customer, share kyc_link for re-submission notifyCustomerRejection(customer_id, rejection_reasons); } res.sendStatus(200); }); ``` *** ## UI/UX best practices **Progress indicators** Show a clear multi-step progress bar so customers know where they are in the verification process. For individual KYC: Personal Info → Address & Documents → ID Document → Financial Info → Review & Submit. **Clear error messages** Display field-level validation errors immediately, not just on submit. Translate API error codes into user-friendly language. The API returns a `data` object with field-specific error arrays on `422` responses. **Document upload previews** Always show a preview of uploaded documents before submission. This helps customers catch blurry or incorrectly oriented images before they fail review. ```jsx theme={null} function DocumentPreview({ url, label }) { if (!url) return null; const isImage = /\.(jpg|jpeg|png|heic)$/i.test(url) || url.startsWith('data:image'); return (

{label} preview:

{isImage ? ( {label} ) : (

📄 PDF uploaded

)}
); } ``` **Mobile camera support** Use `capture="environment"` on file inputs to open the rear camera directly on mobile: ```html theme={null} ``` **Selfie guidance** For the selfie step, display on-screen guidelines (oval face outline, lighting tips) before the customer takes their photo to reduce re-submission rates. **Retry on rejection** When a customer's KYC is rejected, use the `kyc_link` from the status response to send them back to the hosted flow for corrections. ```javascript theme={null} const statusData = await getKycStatus(token, customerId); if (statusData.status === 'rejected') { const kycLink = statusData.kyc_link; // Show retry button that redirects to kycLink console.log('Rejection reasons:', statusData.kyc_rejection_reasons); } ``` # Payouts Source: https://docs.yativo.com/yativo-fiat/payouts Send single payments or bulk disbursements to multiple beneficiaries in one request Yativo provides two payout paths depending on your use case: | Path | Best for | | --------------------- | ----------------------------------------------------------- | | `POST /payout/simple` | A single payment to one beneficiary | | `POST /payout/batch` | Multiple payments to different beneficiaries in one request | Both require a saved beneficiary with an attached payment method. See [Send Money](/yativo-fiat/send-money) for setting up beneficiaries. All payout requests require an `Idempotency-Key` header and the `chargeWallet` middleware — meaning your wallet balance is charged at submission time. *** ## Single Payout Send one payment to a saved beneficiary payment method. ``` POST https://api.yativo.com/api/v1/payout/simple ``` Amount to send in the debit wallet currency. The ID of the saved beneficiary payment method (from `POST /beneficiaries/payment-methods`). Optional beneficiary UUID. Useful for tracking but not required if `beneficiary_details_id` is provided. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/payout/simple' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: payout-simple-001' \ -d '{ "amount": 250, "beneficiary_details_id": 42 }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/payout/simple', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `payout-simple-${Date.now()}`, }, body: JSON.stringify({ amount: 250, beneficiary_details_id: 42, }), }); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "transaction_id": "txn-a1b2c3d4-e5f6-7890-abcd-ef1234567890", "status": "processing", "amount": "250.00", "currency": "CLP", "beneficiary_id": 42, "created_at": "2026-06-01T10:00:00.000000Z" } } ``` ```json Insufficient balance theme={null} { "status": "error", "status_code": 402, "message": "Insufficient wallet balance" } ``` *** ## Batch Payout Send multiple payments in a single request. Each item in the `payouts` array is processed independently — partial failures are returned in an `errors` array rather than rolling back the entire batch. ``` POST https://api.yativo.com/api/v1/payout/batch ``` Array of payout objects to process. Amount to send for this payout. The saved beneficiary payment method ID. Optional beneficiary UUID for tracking. Batch payouts are processed within a database transaction — if your wallet has insufficient balance for the total amount, the entire batch is rejected before processing begins. Individual line-item errors (e.g. invalid beneficiary) are returned in the `errors` object and do not affect other items. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/payout/batch' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: batch-payout-june-payroll-001' \ -d '{ "payouts": [ { "amount": 500, "beneficiary_details_id": 41 }, { "amount": 750, "beneficiary_details_id": 42 }, { "amount": 300, "beneficiary_details_id": 43 } ] }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/payout/batch', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `batch-${Date.now()}`, }, body: JSON.stringify({ payouts: [ { amount: 500, beneficiary_details_id: 41 }, { amount: 750, beneficiary_details_id: 42 }, { amount: 300, beneficiary_details_id: 43 }, ], }), }); const data = await response.json(); ``` ```python Python theme={null} import requests, time response = requests.post( 'https://api.yativo.com/api/v1/payout/batch', headers={ 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json', 'Idempotency-Key': f'batch-{int(time.time())}', }, json={ 'payouts': [ {'amount': 500, 'beneficiary_details_id': 41}, {'amount': 750, 'beneficiary_details_id': 42}, {'amount': 300, 'beneficiary_details_id': 43}, ] } ) ``` ```json All successful theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "0": { "transaction_id": "txn-aaa", "status": "processing", "amount": "500.00" }, "1": { "transaction_id": "txn-bbb", "status": "processing", "amount": "750.00" }, "2": { "transaction_id": "txn-ccc", "status": "processing", "amount": "300.00" } } } ``` ```json Partial failure theme={null} { "status": "error", "status_code": 400, "data": { "errors": { "1": { "error": "Beneficiary not found" } } } } ``` *** ## List Payouts Retrieve a paginated list of all your payouts. ``` GET https://api.yativo.com/api/v1/payout/get ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payout/get' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Get Single Payout ``` GET https://api.yativo.com/api/v1/payout/fetch/{payout_id} ``` The UUID of the payout to retrieve. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payout/fetch/txn-a1b2c3d4-e5f6-7890-abcd-ef1234567890' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Payout vs. Wallet Payout | | `POST /payout/simple` or `/batch` | `POST /wallet/payout` | | ------------------------ | --------------------------------- | --------------------------------------------- | | **Beneficiary required** | Yes — `beneficiary_details_id` | Yes — `beneficiary_id` | | **Quote support** | No | Yes — pass `quote_id` for locked rate | | **Bulk support** | Yes (`/batch`) | No | | **Use case** | Disbursements, payroll | Single cross-currency payments with rate lock | For a single payment where you want to lock a rate first, use `POST /sendmoney/quote` → `POST /wallet/payout`. For payroll-style bulk disbursements without rate locking, use `POST /payout/batch`. # Business Plans Source: https://docs.yativo.com/yativo-fiat/plans View available subscription plans and manage your account tier Yativo offers tiered business plans that unlock higher transaction limits, additional payment corridors, and priority support. Plans are billed in USD and charged directly from your USD wallet. *** ## Get Current Plan Returns your account's active subscription plan and its features. ``` GET https://api.yativo.com/api/v1/business/plans/current ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/plans/current' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "id": 1, "name": "Starter", "price": "0.00", "currency": "USD", "features": [ { "name": "Virtual Accounts", "value": "5" }, { "name": "Monthly Payout Volume", "value": "$50,000" }, { "name": "API Rate Limit", "value": "100 req/min" } ], "subscribed_at": "2026-01-01T00:00:00.000000Z" } } ``` *** ## List All Plans Browse all available plans and their features. ``` GET https://api.yativo.com/api/v1/business/plans/all ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/plans/all' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "id": 1, "name": "Starter", "price": "0.00", "currency": "USD", "features": [ { "name": "Virtual Accounts", "value": "5" }, { "name": "Monthly Payout Volume", "value": "$50,000" } ] }, { "id": 2, "name": "Growth", "price": "99.00", "currency": "USD", "features": [ { "name": "Virtual Accounts", "value": "50" }, { "name": "Monthly Payout Volume", "value": "$500,000" }, { "name": "Priority Support", "value": "true" } ] }, { "id": 3, "name": "Enterprise", "price": "Custom", "currency": "USD", "features": [ { "name": "Virtual Accounts", "value": "Unlimited" }, { "name": "Monthly Payout Volume", "value": "Custom" }, { "name": "Dedicated Account Manager", "value": "true" } ] } ] } ``` *** ## Subscribe to a Plan Subscribe your account to a specific plan. The plan price is charged immediately from your USD wallet. ``` POST https://api.yativo.com/api/v1/business/plans/subscribe/{plan_id} ``` Requires `Idempotency-Key` header. The plan cost is debited from your USD wallet at the time of subscription. The ID of the plan to subscribe to (from the list plans endpoint). ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/plans/subscribe/2' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: subscribe-growth-001' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Subscription to Growth Business Plan successful", "data": { "plan_id": 2, "plan_name": "Growth", "subscribed_at": "2026-06-01T10:00:00.000000Z" } } ``` ```json Insufficient balance theme={null} { "status": "error", "status_code": 402, "message": "Insufficient wallet balance" } ``` *** ## Upgrade Plan Upgrade your existing plan to a higher tier. The cost difference is prorated and charged from your USD wallet. ``` PUT https://api.yativo.com/api/v1/business/plans/upgrade/{plan_id} ``` The ID of the plan to upgrade to. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/business/plans/upgrade/3' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: upgrade-enterprise-001' ``` Enterprise plans have `"price": "Custom"`. Upgrading to Enterprise will initiate a contact request with the Yativo sales team rather than charging your wallet immediately. # Quickstart Source: https://docs.yativo.com/yativo-fiat/quickstart Get your first payment working in under 10 minutes This guide walks you through creating a customer, issuing a virtual account, and making your first API call — from zero to live in minutes. *** ## Step 1: Create Your Account Go to [app.yativo.com](https://app.yativo.com) and sign up. Yativo uses **passwordless authentication**: 1. Enter your email address 2. A 5-digit OTP is sent to your inbox 3. Enter the OTP to log in You can also sign in with Google. *** ## Step 2: Complete Business KYC Before you can access the API, complete the Business KYC onboarding in the dashboard: 1. Submit your company details (legal name, registration number, address) 2. Upload required documents (certificate of incorporation, etc.) 3. Add and verify your UBOs (Ultimate Beneficial Owners) Once your business is verified, API access is unlocked. *** ## Step 3: Get Your API Credentials 1. Go to **Developer → API Key** in your dashboard 2. Click **Generate Secret** 3. Enter your 4-digit **transaction PIN** when prompted 4. Copy your **App Secret** — it is shown only once 5. Note your **Account ID** displayed on the same page *** ## Step 4: Generate a Bearer Token Use your Account ID and App Secret to obtain a Bearer token: ``` POST /auth/login ``` ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/auth/login' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "YOUR_ACCOUNT_ID", "app_secret": "YOUR_APP_SECRET" }' ``` Response: ```json theme={null} { "status": "success", "data": { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...", "expires_in": 600 } } ``` Tokens expire in **600 seconds** (10 minutes). Refresh using `GET /auth/refresh-token`. *** ## Step 5: Create Your First Customer Create a customer profile for someone you want to serve: ``` POST /customer ``` ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-001' \ -d '{ "customer_name": "Jane Doe", "customer_email": "jane@example.com", "customer_phone": "+5511999999999", "customer_country": "BRA", "customer_type": "individual" }' ``` ```json Success theme={null} { "status": "success", "data": { "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "customer_name": "Jane Doe", "customer_email": "jane@example.com", "customer_phone": "+5511999999999", "customer_status": "active", "customer_country": "BRA" } } ``` *** ## Step 6: Submit KYC for the Customer Submit identity verification for your customer via the Yativo KYC service: ``` POST https://kyc.yativo.com/api/individual-kyc/submit ``` ```bash cURL theme={null} curl -X POST 'https://kyc.yativo.com/api/individual-kyc/submit' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-002' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "type": "individual", "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com", "phone": "11999999999", "calling_code": "+55", "gender": "female", "birth_date": "1990-05-15", "nationality": "BR", "taxId": "12345678901", "selfie_image": "https://example.com/kyc/selfie.jpg", "residential_address": { "street_line_1": "Av. Paulista, 1000", "city": "Sao Paulo", "state": "SP", "postal_code": "01310-100", "country": "BR", "proof_of_address_file": "https://example.com/kyc/proof-of-address.pdf" }, "identifying_information": [ { "type": "passport", "issuing_country": "BR", "number": "AB123456", "date_issued": "2020-01-01", "expiration_date": "2030-01-01", "image_front_file": "https://example.com/kyc/passport-front.jpg" } ], "employment_status": "employed", "most_recent_occupation_code": "132011", "expected_monthly_payments_usd": "0_4999", "source_of_funds": "salary", "account_purpose": "receive_salary", "acting_as_intermediary": false, "uploaded_documents": [ { "type": "bank_statement", "file": "https://example.com/kyc/bank-statement.pdf" } ] }' ``` See the full field reference at [KYC & KYB](/yativo-fiat/kyc), including all enum values, Nigeria-specific fields, and document upload guidance. In sandbox, KYC approves automatically. In production, allow up to a few minutes for verification. *** ## Step 7: Create a Virtual Account Once the customer's KYC is approved (`is_va_approved: true`), issue a virtual account: ``` POST /business/virtual-account/create ``` ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-003' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "BRL" }' ``` ```json Success theme={null} { "status": "success", "data": { "account_number": "9900123456", "account_type": "savings", "currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2" } } ``` Your customer can now receive PIX payments at this account number. You'll receive a `virtual_account.deposit` webhook when funds arrive. *** ## Full Node.js Example ```javascript Node.js theme={null} const BASE_URL = 'https://api.yativo.com/api/v1'; // Step 1: Get Bearer token async function getToken() { const res = await fetch(`${BASE_URL}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ account_id: process.env.YATIVO_ACCOUNT_ID, app_secret: process.env.YATIVO_APP_SECRET, }), }); const { data } = await res.json(); return data.access_token; } // Step 2: Create a customer async function createCustomer(token) { const res = await fetch(`${BASE_URL}/customer`, { method: 'POST', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID(), }, body: JSON.stringify({ customer_name: 'Jane Doe', customer_email: 'jane@example.com', customer_phone: '+5511999999999', customer_country: 'BRA', customer_type: 'individual', }), }); const { data } = await res.json(); return data.customer_id; } // Step 3: Create a virtual account async function createVirtualAccount(token, customerId) { const res = await fetch(`${BASE_URL}/business/virtual-account/create`, { method: 'POST', headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID(), }, body: JSON.stringify({ customer_id: customerId, currency: 'BRL', }), }); return res.json(); } // Run the flow (async () => { const token = await getToken(); const customerId = await createCustomer(token); console.log('Customer ID:', customerId); // After KYC is approved: const account = await createVirtualAccount(token, customerId); console.log('Virtual account:', account.data.account_number); })(); ``` *** ## Next Steps * [Accept Payments](/yativo-fiat/accept-payments) — receive deposits via virtual accounts * [Send Money](/yativo-fiat/send-money) — send cross-border payments * [Sandbox](/yativo-fiat/sandbox) — test your integration safely * [Webhooks](/yativo-fiat/webhooks) — receive real-time payment notifications # Sandbox Environment Source: https://docs.yativo.com/yativo-fiat/sandbox Test your integration without real money The Yativo sandbox lets you develop and test your integration without moving real funds. Payments are simulated, KYC approves automatically, and virtual accounts work end-to-end. *** ## Sandbox Base URL ``` https://smtp.yativo.com/api/v1 ``` All other endpoints remain the same — just swap the base URL. *** ## Getting Started You use the **same Yativo account** for both sandbox and production. Switch between environments by changing the base URL in your requests. 1. **Sign up** at [app.yativo.com](https://app.yativo.com) (if you haven't already) 2. **Get your credentials** — Dashboard → Developer → API Key 3. **Authenticate** using the sandbox base URL: ```bash theme={null} curl -X POST 'https://smtp.yativo.com/api/v1/auth/login' \ -H 'Content-Type: application/json' \ -d '{ "account_id": "YOUR_ACCOUNT_ID", "app_secret": "YOUR_APP_SECRET" }' ``` *** ## Sandbox Behavior | Feature | Sandbox | Production | | ---------------- | ------------------------- | ---------------------- | | Payments | Simulated — no real funds | Real money moves | | KYC | Auto-approves instantly | Takes minutes to hours | | Virtual accounts | Work end-to-end | Live bank accounts | | Exchange rates | Live rates returned | Live rates | | Webhooks | Fired normally | Fired normally | | API logs | Recorded | Recorded | *** ## How to Test Set `https://smtp.yativo.com/api/v1` as your base URL in all requests. Use the same Account ID and App Secret. Call `POST /auth/login` against the sandbox URL to get a token. Use `POST /customer` to create customers. KYC auto-approves in sandbox — no documents needed. Once a customer is created (KYC auto-approved), call `POST /business/virtual-account/create`. Use the sandbox dashboard or API to trigger test deposits to your virtual accounts. Call `POST /sendmoney` or `POST /wallet/payout` — payments are simulated and will transition through statuses. *** ## Example: Full Sandbox Test Flow ```javascript Node.js theme={null} const BASE = 'https://smtp.yativo.com/api/v1'; // 1. Authenticate const { data: auth } = await fetch(`${BASE}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ account_id: process.env.YATIVO_ACCOUNT_ID, app_secret: process.env.YATIVO_APP_SECRET, }), }).then(r => r.json()); const token = auth.data.access_token; const headers = { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID(), }; // 2. Create customer (KYC auto-approves in sandbox) const { data: customer } = await fetch(`${BASE}/customer`, { method: 'POST', headers, body: JSON.stringify({ customer_name: 'Test User', customer_email: 'test@example.com', customer_phone: '+5511999999999', customer_country: 'BRA', customer_type: 'individual', }), }).then(r => r.json()); // 3. Create virtual account const { data: account } = await fetch(`${BASE}/business/virtual-account/create`, { method: 'POST', headers: { ...headers, 'Idempotency-Key': crypto.randomUUID() }, body: JSON.stringify({ customer_id: customer.data.customer_id, currency: 'BRL', }), }).then(r => r.json()); console.log('Test account number:', account.data.account_number); ``` *** ## Differences from Production * **KYC is instant** — submit a customer and `is_kyc_submitted` / `is_va_approved` are set immediately * **No real funds** — wallet balances may be pre-funded in sandbox; payouts simulate the full transaction lifecycle * **Some payment methods may be limited** — not all live corridors are available in sandbox; contact your integration team if you need a specific one * **Webhooks fire normally** — you'll receive all webhook events in sandbox; make sure your test endpoint is reachable *** ## Switching to Production When you're ready to go live: 1. Change your base URL from `https://smtp.yativo.com/api/v1` to `https://api.yativo.com/api/v1` 2. Ensure your business KYC is approved in the dashboard 3. Real customers will need to complete KYC (not auto-approved) 4. Update your webhook URL to point to your production endpoint Your Account ID and App Secret are the same for both environments. Only the base URL changes. # Security Source: https://docs.yativo.com/yativo-fiat/security Best practices for securing your Yativo API integration ## Authentication All API requests must be authenticated. Yativo supports two authentication methods: * **Bearer tokens** — obtained via the magic-link flow or the [API keys](/yativo-fiat/api-keys) endpoint. Include in every request as `Authorization: Bearer `. * **Two-factor authentication (2FA)** — optional TOTP-based 2FA for your account login. Enable it via the [Authentication](/yativo-fiat/authentication) endpoints. Tokens expire after a set period. Use `GET /auth/refresh-token` to get a new one without re-authenticating. *** ## API key hygiene * **One key per environment** — use separate App Secrets for development, staging, and production so you can rotate or revoke one without affecting the others. * **Never expose keys client-side** — API credentials belong on your server. Do not embed them in mobile apps, browser JavaScript, or public repositories. * **Rotate after suspected exposure** — revoke your App Secret in the dashboard and generate a new one immediately if you believe it has been compromised. * **Store in secrets managers** — use environment variables or a dedicated secrets manager (AWS Secrets Manager, HashiCorp Vault, etc.), not plaintext config files. *** ## Webhook signature verification Always verify the `X-Yativo-Signature` header on incoming webhook requests. This prevents replay attacks and spoofed events. ```javascript Node.js theme={null} const crypto = require('crypto'); function verifySignature(rawBody, signature, secret) { const hmac = crypto .createHmac('sha256', secret) .update(rawBody) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(hmac), Buffer.from(signature) ); } ``` Use `crypto.timingSafeEqual` (not `===`) to prevent timing attacks. *** ## HTTPS only The Yativo API only accepts HTTPS connections. Webhook delivery also targets HTTPS endpoints only — HTTP URLs will be rejected on webhook creation. *** ## IP allowlisting For production environments, restrict outbound API calls to Yativo's IP ranges and consider allowlisting inbound webhook IPs on your firewall. Contact support for the current list of Yativo webhook egress IPs. *** ## Idempotency For mutating requests (payouts, deposits, transfers), use the `Idempotency-Key` header to safely retry without risk of duplicate transactions: ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/sendmoney' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Idempotency-Key: your-unique-request-id-abc123' \ -H 'Content-Type: application/json' \ -d '{ ... }' ``` If a request with the same idempotency key succeeds, subsequent requests with that key return the original response without executing the operation again. Keys expire after 24 hours. *** ## Rate limits The API enforces rate limits per API key: | Tier | Requests per minute | | -------- | ------------------- | | Default | 120 | | Elevated | 600 (on request) | When a limit is hit, the API returns `429 Too Many Requests` with a `Retry-After` header indicating when to retry. *** ## Sensitive data handling * Virtual card sensitive details (full PAN, CVV) are returned only on the card detail endpoint and should be displayed in-app temporarily — never logged or stored on your servers. * Yativo is PCI-DSS compliant. Do not log or store raw card data in your systems. * Customer PII (names, emails, phone numbers) should be treated as sensitive. Limit access in your systems to only those who need it. *** ## Error responses Security-related errors you may encounter: | HTTP status | Meaning | | ----------------------- | ---------------------------------------------- | | `401 Unauthorized` | Missing or invalid Bearer token / API key | | `403 Forbidden` | Valid credentials but insufficient permissions | | `429 Too Many Requests` | Rate limit exceeded | All error responses include a machine-readable `code` field: ```json theme={null} { "status": "error", "code": "UNAUTHORIZED", "message": "Invalid or expired access token" } ``` # Send Money Source: https://docs.yativo.com/yativo-fiat/send-money Send cross-border payments via local bank transfer, SPEI, SEPA, ACH, and more Send payments follow a structured flow: discover the payment method for the destination country, collect recipient bank details, lock an exchange rate quote, then execute the transfer. ```typescript theme={null} interface PayoutMethod { id: number; method_name: string; country: string; currency: string; base_currency: string; } interface BeneficiaryPaymentMethod { id: string; beneficiary_id: string; payment_method_id: number; account_details: Record; created_at: string; } interface SendMoneyQuote { quote_id: string; // valid for 5 minutes from_currency: string; to_currency: string; rate: string; amount: string; payout_data: { total_transaction_fee_in_from_currency: string; customer_sent_amount: string; customer_receive_amount: string; customer_total_amount_due: string; }; } ``` *** ## Step 1: Get Supported Payout Countries Retrieve the full list of countries where Yativo supports outbound payments: ``` GET /payment-methods/payout/countries ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout/countries' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": [ { "country": "Chile", "iso3": "CHL" }, { "country": "Mexico", "iso3": "MEX" }, { "country": "Brazil", "iso3": "BRA" }, { "country": "Peru", "iso3": "PER" }, { "country": "Colombia", "iso3": "COL" }, { "country": "Argentina", "iso3": "ARG" } ] } ``` *** ## Step 2: Get Payout Methods for Destination Retrieve available payment rails for the destination country. Use the ISO 3166-1 alpha-3 country code: ``` GET /payment-methods/payout?country={iso3} ``` Destination country ISO 3166-1 alpha-3 code (e.g. `CHL`, `MEX`, `BRA`). ```bash Chile theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout?country=CHL' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Mexico theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout?country=MEX' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Brazil theme={null} curl -X GET 'https://api.yativo.com/api/v1/payment-methods/payout?country=BRA' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success (Chile) theme={null} { "status": "success", "data": [ { "id": 21, "method_name": "Bank Transfer", "country": "CHL", "currency": "CLP", "base_currency": "CLP" } ] } ``` Note the `id` — this is your `payment_method_id` for subsequent steps. *** ## Step 3: Get Required Form Fields Each payment method requires different recipient details (CLABE, account number, routing number, etc.). Retrieve the exact fields needed: ``` GET /beneficiary/form/show/{payment_method_id} ``` The payment method ID from Step 2. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/beneficiary/form/show/21' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Step 4: Create a Beneficiary Create a beneficiary record for the recipient. The `beneficiary_id` returned here is used to attach bank details in Step 5. ``` POST /beneficiaries ``` Recipient's full name (individual) or legal business name. Recipient's email address. ISO 3166-1 alpha-3 country code (e.g. `CHL`, `MEX`, `BRA`). `"individual"` or `"business"`. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: create-beneficiary-001' \ -d '{ "name": "Carlos Mendez", "email": "carlos@example.com", "country": "CHL", "type": "individual" }' ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Beneficiary created successfully", "data": { "beneficiary_id": "ben-7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d", "name": "Carlos Mendez", "email": "carlos@example.com", "type": "individual", "country": "CHL", "created_at": "2026-04-02T10:00:00.000000Z" } } ``` *** ## Step 5: Save Recipient Bank Details Submit the recipient's bank account details using the fields returned in Step 3: ``` POST /beneficiaries/payment-methods ``` The beneficiary ID from Step 4. Payment method ID from Step 2. Key-value pairs of the required fields (e.g. `account_number`, `bank_code`, `clabe`, `pix_key`). ```bash Chile (CLP bank transfer) theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "beneficiary_id": "benef_01HX9KZMB3F7VNQP8R2WDGT4E5", "payment_method_id": 21, "account_details": { "account_number": "12345678", "bank_code": "001", "account_type": "checking" } }' ``` ```bash Mexico (SPEI CLABE) theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "beneficiary_id": "benef_01HX9KZMB3F7VNQP8R2WDGT4E5", "payment_method_id": 30, "account_details": { "clabe": "012345678901234567" } }' ``` ```bash Brazil (PIX) theme={null} curl -X POST 'https://api.yativo.com/api/v1/beneficiaries/payment-methods' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "beneficiary_id": "benef_01HX9KZMB3F7VNQP8R2WDGT4E5", "payment_method_id": 40, "account_details": { "pix_key": "carlos@example.com", "pix_key_type": "email" } }' ``` The response includes a saved payment method `id` for use in Step 7. *** ## Step 6: Get an Exchange Rate Quote (Recommended) Lock in a rate before executing the payment. Quotes are valid for **5 minutes**: ``` POST /sendmoney/quote ``` Source currency code (e.g. `USD`, `EUR`). Destination currency code (e.g. `CLP`, `MXN`, `BRL`). Amount in the source currency. The payment method ID saved in Step 5. This links the quote to the destination account so that executing `POST /sendmoney` knows where to deliver funds. ```bash USD → CLP theme={null} curl -X POST 'https://api.yativo.com/api/v1/sendmoney/quote' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: quote-001' \ -d '{ "from_currency": "USD", "to_currency": "CLP", "amount": 500, "beneficiary_payment_method_id": "pm-3a4b5c6d-7e8f-9a0b-1c2d-3e4f5a6b7c8d" }' ``` ```json Success theme={null} { "status": "success", "data": { "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "from_currency": "USD", "to_currency": "CLP", "rate": "950.00", "amount": "500.00", "payout_data": { "total_transaction_fee_in_from_currency": "11.15", "customer_sent_amount": "500.00", "customer_receive_amount": "462925.00", "customer_total_amount_due": "511.15" } } } ``` Quotes are valid for **5 minutes**. Execute the send money request within this window using the `quote_id`. *** ## Step 7: Send Money Execute the payment using the quote ID: ``` POST /sendmoney ``` The quote ID from Step 6. Guarantees the locked rate. ```bash cURL (with quote) theme={null} curl -X POST 'https://api.yativo.com/api/v1/sendmoney' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-payout-key' \ -d '{ "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed" }' ``` Alternatively, initiate a quick payout directly from your wallet without a quote: ``` POST /wallet/payout ``` ```bash cURL (wallet payout) theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-payout-key' \ -d '{ "debit_wallet": "USD", "payment_method_id": 21, "amount": 500 }' ``` *** ## Step 8: Track the Payment Monitor the payment status in real-time: ``` GET /transaction/tracking/{transactionId} ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/transaction/tracking/a0e9e50e-81be-4bd0-9941-0151e68b9e97' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": [ { "tracking_status": "Payment credited to beneficiary", "created_at": "2026-04-01T10:03:22Z" }, { "tracking_status": "With Beneficiary's Bank/Rail", "created_at": "2026-04-01T10:02:54Z" }, { "tracking_status": "Processed by Yativo", "created_at": "2026-04-01T10:01:45Z" }, { "tracking_status": "Send money initiated", "created_at": "2026-04-01T10:00:00Z" } ] } ``` *** ## Manage Saved Payment Methods ### List All Saved Methods ``` GET /beneficiaries/payment-methods/all ``` ### Update a Saved Method ``` PUT /beneficiaries/payment-methods/update/{id} ``` ### Delete a Saved Method ``` DELETE /beneficiaries/payment-methods/delete/{id} ``` *** ## Transaction Purpose For compliance, submit the purpose of a transaction after initiating it: ``` POST /sendmoney/purpose ``` The transaction ID returned from `POST /sendmoney`. A short description of the payment purpose, e.g. `"family_support"`, `"business_payment"`, `"invoice"`. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/sendmoney/purpose' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: purpose-001' \ -d '{ "transaction_id": "a0e9e50e-81be-4bd0-9941-0151e68b9e97", "purpose": "family_support" }' ``` Yativo supports payouts to LATAM (CHL, MEX, BRA, PER, COL, ARG), USA, and Europe. Contact your integration team for additional corridors. # Currency Swap Source: https://docs.yativo.com/yativo-fiat/swap Convert balances between your wallets instantly at the live exchange rate Currency swap lets you convert funds between any two currency wallets you hold in your Yativo account — for example, moving USD to BRL, EUR to MXN, or CLP to USD — without sending to an external beneficiary. The flow is two steps: first **initiate** to preview the rate and terms, then **process** to execute the conversion and move the balance. *** ## How it works ``` 1. POST /swap/init → preview rate, receive swap details 2. POST /swap/process → debit from_currency wallet, credit to_currency wallet ``` Both wallets must exist before swapping. Create missing wallets with `POST /wallet/create`. *** ## Step 1: Initiate Swap Preview the exchange rate and resulting converted amount before committing. ``` POST https://api.yativo.com/api/v1/swap/init ``` Requires `Idempotency-Key` header. The source wallet currency code (ISO 4217), e.g. `"USD"`, `"EUR"`. The target wallet currency code (ISO 4217), e.g. `"BRL"`, `"MXN"`, `"CLP"`. Amount in the source currency to convert. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/swap/init' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: swap-init-usd-brl-001' \ -d '{ "from_currency": "USD", "to_currency": "BRL", "amount": 500 }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/swap/init', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `swap-init-${Date.now()}`, }, body: JSON.stringify({ from_currency: 'USD', to_currency: 'BRL', amount: 500, }), }); const data = await response.json(); ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "from_currency": "USD", "to_currency": "BRL", "from_amount": "500.00", "to_amount": "2491.00", "exchange_rate": "4.9820", "fee": "5.00", "fee_currency": "USD" } } ``` ```json Insufficient balance theme={null} { "status": "error", "status_code": 400, "message": "Insufficient wallet balance" } ``` ```json Invalid currencies theme={null} { "status": "error", "status_code": 422, "message": "Invalid currencies supplied" } ``` *** ## Step 2: Process Swap Execute the conversion. Funds are debited from the `from_currency` wallet and credited to the `to_currency` wallet at the live rate. ``` POST https://api.yativo.com/api/v1/swap/process ``` Requires `Idempotency-Key` header. Use a **new, unique key** for the process step — reusing the init key will be rejected. The source wallet currency code. The target wallet currency code. Amount in the source currency to convert. Optional description for this swap, recorded on the transaction record. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/swap/process' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: swap-process-usd-brl-001' \ -d '{ "from_currency": "USD", "to_currency": "BRL", "amount": 500 }' ``` ```javascript Node.js theme={null} const response = await fetch('https://api.yativo.com/api/v1/swap/process', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', 'Idempotency-Key': `swap-process-${Date.now()}`, }, body: JSON.stringify({ from_currency: 'USD', to_currency: 'BRL', amount: 500, transaction_purpose: 'Fund BRL wallet for local payouts', }), }); const data = await response.json(); ``` ```python Python theme={null} import requests response = requests.post( 'https://api.yativo.com/api/v1/swap/process', headers={ 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json', 'Idempotency-Key': f'swap-process-{int(time.time())}', }, json={ 'from_currency': 'USD', 'to_currency': 'BRL', 'amount': 500, } ) ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "from_currency": "USD", "to_currency": "BRL", "from_amount": "500.00", "to_amount": "2491.00", "exchange_rate": "4.9820", "transaction_type": "currency_swap", "gateway_id": "currency_swap", "swap_from_currency": "USD", "swap_to_currency": "BRL", "transaction_purpose": "Fund BRL wallet for local payouts", "created_at": "2026-06-01T10:00:00.000000Z" } } ``` *** ## Full example ```javascript Node.js — complete swap flow theme={null} async function swapCurrency(token, fromCurrency, toCurrency, amount) { const BASE = 'https://api.yativo.com/api/v1'; const headers = { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }; // Step 1: Preview the rate const initRes = await fetch(`${BASE}/swap/init`, { method: 'POST', headers: { ...headers, 'Idempotency-Key': `swap-init-${Date.now()}` }, body: JSON.stringify({ from_currency: fromCurrency, to_currency: toCurrency, amount }), }); const preview = await initRes.json(); console.log(`Rate: ${preview.data.exchange_rate} — you receive ${preview.data.to_amount} ${toCurrency}`); // Step 2: Execute const processRes = await fetch(`${BASE}/swap/process`, { method: 'POST', headers: { ...headers, 'Idempotency-Key': `swap-process-${Date.now()}` }, body: JSON.stringify({ from_currency: fromCurrency, to_currency: toCurrency, amount }), }); return processRes.json(); } // Usage const result = await swapCurrency(token, 'USD', 'BRL', 500); console.log('Swap complete:', result.data); ``` *** ## Notes * Both wallets must exist before swapping. Create them with `POST /wallet/create` if needed. * The live rate is fetched at execution time — rates are not locked between `/init` and `/process`. Use `/init` to show the customer a preview, then execute `/process` promptly. * Swaps are recorded as `currency_swap` transactions and appear in your transaction history. * Check available wallet balances with `GET /wallet/balance` before initiating. # Transactions Source: https://docs.yativo.com/yativo-fiat/transactions View, filter, track, and export business transactions ```typescript theme={null} interface Transaction { id: number; // internal numeric ID transaction_id: string; // UUID transaction_amount: string; transaction_status: TransactionStatus; transaction_type: TransactionType; transaction_currency: string; transaction_memo: string; transaction_purpose: string; customer_id: string | null; created_at: string; } type TransactionStatus = | "success" | "complete" | "detected" | "pending" | "In Progress" | "failed"; type TransactionType = | "deposit" | "payout" | "virtual_account" | "transfer" | "card_transaction" | "crypto_deposit"; ``` *** ## List Transactions Retrieve all transactions for your business with optional filters: ``` GET /business/transactions/index ``` Filter by status: `success`, `complete`, `detected`, `pending`, `In Progress`, `failed`. Filter by type: `deposit`, `payout`, `virtual_account`, `transfer`, `card_transaction`, `crypto_deposit`. Filter by customer ID. Filter by exact transaction amount. From date (inclusive), e.g. `2026-04-01`. To date (inclusive), e.g. `2026-04-30`. Page number. Default: `1`. Results per page. Default: `10`. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/transactions/index?status=success&transaction_type=deposit&start_date=2026-04-01&end_date=2026-04-30&page=1&per_page=10' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Records retrieved successfully", "data": [ { "id": 14, "transaction_id": "a0e9e50e-81be-4bd0-9941-0151e68b9e97", "transaction_amount": "1000.00", "transaction_status": "success", "transaction_type": "deposit", "transaction_memo": "payin", "transaction_purpose": "Deposit", "transaction_currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "created_at": "2026-04-01T10:00:00.000000Z" } ], "meta": { "total": 42, "per_page": 10, "current_page": 1, "last_page": 5 } } ``` *** ## Get Transaction Retrieve full details for a single transaction: ``` GET /business/transaction/show/{id} ``` The internal numeric transaction ID (the `id` field, not `transaction_id` UUID). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/transaction/show/14' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` The single transaction response includes additional `payin_method` and `payout_method` objects with full payment method details. *** ## Track Transaction Get a live status timeline for any transaction: ``` GET /transaction/tracking/{transactionId} ``` The transaction UUID (`transaction_id` field). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/transaction/tracking/a0e9e50e-81be-4bd0-9941-0151e68b9e97' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": [ { "tracking_status": "Payment credited to beneficiary", "transaction_type": "withdrawal", "created_at": "2026-04-01T10:03:22.000000Z" }, { "tracking_status": "With Beneficiary's Bank/Rail", "transaction_type": "withdrawal", "created_at": "2026-04-01T10:02:54.000000Z" }, { "tracking_status": "Processed by Yativo", "transaction_type": "withdrawal", "created_at": "2026-04-01T10:01:45.000000Z" }, { "tracking_status": "Send money initiated", "transaction_type": "withdrawal", "created_at": "2026-04-01T10:00:00.000000Z" } ] } ``` *** ## Transactions by Currency Filter all transactions by a specific currency: ``` GET /business/transaction/by-currency?currency={code} ``` Currency code (e.g. `BRL`, `USD`, `CLP`, `MXN`). ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/transaction/by-currency?currency=BRL' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Download Receipt (PDF) Download a receipt for a completed transaction. Returns a **base64-encoded PDF**: ``` GET /business/transaction/{transactionId}/pdf/receipt ``` The transaction UUID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/transaction/a0e9e50e-81be-4bd0-9941-0151e68b9e97/pdf/receipt' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```javascript Node.js decode theme={null} const response = await client.get(`/business/transaction/${txId}/pdf/receipt`); const pdfBuffer = Buffer.from(response.data, 'base64'); fs.writeFileSync('receipt.pdf', pdfBuffer); ``` *** ## Transaction PIN Sensitive operations require verification of your 4-digit transaction PIN. ### Verify PIN ``` POST /pin/verify ``` Your 4-digit transaction PIN. ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/pin/verify' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "pin": "1234" }' ``` ### Set or Update PIN ``` POST /pin/update ``` Your new 4-digit PIN. ```bash theme={null} curl -X POST 'https://api.yativo.com/api/v1/pin/update' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "pin": "5678" }' ``` # Virtual Accounts Source: https://docs.yativo.com/yativo-fiat/virtual-accounts Issue local virtual accounts to collect payments in multiple currencies Virtual accounts give each customer a unique local bank account number. When a payment arrives at that number, it is automatically matched and credited to the right customer — no manual reconciliation needed. Each customer can hold **one virtual account per currency**. KYC approval (`is_va_approved: true`) is required before a virtual account can be issued. ## Supported Rails | Currency | Rail | Countries | Extra required fields | | ------------------- | ------------------ | ---------------- | ------------------------------ | | `BRL` | PIX | Brazil | — | | `MXNBASE` / `MXN` | SPEI | Mexico | — | | `USDBASE` | ACH / Wire | United States | — | | `EURBASE` / `EURDE` | SEPA | Europe / Germany | — | | `MXNUSD` | SPEI (USD-settled) | Mexico | — | | `ARS` | CVU/CBU | Argentina | `document_id`, `document_type` | Argentina accounts require the customer's `document_id` and `document_type` (`"CUIT"`, `"CUIL"`, or `"CDI"`) in the create request. The customer must be an Argentine resident. See the [Regional Payouts guide](/guides/regional-payouts) for details. ```typescript theme={null} interface VirtualAccount { account_id: string; account_number: string; account_type: string; currency: string; customer_id: string; created_at: string; } type SupportedCurrency = | "USDBASE" // USD (standard ACH/wire) | "EURBASE" // EUR (SEPA standard) | "EURDE" // EUR (Germany SEPA) | "MXN" // Mexican Peso via SPEI | "MXNBASE" // Mexican Peso via SPEI | "MXNUSD" // USD-settled via SPEI | "BRL"; // Brazilian Real via PIX ``` *** ## Create Virtual Account ``` POST /business/virtual-account/create ``` The ID of the KYC-approved customer to issue the account to. Currency for the virtual account (see supported values above). ```bash Brazil (PIX) theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "BRL" }' ``` ```bash Mexico (SPEI) theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "MXNBASE" }' ``` ```javascript Node.js theme={null} const { data } = await client.post('/business/virtual-account/create', { customer_id: customerId, currency: 'BRL', }, { headers: { 'Idempotency-Key': crypto.randomUUID() }, }); console.log('Account number:', data.data.account_number); ``` ```json Success theme={null} { "status": "success", "status_code": 201, "message": "Virtual account creation in progress", "data": { "account_id": "va_xxxxxx", "account_number": "9900123456", "account_type": "savings", "currency": "BRL", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "created_at": "2026-04-01T10:00:00Z" } } ``` *** ## List Virtual Accounts ``` GET /business/virtual-account ``` Filter by currency code (e.g. `BRL`, `USD`). Filter by account status. From date (ISO 8601). Search query — account number, customer name, etc. Results per page. Page number. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account?currency=BRL&per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Get Virtual Account ``` GET /business/virtual-account/show/{id} ``` The virtual account ID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account/show/va_xxxxxx' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Virtual Account Transaction History Retrieve all payments received into a specific virtual account: ``` POST /business/virtual-account/history/{account_number} ``` The account number (not the account ID). Filter by customer ID. Filter by payment status. From date (ISO 8601). To date (ISO 8601). Page number. Results per page. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/history/9900123456?start_date=2026-04-01&end_date=2026-04-30' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "data": [ { "amount": 1000, "currency": "BRL", "status": "completed", "credited_amount": 950, "transaction_id": "TXNMP2HK81BHJ", "sender_name": "John Smith", "account_number": "9900123456", "transaction_fees": 50 } ], "pagination": { "total": 12, "per_page": 20, "current_page": 1 } } ``` *** ## Delete Virtual Account ``` DELETE /business/virtual-account/delete-virtual-account/{id} ``` The virtual account ID to delete. ```bash cURL theme={null} curl -X DELETE 'https://api.yativo.com/api/v1/business/virtual-account/delete-virtual-account/va_xxxxxx' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Bulk Account Creation Create virtual accounts for multiple customers in a single request. Useful when onboarding a batch of pre-verified customers. ``` POST https://api.yativo.com/api/v1/business/virtual-account/bulk-account-creation ``` Requires `Idempotency-Key` header. All customers must have `is_va_approved: true` before bulk creation. Array of account creation objects. The KYC-approved customer UUID. Currency for the virtual account (e.g. `"BRL"`, `"MXNBASE"`, `"USDBASE"`). ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/bulk-account-creation' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: bulk-va-june-001' \ -d '{ "accounts": [ { "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "BRL" }, { "customer_id": "c586066b-0f29-468f-b775-15483871a202", "currency": "BRL" }, { "customer_id": "f7e8d9c0-1a2b-3c4d-5e6f-7a8b9c0d1e2f", "currency": "MXNBASE" } ] }' ``` *** ## Enable / Disable Virtual Account Suspend or reactivate a virtual account without deleting it. Suspended accounts stop receiving deposits. ``` PUT https://api.yativo.com/api/v1/business/virtual-account/enable_disable_virtual_account ``` The virtual account ID. `"enable"` or `"disable"`. ```bash Disable theme={null} curl -X PUT 'https://api.yativo.com/api/v1/business/virtual-account/enable_disable_virtual_account' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: disable-va-001' \ -d '{ "account_id": "va_xxxxxx", "action": "disable" }' ``` ```bash Re-enable theme={null} curl -X PUT 'https://api.yativo.com/api/v1/business/virtual-account/enable_disable_virtual_account' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: enable-va-001' \ -d '{ "account_id": "va_xxxxxx", "action": "enable" }' ``` *** ## Refund a Payin Reverse a specific incoming deposit back to the sender. Use this when a customer payment needs to be returned. ``` POST https://api.yativo.com/api/v1/business/virtual-account/refundPayin/{externalId} ``` The external transaction ID of the deposit to refund. This is returned in the `virtual_account.deposit` webhook payload. Requires `Idempotency-Key` header. Refunds are subject to the availability of the underlying payment rail — not all currencies support reversals. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/virtual-account/refundPayin/TXNMP2HK81BHJ' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: refund-TXNMP2HK81BHJ-001' ``` *** ## List All Virtual Account History Retrieve transaction history across all virtual accounts (not scoped to a specific account number): ``` GET https://api.yativo.com/api/v1/business/virtual-account/histories ``` *** ## Get Customer Virtual Accounts List all virtual accounts belonging to a specific customer: ``` GET https://api.yativo.com/api/v1/business/virtual-account/customer/accounts/{customerId} ``` The customer UUID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/virtual-account/customer/accounts/da44a3e6-eb5d-429f-8d17-357aa5a6cdf2' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## KYC Requirement Before issuing a virtual account, the customer's KYC must be approved. Check the `is_va_approved` flag on the customer object: ```bash theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/da44a3e6-eb5d-429f-8d17-357aa5a6cdf2' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` If `is_va_approved` is `false`, submit KYC first. See the [Customers & KYC](/yativo-fiat/kyc) guide. # Virtual Cards Source: https://docs.yativo.com/yativo-fiat/virtual-cards Issue virtual Visa/Mastercard cards to your customers Issue prepaid virtual cards to your customers for online spending. Cards are funded from your wallet balance and can be frozen, unfrozen, topped up, or terminated via the API. Minimum card creation amount is $3.00. The maximum card creation amount and top-up amount is $10,000.00 USD. *** ## Step 1: Issue a Card Create a virtual card for an activated customer: ``` POST /customer/virtual/cards/create ``` The ID of the activated customer. Card currency (e.g. `USD`). Initial funding amount in USD. Minimum $3.00, maximum $10,000.00. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "currency": "USD", "amount": 10.00 }' ``` ```json Success theme={null} { "status": "success", "data": { "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "card_number": "4111 **** **** 1234", "expiry": "04/29", "cvv": "***", "currency": "USD", "balance": "0.00", "status": "active", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2" } } ``` *** ## List Cards Retrieve all virtual cards with pagination: ``` GET /customer/virtual/cards/list ``` Page number. Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/virtual/cards/list?page=1&per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Get Card Details Retrieve a specific virtual card, including sensitive details: ``` GET /customer/virtual/cards/get/{cardId} ``` The virtual card ID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/virtual/cards/get/card_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Fund a Card Top up a card from your wallet balance: ``` POST /customer/virtual/cards/topup ``` The virtual card ID. Amount to add to the card. Minimum $1.00, maximum $10,000.00. Wallet currency to debit from (e.g. `USD`). ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/topup' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 100, "debit_wallet": "USD" }' ``` *** ## Freeze / Unfreeze a Card Temporarily freeze or unfreeze a card: ``` PUT /customer/virtual/cards/update/{cardId} ``` The virtual card ID. `"freeze"` to block the card, `"unfreeze"` to re-enable it. ```bash Freeze theme={null} curl -X PUT 'https://api.yativo.com/api/v1/customer/virtual/cards/update/card_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "action": "freeze" }' ``` ```bash Unfreeze theme={null} curl -X PUT 'https://api.yativo.com/api/v1/customer/virtual/cards/update/card_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "action": "unfreeze" }' ``` *** ## Get Card Transactions Retrieve transaction history for a specific card: ``` GET /customer/virtual/cards/transactions/{cardId} ``` The virtual card ID. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/customer/virtual/cards/transactions/card_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Withdraw from Card Move funds from a card back to your wallet: ``` POST /customer/virtual/cards/withdraw ``` The virtual card ID. Amount to withdraw from the card. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/withdraw' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5", "amount": 50 }' ``` *** ## Terminate a Card Permanently cancel a card. This action is irreversible: ``` POST /customer/virtual/cards/terminate ``` The virtual card ID to terminate. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/customer/virtual/cards/terminate' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "card_id": "card_01HX9KZMB3F7VNQP8R2WDGT4E5" }' ``` Card termination is permanent. Withdraw remaining funds before terminating. # Wallets Source: https://docs.yativo.com/yativo-fiat/wallets Manage multi-currency wallet balances and initiate payouts Your Yativo wallet holds balances in multiple currencies. Fund payouts from your wallet, and receive deposits into it. The wallet API lets you check balances, create new currency wallets, and initiate quick payouts. ```typescript theme={null} interface WalletBalance { name: string; // currency code, e.g. "USD" slug: string; // URL-friendly, e.g. "usd" balance: string; // current balance as string currency: string; // currency code decimal_places: number; meta: { logo: string; // URL to currency logo/flag symbol: string; // e.g. "$", "R$", "S/" fullname: string; // e.g. "US Dollar" precision: string | number; }; } interface TotalBalance { total_balance: number; // total of all wallets converted to USD } ``` *** ## Get Wallet Balance Returns detailed balance information for every currency wallet on your account. ``` GET /wallet/balance ``` Optional: filter by a specific currency code (e.g. `USD`, `BRL`). Omit to return all. ```bash All balances theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/balance' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```bash Single currency theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/balance?currency=USD' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": [ { "name": "USD", "slug": "usd", "balance": "35585.00", "currency": "USD", "decimal_places": 2, "meta": { "logo": "https://cdn.yativo.com/usd.svg", "symbol": "$", "fullname": "US Dollar", "precision": 2 } }, { "name": "BRL", "slug": "brl", "balance": "14200.00", "currency": "BRL", "decimal_places": 2, "meta": { "logo": "https://cdn.yativo.com/brl.svg", "symbol": "R$", "fullname": "Brazilian Real", "precision": "2" } } ] } ``` **Supported currencies:** ARS, BRL, CLP, COP, EUR, MXN, PEN, USD *** ## Get Total Balance Returns the sum of all wallet balances converted to USD at current exchange rates: ``` GET /wallet/balance/total ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/wallet/balance/total' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ```json Success theme={null} { "status": "success", "status_code": 200, "message": "Request successful", "data": { "total_balance": 37629.18 } } ``` *** ## Create a Wallet Create a new currency wallet for your account: ``` POST /wallet/create ``` The currency code for the new wallet (e.g. `COP`, `PEN`, `ARS`). ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/create' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "currency": "COP" }' ``` ```json Success theme={null} { "status": "success", "data": { "currency": "COP", "balance": "0.00" } } ``` *** ## Quick Wallet Payout Initiate a payout directly from your wallet balance without the full send money flow: ``` POST /wallet/payout ``` Currency to debit from your balance (e.g. `"USD"`). The saved beneficiary payment method ID. Quote ID from `POST /sendmoney/quote` or `POST /exchange-rate`. Locks the rate for 5 minutes. Recommended — amount is taken from the quote. Amount to send. Required if `quote_id` is not provided. Uses current market rate. ```bash With quote (recommended) theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-payout-key' \ -d '{ "debit_wallet": "USD", "quote_id": "4a72ecf8-6c8a-4e38-9971-8aabe9f785ed", "payment_method_id": 21 }' ``` ```bash Without quote (market rate) theme={null} curl -X POST 'https://api.yativo.com/api/v1/wallet/payout' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-payout-key' \ -d '{ "debit_wallet": "USD", "amount": 500, "payment_method_id": 21 }' ``` *** ## Display Tips ```javascript theme={null} // Format a wallet balance for display function formatBalance(wallet) { const balance = parseFloat(wallet.balance); const symbol = wallet.meta.symbol; const precision = wallet.decimal_places; return `${symbol}${balance.toFixed(precision)}`; } // Filter out zero balances const activeWallets = wallets.filter(w => parseFloat(w.balance) > 0); ``` Wallets with zero balances are included in the response. Filter client-side if you only want non-zero holdings. # Webhooks Source: https://docs.yativo.com/yativo-fiat/webhooks Receive real-time event notifications for payments, transfers, and account activity Webhooks push event notifications to your server the moment something happens — no polling needed. Configure a single HTTPS endpoint to receive all events, then filter by `event.type` in your handler. All webhook requests from Yativo include an `X-Yativo-Signature` header. Always verify this signature before processing any event. *** ## Set Webhook URL ``` POST /business/webhook ``` Your HTTPS endpoint that will receive webhook events. ```bash cURL theme={null} curl -X POST 'https://api.yativo.com/api/v1/business/webhook' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "url": "https://your-app.com/webhooks/yativo" }' ``` *** ## Get Webhook Configuration ``` GET /business/webhook ``` ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/webhook' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## Update Webhook URL ``` PUT /business/webhook/{webhook_id} ``` The webhook ID returned when the webhook was created. New destination URL. ```bash cURL theme={null} curl -X PUT 'https://api.yativo.com/api/v1/business/webhook/wh-01abc123' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Idempotency-Key: unique-key-here' \ -d '{ "url": "https://your-app.com/webhooks/yativo-v2" }' ``` *** ## Webhook Event Types Your endpoint receives `POST` requests with a JSON body containing an `event.type` field. | Event type | Triggered when | | ------------------------- | ----------------------------------------------------- | | `deposit.created` | A new deposit is initiated | | `deposit.updated` | A deposit status changes (e.g. `pending` → `success`) | | `deposit.completed` | A deposit is successfully completed | | `payout.updated` | A payout status changes (e.g. completed or failed) | | `payout.completed` | A payout is successfully completed | | `customer.created` | A new customer is created | | `customer.kyc.approved` | A customer's KYC is approved | | `customer.kyc.rejected` | A customer's KYC is rejected | | `virtual_account.deposit` | A payment arrives at a virtual account | | `virtual_account.funded` | A virtual account receives funds (settled) | *** ## Event Payloads ### `deposit.created` ```json theme={null} { "event.type": "deposit.created", "payload": { "id": "93df8440-b756-449c-b0e8-190e2bd8e2bf", "amount": 11, "gateway": "23", "currency": "CLP", "status": "pending", "deposit_currency": "USD", "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "created_at": "2026-04-01T17:19:56.000000Z" } } ``` ### `deposit.updated` ```json theme={null} { "event.type": "deposit.updated", "payload": { "id": "93df8440-b756-449c-b0e8-190e2bd8e2bf", "amount": 11, "gateway": "23", "currency": "CLP", "status": "success", "deposit_currency": "USD", "receive_amount": 2681, "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "updated_at": "2026-04-01T17:22:10.000000Z" } } ``` ### `payout.updated` ```json theme={null} { "event.type": "payout.updated", "payload": { "payout_id": "4533bb23-0f2d-4c00-8ce3-a2b4ab727b0e", "amount": "20.00", "currency": "ARS", "debit_wallet": "USD", "beneficiary_id": 5, "status": "completed", "created_at": "2026-04-01T21:32:46.000000Z", "updated_at": "2026-04-01T21:43:59.000000Z" } } ``` ### `customer.created` ```json theme={null} { "event.type": "customer.created", "payload": { "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "customer_name": "Jane Doe", "customer_email": "jane@example.com", "customer_phone": "+5511999999999", "customer_country": "BRA", "customer_status": "active", "customer_kyc_status": "approved", "created_at": "2026-04-01T16:15:20.000000Z" } } ``` ### `virtual_account.deposit` ```json theme={null} { "event.type": "virtual_account.deposit", "payload": { "amount": 1000, "currency": "BRL", "status": "completed", "credited_amount": 950, "transaction_type": "virtual_account_topup", "transaction_id": "TXNMP2HK81BHJ", "customer": { "customer_id": "da44a3e6-eb5d-429f-8d17-357aa5a6cdf2", "customer_name": "Jane Doe", "customer_kyc_status": "approved" }, "source": { "account_number": "93405934593930", "sender_name": "Jane Doe", "transaction_fees": 50, "amount_received": 1000, "credited_amount": 950 } } } ``` *** ## Verifying Webhook Signatures Every webhook request includes an `X-Yativo-Signature` header containing an HMAC SHA256 hex digest of the raw request body, signed with your webhook secret. **Always verify this before trusting the payload.** The signature is computed as: ``` HMAC-SHA256(secret, JSON.stringify(payload)) → hex string ``` Your webhook secret is available in your dashboard under **Developer → Webhooks**. Never process a webhook event without first verifying its signature. Skipping this step exposes your endpoint to spoofed events. ### Verification examples ```javascript Node.js theme={null} const crypto = require('crypto'); app.post('/webhooks/yativo', express.raw({ type: 'application/json' }), (req, res) => { const secret = process.env.YATIVO_WEBHOOK_SECRET; const receivedSignature = req.headers['x-yativo-signature']; const expectedSignature = crypto .createHmac('sha256', secret) .update(req.body) // raw Buffer — do NOT parse before this step .digest('hex'); if (!crypto.timingSafeEqual( Buffer.from(expectedSignature), Buffer.from(receivedSignature) )) { return res.status(401).send('Invalid signature'); } const event = JSON.parse(req.body); // safe to process res.status(200).send('OK'); }); ``` ```python Python theme={null} import hmac import hashlib import json from flask import Flask, request, abort app = Flask(__name__) @app.route('/webhooks/yativo', methods=['POST']) def webhook(): secret = os.environ['YATIVO_WEBHOOK_SECRET'] received_signature = request.headers.get('X-Yativo-Signature', '') expected_signature = hmac.new( secret.encode(), request.data, # raw bytes — do NOT use request.json here hashlib.sha256 ).hexdigest() if not hmac.compare_digest(expected_signature, received_signature): abort(401) event = request.get_json() # safe to process return 'OK', 200 ``` ```php PHP theme={null} webhook( @RequestHeader("X-Yativo-Signature") String receivedSignature, @RequestBody byte[] rawBody ) throws Exception { String secret = System.getenv("YATIVO_WEBHOOK_SECRET"); Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256")); byte[] rawHmac = mac.doFinal(rawBody); StringBuilder hex = new StringBuilder(); for (byte b : rawHmac) hex.append(String.format("%02x", b)); String expectedSignature = hex.toString(); // Constant-time comparison if (!MessageDigest.isEqual( expectedSignature.getBytes(), receivedSignature.getBytes() )) { return ResponseEntity.status(401).body("Invalid signature"); } // safe to process return ResponseEntity.ok("OK"); } ``` ```ruby Ruby theme={null} require 'openssl' post '/webhooks/yativo' do secret = ENV['YATIVO_WEBHOOK_SECRET'] received_signature = request.env['HTTP_X_YATIVO_SIGNATURE'] payload = request.body.read expected_signature = OpenSSL::HMAC.hexdigest('SHA256', secret, payload) unless Rack::Utils.secure_compare(expected_signature, received_signature) halt 401, 'Invalid signature' end event = JSON.parse(payload) # safe to process status 200 end ``` ```csharp C# (.NET) theme={null} [HttpPost("/webhooks/yativo")] public async Task Webhook() { var secret = Environment.GetEnvironmentVariable("YATIVO_WEBHOOK_SECRET"); var receivedSignature = Request.Headers["X-Yativo-Signature"].ToString(); using var reader = new StreamReader(Request.Body); var rawBody = await reader.ReadToEndAsync(); using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret)); var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(rawBody)); var expectedSignature = BitConverter.ToString(hash).Replace("-", "").ToLower(); // Constant-time comparison if (!CryptographicOperations.FixedTimeEquals( Encoding.UTF8.GetBytes(expectedSignature), Encoding.UTF8.GetBytes(receivedSignature) )) return Unauthorized("Invalid signature"); // safe to process return Ok(); } ``` Always use **constant-time comparison** (`crypto.timingSafeEqual`, `hmac.compare_digest`, `hash_equals`, etc.) — never a plain `===` or `==`. Regular string comparison is vulnerable to timing attacks. Use the **raw request body bytes** to compute the signature — not a re-serialized version of the parsed JSON. Parsing and re-stringifying can change whitespace or key order, causing signature mismatches. *** ## Webhook Handler Example ```javascript Node.js (Express) theme={null} app.post('/webhooks/yativo', express.raw({ type: 'application/json' }), (req, res) => { // 1. Verify signature first (see above) verifySignature(req); const event = JSON.parse(req.body); switch (event['event.type']) { case 'deposit.updated': if (event.payload.status === 'success') { creditCustomer(event.payload.customer_id, event.payload.receive_amount); } break; case 'payout.updated': updatePayoutStatus(event.payload.payout_id, event.payload.status); break; case 'virtual_account.deposit': notifyCustomer(event.payload.customer.customer_id, event.payload.credited_amount); break; case 'customer.kyc.approved': enableCustomerFeatures(event.payload.customer_id); break; } res.status(200).send('OK'); }); ``` Respond with a `2xx` status within **10 seconds** to acknowledge receipt. Failed deliveries are retried automatically. *** ## Event Log Retrieve all webhook events sent to your endpoint: ``` GET /business/events/all ``` Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/events/all?per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` ### Get Single Event ``` GET /business/events/show/{id} ``` ```bash theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/events/show/evt_01HX9KZMB3F7VNQP8R2WDGT4E5' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` *** ## API Request Logs Audit all API calls made against your account: ``` GET /business/logs/all ``` Filter by HTTP status code (e.g. `200`, `400`). Filter by HTTP method (`GET`, `POST`, `PUT`, `DELETE`). Page number. Results per page. ```bash cURL theme={null} curl -X GET 'https://api.yativo.com/api/v1/business/logs/all?method=POST&per_page=20' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' ``` # Changelog Source: https://docs.yativo.com/yativo/changelog Latest updates, improvements, and fixes across all Yativo platforms ### Docs * Comprehensive Yativo Fiat documentation with guides, API references, KYC/KYB docs * Added HMAC SHA256 webhook signature verification examples in 7 languages * Docs reordered: Yativo → Yativo Fiat → Fiat API References → Yativo Crypto → Crypto API References * Changelog page added ### Monitoring * Two public status pages for production/live/main: * [status.yativo.com](https://status.yativo.com) (primary) * [status2.yativo.com](https://status2.yativo.com) (backup) * Both pages show real-time uptime, incident history, and scheduled maintenance * Per-service health monitoring for crypto backend (Balance Service, RPC Nodes, XDC WebSocket) * Fiat backend health check endpoints added (`/api/health`, `/api/health/ping`) ### Yativo Crypto SDK * 2FA enforcement on all critical operations: send funds, API key management, swaps, card freeze/unfreeze, auto-forwarding rules * TypeScript SDK updated with `twoFactorCode` parameter on sensitive endpoints * Chrome extension updated with 2FA modal prompt for sensitive actions ### Security * Webhook HMAC SHA256 signature verification documented with multi-language examples * Removed API registration/login from public docs — onboarding exclusively via dashboard * Hardcoded test keys removed from codebase ### Yativo Crypto * Auto-forwarding rules API: create, list, update, delete rules for automatic fund forwarding * Auto-forwarding supports `twoFactorCode` for create/update/delete operations ### Security * XSS sanitization added to all user-facing string inputs across crypto API * Browser extension hardened against XSS injection vectors ### Yativo Fiat * Virtual card operations: activate, create, topup, freeze, withdraw, terminate * Send money quote endpoint: `/sendmoney/quote` for pre-flight rate checks * Wallet creation API: `POST /wallet/create` * PDF transaction receipts: `GET /business/transaction/receipt/{id}` ### SDKs * TypeScript/Node.js SDK released with full crypto API coverage * Python SDK released * PHP SDK released * Java SDK released * Chrome extension with full wallet management UI ### KYC/KYB Platform * Individual KYC submission API at kyc.yativo.com * Business KYB submission with document upload support * Hosted KYC links for no-code integration * Webhook notifications on KYC status changes ### Yativo Fiat * Magic link passwordless authentication * API key generation with PIN protection * Business virtual accounts (SEPA, SPEI, Brazil, USD LatAm) * Service endorsements for regional payment rails ### Launch * Yativo Fiat platform launched at [app.yativo.com](https://app.yativo.com) * Yativo Crypto platform launched at [crypto.yativo.com](https://crypto.yativo.com) * Multi-currency wallets with support for 30+ currencies * Real-time exchange rates and FX conversion * Developer API with sandbox environment at smtp.yativo.com * Webhook infrastructure for real-time event notifications # Welcome to Yativo Source: https://docs.yativo.com/yativo/introduction Global payments infrastructure for businesses and developers Yativo is a payments infrastructure platform built for businesses, fintechs, and developers who need reliable, programmable money movement across borders and across chains. ## Two platforms, one API surface Multi-currency accounts, cross-border transfers, virtual accounts, beneficiary management, and subscription billing. Send and receive money in 50+ currencies. Multi-chain wallets, crypto-funded debit cards, IBAN accounts, token swaps, and a full B2B card issuer program. Build crypto-native financial products. ## Key capabilities | Capability | Platform | Description | | ----------------------- | -------- | ------------------------------------------------------------------- | | Multi-currency accounts | Fiat | Hold and move money in 50+ currencies | | Cross-border transfers | Fiat | Send funds internationally via a single API call | | Virtual accounts | Fiat | Issue receiving accounts per customer or transaction | | Beneficiary management | Fiat | Store and reuse recipient bank details across countries | | Crypto wallets | Crypto | Multi-chain wallet infrastructure with automatic address generation | | Crypto-funded cards | Crypto | Issue debit cards funded from crypto balances | | IBAN accounts | Crypto | European bank accounts linked to crypto wallets | | Token swaps | Crypto | Cross-chain and same-chain token exchange | | Webhooks | Both | Real-time event notifications for all platform activity | | B2B customer management | Both | Create and manage sub-accounts for your own customers | ## Authentication Both platforms authenticate via **Bearer tokens**. Generate a token by exchanging your API key and secret at the authentication endpoint for each platform. All API requests must include: ```http theme={null} Authorization: Bearer YOUR_ACCESS_TOKEN ``` ## Explore the docs Complete endpoint reference with interactive playground. Step-by-step tutorials for common integration patterns. TypeScript, Python, PHP, Java, and React SDKs. Test your integration against live-like sandbox environments.