Requests and quota API
Lists the API routes that show quota and usage and manage requests for more.
Last updated
On this page
GET /v1/quota
The ceiling for one owner and the usage counted against it, computed on every request. Query ?owner=: absent means you; a team slug you belong to is allowed. An owner with no quota of its own gets the default for its kind.
Response: 200.
{ "owner": "karthik", "limit": { "workspaces": 5, "environments": 2, "snapshots": 20, "diskGb": 100, "cpu": 40, "memoryGb": 80, "sandboxes": 5 }, "used": { "workspaces": 2, "environments": 1, "snapshots": 6, "diskGb": 58, "cpu": 8, "memoryGb": 16, "sandboxes": 0, "diskUsedAt": "2026-10-18T06:12:00Z" }, "disk": { "usedGb": 58, "limitGb": 100, "usedAt": "2026-10-18T06:12:00Z" }}| Field | Type | Meaning |
|---|---|---|
owner | string | whose quota this is |
limit | object | the ceiling in seven dimensions: workspaces, environments, snapshots, diskGb, cpu (whole cores), memoryGb, sandboxes |
used | object | the same seven dimensions, as counted now. diskUsedAt is the oldest measurement among the volumes counted, an RFC 3339 string, and is omitted when no volume has been measured yet |
disk | object | usedGb and limitGb again, and usedAt: the disk figure is what the volumes occupy as their nodes last measured it, not a live figure |
Workspaces, environments, snapshots, cpu, memory and sandboxes count live objects. Disk counts what every volume of the owner occupies, detached volumes included, at least 1 GiB each. A create that passes a limit is refused with 409 naming the dimension, see errors.
Errors:
403—session tools act only for {you} and {team}, for a session tool token naming another owner.404—?owner=names a team you are not in.
GET /v1/regions
Lists the regions, for any signed-in caller. Choose from this list when you create a team or ask for a move.
Response: 200.
[{ "id": "centralindia", "name": "Central India", "status": "active" }]| Field | Type | Meaning |
|---|---|---|
id | string | the name to use wherever a region is named |
name | string | the display name |
status | string | a region can be named in a team or in a request only when this is active |
GET /v1/builders/me
The state of your image builder, to tell why a build waits. You cannot start or stop it: it starts when a build needs it and stops when idle. Query ?team=: absent means your personal builder; a team slug you belong to means the team's.
Response: 200.
{ "id": "bld-karthik", "state": "running", "ready": true, "conditions": [ { "type": "Ready", "status": "True", "reason": "Running", "message": "", "lastTransitionTime": "2026-10-18T06:12:00Z" } ]}| Field | Type | Meaning |
|---|---|---|
id | string | bld- and the owner slug |
state | string | creating, running, stopped, error or deleted. A builder that is meant to be stopped and is not running reads stopped |
ready | boolean | true only while the builder is running and its build service answers. A stopped builder is not ready |
conditions | object[] | Status conditions of the builder: type, status, reason, message, lastTransitionTime and sometimes observedGeneration |
Errors:
403— a session tool token naming a team that is not its own.404—?team=names a team you are not in; or the builder has not been created yet, which is what you see before your first build.
The request document
Every request route returns this object. An absent block is left out. decidedBy, decidedAt, note, resolution and createdAt are null until they have a value.
{ "id": "req-0a1b2c3d4e5f6a7b", "owner": "acme", "kind": "quota", "requestedBy": "karthik", "reason": "the build farm needs more environments", "quota": { "environments": 12, "diskGb": 800 }, "state": "pending", "decidedBy": null, "decidedAt": null, "note": null, "resolution": null, "createdAt": "2026-10-18T06:12:00Z"}| Field | Type | Meaning |
|---|---|---|
id | string | req- and 16 hex digits |
owner | string | the person or team the request is for |
kind | string | quota, access, region or other |
requestedBy | string | your handle, set from your token, never from the body |
reason | string | what you wrote |
quota | object, omitted | for quota: the dimensions you want, see below |
access | object, omitted | for access: { "team": "acme", "role": "member" } |
region | object, omitted | for region: { "region": "centralindia" } |
other | object, omitted | for other: { "title": "…", "body": "…" } |
state | string | pending, approved or denied |
decidedBy | string or null | the superadmin who decided |
decidedAt | string or null | RFC 3339 |
note | string or null | the decider's message to you |
resolution | string or null | what approving did, in a sentence: the quota written, the role set, the region recorded, or the text a superadmin typed for an other |
createdAt | string or null | RFC 3339 |
POST /v1/requests
Opens a request. An owner has one pending request per kind; a second of the same kind is refused until the first is decided.
| Field | Type | Required | Rule |
|---|---|---|---|
kind | string | yes | quota, access, region or other |
reason | string | no | Free text; empty is accepted |
owner | string | no | Who the request is for. Absent means you. A team is allowed only for a member whose role is admin or owner |
quota | object | for quota | workspaces, environments, snapshots, diskGb, cpu, memoryGb, sandboxes. Every field is optional and a request raises only the ones it names |
access | object | for access | team (the team you want into, or a different role in) and role: member, admin or owner |
region | object | for region | region only: the id to move the owner to, an active one |
other | object | for other | title and body |
Exactly the block of the kind, and no other. For an access request owner is you, and access.team names the team.
{ "kind": "quota", "owner": "acme", "reason": "the build farm needs more environments", "quota": { "environments": 12, "diskGb": 800 } }Response: 201, the request document, pending.
{ "id": "req-0a1b2c3d4e5f6a7b", "owner": "acme", "kind": "quota", "requestedBy": "karthik", "reason": "the build farm needs more environments", "quota": { "environments": 12, "diskGb": 800 }, "state": "pending", "decidedBy": null, "decidedAt": null, "note": null, "resolution": null, "createdAt": "2026-10-18T06:12:00Z"}A region request moves the whole owner. Approving it is refused (409) while the owner holds any workspace or environment.
Errors:
403—only a team admin can request a team quota: you are a member of the team, not an admin.404— the owner is a team you are not in.409—a request is already pendingfor this owner and kind.422—kind {kind} needs a {kind} block;only the {kind} block belongs on a {kind} request;role must be member, admin or owner; or, as JSON,unknown regionwhen the region does not exist or is not active.503—team lookup not configured on this node, for a team owner.
GET /v1/requests
Lists your requests and your teams' requests, newest first. Query ?owner= narrows to one owner that you can act for.
Response: 200, an array of request documents.
Errors:
404—?owner=is a team you are not in.
GET /v1/requests/{id}
Reads one request, whichever its state.
Response: 200, the request document.
Errors:
404— there is no such request, or its owner is not one that you can act for. The two read the same.