Errors and rate limits
What the Eventdoor REST API returns when it refuses a request, and how the per-credential rate limit works.
When the API refuses a request, it answers with an HTTP status and a JSON body that says why. This page lists the refusals a credential can get and explains the rate limit.
The error body
Every error body is JSON with the reason in message. Some errors add more fields:
| Field | Type | Description |
|---|---|---|
message | string | Why the request was refused. Always present. |
errorCode | string | A machine-readable code, such as rate_limited. |
invalidFields | array | The request fields that failed validation. |
reference | string | A support id. Quote it when you contact support. |
{ "message": "This API credential has expired" }Credential refusals
| Status | Message | What to do |
|---|---|---|
| 401 | Invalid API credential | The token starts with edk_ but is malformed or unknown. Check that you send the whole token, then issue a new credential if it still fails. A token without the edk_ prefix gets no 401 on a public read: it is served anonymously. |
| 401 | This API credential has been revoked | Someone revoked it. Issue a new credential. |
| 401 | This API credential has expired | Issue a new credential. |
| 403 | This operation does not accept API credentials | Use only the operations in the API reference. |
| 403 | This API credential is read-only: it may make GET requests only | Use a Read and write credential for this request. |
| 403 | This API credential is scoped to the organization <slug> | The path names another organization. Use that organization's slug, or a credential for that organization. |
| 403 | This API credential is scoped to the organization <slug>; this operation is not | The operation names no organization. Call an operation under /organizations/{orgSlug}. |
| 403 | A read-only API credential cannot read change history | Reading a broadcast's change history needs a Read and write credential. |
| 400 | A bulk call may carry at most 50 operations | Split the batch into calls of 50 or fewer. See Bulk operations. |
The credential is checked on every request before anything else. A token in the edk_... form that does not authenticate gets 401, even on an operation that would otherwise be public. A bearer token that does not start with edk_ (lowercase) is not treated as a credential: on a public read it is served as an anonymous request, with no error.
The 401 header
Every 401 carries this header:
WWW-Authenticate: Bearer error="invalid_token"Other statuses
- Every operation can return
404(not found),429(rate limited, below) and500(server error). - Write operations can also return
409when the change conflicts with the current state. - Write operations can also return
422when a field breaks a rule, for example astartsAtin the past or anendsAtbeforestartsAt. The body carrieserrorCodeSCHEDULE_INVALIDandinvalidFields. - A create or update can also return
400when it names something that does not exist or is not available to this organization: an unknowngraphicsTemplateIdon an update (the body carriesinvalidFields), or atagIdsentry on a create or update. A create that returns400fortagIdshas already created the broadcast, so look it up before retrying. - Bulk calls return
207with one result per row. See Bulk operations.
If a 500 keeps happening, contact support and quote the reference from the error body when there is one.
Rate limit
Each credential has its own rate limit: a burst of requests it can make at once, which refills over time.
By default a credential can make a burst of about 60 requests, refilling at about 120 per minute. Your platform's operator can change these, and you may occasionally be limited a little sooner or later than that, so always handle 429 rather than counting on an exact number.
What a request costs
- A bulk call costs one request per entry in
operations. - Every other call costs one request, including a list read with
limit=all.
The 429 response
Over the rate limit, a request gets 429 with a Retry-After header, in seconds, and this body:
{
"message": "Too many requests from this API credential. Retry after 3 seconds.",
"errorCode": "rate_limited",
"retryAfterSeconds": 3
}Wait that many seconds, then retry.
Retry after a rate limit
url="$EVENTDOOR_API/organizations/acme/hubs/home-games/broadcasts"
for attempt in 1 2 3 4 5; do
status=$(curl -s -D headers.txt -o body.json -w '%{http_code}' \
-H "Authorization: Bearer $EVENTDOOR_TOKEN" "$url")
[ "$status" != "429" ] && break
wait=$(grep -i '^retry-after:' headers.txt | tr -dc '0-9')
sleep "${wait:-1}"
done
cat body.jsonRetry only the request that got 429. Retrying a 4xx other than 429 without changing anything gets the same refusal.