Skip to main content
Fluz doesn’t sell per-plan API quotas — there are no “Free = X req/min, Pro = Y req/min” tiers and no per-key quota system. Instead, each service applies a protective rate limit to absorb abuse and shield its backend. Normal interactive and application traffic effectively never hits these limits; they exist to catch runaway scripts and abuse. The GraphQL API also limits how much a single query can ask for, measured in cost points. That limit is separate from the request rate and fails differently. See Query cost limits below.
There are no published per-plan quotas to request an increase against. If a well-behaved integration is hitting limits, that usually points to a traffic pattern worth fixing (see Build a well-behaved client) rather than a quota to raise.

How limits are applied

Limits are enforced independently per service and are evaluated globally across that service’s instances — you can’t escape a limit by landing on a different server. A request is identified by a combination of:
  • Your IP address — every request counts against a per-IP limit.
  • Your access token — the full Authorization header. The token limit applies on top of the IP limit, not instead of it. The IP limit is checked first, so every request from one IP shares that IP’s budget whatever token it carries. Requests with no auth header skip the token limiter.
  • The endpoint path — on some public surfaces, specific paths have their own limits.
Exceeding a request rate limit returns HTTP 429 Too Many Requests.

Traffic limits by surface

These are sustained per-second limits. When exceeded, the key is blocked for a short cooldown before requests are accepted again.
The GraphQL API endpoint is the one most integrations call for deposits, purchases, transfers, and reveals — plan around 20 requests per second there. The mobile/app gateway’s per-IP, per-token, and per-endpoint limits are configured per environment and aren’t published as fixed numbers; treat them as protective and back off on 429.

Query cost limits

The GraphQL API scores every query before it runs. A query over any of these limits is rejected without running, no matter how slowly you send requests.

How cost is counted

Each field you select costs 1 point. A field with its own selection set costs 1 point plus 5 times the cost of everything inside it, and a query costs the sum of its top-level fields. Each level of nesting multiplies what’s below it by 5:
The deepest fields are the expensive ones. A top-level field costs 1 point, a field at the fifth level costs 625, and a field at the sixth level, the deepest the depth limit allows, costs 3,125. Eleven fields at the fifth level, or two at the sixth, put a query over 7,000. In practice you reach the cost limit before the depth limit.
  • Page size doesn’t change the cost. Asking for 1 row or 20 costs the same, because cost comes from the fields you select, not the rows returned.
  • __typename costs the same as any other field. Clients that add it to every selection set, as Apollo Client does by default, raise the cost of deep queries.
  • Fragments add levels. An inline fragment (... on Type { }) counts as one level of nesting and a named fragment spread counts as two, so the same fields cost 5 or 25 times more inside a fragment. Write the fields out in place in large queries.
  • Every operation in the document is checked, including ones operationName doesn’t select. One operation over the limit rejects the whole request.

When a query is rejected

The response is HTTP 400 with the reason in the errors array:
The message starts with Syntax Error even though the query is valid GraphQL, and the found value is your query’s cost. Alias and directive limits return the same shape with their own message, for example Syntax Error: Aliases limit of 15 exceeded, found 16. A query over the depth limit is always over the cost limit too, so it gets both errors, cost first. A request over the token limit returns HTTP 500 with the same code, and a batched request returns HTTP 400 with the code BAD_REQUEST and the message Operation batching disabled. Nothing runs when a query is rejected, so no mutation is applied, and sending the same query again returns the same error.

Authentication & security

Sign-in, PIN, and two-factor (2FA) flows are protected separately from general API traffic. Repeated failed attempts — logins, PIN checks, or 2FA verification — and excessive 2FA or SMS requests trigger temporary lockouts that clear on their own after a cooldown. Successful authentication resets these counters.
Don’t auto-retry failed logins, PIN checks, or 2FA. Surface a “try again later” state to the user — automatic retries extend the lockout.

When you exceed a limit

Rate limits and query cost limits fail in different ways, so check the status before you retry: Every rate-limited response uses status 429 Too Many Requests. The body and headers vary by surface:
Header availability is not uniform:
  • Retry-After (integer seconds) is returned on the authentication IP limiter and the PIN/2FA flows. It is not guaranteed on the general GraphQL/web traffic limiters.
  • There are currently no X-RateLimit-Limit, X-RateLimit-Remaining, or X-RateLimit-Reset headers — don’t build logic that depends on them.

Build a well-behaved client

1

Treat 429 as retryable

Honor Retry-After when it’s present. When it isn’t, back off exponentially starting around 1 second (1s → 2s → 4s…) rather than retrying immediately.
2

Keep sustained rates modest

Don’t parallel-blast a surface from a single IP or token. For the GraphQL API, stay comfortably under 20 requests/second and smooth out bursts.
3

Keep queries small

Select only the fields you use, keep nesting shallow, and write fields out in place instead of using fragments in large queries. If a query hits the cost limit, split it into smaller queries instead of retrying it.
4

Don't auto-retry auth failures

Repeated login, PIN, or 2FA failures cause temporary lockouts. Show the user a “try again later” message instead of retrying automatically.
5

Budget per IP, not per token

Every request from one IP counts against the same limit, however many tokens you use. If several workers, services, or customer accounts send traffic through one NAT gateway or proxy, pace them together so their combined rate stays under the limit.
Because Retry-After isn’t guaranteed everywhere, pair your retry logic with idempotency keys so a retried mutation never double-processes a purchase or transfer. For the full error catalog, see Errors.