Data Flow Limiting
Data Flow Limiting
Overview
Vaultody applies two types of limits to API usage: rate limits (how many requests you can make per time window) and pagination limits (how many items are returned per API response). Both are determined by your subscription plan.
Rate Limiting
Each API is subject to a request rate limit. When you exceed the limit, the API returns:
httpHTTP 429 Too Many Requests
{
"error": {
"code": "request_limit_reached",
"message": "The request limit has been reached. Please contact our team or upgrade your plan."
}
}
Handling 429 Responses
When you receive a 429, back off and retry with increasing delays. Do not retry immediately — this will continue to be rate-limited.
Python — exponential backoff:
python
import time
def request_with_retry(method, path, body=None, max_retries=4):
for attempt in range(max_retries):
response = signed_request(method, path, body)
if response.status_code == 429:
wait_seconds = 2 ** attempt # 1s → 2s → 4s → 8s
print(f"Rate limited. Retrying in {wait_seconds}s...")
time.sleep(wait_seconds)
continue
return response
raise Exception("Max retries exceeded after rate limiting")
Node.js — exponential backoff:
javascriptasync function requestWithRetry(method, path, body = null, maxRetries = 4) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await signedRequest(method, path, body);
if (response.status === 429) {
const wait = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s, 8s
console.log(`Rate limited. Retrying in ${wait / 1000}s...`);
await new Promise(r => setTimeout(r, wait));
continue;
}
return response;
}
throw new Error('Max retries exceeded after rate limiting');
}
Best practice: Spread your API calls over time where possible. If you are syncing large amounts of data, use pagination and process pages sequentially rather than in parallel.
Pagination
Vaultody uses cursor-based pagination for all list endpoints. This means pages are navigated using the ID of the last item you received, not a page number. This approach is consistent and reliable even when new records are added between requests. Pagination Parameters
Pagination Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | integer | 50 | Number of items to return per page. Maximum: 50 |
| startingAfter | string | — | The id (or equivalent ID field) of the last item from the previous page. Omit for the first page. |
How It Works
On the first request, omit startingAfter:
httpGET /vaults/{vaultId}/vault-accounts/details?limit=50
The response includes a hasMore field:
{
"apiVersion": "2026-03-20",
"requestId": "601c1710034ed6d407996b30",
"data": {
"limit": 50,
"hasMore": true,
"items": [
{
"vaultAccountId": "68dfaeae39a4b80007c4f707",
"vaultAccountName": "User Alice",
...
}
]
}
}
If hasMore is true, take the vaultAccountId (or the relevant ID field) of the last item in the array and pass it as startingAfter on the next request:
httpGET /vaults/{vaultId}/vault-accounts/details?limit=50&startingAfter=68dfaeae39a4b80007c4f707
Repeat until hasMore is false.
Full Pagination Example
Python — fetch all Vault Accounts:
pythondef get_all_vault_accounts(vault_id):
all_accounts = []
starting_after = None
while True:
params = {'limit': 50}
if starting_after:
params['startingAfter'] = starting_after
resp = signed_request('GET', f'/vaults/{vault_id}/vault-accounts/details', params=params)
data = resp.json()['data']
all_accounts.extend(data['items'])
if not data['hasMore']:
break
# Use the last item's ID as the next cursor
starting_after = data['items'][-1]['vaultAccountId']
return all_accounts
Node.js — fetch all Vault Accounts:
javascriptasync function getAllVaultAccounts(vaultId) {
const allAccounts = [];
let startingAfter = null;
do {
const params = { limit: 50 };
if (startingAfter) params.startingAfter = startingAfter;
const resp = await signedRequest('GET', `/vaults/${vaultId}/vault-accounts/details`, null, params);
const { items, hasMore } = resp.data.data;
allAccounts.push(...items);
startingAfter = hasMore ? items[items.length - 1].vaultAccountId : null;
} while (startingAfter !== null);
return allAccounts;
}
Subscription Tiers API data flow limits and feature availability are determined by your subscription tier. Higher tiers provide increased rate limits, higher Vault Account caps.
For details on what is included in each plan, please contact us or visit the Vaultody pricing page.
Mainnet access is not available on free plans. If you receive a feature_mainnets_not_allowed_for_plan error, your current plan is restricted to testnet. Upgrade your plan to enable mainnet access.