InstafuelInstafuel
FREN
  • Guides
  • Référence
  • Référence API
Guides
  • Démarrage rapide
  • Clés d'API
  • Référence API
Référence
  • Codes d'erreur
  • Glossaire
  • English
Environnement
  • Staging — instafuel-backend-staging.up.railway.app

© Instafuel — Abidjan, Côte d'Ivoire

AccueilDémarrage rapideAuthentificationClés d'APIApporteur d'affairesCrédit walletErreurs et idempotenceLimites et quotasPérimètreWebhooks
powered by Zudoku
Guides

Limites et quotas

Limitation de débit

Chaque réponse porte l'état de votre quota :

Code
X-RateLimit-Limit: 600 X-RateLimit-Remaining: 583 X-RateLimit-Reset: 1788171600
En-têteSignification
X-RateLimit-Limitrequêtes autorisées sur la fenêtre courante
X-RateLimit-Remainingrequêtes restantes
X-RateLimit-Resethorodatage Unix (secondes) de la remise à zéro

Un dépassement renvoie 429 :

{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Trop de requêtes, réessayez après la fenêtre indiquée", "retryAfterSeconds": 34 } }

Respectez X-RateLimit-Reset plutôt que de retenter immédiatement : retenter en boucle sur un 429 prolonge la coupure.

Code
async function appeler(url, options, tentative = 0) { const reponse = await fetch(url, options); if (reponse.status !== 429 || tentative >= 3) return reponse; const reset = Number(reponse.headers.get("X-RateLimit-Reset")) * 1000; const attente = Math.max(reset - Date.now(), 2 ** tentative * 1000); await new Promise((r) => setTimeout(r, attente)); return appeler(url, options, tentative + 1); }
Code
import time def appeler(session, url, entetes, tentative=0): reponse = session.get(url, headers=entetes, timeout=30) if reponse.status_code != 429 or tentative >= 3: return reponse reset = int(reponse.headers["X-RateLimit-Reset"]) attente = max(reset - time.time(), 2**tentative) time.sleep(attente) return appeler(session, url, entetes, tentative + 1)

Les quotas sont fixés par compte apporteur, pas par clé : ajouter des clés ne les augmente pas. Si votre volume légitime les dépasse, demandez un relèvement à votre interlocuteur Instafuel plutôt que de contourner.

Les écritures coûtent plus cher que les lectures

Les opérations d'écriture ont une fenêtre plus étroite que les lectures. Une boucle d'onboarding en masse doit être étalée, pas envoyée en rafale.

Pagination

Toutes les collections sont paginées, avec la même forme.

ParamètreDéfautMaximum
page1—
perPage20100
curl "https://instafuel-backend-staging.up.railway.app/v1/papi/transactions?page=2&perPage=50" \ -H "Authorization: Bearer $INSTAFUEL_API_KEY"
{ "data": [ { "ref": "TRX-9D02C15E", "companyId": 4790, "station": { "id": 12, "name": "Station Yopougon Ananeraie" }, "driver": { "id": 3311, "name": "Salif Traoré" }, "vehicle": { "id": 812, "registration": "5678 CD 01" }, "fuelType": "SUPER", "liters": { "estimate": 30, "actual": 30 }, "selfService": false, "unitPriceFcfa": 880, "amountFcfa": 26400, "status": "CONFIRMED", "createdAt": "2026-08-29T16:05:52.000Z", "confirmedAt": "2026-08-29T16:05:52.000Z" }, { "ref": "TRX-1A73F4B0", "companyId": 4832, "station": { "id": 12, "name": "Station Plateau" }, "driver": { "id": 3311, "name": "Yao N'Guessan" }, "vehicle": { "id": 812, "registration": "1234 AB 01" }, "fuelType": "GASOIL", "liters": { "estimate": 55, "actual": 55 }, "selfService": false, "unitPriceFcfa": 750, "amountFcfa": 41250, "status": "PREAUTHORIZED", "createdAt": "2026-08-29T11:22:07.000Z", "confirmedAt": "2026-08-29T11:22:07.000Z" } ], "pagination": { "page": 2, "perPage": 50, "total": 318, "totalPages": 7 } }

Une transaction PENDING est un plein ouvert : les fonds sont réservés, pas encore débités. Ne l'additionnez pas avec les VALIDATED dans un total de dépenses.

Parcours complet, sans surcharger l'API :

Code
async function toutesLesTransactions(base, params = {}) { const tout = []; let page = 1; let totalPages = 1; while (page <= totalPages) { const query = new URLSearchParams({ ...params, page: String(page), perPage: "100", }); const reponse = await appeler(`${base}/v1/papi/transactions?${query}`, { headers: { Authorization: `Bearer ${process.env.INSTAFUEL_API_KEY}` }, }); const { data, pagination } = await reponse.json(); tout.push(...data); totalPages = pagination.totalPages; page += 1; } return tout; }
Code
<?php function toutesLesTransactions(string $base, array $params = []): array { $tout = []; $page = 1; $totalPages = 1; while ($page <= $totalPages) { $query = http_build_query($params + ['page' => $page, 'perPage' => 100]); [$statut, $corps] = appeler($base . '/v1/papi/transactions?' . $query); $tout = array_merge($tout, $corps['data']); $totalPages = $corps['pagination']['totalPages']; $page++; } return $tout; }

Les collections triées par date bougent pendant que vous paginez

Les transactions sont renvoyées de la plus récente à la plus ancienne. Si de nouvelles arrivent entre deux pages, un élément peut être vu deux fois ou manqué.

Pour un export fiable, bornez la période avec from et to sur des dates révolues, ou dédupliquez sur ref à l'arrivée.

Gros volumes

Il n'existe pas d'export de fichier sur cette API : elle ne produit que du JSON. Deux réflexes suffisent pour tenir la charge.

Découpez par période, pas par page. Une plage d'un mois découpée en jours donne des lots stables, rejouables, et évite la dérive de pagination décrite plus haut.

Consolidez avec la synthèse. Pour des totaux, GET /v1/papi/reports/portfolio-summary renvoie en un appel ce que la pagination des transactions vous ferait recalculer sur des centaines de pages.

Code
GET /v1/papi/reports/portfolio-summary?from=2026-08-01&to=2026-08-31

Si vous avez besoin d'un classeur, il se télécharge depuis le portail partenaire.

Fraîcheur des données

DonnéeFraîcheur
Solde de wallet, transactionstemps réel
Soldes de tout le portefeuilletemps réel, calculés à l'appel
Synthèse du portefeuillecalculée à l'appel, sur la période demandée

Le solde renvoyé est celui de l'instant : availableFcfa retire déjà les pleins ouverts. C'est ce chiffre qu'il faut afficher à un client, pas balanceFcfa.

Idempotence et rejeu

L'en-tête X-Idempotency-Key et la politique de rejeu sont décrits dans Erreurs et idempotence. Rappel utile ici : un 429 se retente avec la même clé.

Délais et coupures

Prévoyez un délai d'attente côté client d'au moins 30 secondes sur les écritures et les dépôts de preuve : un fichier de 10 Mo sur une liaison ivoirienne moyenne n'arrive pas en deux secondes.

En cas de coupure avant la réponse, ne devinez pas — rejouez avec la même clé d'idempotence.

Last modified on September 2, 2026
Erreurs et idempotencePérimètre
On this page
  • Limitation de débit
  • Pagination
  • Gros volumes
  • Fraîcheur des données
  • Idempotence et rejeu
  • Délais et coupures
JSON
Javascript
Javascript
PHP
JSON
Javascript