{"openapi":"3.1.0","info":{"title":"Limitry API","version":"1.0.0","description":"The Limitry API. Every rule below has a page in the [docs](https://limitry.com/docs/).\n\n- **Authentication:** send `Authorization: Bearer <token>` — a workspace API key, or a personal access token plus `X-Workspace: <workspace-slug>`. [Authentication](https://limitry.com/docs/authentication/)\n- **Errors:** every error has the same shape, `{ \"error\": { \"code\", \"message\" } }`; branch on `code`. [Errors](https://limitry.com/docs/errors/)\n- **Pagination:** lists take `limit` and `cursor`; pass back `nextCursor` until it is `null`. [Pagination](https://limitry.com/docs/pagination/)\n- **Rate limits:** too many requests answer `429` with `Retry-After`. [API rate limits](https://limitry.com/docs/errors/#api-rate-limits)\n- **Idempotency:** send an `Idempotency-Key` header to retry a write safely. [Idempotency](https://limitry.com/docs/idempotency/)"},"security":[{"apiKey":[]},{"pat":[]}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Workspace API key (create under Settings → API keys in the app)."},"pat":{"type":"http","scheme":"bearer","description":"Personal access token (create under Account → API tokens in the app). Acts as the user: on workspace routes send `X-Workspace: <workspace-slug>`; the token's scopes (workspaces, `<family>:<read|write>` scopes) apply. On /v1/user/* it is the only credential."}},"schemas":{"UserMe":{"type":"object","properties":{"id":{"type":"string","example":"k3TAiF2ZP5sQxWbVJd8mR1cyNGuh4Eo9"},"name":{"type":"string","example":"Casey Customer"},"email":{"type":"string","example":"casey@example.com"},"workspaces":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","example":"Acme Inc."},"slug":{"type":"string","example":"acme"},"role":{"type":"string","example":"owner"}},"required":["id","name","slug","role"]}}},"required":["id","name","email","workspaces"]},"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"unauthorized"},"message":{"type":"string","example":"Unauthorized"},"requestId":{"type":"string"},"docs":{"type":"string","description":"Link to this error code's entry in the documentation — how to fix it.","example":"https://example.com/docs/errors/#unauthorized"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}},"required":["path","message"]}}},"required":["code","message"]}},"required":["error"]},"Workspace":{"type":"object","properties":{"id":{"type":"string","example":"k3TAiF2ZP5sQxWbVJd8mR1cyNGuh4Eo9"},"name":{"type":"string","example":"Acme Inc."}},"required":["id","name"]},"AuditEventPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AuditEvent"}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= to fetch the next page."}},"required":["items","nextCursor"]},"AuditEvent":{"type":"object","properties":{"id":{"type":"string","example":"evt_k3TAiF2ZP5sQxWbV"},"action":{"type":"string","example":"member.invited"},"actorType":{"type":"string","example":"user","description":"Who is accountable: `user`, `staff`, `system` or `api_key`."},"credential":{"type":["object","null"],"properties":{"type":{"type":"string","example":"pat","description":"`api_key` or `pat`."},"name":{"type":["string","null"],"example":"ci"}},"required":["type","name"],"description":"The API credential the action came through, as named when it happened; null for actions taken in the app."},"createdAt":{"type":"string","example":"2026-08-19T12:00:00.000Z"}},"required":["id","action","actorType","credential","createdAt"]},"MemberPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= to fetch the next page."}},"required":["items","nextCursor"]},"Member":{"type":"object","properties":{"id":{"type":"string","description":"The membership's id."},"userId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","example":"member","description":"`owner`, `admin`, `member` or `guest`."},"joinedAt":{"type":"string","example":"2026-08-19T12:00:00.000Z"}},"required":["id","userId","name","email","role","joinedAt"]},"InvitationPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= to fetch the next page."}},"required":["items","nextCursor"]},"Invitation":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"role":{"type":["string","null"],"example":"member"},"teamIds":{"type":"array","items":{"type":"string"},"description":"Teams the person joins on accepting (besides the default team, unless a guest)."},"expiresAt":{"type":"string","example":"2026-08-21T12:00:00.000Z"},"createdAt":{"type":"string","example":"2026-08-19T12:00:00.000Z"}},"required":["id","email","role","teamIds","expiresAt","createdAt"]},"ApprovalRequest":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string","example":"workspace.apiKey.create"},"title":{"type":"string"},"summary":{"type":"string","description":"Exactly what will happen, as the person reads it."},"input":{"type":"object","additionalProperties":{}},"reason":{"type":"string"},"status":{"type":"string","enum":["pending","approved","completed","denied","failed","expired"],"description":"`approved` = waiting for the CLI to redeem it (a secret-producing action asked from the CLI)."},"requestedBy":{"type":["string","null"]},"expiresAt":{"type":"string"},"createdAt":{"type":"string"},"decidedAt":{"type":["string","null"]},"result":{"type":["object","null"],"additionalProperties":{},"description":"The outcome — never a secret."},"secret":{"type":["object","null"],"properties":{"name":{"type":"string"},"envVar":{"type":"string"}},"required":["name","envVar"],"description":"Set when the action creates a secret."},"approveUrl":{"type":"string","description":"Where a person approves or denies it — show it to them."}},"required":["id","action","title","summary","input","reason","status","requestedBy","expiresAt","createdAt","decidedAt","result","secret","approveUrl"]},"WorkspaceUsage":{"type":"object","properties":{"periodStart":{"type":"string","example":"2026-10-17T14:30:00.000Z","description":"When this period began: a month after the last, from the billing date."},"periodEnd":{"type":"string","example":"2026-11-17T14:30:00.000Z","description":"When the counts reset."},"meters":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","example":"webhook_deliveries"},"description":{"type":"string"},"used":{"type":"integer"},"limit":{"type":["integer","null"],"description":"The plan's limit this period; null = unlimited."}},"required":["id","description","used","limit"]}},"notices":{"type":"array","items":{"type":"string"},"description":"Things to know about these numbers, such as some usage being unavailable right now."}},"required":["periodStart","periodEnd","meters"]},"TeamPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Team"}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= to fetch the next page."}},"required":["items","nextCursor"]},"Team":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"isDefault":{"type":"boolean","description":"The team every member (not guests) belongs to."},"memberIds":{"type":"array","items":{"type":"string"},"description":"The user ids of the team's members."},"createdAt":{"type":"string","example":"2026-08-19T12:00:00.000Z"}},"required":["id","name","isDefault","memberIds","createdAt"]},"WebhookEndpointPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= to fetch the next page."}},"required":["items","nextCursor"]},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","example":"we_3f0c…"},"url":{"type":"string","example":"https://example.com/hooks"},"description":{"type":["string","null"]},"enabled":{"type":"boolean","description":"False after 20 failed attempts in a row (retries count); re-enable to resume."},"eventTypes":{"type":["array","null"],"items":{"type":"string"},"description":"The event types it receives (see event-types); null = every event."},"environment":{"type":["string","null"],"example":"live","description":"The environment it belongs to, where the product has them: it receives only that environment's events and is managed with a credential acting in it. Null otherwise."},"consecutiveFailures":{"type":"integer"},"lastStatus":{"type":["integer","null"]},"lastAttemptAt":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","url","description","enabled","eventTypes","environment","consecutiveFailures","lastStatus","lastAttemptAt","createdAt"]},"WebhookEndpointCreated":{"type":"object","properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"secret":{"type":"string"}},"required":["endpoint","secret"]},"WebhookDeliveryOutcome":{"type":"object","properties":{"deliveryId":{"type":"string"},"queued":{"type":"boolean","description":"True when queued for delivery (with retries); false when attempted immediately."},"ok":{"type":"boolean","description":"When attempted immediately: whether it was accepted."},"status":{"type":["integer","null"]}},"required":["deliveryId","queued"]},"WebhookDeliveryPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= to fetch the next page."}},"required":["items","nextCursor"]},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string","example":"del_8a1b…"},"eventId":{"type":"string","example":"evt_51c2…"},"eventType":{"type":"string","example":"workspace.member.joined"},"status":{"type":"string","example":"delivered","description":"`pending`, `delivered` or `failed`."},"attempts":{"type":"integer"},"lastStatus":{"type":["integer","null"]},"lastAttemptAt":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","eventId","eventType","status","attempts","lastStatus","lastAttemptAt","createdAt"]},"LimitPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Limit"}},"nextCursor":{"type":["string","null"],"description":"Pass as ?cursor= to fetch the next page."}},"required":["items","nextCursor"]},"Limit":{"type":"object","properties":{"id":{"type":"string","example":"lim_3f0c…"},"name":{"type":"string","example":"AI budget"},"subject":{"$ref":"#/components/schemas/LimitSubject"},"action":{"type":"string","example":"ai-call","description":"The action it limits; `*` for every action."},"amount":{"type":"integer","example":200,"description":"How many units per window — for a `concurrent` limit, how many at once."},"unit":{"type":"string","example":"cents"},"window":{"type":"string","enum":["minute","hour","day","week","month","year","total","concurrent"],"example":"month","description":"`minute`, `hour`, `day`, `week`, `month` or `year`: a period of `every` of them, refilled where `start` says (or rolling: see `rolling`). `total`: a balance that never resets, topped up by grants. `concurrent`: at most `amount` held reservations at once."},"every":{"type":"integer","example":1,"description":"How many `window` units a period lasts: `window: \"month\", every: 3` is a quarter, `window: \"hour\", every: 5` five hours. Default: 1."},"start":{"type":"string","enum":["calendar","anchor","first_use"],"example":"calendar","description":"Where a period begins. `calendar`: UTC boundaries (midnight, Monday, the 1st, 1 January). `anchor`: from the subject's anchor, its billing date, set with `subjects.update` (its first check until then), so an annual plan can refill monthly from its start day. `first_use`: at the first check after the previous period ended. Default: calendar."},"rolling":{"type":"boolean","description":"Counts the last minute, hour or day at the moment of the check instead of the calendar window."},"enabled":{"type":"boolean"},"archivedAt":{"type":["string","null"],"description":"When it was archived (deleting archives it); null while active. An archived limit isn't enforced; its usage history and credit grants stay."},"failMode":{"type":"string","enum":["open","closed"],"example":"closed","description":"What your code should do when Limitry cannot be reached: `open` allows, `closed` denies."},"version":{"type":"integer","description":"Increases on every change."},"createdAt":{"type":"string","example":"2026-10-04T12:00:00.000Z"},"updatedAt":{"type":"string","example":"2026-10-04T12:00:00.000Z"}},"required":["id","name","subject","action","amount","unit","window","every","start","rolling","enabled","archivedAt","failMode","version","createdAt","updatedAt"]},"LimitSubject":{"type":"object","properties":{"kind":{"type":"string","example":"user","description":"Your own label for who is checked: user, apikey, agent, team …"},"id":{"type":["string","null"],"example":null,"description":"One subject, or null for every subject of this kind."}},"required":["kind","id"]},"LimitInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"example":"AI budget","description":"A name for the limit, unique among its environment's active limits."},"subjectKind":{"type":"string","minLength":1,"maxLength":100,"example":"user","description":"Your own label for who is checked."},"subjectId":{"type":["string","null"],"minLength":1,"maxLength":100,"description":"One subject; omit or null for every subject of the kind. A subject's own limit replaces the kind's limits with the same action and window."},"action":{"type":"string","minLength":1,"maxLength":100,"example":"ai-call","description":"The action to limit; `*` for every action."},"amount":{"type":"integer","minimum":1,"maximum":1000000000,"example":200,"description":"How many units each subject may use per window."},"unit":{"type":"string","minLength":1,"maxLength":40,"example":"cents","description":"What the amount counts (display only). Default: units."},"window":{"type":"string","enum":["minute","hour","day","week","month","year","total","concurrent"],"example":"month","description":"`minute`, `hour`, `day`, `week`, `month` or `year`: a period of `every` of them, refilled where `start` says (or rolling: see `rolling`). `total`: a balance that never resets, topped up by grants. `concurrent`: at most `amount` held reservations at once."},"every":{"type":"integer","minimum":1,"maximum":1000,"example":1,"description":"How many `window` units a period lasts: `window: \"month\", every: 3` is a quarter, `window: \"hour\", every: 5` five hours. Default: 1."},"start":{"type":"string","enum":["calendar","anchor","first_use"],"example":"calendar","description":"Where a period begins. `calendar`: UTC boundaries (midnight, Monday, the 1st, 1 January). `anchor`: from the subject's anchor, its billing date, set with `subjects.update` (its first check until then), so an annual plan can refill monthly from its start day. `first_use`: at the first check after the previous period ended. Default: calendar."},"rolling":{"type":"boolean","description":"Count the last window instead of the calendar one (minute, hour or day only). Default: false."},"enabled":{"type":"boolean","description":"Whether checks enforce it. Default: true."},"failMode":{"type":"string","enum":["open","closed"],"description":"What your code should do when Limitry can't be reached: `open` (allow) or `closed` (deny). Default: open."}},"required":["name","subjectKind","action","amount","window"]},"LimitPatch":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"example":"AI budget","description":"A name for the limit, unique among its environment's active limits."},"subjectKind":{"type":"string","minLength":1,"maxLength":100,"example":"user","description":"Your own label for who is checked."},"subjectId":{"type":["string","null"],"minLength":1,"maxLength":100,"description":"One subject; omit or null for every subject of the kind. A subject's own limit replaces the kind's limits with the same action and window."},"action":{"type":"string","minLength":1,"maxLength":100,"example":"ai-call","description":"The action to limit; `*` for every action."},"amount":{"type":"integer","minimum":1,"maximum":1000000000,"example":200,"description":"How many units each subject may use per window."},"unit":{"type":"string","minLength":1,"maxLength":40,"example":"cents","description":"What the amount counts (display only). Default: units."},"window":{"type":"string","enum":["minute","hour","day","week","month","year","total","concurrent"],"example":"month","description":"`minute`, `hour`, `day`, `week`, `month` or `year`: a period of `every` of them, refilled where `start` says (or rolling: see `rolling`). `total`: a balance that never resets, topped up by grants. `concurrent`: at most `amount` held reservations at once."},"every":{"type":"integer","minimum":1,"maximum":1000,"example":1,"description":"How many `window` units a period lasts: `window: \"month\", every: 3` is a quarter, `window: \"hour\", every: 5` five hours. Default: 1."},"start":{"type":"string","enum":["calendar","anchor","first_use"],"example":"calendar","description":"Where a period begins. `calendar`: UTC boundaries (midnight, Monday, the 1st, 1 January). `anchor`: from the subject's anchor, its billing date, set with `subjects.update` (its first check until then), so an annual plan can refill monthly from its start day. `first_use`: at the first check after the previous period ended. Default: calendar."},"rolling":{"type":"boolean","description":"Count the last window instead of the calendar one (minute, hour or day only). Default: false."},"enabled":{"type":"boolean","description":"Whether checks enforce it. Default: true."},"failMode":{"type":"string","enum":["open","closed"],"description":"What your code should do when Limitry can't be reached: `open` (allow) or `closed` (deny). Default: open."}}},"LimitSyncResult":{"type":"object","properties":{"dryRun":{"type":"boolean","description":"True when nothing was written: this is the plan."},"created":{"type":"array","items":{"type":"string"},"example":["AI budget"],"description":"Names of the limits created."},"updated":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"changes":{"type":"object","additionalProperties":{"type":"object","properties":{"from":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]},"to":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},"required":["from","to"]},"example":{"amount":{"from":200,"to":300}},"description":"Each changed field, from its old value to the new."}},"required":["name","changes"]},"description":"The limits changed, field by field."},"archived":{"type":"array","items":{"type":"string"},"description":"Names of the limits archived (with `archiveMissing`)."},"unchanged":{"type":"array","items":{"type":"string"},"description":"Names of the limits that already matched."}},"required":["dryRun","created","updated","archived","unchanged"]},"LimitSyncInput":{"type":"object","properties":{"limits":{"type":"array","items":{"$ref":"#/components/schemas/LimitInput"},"maxItems":200,"example":[{"name":"AI budget","subjectKind":"user","action":"ai-call","amount":200,"unit":"cents","window":"month"}],"description":"Every limit you want, each described whole: an omitted field is its default, as on create. Names are the key and must be unique in the list. At most 200."},"archiveMissing":{"type":"boolean","description":"Archive the environment's active limits whose names aren't in `limits` (restorable). Default: false, which leaves them alone."},"dryRun":{"type":"boolean","description":"Answer what the sync would do and change nothing. Default: false."}},"required":["limits"]},"LimitGrant":{"type":"object","properties":{"id":{"type":"string","example":"grt_…"},"limitId":{"type":"string"},"subject":{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"]},"amount":{"type":"integer"},"note":{"type":"string"},"createdByUserId":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","limitId","subject","amount","note","createdByUserId","createdAt"]},"LimitGrantInput":{"type":"object","properties":{"subject":{"type":"object","properties":{"kind":{"type":"string","minLength":1,"maxLength":100},"id":{"type":"string","minLength":1,"maxLength":200}},"required":["kind","id"],"example":{"kind":"team","id":"team_42"},"description":"Who gets the credits, as `{\"kind\": \"team\", \"id\": \"team_42\"}`."},"amount":{"type":"integer","example":5000,"description":"Credits to add; negative to take them back. Not 0."},"note":{"type":"string","maxLength":200,"example":"October top-up","description":"Required when `amount` is negative."}},"required":["subject","amount"]},"CheckDecision":{"type":"object","properties":{"id":{"type":"string","example":"chk_9d2e…"},"allowed":{"type":"boolean","description":"The answer. `false` is a normal answer, not an error — branch on it."},"reason":{"type":["object","null"],"properties":{"code":{"type":"string","enum":["limit_exceeded","too_many_reservations"]},"limit":{"type":["string","null"],"example":"lim_3f0c…"}},"required":["code","limit"],"description":"Why not, when `allowed` is false: a limit is used up (`limit` names it), or the subject already holds the most open reservations (1,000)."},"remaining":{"type":"array","items":{"$ref":"#/components/schemas/CheckRemaining"},"description":"Every limit that applied, and what is left in its window."},"retryAfterSeconds":{"type":["integer","null"],"description":"When `allowed` is false: seconds until it could be allowed."},"reservation":{"type":"object","properties":{"id":{"type":"string","example":"rsv_WyJ1c2VyIiwidV80MiJd_9f…"},"expiresAt":{"type":"string"}},"required":["id","expiresAt"],"description":"With `mode: reserve`, when allowed: the hold — commit or release it before `expiresAt`, or it releases itself."}},"required":["id","allowed","reason","remaining","retryAfterSeconds"]},"CheckRemaining":{"type":"object","properties":{"limit":{"type":"string","example":"lim_3f0c…"},"name":{"type":"string","example":"AI budget"},"unit":{"type":"string","example":"cents"},"window":{"type":"string","enum":["minute","hour","day","week","month","year","total","concurrent"]},"rolling":{"type":"boolean","description":"The limit counts the last window, not the calendar one."},"failMode":{"type":"string","enum":["open","closed"],"description":"What to do if Limitry cannot be reached next time: `open` allows, `closed` denies. SDKs remember it."},"remaining":{"type":"integer","example":195},"resetsAt":{"type":["string","null"],"example":"2026-11-01T00:00:00.000Z","description":"When the window resets — for a rolling limit, when its oldest use leaves the window. Null when nothing will: a balance (`total`), a `concurrent` limit, a rolling limit with nothing in use."}},"required":["limit","name","unit","window","rolling","failMode","remaining","resetsAt"]},"CheckRequest":{"type":"object","properties":{"subject":{"$ref":"#/components/schemas/CheckSubject"},"shared":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","minLength":1,"maxLength":100},"id":{"type":"string","minLength":1,"maxLength":200}},"required":["kind","id"]},"maxItems":4,"example":[{"kind":"team","id":"team_42"}],"description":"Shared subjects it also draws from — a team's, org's or project's pool (at most 4). Every limit on every subject must fit; all are charged, or none."},"action":{"type":"string","minLength":1,"maxLength":100,"example":"ai-call","description":"What the subject wants to do."},"cost":{"type":"integer","minimum":1,"maximum":1000000000,"example":5,"description":"Units it would use. Default 1."},"mode":{"type":"string","enum":["consume","preview","reserve"],"example":"consume","description":"`consume` (default) decides and uses; `preview` decides without using; `reserve` decides and HOLDS `cost` (an estimate) until you commit the actual amount or release it — see `reservation` in the answer. Only a reservation takes a slot of a `concurrent` limit."},"ttlSeconds":{"type":"integer","minimum":1,"maximum":3600,"example":300,"description":"With `reserve`: how long the hold lasts before it releases itself. Default 300, at most 3600."}},"required":["subject","action"]},"CheckSubject":{"type":"object","properties":{"kind":{"type":"string","minLength":1,"maxLength":100,"example":"user","description":"Your own label for who is acting: user, apikey, agent …"},"id":{"type":"string","minLength":1,"maxLength":200,"example":"usr_123","description":"Who exactly, in your product."}},"required":["kind","id"],"description":"Who is acting, as `{\"kind\": \"user\", \"id\": \"usr_123\"}`."},"Reservation":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["held","committed","released","expired"],"description":"`expired`: nobody settled it in time, so it gave its hold back."},"reserved":{"type":"integer","description":"The amount held."},"cost":{"type":"integer","description":"What it finally used: the committed cost; 0 when released."},"expiresAt":{"type":"string"}},"required":["id","status","reserved","cost","expiresAt"]},"ReservationExtend":{"type":"object","properties":{"ttlSeconds":{"type":"integer","minimum":1,"maximum":3600,"example":600,"description":"Seconds from now. Default 300."}}},"ReservationCommit":{"type":"object","properties":{"cost":{"type":"integer","minimum":0,"example":3,"description":"The amount actually used."}},"required":["cost"]},"UsageStanding":{"type":"object","properties":{"subject":{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"]},"environment":{"type":"string","example":"live"},"limits":{"type":"array","items":{"type":"object","properties":{"limit":{"type":"string"},"name":{"type":"string"},"subject":{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"]},"shared":{"type":"boolean","description":"On a shared subject, not this one."},"action":{"type":"string"},"unit":{"type":"string"},"window":{"type":"string","enum":["minute","hour","day","week","month","year","total","concurrent"]},"rolling":{"type":"boolean"},"amount":{"type":"integer"},"used":{"type":"integer"},"remaining":{"type":"integer","description":"A balance's can exceed `amount` once credits are granted."},"resetsAt":{"type":["string","null"]}},"required":["limit","name","subject","shared","action","unit","window","rolling","amount","used","remaining","resetsAt"]}}},"required":["subject","environment","limits"]},"UsageBySubject":{"type":"object","properties":{"limitId":{"type":"string"},"windowStart":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"subject":{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"]},"used":{"type":"integer"},"remaining":{"type":"integer"},"denied":{"type":"integer"},"over":{"type":"boolean"}},"required":["subject","used","remaining","denied","over"]}}},"required":["limitId","windowStart","items"]},"UsageSeries":{"type":"object","properties":{"limitId":{"type":"string"},"granularity":{"type":"string","enum":["hour","day"]},"points":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string"},"used":{"type":"integer"},"allowed":{"type":"integer"},"denied":{"type":"integer"}},"required":["start","used","allowed","denied"]}}},"required":["limitId","granularity","points"]},"Subject":{"type":"object","properties":{"subject":{"$ref":"#/components/schemas/SubjectRef"},"anchor":{"type":["string","null"],"example":"2026-03-17T14:30:00.000Z","description":"When its `anchor` limits' periods start from: its billing date, else its first counted check. Null until it has one."}},"required":["subject","anchor"]},"SubjectRef":{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"]},"SubjectUpdate":{"type":"object","properties":{"anchor":{"type":"string","format":"date-time","example":"2026-03-17T14:30:00Z","description":"The date and time its periods start from (ISO 8601), such as a subscription's start."}},"required":["anchor"]},"SubjectResetResult":{"type":"object","properties":{"subject":{"$ref":"#/components/schemas/SubjectRef"},"reset":{"type":"array","items":{"type":"string"},"description":"The limits that were refilled."}},"required":["subject","reset"]},"SubjectReset":{"type":"object","properties":{"limitId":{"type":"string","example":"lim_3f0c…","description":"Just this limit. Default: every limit on the subject."}}}},"parameters":{}},"paths":{"/user/me":{"get":{"operationId":"user.me","summary":"Get the current user","description":"Returns the user the personal access token belongs to, with their workspace memberships. Useful as an integration smoke test (\"who am I?\").","x-mcp":{"expose":false,"reason":"Personal access tokens only; an agent's connection acts in one workspace (workspace_get)."},"security":[{"pat":[]}],"responses":{"200":{"description":"The user the token authenticates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMe"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Personal access tokens are disabled in this deployment (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Personal access tokens"]}},"/user/token":{"delete":{"operationId":"user.revokeToken","summary":"Revoke the token making this request","description":"Revokes the personal access token used to call it — signing out from a script or the CLI (`logout`). The token stops working immediately; other tokens are untouched.","x-mcp":{"expose":false,"reason":"Revokes a person's own credential; agents connect through OAuth, not personal tokens."},"security":[{"pat":[]}],"responses":{"204":{"description":"Revoked."},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Personal access tokens are disabled in this deployment (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Personal access tokens"]}},"/workspace":{"get":{"operationId":"workspace.get","summary":"Get the current workspace","description":"Returns the Workspace the credential acts in — the API key's own, or the one named by X-Workspace for a personal access token. Useful as an integration smoke test (\"who am I?\").","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace:read","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The Workspace the key authenticates.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Workspace"]}},"/workspace/audit-events":{"get":{"operationId":"workspace.auditEvents.list","summary":"List workspace audit events","description":"The workspace's audit trail, newest first. Paginate with the opaque `nextCursor` token; `limit` is clamped to 1–100 (default 25). Owner-only for personal access tokens, like the audit page in the application; a Workspace API key is its workspace and always passes.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.audit:read","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25,"example":25,"description":"Items per page, 1–100 (default 25)."},"required":false,"description":"Items per page, 1–100 (default 25).","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque token from a previous page's nextCursor."},"required":false,"description":"Opaque token from a previous page's nextCursor.","name":"cursor","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"One page of audit events, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditEventPage"}}}},"400":{"description":"Malformed cursor or query (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Audit events"]}},"/workspace/members":{"get":{"operationId":"workspace.members.list","summary":"List workspace members","description":"The workspace's members with their roles, newest first. Paginate with the opaque `nextCursor`; `limit` is clamped to 1–100 (default 25). Members are invited, removed and given roles in the app.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.members:read","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25,"example":25,"description":"Items per page, 1–100 (default 25)."},"required":false,"description":"Items per page, 1–100 (default 25).","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque token from a previous page's nextCursor."},"required":false,"description":"Opaque token from a previous page's nextCursor.","name":"cursor","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"One page of members, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberPage"}}}},"400":{"description":"Malformed cursor or query (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Workspace"]}},"/workspace/invitations":{"get":{"operationId":"workspace.invitations.list","summary":"List pending invitations","description":"Invitations sent and not yet accepted, declined or expired, newest first. Owners and admins only for a personal credential, as in the app. Paginate with the opaque `nextCursor`.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.members:read","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25,"example":25,"description":"Items per page, 1–100 (default 25)."},"required":false,"description":"Items per page, 1–100 (default 25).","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque token from a previous page's nextCursor."},"required":false,"description":"Opaque token from a previous page's nextCursor.","name":"cursor","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"One page of pending invitations, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationPage"}}}},"400":{"description":"Malformed cursor or query (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Workspace"]}},"/workspace/approval-actions":{"get":{"operationId":"workspace.approvalActions.list","summary":"List the actions you can ask approval for","description":"Actions a credential may not take itself but may ASK a person to approve: each one's input (JSON Schema), who can approve it, and whether it creates a secret.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.approvals:read","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The approvable actions.","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"approverRoles":{"type":"array","items":{"type":"string"}},"createsSecret":{"type":"boolean"},"input":{"type":"object","additionalProperties":{}}},"required":["id","title","approverRoles","createsSecret","input"]}}},"required":["items"]}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Approvals"]}},"/workspace/approval-requests":{"post":{"operationId":"workspace.approvalRequests.create","summary":"Ask a person to approve an action","description":"Files a request for an action you may not take yourself (see approval-actions) and notifies everyone who can approve it. Show the person `approveUrl` and why you need it; then check the request until it is decided (it expires after 24 hours). A personal access token or an app a person connected may ask — not a workspace API key.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.approvals:write","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","example":"workspace.apiKey.create","description":"An action id from approval-actions."},"input":{"type":"object","additionalProperties":{},"example":{"name":"acme-web","scopes":["workspace:read"]},"description":"The action's input, per its JSON Schema."},"reason":{"type":"string","minLength":1,"maxLength":500,"description":"Why — the person reads it before deciding."}},"required":["action","input","reason"]}}}},"responses":{"201":{"description":"The request, pending.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRequest"}}}},"400":{"description":"Unknown action or invalid input (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Approvals"]}},"/workspace/approval-requests/{requestId}":{"get":{"operationId":"workspace.approvalRequests.get","summary":"Check an approval request","description":"The request you filed: pending, denied, completed (the action ran — see `result`), approved (waiting for the CLI to redeem it), failed or expired.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.approvals:read","parameters":[{"schema":{"type":"string","description":"The request's id."},"required":true,"description":"The request's id.","name":"requestId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalRequest"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not one of yours (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Approvals"]}},"/workspace/approval-requests/{requestId}/redeem":{"post":{"operationId":"workspace.approvalRequests.redeem","summary":"Redeem an approved request","description":"Runs an approved, secret-producing action ONCE and returns its secret — to the personal access token that asked, only. The CLI writes it to a file without printing it.","x-mcp":{"expose":false,"reason":"Returns a secret; secrets never enter an agent's conversation — the CLI writes them to a file."},"x-cli":{"command":"workspace approval-requests redeem","args":["requestId"]},"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.approvals:write","parameters":[{"schema":{"type":"string","description":"The request's id."},"required":true,"description":"The request's id.","name":"requestId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"Done; the secret, once.","content":{"application/json":{"schema":{"type":"object","properties":{"request":{"$ref":"#/components/schemas/ApprovalRequest"},"secret":{"type":["string","null"]},"envVar":{"type":["string","null"]}},"required":["request","secret","envVar"]}}}},"400":{"description":"Not approved, already redeemed or expired (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Not yours (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Approvals"]}},"/workspace/usage":{"get":{"operationId":"workspace.usage","summary":"Get your plan's usage this period","description":"How much of each meter the workspace used this period, with the plan's limit for it (null = unlimited). A period is a month from the workspace's billing date: its subscription's (an annual plan refills monthly from its start), else the day the workspace was created.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace:read","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"This period's usage.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUsage"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Workspace"]}},"/workspace/teams":{"get":{"operationId":"workspace.teams.list","summary":"List teams","description":"The workspace's teams with their members' user ids, newest first. Paginate with the opaque `nextCursor`; `limit` is clamped to 1–100 (default 25). Teams are created and staffed in the app.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.teams:read","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25,"example":25,"description":"Items per page, 1–100 (default 25)."},"required":false,"description":"Items per page, 1–100 (default 25).","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque token from a previous page's nextCursor."},"required":false,"description":"Opaque token from a previous page's nextCursor.","name":"cursor","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"One page of teams, newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamPage"}}}},"400":{"description":"Malformed cursor or query (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Workspace"]}},"/workspace/webhook-endpoints":{"get":{"operationId":"workspace.webhookEndpoints.list","summary":"List webhook endpoints","description":"The workspace's outgoing webhook endpoints, newest first, without their signing secrets. A workspace has at most 10, so the list is a single page (`nextCursor` is null).","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:read","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The endpoints.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointPage"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]},"post":{"operationId":"workspace.webhookEndpoints.create","summary":"Add a webhook endpoint","description":"Registers an https URL to receive the workspace's events, signed Svix-compatibly. The response carries the endpoint's signing secret (`whsec_…`) — shown ONCE, store it to verify deliveries. Private and non-https hosts are refused; at most 10 per workspace.","x-mcp":{"expose":false,"reason":"Changes where workspace data is sent. A person configures webhook endpoints (Settings → Webhooks in the app)."},"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:write","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"example":"https://example.com/hooks","description":"The https URL that receives the events."},"description":{"type":"string","maxLength":200,"description":"A note for people managing the endpoint."},"eventTypes":{"type":"array","items":{"type":"string"},"maxItems":100,"example":["workspace.member.joined"],"description":"Only these event types (see event-types); omit for every event."}},"required":["url"]}}}},"responses":{"201":{"description":"The endpoint and its signing secret (shown once).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreated"}}}},"400":{"description":"Invalid request (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]}},"/workspace/webhook-endpoints/{endpointId}":{"get":{"operationId":"workspace.webhookEndpoints.get","summary":"Get a webhook endpoint","description":"One endpoint, without its signing secret: whether it is enabled, its consecutive failures and its last delivery status.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:read","parameters":[{"schema":{"type":"string","example":"we_3f0c…"},"required":true,"name":"endpointId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such endpoint (or delivery) in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]},"delete":{"operationId":"workspace.webhookEndpoints.delete","summary":"Remove a webhook endpoint","description":"Stops all deliveries to the endpoint and deletes it with its secret. Its delivery history goes with it.","x-mcp":{"expose":false,"reason":"Changes where workspace data is sent. A person configures webhook endpoints (Settings → Webhooks in the app)."},"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:write","parameters":[{"schema":{"type":"string","example":"we_3f0c…"},"required":true,"name":"endpointId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"204":{"description":"Removed."},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such endpoint (or delivery) in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]}},"/workspace/webhook-endpoints/{endpointId}/enable":{"post":{"operationId":"workspace.webhookEndpoints.enable","summary":"Re-enable a webhook endpoint","description":"Resumes deliveries to an endpoint that was disabled after repeated failures, keeping its signing secret; the failure count resets.","x-mcp":{"expose":false,"reason":"Changes where workspace data is sent. A person configures webhook endpoints (Settings → Webhooks in the app)."},"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:write","parameters":[{"schema":{"type":"string","example":"we_3f0c…"},"required":true,"name":"endpointId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The re-enabled endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such endpoint (or delivery) in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]}},"/workspace/webhook-endpoints/{endpointId}/test":{"post":{"operationId":"workspace.webhookEndpoints.test","summary":"Send a test event","description":"Sends a `ping` event to the endpoint, signed like every delivery — the way to check an integration verifies and accepts deliveries.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:write","parameters":[{"schema":{"type":"string","example":"we_3f0c…"},"required":true,"name":"endpointId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"202":{"description":"The test delivery was sent or queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryOutcome"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such endpoint (or delivery) in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]}},"/workspace/webhook-endpoints/{endpointId}/deliveries":{"get":{"operationId":"workspace.webhookDeliveries.list","summary":"List an endpoint's deliveries","description":"Delivery history for one endpoint, newest first: each event's status, attempts and last HTTP status (payloads are not returned). Kept for 30 days. Paginate with the opaque `nextCursor`.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:read","parameters":[{"schema":{"type":"string","example":"we_3f0c…"},"required":true,"name":"endpointId","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25,"example":25,"description":"Items per page, 1–100 (default 25)."},"required":false,"description":"Items per page, 1–100 (default 25).","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque token from a previous page's nextCursor."},"required":false,"description":"Opaque token from a previous page's nextCursor.","name":"cursor","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"One page of deliveries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryPage"}}}},"400":{"description":"Invalid request (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such endpoint (or delivery) in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]}},"/workspace/webhook-endpoints/{endpointId}/deliveries/{deliveryId}/redeliver":{"post":{"operationId":"workspace.webhookDeliveries.redeliver","summary":"Redeliver an event","description":"Sends a recorded delivery's event again, as a new delivery with its own history entry; the event id is unchanged, so receivers can deduplicate. The endpoint must be enabled.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:write","parameters":[{"schema":{"type":"string","example":"we_3f0c…"},"required":true,"name":"endpointId","in":"path"},{"schema":{"type":"string","example":"del_8a1b…"},"required":true,"name":"deliveryId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"202":{"description":"The redelivery was sent or queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryOutcome"}}}},"400":{"description":"Invalid request (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such endpoint (or delivery) in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]}},"/workspace/event-types":{"get":{"operationId":"workspace.eventTypes.list","summary":"List event types","description":"Every workspace event a webhook endpoint can subscribe to, with what it means. Pass some as `eventTypes` when adding an endpoint; an endpoint without a list receives them all.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"workspace.webhooks:read","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The event types.","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","example":"workspace.member.joined"},"description":{"type":"string"}},"required":["type","description"]}}},"required":["items"]}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Webhooks"]}},"/limits":{"get":{"operationId":"limits.list","summary":"List limits","description":"The workspace's active limits, newest first (`archived=true`: the archived ones). Filter by `subjectKind` and `action`; paginate with the opaque `nextCursor` token.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:read","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25,"example":25,"description":"Items per page, 1–100 (default 25)."},"required":false,"description":"Items per page, 1–100 (default 25).","name":"limit","in":"query"},{"schema":{"type":"string","description":"Opaque token from a previous page's nextCursor."},"required":false,"description":"Opaque token from a previous page's nextCursor.","name":"cursor","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":100,"description":"Only this kind."},"required":false,"description":"Only this kind.","name":"subjectKind","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":100,"description":"Only this action."},"required":false,"description":"Only this action.","name":"action","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"`true`: the archived limits instead."},"required":false,"description":"`true`: the archived limits instead.","name":"archived","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"One page of limits.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitPage"}}}},"400":{"description":"Malformed cursor or query (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]},"post":{"operationId":"limits.create","summary":"Create a limit","description":"Limits how much of an action a subject may use per window — for example 200 cents of `ai-call` a month for every `user`. Checks enforce it from then on. Names are unique among the environment's active limits. Owners and admins only, for a person's token.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:write","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitInput"}}}},"responses":{"201":{"description":"The new limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Limit"}}}},"400":{"description":"Invalid request, such as a duplicate name (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]}},"/limits/{limitId}":{"get":{"operationId":"limits.get","summary":"Get a limit","description":"One limit: who it applies to, the action, amount and window.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:read","parameters":[{"schema":{"type":"string","example":"lim_3f0c…"},"required":true,"name":"limitId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Limit"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]},"patch":{"operationId":"limits.update","summary":"Change a limit","description":"Changes any of a limit's fields; checks use the new rule within a minute. Owners and admins only, for a person's token.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:write","parameters":[{"schema":{"type":"string","example":"lim_3f0c…"},"required":true,"name":"limitId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitPatch"}}}},"responses":{"200":{"description":"The changed limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Limit"}}}},"400":{"description":"Invalid request, such as a duplicate name (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]}},"/limits/{limitId}/archive":{"post":{"operationId":"limits.archive","summary":"Archive a limit","description":"Stops a limit: checks stop enforcing it within a minute, and it leaves the list. It is archived, not erased — its usage history and credit grants stay, and `POST /v1/limits/{limitId}/restore` brings it back. Owners and admins only, for a person's token.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:write","parameters":[{"schema":{"type":"string","example":"lim_3f0c…"},"required":true,"name":"limitId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"204":{"description":"Archived."},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]}},"/limits/{limitId}/restore":{"post":{"operationId":"limits.restore","summary":"Restore an archived limit","description":"Brings an archived limit back into force — refused while an active limit has its name. Owners and admins only, for a person's token.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:write","parameters":[{"schema":{"type":"string","example":"lim_3f0c…"},"required":true,"name":"limitId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The restored limit.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Limit"}}}},"400":{"description":"Invalid request, such as a duplicate name (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]}},"/limits/sync":{"post":{"operationId":"limits.sync","summary":"Sync limits from a list","description":"Makes the environment's limits match `limits`, by name: creates the missing, changes those that differ (an omitted field means its default) and, with `archiveMissing`, archives active limits the list doesn't name. Running it twice changes nothing the second time. Limitry checks the whole list first, and a problem anywhere changes nothing (400, each problem in `details`); then it writes every change at once. `dryRun` answers the plan without writing. For keeping limits in a file in your repository (`limitry sync`). Owners and admins only, for a person's token.","x-cli":{"shortcut":"sync [file]"},"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:write","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitSyncInput"}}}},"responses":{"200":{"description":"What changed, or with `dryRun`, what would.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitSyncResult"}}}},"400":{"description":"Something in the list is invalid, such as a name twice; nothing was changed (code: invalid_request, each problem in `details`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]}},"/limits/{limitId}/grants":{"get":{"operationId":"limits.grants.list","summary":"List a balance's grants","description":"Credits added to subjects' balances for this limit, newest first.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:read","parameters":[{"schema":{"type":"string","example":"lim_3f0c…"},"required":true,"name":"limitId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The grants.","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LimitGrant"}}},"required":["items"]}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]},"post":{"operationId":"limits.grants.create","summary":"Add credits to a balance","description":"Adds `amount` to one subject's balance — a limit whose window is `total`. A negative `amount` takes credits back (a refund, a chargeback) and needs a `note` saying why; the balance may go below zero, and checks are refused until it is topped up. Owners and admins, or a workspace API key; an agent asks a person (the `limit.grant` approval).","x-mcp":{"expose":false,"reason":"Adding credits gives value away; an agent asks a person (limit.grant approval)"},"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:write","parameters":[{"schema":{"type":"string","example":"lim_3f0c…"},"required":true,"name":"limitId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitGrantInput"}}}},"responses":{"201":{"description":"The grant — the balance is raised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitGrant"}}}},"400":{"description":"Invalid request, such as a duplicate name (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Limits"]}},"/checks":{"post":{"operationId":"checks.create","summary":"Check whether a subject may act","description":"Asks whether `subject` may do `action` at `cost`, given every enabled limit that applies, and — in `consume` mode — uses it. Always 200 for a decision: read `allowed`; `remaining` shows what is left per limit and `retryAfterSeconds` when to try again. An `Idempotency-Key` header makes a retried check return the same decision without using twice. Its API-key check is cached briefly for speed: a revoked key can keep working here for up to 60 seconds.","x-credential-cache":true,"x-cli":{"shortcut":"check <kind>:<id> <action>"},"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"checks:write","parameters":[{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckRequest"}}}},"responses":{"200":{"description":"The decision — allowed or not.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckDecision"}}}},"400":{"description":"Invalid request (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"The workspace is more than 10% past its plan's monthly allowed checks or active subjects (code: plan_limit_reached): no decision — apply the limit's fail mode, as when Limitry is unreachable. The SDK does this for you.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"This Idempotency-Key was used for a different check (code: idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Checks"]}},"/reservations/{reservationId}/extend":{"post":{"operationId":"reservations.extend","summary":"Extend a reservation","description":"Keeps a hold for longer work: it now expires `ttlSeconds` from now (default 300, at most 3600) — call it again as a heartbeat. Only a held reservation can be extended. Its API-key check is cached briefly for speed: a revoked key can keep working here for up to 60 seconds.","x-credential-cache":true,"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"checks:write","parameters":[{"schema":{"type":"string"},"required":true,"name":"reservationId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationExtend"}}}},"responses":{"200":{"description":"The reservation, settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reservation"}}}},"400":{"description":"Already settled the other way, or an invalid cost (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such reservation in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Reservations"]}},"/reservations/{reservationId}/commit":{"post":{"operationId":"reservations.commit","summary":"Commit a reservation","description":"Settles a hold with the ACTUAL amount used (`cost`): less than held gives the rest back at once; more is charged in full — the work happened. A commit after the hold expired still charges `cost`. Repeating a commit answers the same. Its API-key check is cached briefly for speed: a revoked key can keep working here for up to 60 seconds.","x-credential-cache":true,"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"checks:write","parameters":[{"schema":{"type":"string"},"required":true,"name":"reservationId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationCommit"}}}},"responses":{"200":{"description":"The reservation, settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reservation"}}}},"400":{"description":"Already settled the other way, or an invalid cost (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such reservation in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Reservations"]}},"/reservations/{reservationId}/release":{"post":{"operationId":"reservations.release","summary":"Release a reservation","description":"Gives the whole hold back — the work did not happen. Repeating a release answers the same; releasing a committed reservation is refused. Its API-key check is cached briefly for speed: a revoked key can keep working here for up to 60 seconds.","x-credential-cache":true,"security":[{"apiKey":[]},{"pat":[]}],"x-scope":"checks:write","parameters":[{"schema":{"type":"string"},"required":true,"name":"reservationId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The reservation, settled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reservation"}}}},"400":{"description":"Already settled the other way, or an invalid cost (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such reservation in this workspace (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Reservations"]}},"/usage/standing":{"get":{"operationId":"usage.standing","summary":"Get where a subject stands","description":"Every enabled limit on one subject — and on its shared subjects (`shared`, comma-separated `kind:id`, such as `team:team_42`) — with what is used, what is left and when it resets, exact as of now. For showing an end user where they stand: call it from your server with your key, never from a browser. Not a check: nothing is counted. A subject with no limit here answers an empty `limits` list.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:read","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":100,"example":"user","description":"The subject's kind, as your checks send it."},"required":true,"description":"The subject's kind, as your checks send it.","name":"kind","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":200,"example":"usr_123","description":"The subject's id, as your checks send it."},"required":true,"description":"The subject's id, as your checks send it.","name":"id","in":"query"},{"schema":{"type":"string","description":"Shared subjects to include, comma-separated `kind:id` (up to 4).","example":"team:team_42"},"required":false,"description":"Shared subjects to include, comma-separated `kind:id` (up to 4).","name":"shared","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"Where the subject stands.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageStanding"}}}},"400":{"description":"Invalid subject (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Usage"]}},"/usage/subjects":{"get":{"operationId":"usage.subjects","summary":"List who is using a limit now","description":"A limit's subjects in its CURRENT window, most used first: units used, what is left, how many checks were denied — `over` when any were. Up to about a minute behind live checks.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:read","parameters":[{"schema":{"type":"string","example":"lim_3f0c…","description":"The limit."},"required":true,"description":"The limit.","name":"limitId","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"How many subjects, most used first: 1–200. Default 50."},"required":false,"description":"How many subjects, most used first: 1–200. Default 50.","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The subjects.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageBySubject"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Usage"]}},"/usage":{"get":{"operationId":"usage.query","summary":"Get a limit's usage over time","description":"Units used, checks allowed and denied for one limit — across all subjects, or one (`subjectKind` + `subjectId`) — per hour or per day (UTC), every bucket in the range included. Up to about a minute behind live checks. Default: the last 30 days, by day.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:read","parameters":[{"schema":{"type":"string","example":"lim_3f0c…","description":"The limit."},"required":true,"description":"The limit.","name":"limitId","in":"query"},{"schema":{"type":"string","example":"user","description":"With `subjectId`: one subject's usage, not every subject's."},"required":false,"description":"With `subjectId`: one subject's usage, not every subject's.","name":"subjectKind","in":"query"},{"schema":{"type":"string","example":"usr_123","description":"With `subjectKind`: one subject's usage."},"required":false,"description":"With `subjectKind`: one subject's usage.","name":"subjectId","in":"query"},{"schema":{"type":"string","format":"date-time","example":"2026-10-01T00:00:00Z","description":"Start of the range (ISO 8601). Default: 30 days before `to`."},"required":false,"description":"Start of the range (ISO 8601). Default: 30 days before `to`.","name":"from","in":"query"},{"schema":{"type":"string","format":"date-time","example":"2026-10-31T00:00:00Z","description":"End of the range (ISO 8601). Default: now."},"required":false,"description":"End of the range (ISO 8601). Default: now.","name":"to","in":"query"},{"schema":{"type":"string","enum":["hour","day"],"default":"day","description":"One bucket per `hour` or per `day` (UTC). Default: day."},"required":false,"description":"One bucket per `hour` or per `day` (UTC). Default: day.","name":"granularity","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The series.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSeries"}}}},"400":{"description":"Invalid range (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Usage"]}},"/subjects/{subjectKind}/{subjectId}":{"get":{"operationId":"subjects.get","summary":"Get a subject","description":"A subject's anchor: when its `anchor` limits' periods start from. A subject is yours (a user, a team, an agent) and exists once a check names it.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:read","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":100,"example":"team"},"required":true,"name":"subjectKind","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":200,"example":"team_42"},"required":true,"name":"subjectId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"responses":{"200":{"description":"The subject.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subject"}}}},"400":{"description":"Unknown environment (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Subjects"]},"patch":{"operationId":"subjects.update","summary":"Set a subject's anchor","description":"Sets when a subject's `anchor` limits' periods start from: typically its subscription's start date, from your billing system's webhook, so its allowance refills on its own billing day (monthly for an annual plan, too). Owners and admins only, for a person's token.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:write","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":100,"example":"team"},"required":true,"name":"subjectKind","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":200,"example":"team_42"},"required":true,"name":"subjectId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectUpdate"}}}},"responses":{"200":{"description":"The subject, with its new anchor.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subject"}}}},"400":{"description":"Invalid anchor (code: invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Subjects"]}},"/subjects/{subjectKind}/{subjectId}/reset":{"post":{"operationId":"subjects.reset","summary":"Reset a subject's limits","description":"Refills one limit on a subject (`limitId`), or every limit on it (`{}`), at once: for goodwill, a promotion or support. The schedule doesn't move: the next refill is still the usual one. A balance goes back to its amount; a concurrent limit is skipped. Send an Idempotency-Key and a repeat resets once. Owners and admins only, for a person's token.","security":[{"apiKey":[]},{"pat":[]}],"x-scope":"limits:write","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":100,"example":"team"},"required":true,"name":"subjectKind","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":200,"example":"team_42"},"required":true,"name":"subjectId","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","example":"acme"},"required":false,"description":"Workspace slug. REQUIRED when authenticating with a personal access token (400 without it); ignored for API keys.","name":"x-workspace","in":"header"},{"schema":{"type":"string","minLength":1,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","example":"live"},"required":false,"description":"The environment the request acts in; without it, the product's default. An API key bound to an environment always acts in its own (403 naming another); an unknown environment is 400.","name":"x-environment","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectReset"}}}},"responses":{"200":{"description":"What was reset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectResetResult"}}}},"401":{"description":"Missing, malformed, invalid, revoked, or expired credential — API key or personal access token (code: unauthorized).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"A personal access token that cannot act in the named workspace (unknown slug, not a member, or excluded by the token's scopes), is not granted this route's scope, or lacks the workspace role the route requires (code: forbidden).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"No such limit on this subject (code: not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Per-key quota exhausted (code: rate_limited); retry after the Retry-After header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Checks are unavailable (code: internal_error).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"tags":["Subjects"]}}},"webhooks":{},"tags":[{"name":"Checks"},{"name":"Reservations"},{"name":"Limits"},{"name":"Subjects"},{"name":"Usage"},{"name":"Workspace"},{"name":"Webhooks"},{"name":"Approvals"},{"name":"Audit events"},{"name":"Personal access tokens"}]}