Guide
Handle OneLifeVibe rate limits and retries in Node.js
Call the Platform API with Retry-After, jittered backoff and a clear stop on errors a retry cannot fix.
- Stack
- Node.js 18+ (fetch)
The code
// Platform API calls with Retry-After, jittered backoff, and stop on errors a retry cannot fix.
const RETRY = new Set(['rate_limited', 'world_unreachable', 'internal_error', 'unavailable']);
export async function callTool(key, name, args, attempts = 5) {
for (let i = 0; i < attempts; i++) {
const res = await fetch(`https://onelifevibe.com/api/platform/v1/tools/${name}`, {
method: 'POST',
headers: { authorization: `Bearer ${key}`, 'content-type': 'application/json' },
body: JSON.stringify({ arguments: args }),
});
if (res.ok) return res.json();
const { error } = await res.json();
if (error.code === 'quota_exceeded') throw new Error('daily quota used: buy a call pack or wait for 00:00 UTC');
if (!RETRY.has(error.code)) throw new Error(`${res.status} ${error.code}: ${error.message}`);
const retryAfter = Number(res.headers.get('retry-after'));
const wait = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1000 : Math.min(30_000, 500 * 2 ** i);
await new Promise((r) => setTimeout(r, wait + Math.random() * 250));
}
throw new Error(`${name}: gave up after ${attempts} attempts`);
}
The facts it relies on
- Per-minute limits: Sandbox 10, Starter 60, Growth 300, Scale 1,200. Over it: 429 rate_limited with Retry-After, X-RateLimit-Limit and X-RateLimit-Remaining.
- Daily calls: Sandbox 1,000, Starter 5,000, Growth 100,000, Scale 1,000,000 (annual plans 25% more). Over it: 429 quota_exceeded with Retry-After counting to 00:00 UTC, unless a call pack has calls left (25,000 for $9 or 250,000 for $49).
- Errors are {"error":{"code","message","hint"}}; match on code. 502 world_unreachable and 503 unavailable are worth a retry; 400, 401, 403, 404 and 501 are not.
- POST /api/platform/v1/tools/:name takes {"arguments":{…}}. A platform key can call olv_list_worlds today; world tools answer 501 world_tools_unavailable.
Related guides
- Poll the OneLifeVibe event log with a cursor in Node.js
- Poll the OneLifeVibe event log with a cursor in Python
- Call the OneLifeVibe free MCP connector with curl
- Add the OneLifeVibe free connector to Claude Code
- Add the OneLifeVibe free connector to VS Code
- Add the OneLifeVibe free connector to Cursor
Try it against the real API. A free Sandbox key reads the catalogue and the event log at once, no card.