Working with accounts
Overview
Scope: tb:accounts:read / tb:accounts:write
The model
| Object | What it is |
|---|---|
| VirtualAccount | A named container. The account itself has no currency and no balance fields. |
| VirtualBalance | The balance in one specific currency. One account can hold several balances, one per currency. |
Every balance carries three amounts: availableAmount (spendable now), holdAmount (locked against active operations) and totalAmount = availableAmount + holdAmount.
Money lives on balances, not on accounts.
To see how much money an account holds, request its balances, not the account.
The first account already exists
When a client passes KYC (individual) or KYB (company), their first virtual account is created automatically. The partner does nothing.
List the client's accounts
/v1/accountsAuth: Bearer access token — how to use the access token.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| ids[] | — | Optional | Filter by account UUIDs. | |
| statuses[] | — | Optional | ACTIVE, PROCESSING, BLOCKED, CLOSED. | |
| categories[] | — | Optional | INDIVIDUAL, CORPORATE. | |
| types[] | — | Optional | Account type, e.g. PERSONAL, BUSINESS. | |
| tags[] | — | Optional | Filter by tags. | |
| excludeZeroBalances | — | Optional | true — only accounts with a non-zero balance in at least one currency. | |
| virtualBalanceCurrencyIds[] | — | Optional | Only accounts holding a balance in the given currencies. | |
| search | — | Optional | Search across description and id. | |
| pagination[limit] · pagination[skip] | — | Optional | Pagination. |
/v1/accountscurl 'https://sandbox-bank.tedr.com/open-banking/v1/accounts' \
-H 'Authorization: Bearer <access-token>'
const response = await fetch('https://sandbox-bank.tedr.com/open-banking/v1/accounts', {
headers: { Authorization: 'Bearer <access-token>' },
});
const { data } = await response.json();
import requests
response = requests.get(
'https://sandbox-bank.tedr.com/open-banking/v1/accounts',
headers={'Authorization': 'Bearer <access-token>'},
)
data = response.json()['data']
{
"status": "SUCCESS",
"data": {
"nodes": [
{
"id": "05155318-22a3-45aa-9db0-0ebfe8f21e8c",
"description": "Main account",
"status": "ACTIVE",
"category": "INDIVIDUAL",
"type": "PERSONAL",
"ledgerType": "PASSIVE",
"tag": "main_account",
"createdAt": 1704067200000,
"updatedAt": 1705312800000
}
],
"count": 1,
"cursor": 1
}
}
Internal system accounts are never returned.
Timestamps are numbers.
createdAt / updatedAt are Unix timestamps in milliseconds, not ISO strings.
Create an additional account
/v1/accountsAuth: Bearer access token — how to use the access token.
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| description | string | Optional | Account name / description. | |
| currencyIds | UUID[] | Optional | Currencies to open balances in; a zero balance is created for each. Obtain the ids from the Dictionary. |
/v1/accountscurl -X POST 'https://sandbox-bank.tedr.com/open-banking/v1/accounts' \
-H 'Authorization: Bearer <access-token>' \
-H 'Content-Type: application/json' \
-d '{
"description": "Business account",
"currencyIds": [
"99d41c98-93d1-471a-a73a-4cac9e3587e7",
"2e5d9800-f467-4eb7-ad47-1f67a874a908"
]
}'
const response = await fetch('https://sandbox-bank.tedr.com/open-banking/v1/accounts', {
method: 'POST',
headers: {
Authorization: 'Bearer <access-token>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
description: 'Business account',
currencyIds: [
'99d41c98-93d1-471a-a73a-4cac9e3587e7',
'2e5d9800-f467-4eb7-ad47-1f67a874a908',
],
}),
});
const { data } = await response.json();
import requests
response = requests.post(
'https://sandbox-bank.tedr.com/open-banking/v1/accounts',
headers={'Authorization': 'Bearer <access-token>'},
json={
'description': 'Business account',
'currencyIds': [
'99d41c98-93d1-471a-a73a-4cac9e3587e7',
'2e5d9800-f467-4eb7-ad47-1f67a874a908',
],
},
)
data = response.json()['data']
Both fields are optional; an account created without currencyIds has no balances until they are added.
The account is returned with status PROCESSING while it is being set up, and becomes ACTIVE afterwards.
Read the account balances
/v1/accounts/:accountId/balancesAuth: Bearer access token — how to use the access token.
Query parameters: currencyIds[], currencyTickers[], statuses[], pagination[limit], pagination[skip].
/v1/accounts/:accountId/balancescurl 'https://sandbox-bank.tedr.com/open-banking/v1/accounts/<accountId>/balances' \
-H 'Authorization: Bearer <access-token>'
const response = await fetch('https://sandbox-bank.tedr.com/open-banking/v1/accounts/<accountId>/balances', {
headers: { Authorization: 'Bearer <access-token>' },
});
const { data } = await response.json();
import requests
response = requests.get(
'https://sandbox-bank.tedr.com/open-banking/v1/accounts/<accountId>/balances',
headers={'Authorization': 'Bearer <access-token>'},
)
data = response.json()['data']
{
"status": "SUCCESS",
"data": {
"nodes": [
{
"id": "3f0f1f8a-0f4d-4c2c-9a6a-2d63bd8dd0f1",
"virtualAccount": { "id": "05155318-22a3-45aa-9db0-0ebfe8f21e8c" },
"currency": {
"id": "99d41c98-93d1-471a-a73a-4cac9e3587e7",
"ticker": "USD",
"network": { "name": "FIAT" }
},
"availableAmount": "1150.50",
"holdAmount": "100.00",
"totalAmount": "1250.50",
"description": null,
"status": "ACTIVE",
"createdAt": 1704067200000,
"updatedAt": 1717237800000
}
],
"count": 1,
"cursor": 1
}
}
The parent account is an object.
It is returned as virtualAccount: { id } — not as a flat virtualAccountId string.
Read a single account
/v1/accounts/:accountIdAuth: Bearer access token — how to use the access token.
/v1/accounts/:accountIdcurl 'https://sandbox-bank.tedr.com/open-banking/v1/accounts/<accountId>' \
-H 'Authorization: Bearer <access-token>'
const response = await fetch('https://sandbox-bank.tedr.com/open-banking/v1/accounts/<accountId>', {
headers: { Authorization: 'Bearer <access-token>' },
});
const { data } = await response.json();
import requests
response = requests.get(
'https://sandbox-bank.tedr.com/open-banking/v1/accounts/<accountId>',
headers={'Authorization': 'Bearer <access-token>'},
)
data = response.json()['data']
Returns the same object as the list endpoint. An account that does not belong to the client returns 404.
