# Shared quotas (allowances)

> Fixed-window shared quotas with durable FIFO waiting. The API calls them allowances.

Source: https://docs.getrunstate.com/api/quotas/

<!-- Generated by apps/docs/scripts/gen-api.mjs from packages/contracts/openapi.yaml. Do not edit. -->

All paths are relative to the API base URL (`https://api.getrunstate.com`) and require `Authorization: Bearer <api key>`. See [the API overview](https://docs.getrunstate.com/api/) for authentication, idempotency and the error envelope.

## GET /allowances

```http
GET /v1/spaces/{spaceId}/allowances
```

Read-only allowance list with current-window balances.

- **Key permission:** `coordination_read`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |

**Responses**

| Status | Meaning |
| --- | --- |
| `200` | Allowances |

```bash
curl -X GET "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/allowances" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY"
```

## POST /allowances

```http
POST /v1/spaces/{spaceId}/allowances
```

Configure a shared quota (fixed-window consumable units)

- **Key permission:** `resource_config`
- **Idempotency-Key header:** required
- **TypeScript SDK:** `rs.quotas.ensure()`
- **Python SDK:** `rs.quotas.ensure()`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |

**Request body** (JSON)

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `unitsLimit` | integer | yes | min 1 |
| `windowSeconds` | integer | yes | min 1 |

**Responses**

| Status | Meaning |
| --- | --- |
| `201` | Created allowance |
| `409` | Error envelope `{"error":{"code","message","requestId"}}` |

```bash
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/allowances" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"name":"<name>","unitsLimit":1,"windowSeconds":1}'
```

## GET /allowances/{id}

```http
GET /v1/spaces/{spaceId}/allowances/{id}
```

Current-window balance and cooldown for one allowance.

- **Key permission:** `coordination_read`
- **TypeScript SDK:** `quota.status()`
- **Python SDK:** `quota.status()`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |
| `id` | string (uuid) | required |

**Responses**

| Status | Meaning |
| --- | --- |
| `200` | Allowance status |
| `404` | Error envelope `{"error":{"code","message","requestId"}}` |

```bash
curl -X GET "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/allowances/<id>" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY"
```

## POST /allowances/{id}/consume

```http
POST /v1/spaces/{spaceId}/allowances/{id}/consume
```

Consume window units now (work_key dedup applies)

- **Key permission:** `resource_config`
- **Idempotency-Key header:** required
- **TypeScript SDK:** `run.quota(name).tryTake() / .take()`
- **Python SDK:** `run.quota(name).try_take() / .take()`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |
| `id` | string (uuid) | required |

**Request body** (JSON)

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `scopeId` | string (uuid) | yes |  |
| `units` | integer | yes | min 1 |
| `holder` | string | yes |  |
| `workKey` | string | no | length 1–512 |

**Responses**

| Status | Meaning |
| --- | --- |
| `201` | Consumption recorded |
| `429` | Error envelope `{"error":{"code","message","requestId"}}` |

```bash
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/allowances/<id>/consume" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"scopeId":"<run id>","units":1,"holder":"worker-1"}'
```

## POST /allowances/{id}/wait

```http
POST /v1/spaces/{spaceId}/allowances/{id}/wait
```

Enqueue durably for units; strict FIFO, head-of-line blocking.

- **Key permission:** `resource_config`
- **Idempotency-Key header:** required
- **TypeScript SDK:** `quota.take() (when the window is exhausted)`
- **Python SDK:** `quota.take() (when the window is exhausted)`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |
| `id` | string (uuid) | required |

**Request body** (JSON)

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `scopeId` | string (uuid) | yes |  |
| `units` | integer | yes | min 1 |
| `holder` | string | yes |  |
| `ttlSeconds` | integer | no | 5–3600 |

**Responses**

| Status | Meaning |
| --- | --- |
| `201` | waiterId and state (GRANTED on fast path) |

```bash
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/allowances/<id>/wait" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"scopeId":"<run id>","units":1,"holder":"worker-1"}'
```

## POST /allowances/{id}/cooldown

```http
POST /v1/spaces/{spaceId}/allowances/{id}/cooldown
```

Provider-reported backoff; blocks consumption and grants until expiry.

- **Key permission:** `resource_config`
- **TypeScript SDK:** `quota.cooldown()`
- **Python SDK:** `quota.cooldown()`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |
| `id` | string (uuid) | required |

**Request body** (JSON)

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `seconds` | integer | yes | 1–3600 |
| `reason` | string | no | max length 512 |

**Responses**

| Status | Meaning |
| --- | --- |
| `200` | cooldownUntil |
| `404` | Error envelope `{"error":{"code","message","requestId"}}` |

```bash
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/allowances/<id>/cooldown" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"seconds":1}'
```

## GET /allowance-waiters/{id}

```http
GET /v1/spaces/{spaceId}/allowance-waiters/{id}
```

Durable allowance waiter state.

- **Key permission:** `coordination_read`
- **TypeScript SDK:** `quota.take() (polls its waiter)`
- **Python SDK:** `quota.take() (polls its waiter)`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |
| `id` | string (uuid) | required |

**Responses**

| Status | Meaning |
| --- | --- |
| `200` | Waiter |
| `404` | Error envelope `{"error":{"code","message","requestId"}}` |

```bash
curl -X GET "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/allowance-waiters/<id>" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY"
```

## POST /allowance-waiters/{id}/cancel

```http
POST /v1/spaces/{spaceId}/allowance-waiters/{id}/cancel
```

Cancel a WAITING allowance waiter (cleanup, ungated)

- **Key permission:** `coordination_write`
- **TypeScript SDK:** `quota.take() (on timeout, best effort)`
- **Python SDK:** `quota.take() (on timeout, best effort)`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |
| `id` | string (uuid) | required |

**Responses**

| Status | Meaning |
| --- | --- |
| `200` | CANCELLED |
| `409` | Error envelope `{"error":{"code","message","requestId"}}` |

```bash
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/allowance-waiters/<id>/cancel" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
```
