Results, rate limits and errors
Every status and error the Members API answers, and the limits behind them.
Results
A membership check answers one of three statuses. The Members API passes on the status, never the reason.
status | Eligibility | Signed-in member |
|---|---|---|
valid | The applicant passes and lands in your frontend's community | A valid membership, also under the grace rule |
not_valid | Not, for whatever reason | A register refused it at the last check |
unavailable | A register could not answer; ask again later | The register has not answered for 7 days since the last valid check |
null | – | No organisation membership |
The grace rule: while a register is unavailable, a member whose last valid check is less than 7 days old keeps their last result. That is why the signed-in member stays valid while an external register is down, and unavailable only after 7 days.
Errors
Every error has the same body, {"error": "<code>"}:
| Status | error | When | What to do |
|---|---|---|---|
| 400 | invalid_request | Eligibility: a body that is not JSON or misses or breaks a field, or a missing or bad X-Applicant-IP | Fix the request |
| 401 | unauthenticated | The key, or for the signed-in member the token, is refused; with WWW-Authenticate: Bearer | Check the key; treat a user as signed out |
| 413 | too_large | Eligibility: a body over 4 KB | Send only the four fields |
| 429 | rate_limited | A rate limit is reached; there is no Retry-After | Tell the applicant to try later |
| 503 | unavailable | The Studio itself failed | Retry later; the key and token are fine |
Rate limits for eligibility
The Studio counts failed checks from its check log: a not_valid answer, including an applicant outside your frontend's community.
| Counted per | Limit |
|---|---|
| Member code | 5 in 15 minutes |
| Applicant network: the IPv4 address, or the /64 an IPv6 address is in | 20 in 15 minutes |
| Frontend | 500 in an hour |
- The ways one member code can be typed count as one code: variants that differ only in a leading plus sign or zeros, case, spaces, invisible characters or compatibility forms (such as fullwidth digits) share one budget. A separator such as
-still makes a different code. - An
unavailableanswer and a request already refused as rate limited are not failed checks. - A check that is still running counts as failed until it is logged, so simultaneous requests cannot all pass before any of them is counted.
- A refused request asks no register.
Rate limit for the signed-in member
600 requests per frontend user in an hour that starts with their first counted request. Refused requests are not counted.