Getting Started
Make your first call to the SoveraEx Integration Layer API in minutes: connectivity, authentication, users, wallets and deposit addresses.
The SovX API lets you onboard users, provision wallets, and move crypto behind a single REST interface. This guide walks the path end to end—confirm connectivity, log in, create a user, give them a wallet, and generate a deposit address—so you go from zero to a funded address in minutes. You log in for a Bearer token, then send your owner x-api-key over HTTPS for SX Connect calls.
Conventions
- Envelope: every response is
{ success, data, meta:{ timestamp, version, trace_id } }; lists addmeta.pagination. - Timestamps:
created_at/updated_at, ISO 8601. - Statuses: uppercase (
PENDING,VERIFIED,COMPLETED, …). - Pagination & filters: the
filter[...]family —filter[limit],filter[skip],filter[sort],filter[where][field]. - Auth by audience:
x-api-key(owner) for SX Connect ·Authorization: Bearer(user token) for SX Users ·Authorization: Bearer(account session) for SX Customers.
Prerequisites
You'll need:
- A Sovera account — your login email and password. Log in for a Bearer token, then mint your customer API credentials (your owner
x-api-key) from it. See Authentication for the full three-tier flow. - Development Environment
- cURL, Postman, or your preferred HTTP client
- Basic understanding of REST APIs
- JSON knowledge
Quick Start
Step 1: Test Connectivity
Hit the health endpoint to confirm you can reach the API. It needs no authentication and returns status: "healthy" when the service is up—a quick way to rule out network or base-URL problems before you debug credentials. database.status tells you whether the service reached its datastore.
curl -X GET "https://api.sandbox.sovera.io/sovx/v1/health" \
-H "accept: application/json"Expected Response:
{
"status": "healthy",
"timestamp": "2026-03-12T00:00:00.000Z",
"environment": "staging",
"service": "Sovera Integration Service",
"version": "1.0.0",
"database": {
"status": "connected"
}
}Step 2: Log in
Authenticate with your Sovera account email and password. Login returns a Bearer session token—send it as Authorization: Bearer <token> to manage your Connect APIs, and use it to mint your customer API credentials (your owner x-api-key) and per-user tokens. See Authentication for the full three-tier flow.
curl -X POST "https://api.sandbox.sovera.io/sovx/v1/auth/login" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"email": "[email protected]",
"password": "your-password"
}'Expected Response: a Bearer session token to send on Connect API calls, plus the refresh_token that mints the next one.
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires": "2026-03-12T01:00:00.000Z",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}One session at a time
Each login or refresh invalidates the token issued before it. Logging in twice, or refreshing while another request is in flight, retires the token you're still holding and the next call fails with 401 Invalid authentication token. Keep one session per account and store the newest token and refresh_token every time.
The session token lasts an hour. Trade the refresh_token for a fresh one instead of logging in again—that keeps you on a single session. Store the refresh_token this returns and use it for the next refresh; the API may hand back the same value or a new one, so never assume it rotates.
curl -X POST "https://api.sandbox.sovera.io/sovx/v1/auth/refresh/token" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'Expected Response: the same three fields as login.
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires": "2026-03-12T02:00:00.000Z",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Step 3: Create a Customer
Register the customer that anchors your integration. Authenticate with the Bearer token from Step 2. The response returns the customer_id you'll need to mint credentials next. See Create Customer for the full schema.
The customer_id must already exist
customer_id isn't a name you invent here—it's the identifier your Sovera account already owns. An unknown value returns 403 with Customer id must belong to you and should be valid, and one you've already registered returns 409 Customer with this ID already exists.
curl -X POST "https://api.sandbox.sovera.io/sovx/v1/customers" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_SESSION_TOKEN" \
-d '{
"email": "[email protected]",
"customer_id": "corp-redundant-firewall",
"entity_name": "Hedge Fund e-commerce"
}'Expected Response:
{
"success": true,
"data": {
"email": "[email protected]",
"customer_id": "corp-redundant-firewall",
"entity_name": "Hedge Fund e-commerce"
},
"meta": {
"timestamp": "2026-03-12T00:00:00.000Z",
"version": "v1",
"trace_id": "abc-123-def-456"
}
}Step 4: Generate API Credentials
Mint the customer's API key. Authenticate with the Bearer token from Step 2 and pass the customer_id from Step 3. The response returns a customer_secret—this is the owner x-api-key you'll send on every User API call below. It's shown only once, so capture it now.
curl -X POST "https://api.sandbox.sovera.io/sovx/v1/customers/corp-redundant-firewall/credentials" \
-H "accept: application/json" \
-H "Authorization: Bearer YOUR_SESSION_TOKEN"Expected Response:
{
"success": true,
"data": {
"customer_id": "corp-redundant-firewall",
"customer_secret": "uiFkvaYbt1YfBO2NiXyi1txbdysIxa8H"
},
"meta": {
"timestamp": "2026-03-12T00:00:00.000Z",
"version": "v1",
"trace_id": "abc-123-def-456"
}
}Step 5: Create Your First User
Using your owner x-api-key (the customer_secret from Step 4), create the user who'll own the wallet. The response returns a user_id—you'll pass it in the path for every wallet and address call that follows, so hold on to it.
Every field below is required. account_type accepts individual or corporate, account_role accepts third, and account_purpose accepts trading or investing. Names take letters, spaces, hyphens and apostrophes—a digit fails validation. Send the residential and ID details under individual.
curl -X POST "https://api.sandbox.sovera.io/sovx/v1/users" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key-here" \
-d '{
"account_type": "individual",
"account_role": "third",
"account_purpose": "investing",
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]",
"phone_country_code": "US",
"phone_number": "2252542523",
"individual": {
"dob": "1990-10-15",
"residential_country_code": "US",
"residential_address": "123 Safe Lane",
"residential_city": "Cheyenne",
"residential_state": "WY",
"residential_postal_code": "82001",
"id_type": "ssn",
"id_number": "123456789",
"id_country_code": "US"
}
}'Expected Response: the new user, status: "PENDING" until verification completes.
{
"success": true,
"data": {
"account_type": "individual",
"account_role": "third",
"account_purpose": "investing",
"user_id": "f4057807-52cf-4083-9ecb-283ef354fb2b",
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]",
"phone_country_code": "US",
"phone_number": "2252542523",
"status": "PENDING",
"individual": {
"dob": "1990-10-15",
"residential_country_code": "US",
"residential_address": "123 Safe Lane",
"residential_city": "Cheyenne",
"residential_state": "WY",
"residential_postal_code": "82001",
"id_type": "ssn",
"id_number": "123456789",
"id_country_code": "US"
},
"created_at": "2026-03-12T00:00:00.000Z",
"updated_at": "2026-03-12T00:00:00.000Z"
},
"meta": {
"timestamp": "2026-03-12T00:00:00.000Z",
"version": "v1",
"trace_id": "abc-123-def-456"
}
}Duplicates
Email and phone number are unique per customer. Reusing either returns 409 with User with this phone number already exists.
Step 6: Create a Wallet
Give the user a wallet for the networks they'll hold. Pass the user_id from Step 5 in the path and name the wallet so it's easy to recognize later. name and networks are both required: networks is an array of network and currency pairs, and the network name carries the networks/ prefix. Call Vault Networks for the exact names you can use.
curl -X POST "https://api.sandbox.sovera.io/sovx/v1/users/f4057807-52cf-4083-9ecb-283ef354fb2b/wallets" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key-here" \
-d '{
"name": "My BTC Wallet",
"networks": [
{ "name": "networks/bitcoin-testnet", "currency": "btc" }
]
}'Expected Response: the wallet, and a deposit address for every network you asked for.
{
"success": true,
"data": {
"wallet_id": "f9dc22dd-5f78-4e5e-86ff-6c038137b43b",
"vault_wallet_id": "13830d8679a4",
"name": "My BTC Wallet",
"wallet_type": "virtual",
"networks": [
{ "name": "networks/bitcoin-testnet", "currency": "btc" }
],
"addresses": [
{
"address_id": "002f5fa8-deb2-434a-9c3e-b542b9f069a1",
"currency": "btc",
"network": "networks/bitcoin-testnet",
"address": "tb1q77f9k74y2kxcxu80k2mm2lxe54y28wphjva43s"
}
],
"is_active": true,
"created_at": "2026-03-12T00:00:00.000Z"
},
"meta": {
"timestamp": "2026-03-12T00:00:00.000Z",
"version": "v1",
"trace_id": "abc-123-def-456"
}
}You already have a deposit address
Creating the wallet provisions an address for each network in the request—read it from data.addresses. Step 7 is for minting an additional address on a wallet that already exists; you don't need it to start receiving deposits.
Wallet calls returning 500
A 500 on this endpoint or on Vault Networks means the vault behind your customer isn't configured yet. That's a setup step on our side, not something you can fix in the request—reach out and we'll provision it.
Vault Networks
List the networks your vault supports. Use the name values verbatim in the networks array above.
curl -X GET "https://api.sandbox.sovera.io/sovx/v1/vault/networks" \
-H "accept: application/json" \
-H "x-api-key: your-api-key-here"{
"success": true,
"data": [
{
"name": "networks/bitcoin-testnet",
"display_name": "Bitcoin Testnet",
"currency": "assets/native.bitcoin-testnet"
},
{
"name": "networks/ethereum-mainnet",
"display_name": "Ethereum Mainnet",
"currency": "assets/native.ethereum-mainnet"
}
]
}Step 7: Generate Deposit Address
Mint an additional on-chain address on an existing wallet. Plug in the wallet_id from the previous step and the currency and network you want to accept. Both fields are required. That's the full path—from a health check to a funded address.
Network name format differs here
This endpoint takes the network without the networks/ prefix—bitcoin-testnet, not networks/bitcoin-testnet. Step 6 takes it with the prefix.
curl -X POST "https://api.sandbox.sovera.io/sovx/v1/wallets/{wallet_id}/address" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: your-api-key-here" \
-d '{
"currency": "btc",
"network": "bitcoin-testnet"
}'Expected Response: the wallet with the address that was just minted.
{
"success": true,
"data": {
"wallet_id": "f9dc22dd-5f78-4e5e-86ff-6c038137b43b",
"vault_wallet_id": "13830d8679a4",
"user_id": "f4057807-52cf-4083-9ecb-283ef354fb2b",
"name": "My BTC Wallet",
"addresses": [
{
"address_id": "c0324298-16c7-4259-b578-9806cbfa261d",
"currency": "btc",
"network": "bitcoin-testnet",
"address": "tb1qhc3mzjm9wewl2kv3p9vvxu3me9vk34lm8adh26"
}
],
"created_at": "2026-03-12T00:00:00.000Z",
"updated_at": "2026-03-12T00:00:00.000Z"
},
"meta": {
"timestamp": "2026-03-12T00:00:00.000Z",
"version": "v1",
"trace_id": "abc-123-def-456"
}
}Next Steps
Explore further:
- User Onboarding Workflow — Complete user setup process
- Trading Operations — Execute trades
- Withdrawal Flow — Process withdrawals
- API Reference — Full endpoint documentation
Common Issues
Every error returns the standard envelope—read errors[0].code and errors[0].message to see exactly what failed, and check Error Codes for the full list.
Authentication Failed (401)
Problem: Invalid or missing API key.
Solution:
- Verify your API key is correct
- Ensure the header is
x-api-key(lowercase) - Check that your API key hasn't expired
Rate Limit Exceeded (429)
Problem: Too many requests.
Solution:
- Check rate limit headers in the response
- Implement exponential backoff
- Contact support for higher limits
Validation Error (400)
Problem: Invalid request data.
Solution:
- Check the error message for specific field issues
- Verify all required fields are present
- Ensure data types match the schema
Support
Need help? Reach out:
- Email: [email protected]
- Documentation: https://docs.sovera.io
- API Status: https://status.sovera.io