Introduction
Welcome to the Tulu Switch API Reference. This section documents every available endpoint, request parameters, and response shapes. All requests use JSON over HTTPS, and every route requires a short-lived JWT access token.
Channels
Every customer, wallet, and transaction belongs to one channel. Choose the channel that fits how your platform manages funds.
channel: WALLETEach customer gets a virtual account number linked to a real bank account. Funds move through the virtual layer. Best for platforms where customers need an account number to receive transfers.
Key endpoints: POST /v2/customers · POST /v2/customers/:id/wallets · POST /v2/purse/deposit
channel: ACCOUNTEach customer gets a dedicated bank account that holds money directly. Best for platforms where customers need a real account to hold and manage balances.
Key endpoints: POST /v2/customers · POST /v2/checkout/accounts
channel: STABLECOINCustomer-level stablecoin wallets on supported networks (Hedera, Base, etc.). Supports HBAR, USDC, USDT, and other token currencies. Each customer has independent balances and transfer capability.
Key endpoints: POST /v2/stablecoin/customers/wallets · POST /v2/stablecoin/customers/send
Base URLs
Tulu Switch has two API base URLs — one per environment. Use the matching base URL and key prefix together.
TEST—https://api.sandbox.switch.tulupay.com| Environment | Base URL | Key prefix |
|---|---|---|
| TEST (Sandbox) | https://api.sandbox.switch.tulupay.com | pk_test_ / sk_test_ |
| LIVE (Production) | https://api.switch.tulupay.com | pk_live_ / sk_live_ |
pk_test_ key to the LIVE base URL (or vice versa) will return a 401.Authentication
All API requests require a short-lived JWT access token in the Authorization header.
- Generate your API Keys from Account > Developers in the dashboard.
- Exchange your key pair for a token via the Authenticate endpoint.
- Include the token in every request as
Authorization: Bearer <accessToken>. - Tokens expire after 15 minutes by default. Use the Refresh endpoint to renew without re-authenticating.
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Request Format
- All request bodies must be sent as JSON with
Content-Type: application/json - Path parameters (e.g.
:id,:reference) must be URL-encoded - Validate payloads before sending — the API returns a 400 with field-level errors on validation failures
{
"firstName": "Ada",
"lastName": "Obi",
"email": "ada.obi@example.com",
"country": "NG",
"channel": "WALLET",
"currency": "NGN"
}Response Format
All responses follow the same envelope regardless of success or failure:
success — true on success, false on any error
statusCode — HTTP status code (200, 400, 401, etc.)
message — human-readable result description
data — response payload; null on errors
errors — validation error details (present on 400 responses)
timestamp — ISO 8601 datetime of the response
{
"success": true,
"statusCode": 200,
"message": "Success",
"data": { ... },
"timestamp": "2025-01-01T00:00:00.000Z"
}{
"success": false,
"statusCode": 400,
"message": "Currency NGN is not supported for the STABLECOIN channel",
"errors": ["currency must be one of: USDC, USDT"],
"data": null,
"timestamp": "2025-01-01T00:00:00.000Z",
"path": "/v2/purse/deposit"
}