Stridee
Stridee Docs

Errors & rate limits

Status codes, the error body, and what to do when you are throttled.

Errors come back as JSON with a stable code. Branch on the code, log the message, and show neither to an end user.

409 Conflict
{
  "error": {
    "code": "encryption_key_unconfirmed",
    "message": "That key was never confirmed, so its private half may not exist anywhere.",
    "request_id": "8f3d1b47-6a2e-4c90-b5d8-0e71fa3c26b9"
  }
}

Every signed request is answered with a Request-Id header, error or not, and it carries the same id. Quote it in Discord and we can find the exact call in request logs, where it is the id in the last column. Refused requests are logged there too — so a 401 you cannot explain from your side is a row we can read from ours.

Status codes

StatusMeaningWhat to do
400The request is malformedFix the call; retrying won't help
401Not signed inSign in again
403Authenticated, but not permittedCheck the account is connected and the scope is granted
404No such resource, or not yoursTreat as gone; don't retry
409Conflicts with current stateRe-read, then decide
429Rate limitedBack off — see below
5xxOursRetry with backoff; we're already paged

The ways a key request is refused

  • encryption_key_unconfirmed — the key exists but nobody confirmed the private half reached disk, so it cannot be assigned to an endpoint. Confirm it on Keys.
  • encryption_key_in_use — an endpoint still names it. Assign that endpoint another key before revoking this one; the message says which URL is holding it.
  • encryption_key_unusable — the bytes registered are not a usable X25519 public key. Nothing in 32 raw bytes names a curve, so this is only knowable at first use — register a fresh key with openssl genpkey -algorithm x25519 and assign it.

Rate limits

Every response carries the current window:

Text
stridee-ratelimit-limit: 600
stridee-ratelimit-remaining: 573
stridee-ratelimit-reset: 41

reset is seconds until the window rolls. A 429 also carries Retry-After; honour it rather than your own backoff, and jitter your retries so a fleet doesn't resynchronise into the next window.

Limits are per account. If you are polling to stay current, webhooks will cost you a fraction of the requests and get you the data sooner.

Pings are capped separately, at 10 per endpoint per minute.

Retrying safely

  • GET is safe to retry. So is DELETE — a second one gets a 404, which is the state you wanted.
  • Writes take an Idempotency-Key header. Reuse the same key on a retry and you get the original response back rather than a second resource.
  • Retry 429 and 5xx. Never retry 400, 403 or 404; the answer will not change.

Something wrong or missing on this page? Tell us in Discord.