Evyoo POS API v1

Erreurs

Quand quelque chose ne va pas, l'API répond avec un code HTTP et un corps JSON qui dit pourquoi. Le message est écrit pour qu'un développeur sache quoi corriger.

La forme d'une erreur#

json
{
  "error": {
    "code": "insufficient_scope",
    "message": "This token does not carry the required permission: invoices:read",
    "request_id": "81c82f5c6e2eb5aa"
  }
}
ChampSens
codeUn code stable, fait pour un programme : testez-le plutôt que le message.
messageUne explication lisible. Elle peut être reformulée : ne la comparez pas.
request_idL'identifiant de la requête. Citez-le au support : il retrouve la ligne exacte du journal. Le même identifiant est dans l'en-tête X-Request-Id.
details(erreur 400) La liste des paramètres fautifs, avec la raison de chacun.

Les codes#

HTTPcodeQuandQue faire
400invalid_parameterUn paramètre de la requête est invalide ou inconnu.Lire error.details : chaque faute y est, avec le paramètre concerné. Corriger.
400invalid_request(/auth/token) Corps illisible, ou grant_type absent.Envoyer un corps en JSON ou en formulaire, avec grant_type.
400unsupported_grant_type(/auth/token) grant_type n'est pas client_credentials.Utiliser client_credentials.
400invalid_scope(/auth/token) Vous demandez une permission que votre clé n'a pas.Demander moins, ou faire ajouter la permission.
401invalid_client(/auth/token) Clé d'accès ou code de sécurité absent ou faux.Vérifier les deux clés.
401missing_tokenAucun en-tête Authorization.Envoyer Authorization: Bearer <jeton>. Tester avec /status pour voir si l'en-tête arrive.
401invalid_tokenJeton expiré, inconnu ou révoqué, ou en-tête mal formé.Demander un nouveau jeton.
403https_requiredLa requête n'est pas en HTTPS.Utiliser https://.
403insufficient_scopeVotre jeton n'a pas la permission de cette ressource.Faire ajouter la permission à votre clé.
404not_foundLa ressource, la route ou l'identifiant n'existe pas, ou l'élément n'est pas visible pour votre clé (par exemple une autre succursale).Vérifier l'adresse et l'identifiant.
405method_not_allowedLa méthode n'est pas permise.Utiliser GET (l'en-tête Allow le rappelle).
413payload_too_largeLe corps de la requête dépasse 1 Mo.Le réduire.
429rate_limitedTrop de requêtes dans la minute.Attendre Retry-After secondes.
429too_many_attempts(/auth/token) Trop d'échecs : vous êtes bloqué.Attendre Retry-After secondes (15 minutes au plus), corriger vos clés.
500internal_errorUne erreur inattendue chez nous.Réessayer une fois ; sinon écrire au support avec le request_id.
503api_not_enabledL'API n'est pas activée pour votre entreprise.Contacter Evyoo.
503service_unavailableLe service est momentanément indisponible.Réessayer après Retry-After secondes.

Les limites#

LimiteValeurRemarque
Requêtes par minute60 par défautRéglable par clé : votre limite réelle est dans l'en-tête X-RateLimit-Limit. Elle compte votre clé, pas chaque jeton : redemander un jeton ne la contourne pas.
Demandes de jeton10 par minute et par adresse IPGardez votre jeton (S'authentifier).
Échecs d'authentification5 (même clé, même adresse) ou 20 (même adresse)Blocage de 15 minutes.
Taille d'une page100 élémentsper_page.
Nombre de pages10 000page.
Durée d'un jeton15 minutesRéglable par clé : voir expires_in.
RechercheDe 2 à 100 caractèressearch.
Tri3 champssort.

Quand on dépasse la limite#

Vous recevez 429 rate_limited et l'en-tête Retry-After : le nombre de secondes à attendre. Une bonne conduite : lire X-RateLimit-Remaining et ralentir avant d'arriver à zéro ; sur un 429, attendre Retry-After, puis reprendre.

javascript
// Réessaie après un 429, en respectant Retry-After (trois tentatives au plus).
async function lireAvecPatience(url, options, tentatives = 3) {
  for (let essai = 1; essai <= tentatives; essai++) {
    const reponse = await fetch(url, options);
    if (reponse.status !== 429 || essai === tentatives) return reponse;

    const attente = Number(reponse.headers.get("Retry-After") || 5);
    await new Promise((fini) => setTimeout(fini, attente * 1000));
  }
}
python
# Réessaie après un 429, en respectant Retry-After (trois tentatives au plus).
import time
import requests

def lire_avec_patience(url, tentatives=3, **options):
    for essai in range(1, tentatives + 1):
        reponse = requests.get(url, **options)
        if reponse.status_code != 429 or essai == tentatives:
            return reponse
        time.sleep(int(reponse.headers.get("Retry-After", 5)))