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

HomeQuickstartAuthenticationAPI keysBusiness introducerWallet creditErrors and idempotencyLimits and quotasScopeWebhooks
powered by Zudoku
Guides

Limits and quotas

Rate limiting

Every response carries the state of your quota:

Code
X-RateLimit-Limit: 600 X-RateLimit-Remaining: 583 X-RateLimit-Reset: 1788171600
HeaderMeaning
X-RateLimit-Limitrequests allowed in the current window
X-RateLimit-Remainingrequests left
X-RateLimit-ResetUnix timestamp (seconds) of the reset

Going over returns 429:

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

Respect X-RateLimit-Reset instead of retrying straight away: hammering a 429 extends the outage.

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

Quotas are set per introducer account, not per key: adding keys does not raise them. If your legitimate volume exceeds them, ask your Instafuel contact for a higher limit rather than working around it.

Writes cost more than reads

Write operations have a narrower window than reads. A bulk onboarding loop must be spread out, not fired in a burst.

Pagination

Every collection is paginated, with the same shape.

ParameterDefaultMaximum
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 } }

A PENDING transaction is an open fill-up: funds are held, not yet debited. Do not add it to VALIDATED ones in a spend total.

Walking the whole collection without hammering the API:

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

Date-sorted collections move while you paginate

Transactions come back newest first. If new ones land between two pages, an item can be seen twice or missed.

For a reliable export, bound the period with from and to on elapsed dates, or deduplicate on ref on arrival.

Large volumes

There is no file export on this API: it only produces JSON. Two habits are enough to hold the load.

Slice by period, not by page. A one-month range cut into days gives stable, replayable batches, and avoids the pagination drift described above.

Consolidate with the summary. For totals, GET /v1/papi/reports/portfolio-summary returns in one call what paginating transactions would make you recompute over hundreds of pages.

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

If you need a spreadsheet, download it from the partner portal.

Data freshness

DataFreshness
Wallet balance, transactionsreal time
Portfolio-wide balancesreal time, computed on the fly
Portfolio summarycomputed at call time over the requested period

For a real-time display of a company's balance, read its wallet directly rather than the consolidated summary.

Idempotency and replay

The X-Idempotency-Key header and the retry policy are covered in Errors and idempotency. Worth repeating here: a 429 is retried with the same key.

Timeouts and drops

Allow a client-side timeout of at least 30 seconds on writes and proof uploads: a 10 MB file over an average Ivorian link does not arrive in two seconds.

If the connection drops before the response, do not guess — replay with the same idempotency key.

Last modified on September 2, 2026
Errors and idempotencyScope
On this page
  • Rate limiting
  • Pagination
  • Large volumes
  • Data freshness
  • Idempotency and replay
  • Timeouts and drops
JSON
Javascript
Javascript
PHP
JSON
Javascript