State Handles
State handles provide explicit persistence for built-in stateful tools (kv.*, tasks.write) used with /responses.
Create a State Handle
POST /api/v1/state-handles
Authentication
Requires either:
- Secret key (
mr_sk_*): Backend use with full project access - Owner bearer token: Account session token from
/auth/login(dashboard/server-side) - Customer bearer token: Customer scoped token for data-plane access
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
ttl_seconds |
integer | No | Optional time-to-live in seconds (1 to 31,536,000; max 1 year) |
Response
| Field | Type | Description |
|---|---|---|
id |
string | State handle ID (UUID) |
project_id |
string | Project ID that owns the handle |
customer_id |
string | Customer ID (present for customer-scoped tokens) |
created_at |
string | Creation timestamp (UTC) |
expires_at |
string | Expiration timestamp (UTC), if a TTL was set |
Example
curl -X POST https://api.modelrelay.ai/api/v1/state-handles \
-H "Authorization: Bearer mr_sk_..." \
-H "Content-Type: application/json" \
-d '{"ttl_seconds":86400}'
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"project_id": "11111111-2222-3333-4444-555555555555",
"created_at": "2025-01-15T10:30:00.000Z",
"expires_at": "2025-01-16T10:30:00.000Z"
}
Use the returned id as state_id in /responses to persist tool state across calls.
List State Handles
GET /api/v1/state-handles
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
limit |
integer | No | Max results (default 50, max 100) |
offset |
integer | No | Offset for pagination |
Response
{
"state_handles": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"project_id": "11111111-2222-3333-4444-555555555555",
"created_at": "2025-01-15T10:30:00.000Z",
"expires_at": "2025-01-16T10:30:00.000Z"
}
],
"next_cursor": "50"
}
Delete a State Handle
DELETE /api/v1/state-handles/{state_id}
Response
Returns 204 No Content when the handle is deleted.