To ensure reliability and fairness across all users, Tsara enforces API rate limits on every endpoint.
These limits prevent abuse and maintain system stability while allowing high-volume applications to operate efficiently.
🚀 Overview
Each API key is allowed a certain number of requests per minute (RPM).
If your application exceeds these limits, Tsara will respond with a 429 Too Many Requests error.
Rate limits apply per:
- API key
- Endpoint
- Environment (Sandbox and Production are independent)
📊 Default Rate Limits
| Endpoint Group | Requests per Minute | Notes |
|---|---|---|
| Read (GET) | 120 RPM | Listing wallets, balances, transactions, etc. |
| Write (POST/PUT) | 60 RPM | Creating transfers, customers, onramps, etc. |
| Webhook Delivery | Unlimited | Event-based, not rate-limited. |
| Authentication / Identity | 30 RPM | BVN/NIN/CAC verifications. |
💡 If you require higher limits, contact [email protected] with your business use case.
⚠️ Exceeding Rate Limits
When your app exceeds a limit, Tsara will return an HTTP 429 response:
Example
{
"success": false,
"error": {
"code": "rate_limit_exceeded",
"message": "Too many requests. Please wait before retrying.",
"hint": "Retry after 30 seconds."
},
"request_id": "req_lim001"
}Headers returned:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 30🧠 Best Practices
-
Implement Retry Logic
Use exponential backoff — retry after the time specified inRetry-After. -
Monitor Remaining Quota
Use the headersX-RateLimit-RemainingandX-RateLimit-Resetto adjust request timing dynamically. -
Batch Requests
Group smaller API calls into bulk requests when possible. -
Cache Read Responses
For high-frequency reads (like balances or transaction history), cache results to minimize redundant requests. -
Separate Sandbox & Live Keys
Each environment tracks limits independently — never reuse keys.
🧾 Example Retry Logic (Node.js)
import axios from "axios";
async function makeRequest() {
try {
const res = await axios.get("https://sandbox.tsara.ng/v1/wallets", {
headers: { Authorization: "Bearer YOUR_SECRET_KEY" }
});
console.log(res.data);
} catch (err) {
if (err.response?.status === 429) {
const retryAfter = err.response.headers["retry-after"] || 30;
console.log(`Rate limit hit. Retrying after ${retryAfter}s...`);
setTimeout(makeRequest, retryAfter * 1000);
} else {
console.error("API Error:", err.response?.data || err.message);
}
}
}
makeRequest();🧩 Advanced Options
- Enterprise customers can request higher rate limits for high-volume or mission-critical workloads.
- Webhook deliveries are never rate-limited — they queue automatically.
- Monitoring dashboards are available in Tsara to visualize request usage per API key.
🔗 Related Pages
- Errors — Learn about 429 and other response codes.
- Authentication — Use separate keys for sandbox and live environments.
- SDKs & Libraries — Recommended techniques for managing retries safely.