Sari la conținut

Esențialul API-ului

Tratează neprevăzutul.

Coduri stabile în funcție de care decizi și când să reîncerci.

Fiecare eșec are un message tradus și, în afară de o simplă eroare de validare, un code stabil. Decide în funcție de cod — mesajul este tradus pe server și se va schimba.

Exemplu de cod
{
  "message": "This API key is not entitled to this lottery.",
  "code": "lottery_not_entitled"
}

O eroare de validare — un parametru pe care API-ul nu l-a putut accepta — nu are code. Este un 422 care are în schimb harta errors a Laravel, cu parametrul drept cheie:

Exemplu de cod
{
  "message": "This is not a date the API can read.",
  "errors": { "filter.from": ["This is not a date the API can read."] }
}

Un filtru, o sortare sau o includere nedeclarată le are pe amândouă: unul dintre codurile invalid_* de mai jos și o intrare în errors sub filter, sort sau include.

Codurile

HTTPcodeSemnificație
401api_key_missingNu a fost prezentată nicio credențială
401invalid_api_keyCheie necunoscută sau incorect formată
401api_key_revokedCheia a fost revocată
401api_key_expiredCheia a depășit data de expirare
402subscription_requiredContul nu are un plan activ sau perioada de probă s-a încheiat (trial_ended_at)
403origin_not_allowedCheie legată de browser, apelată din altă origine
403insufficient_scopeCheia ta nu are permisiunea cerută de această rută
403lottery_not_entitledJocul există, dar nu este în selecția ta
403plan_upgrade_requiredPlanul nu include această rută; required_plan numește cel mai ieftin plan care o include
403history_not_includedRezultatul e mai vechi decât istoricul inclus în planul tău — sau, pe o cheie de sandbox, mai nou decât întârzierea ei de șapte zile ori mai vechi decât ultimele 50 de rezultate
403export_not_permittedCheia cu care a fost cerut exportul a fost revocată, a expirat sau nu mai are exports:read, deci linkul nu mai merge
404not_foundURL necunoscut sau înregistrare necunoscută — intenționat identice
410export_expiredFișierul exportului a fost șters; cere un export nou
422invalid_filterCu filtrele permise în mesaj
422invalid_sortCu câmpurile sortabile în mesaj
422invalid_includeCu relațiile care pot fi incluse în mesaj
422invalid_queryȘirul de interogare nu a putut fi citit
422ticket_check_unsupportedBiletele acestui joc nu pot fi verificate încă (ticket_check.kind e null pe joc)
422distributions_unsupportedDistribuțiile extragerilor nu se potrivesc acestui joc: jocurile de tip bingo, unde numărul de bile extrase e chiar rezultatul, și jocurile cu mai multe urne (statistics.distributions e false pe joc)
422generator_unsupportedPentru acest joc nu se pot genera bilete: jocurile de tip bingo, jocurile cu mai multe urne și cursele (tools.generate e false pe joc)
422generator_impossibleNiciun bilet nu poate respecta aceste filtre împreună; mesajul spune care nu poate fi îndeplinit
422generator_space_too_smallFiltrele permit mai puține bilete diferite decât cere count; mesajul spune câte
422generator_filters_too_narrowNiciun bilet generat nu a trecut de filtre (sau toate cele care au trecut ieșiseră deja): relaxează-le
422wheel_unsupportedSistemele reduse se construiesc doar pentru jocurile în care un bilet e un set de numere diferite: nu pentru jocurile pe cifre, cele cu mai multe urne sau curse (tools.wheel e false pe joc)
422wheel_too_largeSistemul redus cerut e prea mare pentru a fi calculat: alege mai puține numere sau altă garanție
422not_enough_drawsFiltrele din extragerile trecute cer cel puțin 100 de extrageri în window
422ticket_check_too_largePrea multe extrageri pentru atâtea bilete deodată: verifică mai puține bilete sau o fereastră mai scurtă
422webhook_limit_reachedCheia are deja numărul maxim permis de abonamente webhook
422delivery_still_retryingLivrarea e încă reîncercată și nu poate fi reluată deocamdată
429rate_limit_exceededVârf pe minut. retry_after este în secunde
429quota_exceededCota zilnică s-a epuizat. Reîncearcă după resetarea UTC, nu peste o secundă
429stream_limit_reachedContul are deja numărul maxim permis de fluxuri live
429stream_capacity_reachedFluxul a atins capacitatea maximă pentru toți clienții
429export_limit_reachedContul a cerut toate exporturile incluse în plan luna aceasta; resets_at spune când se reînnoiește plafonul
429export_in_progressContul pregătește deja câte exporturi poate simultan; încearcă din nou când unul e gata

Un widget răspunde cu un mesaj în cadrul lui, nu cu JSON; codurile lui (widget_*) sunt listate în Widget-uri.

Reîncercări

Un 429 are retry_after în secunde și un header Retry-After. Cele două coduri pentru limita de cereri înseamnă lucruri diferite și merită tratate diferit: rate_limit_exceeded se rezolvă în cursul minutului, în timp ce quota_exceeded nu se rezolvă până la miezul nopții UTC — o reîncercare peste o secundă irosește cererea și se contorizează oricum.

Înregistrările necunoscute și URL-urile necunoscute primesc intenționat același răspuns. Dacă le-am deosebi, un apelant ar putea enumera ce există.

ID-urile cererilor

Fiecare răspuns dat după autentificare are un header X-Request-Id, inclusiv cele reușite:

Exemplu de cod
X-Request-Id: 01a115a8-4360-7128-8584-0bce749aabfa

Salvează-l în jurnal lângă propria eroare. Când scrii la suport despre un apel eșuat, ID-ul cererii ne permite să găsim exact acel apel — butonul Întreabă suportul despre acest apel din jurnalul cererilor îl completează pentru tine. Tot așa găsești și tu apelul: Jurnalul cererilor din spațiul de lucru păstrează fiecare cerere timp de 30 de zile, cu statusul, timpul de răspuns și code-ul și message-ul returnate, și îl poți căuta după ID-ul cererii.

Un 401 sau un 403 origin_not_allowed răspunde înainte ca cheia să fie acceptată, așa că nu are ID de cerere și nu apare în jurnal.

E problema noastră?

Pagina de stare arată, cu verificări în fiecare minut, dacă API-ul răspunde, dacă rezultatele noi sosesc la timp și dacă webhook-urile pleacă din coadă. Când raportează o perturbare, nu ai nimic de reparat de partea ta.