API Docs

Errors.

One envelope, stable codes, and three places a call can be refused.

520 words · ~2 min read

Every error is JSON with the same shape:

{"error": "rate_limited", "message": "API rate limit exceeded", "retryAfter": 47}
  • error is the stable machine-readable code. Test on this.
  • message is for humans and may change.
  • retryAfter appears only on 429, in seconds until the window resets. The same value is sent as a Retry-After header.
  • Some codes add context. ambiguous_client includes a clients array.

A call can fail at three points. Knowing which one tells you what to do about it.

Refused by the server

Nothing reached the user's app.

  • 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 retryAfter seconds. Idempotent retries after a 429 re-execute, since nothing happened.
  • 400 bad_request. A required field is missing, usually effect_id or rule_id.
  • 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.

Any of these can come back from a relayed endpoint. See Targeting.

Refused by the app

The call reached the user's computer and the app said no. These come back with the app's own 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. Unknown effect_id.
  • 404 rule_not_found. Unknown rule_id, or a trigger that is disabled or gated. The two cases are deliberately indistinguishable.
  • 403 premium_required. The effect needs a supporter membership on the target account and it has lapsed.
  • 403 high_risk_disabled. The user has "Disable High Risk Effects" on and this effect is strobe-class.
  • 403 not_remotely_fireable. The Clear effect and the forced browser can only be fired on the computer they run on.
  • 403 unlock_unavailable. A type-to-unlock cover, on a platform whose overlay cannot take typing.
  • 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.
  • 403 target_patreon_required. The friend needs an active supporter subscription to receive effects.
  • 502 rules_unavailable. The friend's app refused to list, or predates the feature.

What to retry

Retry 429, 503 and 504 with backoff. Retry POST triggers with the same Idempotency-Key so a lost response never fires twice. Do not retry 401, 403 or 404 until something has changed on the user's side. Stops and clears are always safe to send again.