Errors

Error codes and retry behaviour.

API errors use an error code and may include a message:

{"error": "rate_limited", "message": "API rate limit exceeded", "retryAfter": 47}
  • error is the machine-readable code. Use it to handle the failure.
  • message is optional and may change.
  • Rate-limit responses can include retryAfter, the seconds until the window resets, with the same value in the Retry-After header. Invalid-key throttling may omit both.
  • Some codes add context. ambiguous_client includes a clients array.

Malformed JSON, missing fields, invalid field types or a missing JSON content type can return a framework error without this JSON format. Check the HTTP status before parsing the body.

Refused by the server

These errors occur before the server forwards the request.

  • 401 unauthorized. Missing, wrong or revoked key. Stop retrying and ask the user for a new one.
  • 403 patreon_required. The key's account has no active supporter subscription. The user fixes this at account.kinkyraven.com.
  • 429 rate_limited. Wait for the supplied retry interval, or use backoff if none is supplied. The server does not cache this error for idempotency.
  • 400 bad_request. An effect_id or rule_id is empty.
  • 400 bad_effect. The effect_id is over 128 characters or contains control characters.
  • 400 bad_rule. The rule_id is over 128 characters or contains control characters.

Refused by the relay

The server tried to reach a device and could not.

  • 404 client_not_found. The client_id you passed is not on this account.
  • 409 ambiguous_client. Several of the user's computers are online and you passed no client_id. The body lists them.
  • 503 device_offline. The target is offline, or nothing is online.
  • 504 client_timeout. The app did not answer within 10 seconds.

These errors apply to calls that select a device on your own account. Friend endpoints list their delivery errors separately. See Targeting.

Refused by the app

These errors come from the app and retain its HTTP status.

  • 403 remote_disabled. Online connection is switched off in the app.
  • 409 session_off. No effects session is running. The user has to start one.
  • 404 effect_not_found. The effect is unknown or unavailable in the remote library.
  • 404 rule_not_found. Unknown rule_id, or a trigger that is disabled or gated. The two cases are deliberately indistinguishable.
  • 403 effect_disabled. The user disabled the effect.
  • 403 premium_required. The target account lacks the entitlement for the effect or remote sequence.
  • 403 high_risk_disabled. The user has "Disable High Risk Effects" on and this effect is strobe-class.
  • 403 not_remotely_fireable. Direct effect calls cannot fire Clear, always-on-top Strobe Clear, or browser effects.
  • 403 unlock_unavailable. The target platform cannot accept typing for a Type to Unlock or Screen Shutdown effect.
  • 403 or 400 app_outdated. The user's app predates this endpoint. They need to update.

Friend paths only

  • 404 not_friends. Not on the key owner's friends list.
  • 403 friend_control_disabled. The friend has not allowed the key's owner control. Listing their triggers fails with this.
  • 403 friend_trigger_disabled. Same switch, reported when firing.
  • 502 rules_unavailable. The friend's app refused to list, or predates the feature.

What to retry

Use backoff for temporary failures and honour Retry-After when present. Retry a trigger with the same Idempotency-Key within 5 minutes to retrieve its stored response. Concurrent requests and server restarts can still cause duplicate execution.

The server also stores delivery errors such as 503 device_offline and 504 client_timeout. Retrying with the same key returns that error without another delivery attempt. After a confirmed offline failure, use a new key when the device reconnects. After a timeout, the app may have executed the request, so a new key can fire it again.

Do not retry 401, 403 or 404 until the cause changes. Stops and clears are safe to send again.