NOTE
The limit is per key and per minute, and depends on the server's plan: 60 on Plus, 300 on Premium and 1200 on Business. Each key has its own allowance.
Every response carries X-RateLimit-Limit (the allowance) and X-RateLimit-Remaining (what is left this minute).
Going over: 429 rate_limited with Retry-After (the seconds to wait) and X-RateLimit-Reset (the unix time the window resets). Wait that long before retrying.
Separately, 30 failed authentications in a minute from one IP get that IP a 429.
NOTE
Lists return meta.next_cursor. For the next page, pass it as ?cursor=. On the last page it is null.
limit goes from 1 to 100 (25 by default).
order is desc (newest first, the default) or asc. While following a cursor, do not change order or the filters.
A cursor only works with its own server's keys: otherwise, 400 invalid_cursor.
const API = 'https://api.blixye.com/v1';
const headers = { Authorization: 'Bearer ' + process.env.BLIXYE_API_KEY };
let cursor = null;
for (;;) {
const url = new URL(API + '/characters');
url.searchParams.set('limit', '100');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, { headers });
if (res.status === 429) {
const wait = Number(res.headers.get('Retry-After') || '1');
await new Promise((r) => setTimeout(r, wait * 1000));
continue;
}
if (!res.ok) throw new Error((await res.json()).error.code);
const { data, meta } = await res.json();
for (const character of data) console.log(character.id, character.name);
if (!meta.next_cursor) break;
cursor = meta.next_cursor;
}
const API = 'https://api.blixye.com/v1';
const headers = { Authorization: 'Bearer ' + process.env.BLIXYE_API_KEY };
let cursor = null;
for (;;) {
const url = new URL(API + '/characters');
url.searchParams.set('limit', '100');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, { headers });
if (res.status === 429) {
const wait = Number(res.headers.get('Retry-After') || '1');
await new Promise((r) => setTimeout(r, wait * 1000));
continue;
}
if (!res.ok) throw new Error((await res.json()).error.code);
const { data, meta } = await res.json();
for (const character of data) console.log(character.id, character.name);
if (!meta.next_cursor) break;
cursor = meta.next_cursor;
}
NOTE
const API = 'https://api.blixye.com/v1';
const headers = { Authorization: 'Bearer ' + process.env.BLIXYE_API_KEY };
let cursor = null;
for (;;) {
const url = new URL(API + '/characters');
url.searchParams.set('limit', '100');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, { headers });
if (res.status === 429) {
const wait = Number(res.headers.get('Retry-After') || '1');
await new Promise((r) => setTimeout(r, wait * 1000));
continue;
}
if (!res.ok) throw new Error((await res.json()).error.code);
const { data, meta } = await res.json();
for (const character of data) console.log(character.id, character.name);
if (!meta.next_cursor) break;
cursor = meta.next_cursor;
}
GET /v1/events works the other way round: oldest first, and next_cursor is always there. Store it and send it on the next poll. Without a cursor, it starts 30 days back (API v1: events).
GET /v1/events works the other way round: oldest first, and next_cursor is always there. Store it and send it on the next poll. Without a cursor, it starts 30 days back (API v1: events).
NOTE
GET /v1/events works the other way round: oldest first, and next_cursor is always there. Store it and send it on the next poll. Without a cursor, it starts 30 days back (API v1: events).