Authentication & Rate Limits
Every request to the Flxpoint API carries a single token in the X-API-TOKEN header. There are three token types — Account, Source, and Channel — each with a different scopeWhat the token is allowed to doA token's scope is the set of endpoints and resources it can hit. Account tokens have the broadest scope; Source / Channel tokens are deliberately narrow so a leak doesn't expose the whole workspace. and its own rate-limit bucketEach token tracks its own 2-req/s budgetRate limits are per token, not per account. If you have 5 Source tokens and one Account token, that's 6 separate 2-req/s buckets — 12 req/s aggregate. They never share or steal from each other..
Biggest source of 401 errors: using the wrong token type. An Account token isn't a superset of Source / Channel tokens — each type is scoped to specific endpoints. A single token-type mismatch can silently fail thousands of requests before anyone notices. The token matrix below shows which token you need per resource.
The request header
All requests use the same header. Do not use Authorization: Bearer — that's a common mistake when porting client code from other APIs.
X-API-TOKEN: YOUR_TOKENA complete request:
curl -X GET "https://api.flxpoint.com/account" \
-H "Accept: application/json" \
-H "X-API-TOKEN: YOUR_TOKEN"Token tester
Paste your X-API-TOKEN, hit Test, get a verdict in a second. We proxy through our server; your token isn't logged or stored.
Tip: a 200 response means the token + scope are good for GET /account. Source / Channel tokens may return 403 here even though they work for their own scoped endpoints.
Token types
Account token
Workspace-wide access. Use for admin work and for endpoints that cross resource boundaries. Account tokens cannot perform source-scoped or channel-scoped operations — those are intentionally excluded for blast-radius reasons.
Source token
Scoped to a single Source (a supplier / warehouse / 3PL). Use when you're integrating as a supplier: pushing inventory, acknowledging fulfillment requests, reporting shipments. Each source has its own 2 req/s bucket — 10 sources with their own tokens effectively give you 20 req/s aggregate.
Channel token
Scoped to a single Channel (a marketplace / storefront / POS). Use when you're pushing orders in, pulling listings to publish, or syncing shipment status back out.
Token → endpoint matrix
Pick a token type below to see only what it can touch. When in doubt, send with a Source or Channel token first — an Account token on a scoped endpoint returns 401 Unauthorized or 403 Forbidden.
Token scope visualizer
Click a token type to see only what it can touch. Wrong-scope tokens are the #1 cause of 401 / 403 errors.
| Resources | Account | Source | Channel |
|---|---|---|---|
| Account, Vendor, Connection, Routing | ✓ | — | — |
| Inventory (push), Purchase Order, Fulfillment Request, Source Invoice, Inbound Shipments | ✓ | ✓ | — |
| Product, Product Builder, MappingSet, MappingTemplate, Workflow | ✓ | — | — |
| Listing, Listing Builder, Order, Shipment, Returns, RMA | ✓ | — | ✓ |
| Webhook, Webhook Events, Events, Package | ✓ | — | — |
Per-operation scope is the source of truth — the security block on each endpoint in the reference is what the server actually checks.
Per-operation scope is the source of truth — see the API reference for the exact security block on each endpoint.
Regenerating & rotating tokens
Regenerating a token in Flxpoint immediately invalidates the previous value. Any integration still sending the old token starts returning 401 at once, so rotate deliberately:
- Keep each token in one place — a secrets manager or a single env var — not copy-pasted across scripts. Then a rotation is a one-line change, not a hunt.
- After regenerating, update every integration that used the old token and re-run the health check for each.
- Treat a sudden
401on a token that worked yesterday as "the token changed" (regenerated, or a related setting changed), not "the API is down". Confirm with the health check before digging further.
Rate limits
2 requests per second, per token. That's a rolling limit — burst traffic above 2 req/s in any 1-second window returns 429 Too Many Requests.
The Retry-After header
When you get a 429, the response includes a Retry-After header with the number of seconds to wait. Honor it. Retrying before the window clears just adds to the queue and can compound the problem.
HTTP/1.1 429 Too Many Requests
Retry-After: 1
Content-Type: application/json
{"error":"Too many requests","data":{"limit":2,"window":"1s"}}Recommended retry pattern
Exponential backoffWait longer between each retry — 1s, 2s, 4s, 8s...Instead of retrying immediately (which keeps you over the limit), you double the wait between each retry. This gives the server time to recover and prevents stampedes when many clients retry at once. with jitterA small random offset added to each waitIf 100 clients all back off by exactly the same amount, they all retry at the same instant — and the server gets hammered again. Adding a small random offset (e.g. ±30%) spreads the retry traffic out so no single second sees a wave., capped at a sensible max. Don't retry non-429 errors the same way — 401 / 403 / 4xx validation errors will never succeed on retry.
async function flxRequest(url, opts, maxRetries = 4) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fetch(url, opts);
if (res.status !== 429) return res;
const retryAfter = Number(res.headers.get("retry-after") ?? 1);
// exponential backoff with jitter, capped at 16s
const backoff = Math.min(retryAfter * 2 ** attempt, 16);
const jitter = Math.random() * 0.3 * backoff;
await new Promise(r => setTimeout(r, (backoff + jitter) * 1000));
}
throw new Error("Rate-limited after " + maxRetries + " retries");
}Scaling throughput legally
The rate limit is per token, not per account. Two ways to scale:
- One token per source / channel. 10 source integrations with dedicated tokens = 20 req/s aggregate. This is the intended path.
- Batch where possible. Endpoints like
POST /inventory/parentsaccept up to 20 parents per call;PUT /inventory/variantsaccepts 50. A batch call counts as one request.
You get one token per source or channel — you can't mint several tokens for the same one to multiply throughput, and every call made with a given token shares that token's single 2 req/s bucket. If a genuine high-volume use case needs more than the per-token limit allows, the limit can be raised on request — contact support@flxpoint.com with your use case and expected volume.
What you should not do: hammer Flxpoint from a tight loop to "poll as fast as possible". Aggressive polling in both directions can crash your own server infrastructure. See Polling fulfillment requests for the right pattern.
Errors you'll see
| Status | Meaning | What to check |
|---|---|---|
401 | Missing, malformed, or wrong-type token | Header name is exactly X-API-TOKEN. Token matches the resource you're hitting (see matrix). Not using Authorization: Bearer. |
403 | Token is valid but doesn't have scope | Upgrade to the correct token type, or ask an Account admin to grant the scope. |
429 | Rate limit exceeded | Back off per Retry-After. If you're hitting this at steady state, split work across multiple tokens or batch. |
500 | Server error | Retry with backoff (idempotent calls only). If it persists for the same payload, open a ticket with the request body and the response ID. |
Seeing "You do not have access to perform this action"? This 401/403 almost always means the token type is wrong for the endpoint — not that the token itself is invalid. A token that reads inventory fine can still 401 on product or order endpoints. Match the token to the resource (see the matrix) before assuming the token is bad.Quick health check
Before building anything, confirm the token works:
curl -v "https://api.flxpoint.com/account" \
-H "X-API-TOKEN: YOUR_TOKEN"A 200 with your account JSON means you're in. A 401 means the header or token is wrong — don't proceed until that returns 200.
Related
- Date formatting — every datetime in requests and responses uses ISO 8601.
- Integrating as a Source — the full Source-side flow.
- Integrating as a Channel — the full Channel-side flow.
- Polling fulfillment requests — how to avoid rebuilding Flxpoint's state locally.