Authentication
The partner API authenticates with an API key, sent as a header on every request. There is no login, no password, no token to refresh: the key is the only secret.
Code
No user login here
/v1/papi/* is a machine API, meant for your server. Your clients' human accounts (fleet manager, finance director) sign in to the Instafuel dashboard with their own password — that journey does not go through this API and is not documented here.
An authenticated call
GET /v1/papi/me is the right health check: it changes nothing, costs little, and tells you exactly what the key allows.
The two prefixes
| Prefix | Environment | Base URL | Effect |
|---|---|---|---|
ifp_test_* | staging | https://instafuel-backend-staging.up.railway.app | test data, no real money |
ifp_live_* | production | provided with the key | real money |
The prefix is part of the key: you read it, you do not guess it. A test key presented against production is rejected with 401, and vice versa — the two environments share no data.
That separation gives you a control which is easy to automate: if your test code holds a key that does not start with ifp_test_, stop before the call.
Code
Code
Where the key belongs
An API key never lives on the client side
It grants access to your entire portfolio. It belongs in an environment variable or a secret manager, on your server. Never in a Git repository, never in a browser JavaScript bundle, never in a mobile app — even "obfuscated", it is extractable in minutes.
If your web interface must display portfolio data, route it through your own backend: that backend holds the key and applies your own access rules.
Authentication errors
| HTTP | error.code | Cause | What to do |
|---|---|---|---|
| 401 | PAPI_KEY_MISSING | Authorization header absent | add the header |
| 401 | PAPI_KEY_INVALID | unknown key, revoked, or wrong environment | check the prefix and the base URL |
| 401 | PAPI_KEY_EXPIRED | key past its expiry | issue a new one, see API keys |
| 403 | PAPI_IP_FORBIDDEN | calling address not in the allow list | add your server's outbound IP |
| 403 | PAPI_SCOPE_MISSING | the key lacks the scope this operation needs | use a key carrying it |
| 403 | RESELLER_INACTIVE | introducer account disabled | contact Instafuel |
A key revoked after a botched rotation gives this — that is the trace to look for when an integration goes dark at once:
A valid key missing the required scope:
Branch on error.code, never on message — see Errors and idempotency.
What the key determines
The key carries your identity and your scope. You do not pick which company you call for: you call, and the server narrows the answer to your portfolio. No parameter widens that view — see Scope.
It also carries its scopes: a read-only key returns 403 PAPI_SCOPE_MISSING on any write, with no side effect.
