{
 "shape": "{\"error\": \"<code>\", \"message\": \"...\", \"request_id\": \"...\", ...extra fields}",
 "api_revision": 39,
 "errors": [
  {
   "code": "bad_request",
   "you_should": "Fix the request",
   "meaning": "Malformed HTTP or JSON",
   "http": 400,
   "returned_today": true
  },
  {
   "code": "unauthorized",
   "you_should": "Stop; tell the owner the key needs replacing",
   "meaning": "Key missing or wrong; `reason` = `key_rotated` or `agent_removed` when Bridgit knows",
   "http": 401,
   "returned_today": true
  },
  {
   "code": "forbidden_source",
   "you_should": "Check Tailscale",
   "meaning": "Caller is not on the tailnet",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "capability_disabled",
   "you_should": "Tell the owner which switch (`setting` field)",
   "meaning": "Master switch off",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "permission_denied",
   "you_should": "Tell the owner; the Access screen fixes it",
   "meaning": "Android permission not granted (`permission` field)",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "access_needed",
   "you_should": "Tell the owner; Bridgit also notifies them",
   "meaning": "Android special access off (`setting` field)",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "pairing_closed",
   "you_should": "Ask the owner to open one",
   "meaning": "No pairing window open",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "screen_denied",
   "you_should": "Don't ask again soon",
   "meaning": "The owner denied screen access",
   "http": 403,
   "returned_today": false
  },
  {
   "code": "consent_expired",
   "you_should": "Ask for a new owner-approved grant",
   "meaning": "No active screen-sharing grant",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "setting_locked",
   "you_should": "Ask the owner to change it on the phone",
   "meaning": "Agents can't change this setting (`key`, `reason`: gate, disconnects, owner_only, android or status)",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "email_required",
   "you_should": "Send the owner's address with POST /v1/owner/email, then ask them to tap the link in the email",
   "meaning": "The first 24 hours are over and the owner hasn't verified an email (`state`: none or pending)",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "agent_not_allowed",
   "you_should": "Ask the owner to change agent permissions",
   "meaning": "This agent lacks a capability grant",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "not_found",
   "you_should": "Fix the request",
   "meaning": "Unknown endpoint or id",
   "http": 404,
   "returned_today": true
  },
  {
   "code": "photo_not_found",
   "you_should": "Refresh the list",
   "meaning": "Gallery item gone or outside access",
   "http": 404,
   "returned_today": true
  },
  {
   "code": "sensor_busy",
   "you_should": "Retry once after a few seconds",
   "meaning": "Sensor in use or capture running",
   "http": 409,
   "returned_today": true
  },
  {
   "code": "device_locked",
   "you_should": "Ask the owner to unlock",
   "meaning": "Needs the phone unlocked",
   "http": 409,
   "returned_today": true
  },
  {
   "code": "payload_too_large",
   "you_should": "Ask for a smaller size (`photo_id` given)",
   "meaning": "Over 12 MB base64 (40 MB raw)",
   "http": 413,
   "returned_today": true
  },
  {
   "code": "invalid_parameter",
   "you_should": "Fix; never retry unchanged",
   "meaning": "Bad value",
   "http": 422,
   "returned_today": true
  },
  {
   "code": "not_supported",
   "you_should": "Don't retry",
   "meaning": "Android doesn't allow this (for example Wi-Fi toggle)",
   "http": 422,
   "returned_today": true
  },
  {
   "code": "rate_limited",
   "you_should": "Wait",
   "meaning": "Over a limit (`retry_after_s`)",
   "http": 429,
   "returned_today": true
  },
  {
   "code": "too_many_open",
   "you_should": "Wait for answers or cancel some",
   "meaning": "Too many open questions/notices",
   "http": 429,
   "returned_today": true
  },
  {
   "code": "notifications_required",
   "you_should": "Tell the owner to turn notifications on",
   "meaning": "Bridgit's notifications are off, so captures are refused (PRD-05)",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "forbidden",
   "you_should": "Don't retry",
   "meaning": "Not allowed for this agent (`reason`, for example `fixer_mode_off` or `super_powers_off`: the owner hasn't given you Bridgit Fixer Mode or Agent Super Powers)",
   "http": 403,
   "returned_today": true
  },
  {
   "code": "in_progress",
   "you_should": "Wait, then retry with the same key",
   "meaning": "Same `Idempotency-Key` still running",
   "http": 409,
   "returned_today": true
  },
  {
   "code": "conflict",
   "you_should": "Read it with GET /v1/interactions/{id}; start a new one if needed",
   "meaning": "The interaction isn't in a state for this (for example a text panel that's closed or finished)",
   "http": 409,
   "returned_today": true
  },
  {
   "code": "idempotency_expired",
   "you_should": "Don't repeat; use a new key only if you really want a new capture",
   "meaning": "Same `Idempotency-Key` already done, but its media result is no longer replayed (15 min, API-13)",
   "http": 409,
   "returned_today": true
  },
  {
   "code": "quota_exceeded",
   "you_should": "Remove old transfers or wait for retention",
   "meaning": "Daily data, file storage or relay job quota used up (`limit`)",
   "http": 429,
   "returned_today": true
  },
  {
   "code": "too_many_waits",
   "you_should": "Close some waits",
   "meaning": "Too many open `wait` requests (SEC-08a)",
   "http": 429,
   "returned_today": true
  },
  {
   "code": "upstream_failed",
   "you_should": "Retry in a few minutes",
   "meaning": "A service Bridgit asks on your behalf (MET Norway for weather) failed and nothing was cached (`service`, `upstream_status` or `reason`)",
   "http": 502,
   "returned_today": true
  },
  {
   "code": "callback_failed",
   "you_should": "Check the receiver; the owner sees the host in Activity",
   "meaning": "Your callback URL didn't accept the test event (`http_status` or `reason` field)",
   "http": 502,
   "returned_today": true
  },
  {
   "code": "internal_error",
   "you_should": "Report via `POST /v1/feedback`",
   "meaning": "Bridgit bug",
   "http": 500,
   "returned_today": true
  },
  {
   "code": "service_start_blocked",
   "you_should": "Ask the owner to open Bridgit once",
   "meaning": "Android hasn't given the service this sensor",
   "http": 503,
   "returned_today": true
  },
  {
   "code": "team_unavailable",
   "you_should": "Retry later, or register at the backend directly",
   "meaning": "The Bridgit team backend can't be reached",
   "http": 503,
   "returned_today": true
  },
  {
   "code": "capture_timeout",
   "you_should": "Retry once",
   "meaning": "Sensor didn't answer in time",
   "http": 504,
   "returned_today": true
  },
  {
   "code": "phone_unreachable",
   "you_should": "Retry later",
   "meaning": "(Relay) phone didn't pick up the job",
   "http": 504,
   "returned_today": false
  }
 ]
}
