APIPočetak
Limiti i kvote
Zahtjevi u minuti, jedinice u mjesecu, veličina liste i kako ih poštovati.
Sandbox
Besplatno
uz svaki nalog s API pristupom
- Zahtjeva
- 60 / min
- Mjesečno
- Bez naplate
- U listi
- 10
- Praćenje
- 10
Business
500 KM
mjesečno, uz cijelu platformu
- Zahtjeva
- 120 / min
- Mjesečno
- 10.000 jedinica
- U listi
- 100
- Praćenje
- 1.000
Enterprise
Po dogovoru
ugovor, SLA i vaš model
- Zahtjeva
- Po ugovoru
- Mjesečno
- Po ugovoru
- U listi
- Do 1.000
- Praćenje
- Po ugovoru
Zahtjevi u minuti
Limit važi u kliznom prozoru od 60 sekundi. Svi live ključevi kompanije s ugovorom dijele isti limit, pa i više ključeva ne daje više zahtjeva. Svaki odgovor kaže gdje ste:
| Zaglavlje | Značenje |
|---|---|
x-request-id | Oznaka zahtjeva. Pošaljite svoju (x-request-id, 8–64 znaka) da je pratite kroz svoje logove. |
x-ratelimit-limit | Zahtjeva u minuti koje plan dozvoljava. |
x-ratelimit-remaining | Koliko ih je ostalo u tekućem prozoru. |
x-ratelimit-reset | Sekundi do novog prozora. |
x-quota-remaining | Live ključevi s mjesečnom kvotom: preostale jedinice (manja od kvote ugovora i limita ključa). |
retry-after | Uz 429 rate_limited: sekundi do ponovnog pokušaja. |
Preko limita API vraća 429 rate_limited sa zaglavljem Retry-After u sekundama.
Jedinice u mjesecu
Kvota ugovora važi za kalendarski mjesec po UTC-u i dijele je svi live ključevi kompanije. Kad je potrošena, naplatni endpointi vraćaju 429 quota_exceeded s quota, used i resets_at; besplatna čitanja rade i dalje. Ključ može imati i svoj, manji mjesečni limit (429 key_limit_reached). Šta troši jedinice: Obračun.
usage.threshold_reached, da kvota ne istekne iznenada.Kako poštovati limite
- Ponavljajte samo
429i5xx. Ostale greške ne nestaju ponavljanjem. - Na
429 rate_limitedsačekajteRetry-After; na5xxeksponencijalno (1 s, 2 s, 4 s…) s malo slučajnosti, najviše nekoliko puta. 429 quota_exceededne ponavljajte doresets_at.- Za mnogo vozila koristite masovnu procjenu umjesto stotina pojedinačnih poziva.
async function cifra(path, init = {}, attempt = 0) {
const res = await fetch(`https://api.cifra.ba${path}`, {
...init,
headers: {
Authorization: `Bearer ${process.env.CIFRA_API_KEY}`,
"Content-Type": "application/json",
...init.headers,
},
});
const retryable = res.status === 429 || res.status >= 500;
if (retryable && attempt < 4) {
const problem = await res.json().catch(() => ({}));
if (problem.code === "quota_exceeded") throw new Error(problem.detail);
const wait = Number(res.headers.get("retry-after")) * 1000 ||
2 ** attempt * 1000 + Math.random() * 250;
await new Promise((r) => setTimeout(r, wait));
return cifra(path, init, attempt + 1);
}
const body = await res.json();
if (!res.ok) throw Object.assign(new Error(body.detail), body);
return body;
}