Every run registered in the workspace, oldest first, as its header - objective, agent, scope, status, executing device, results, economics, rating.
API reference sections
HTTP API reference
Runs and schedules
Work delegated to an agent as runs, their history and MCP endpoint, and repeating schedules.
20 operations. The contract has no example values, so example bodies are generated from each schema: every field is shown with a placeholder of its type.
GET/v1/runs
- Authorization
- Bearer token with
runs.read - Operation id
- runs_list
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| workspacerequired | query | string (uuid) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | ListRunsResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"runs": [
{
"run": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"version": "00000000-0000-4000-8000-000000000000",
"kind": "document"
}
],
"grants": [],
"status": {
"state": "created"
},
"failure_reason": "capability_not_negotiated",
"environment": {
"device": "string",
"kind": "local_device"
},
"artifacts": [],
"economics": {
"orchestrator_turns": 0,
"human_turns": 0,
"turns_with_usage": 0,
"input": {
"known": 0,
"unavailable_turns": 0
},
"output": {
"known": 0,
"unavailable_turns": 0
},
"cached_input": {
"known": 0,
"unavailable_turns": 0
},
"tool_calls": 0,
"interventions": 0,
"elapsed_ms": null,
"models": [],
"complete": false
},
"rating": {
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"rated_at_ms": 0
},
"origin": {
"origin": "manual"
}
}
],
"sessions": {},
"documents": {},
"trashed": [
{
"header": {
"run": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"version": "00000000-0000-4000-8000-000000000000",
"kind": "document"
}
],
"grants": [],
"status": {
"state": "created"
},
"failure_reason": "capability_not_negotiated",
"environment": {
"device": "string",
"kind": "local_device"
},
"artifacts": [],
"economics": {
"orchestrator_turns": 0,
"human_turns": 0,
"turns_with_usage": 0,
"input": {
"known": 0,
"unavailable_turns": 0
},
"output": {
"known": 0,
"unavailable_turns": 0
},
"cached_input": {
"known": 0,
"unavailable_turns": 0
},
"tool_calls": 0,
"interventions": 0,
"elapsed_ms": null,
"models": [],
"complete": false
},
"rating": {
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"rated_at_ms": 0
},
"origin": {
"origin": "manual"
}
},
"document": {},
"trashed_at_ms": 0,
"artifacts": "keep"
}
]
}curl "http://127.0.0.1:$PORT/v1/runs?workspace=$WORKSPACE" \
-H "Authorization: Bearer $KORU_TOKEN"POST/v1/runs
202 with the run's id, its Run document and its status. The client mints the run id, so a retried request is the same run. The request is durable - intent, captured context and Run document - before this answers; the start follows on the worker.
- Authorization
- Bearer token with
runs.write - Operation id
- runs_create
Request body (required)
application/json CreateRunRequest
| Field | Type | Description |
|---|---|---|
| runrequired | RunId | |
| workspacerequired | WorkspaceId | The workspace the Run document is registered in. |
| requested_byrequired | ActorRef | |
| objectiverequired | Objective | What a person asked the agent to do (D9). The one field of a run that is a prompt, and therefore the one field that must never be reported. |
| agentrequired | SessionProfileKey | Stable identity for a launch profile. Built-ins remain readable across machines; user-created profiles are opaque UUIDs. |
| requested_model | DelegateModelName or null | Explicit model intent. New clients use the v2 create route when present. |
| scoperequired | WorkspaceScope | The working folder a run is admitted to (P1.5) and started in. Identity is a [ `None` is unreachable at admission. It exists so a request can be built before a scope is chosen and so the modal has a state to refuse; P1.5 makes it impossible to start a run with it. M4 adds git shapes - a worktree per run - as new variants, which is why this is an enum. |
| context | array of RunContextItem | Default |
| grants | array of WorkspaceId | The workspaces the run's tools may reach (D28). Empty denies all workspace access. Default |
{
"run": "00000000-0000-4000-8000-000000000000",
"workspace": {},
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [],
"grants": []
}Responses
| Status | Description | Body |
|---|---|---|
| 202 | See above. | CreateRunResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"run": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"status": {
"state": "created"
}
}curl -X POST "http://127.0.0.1:$PORT/v1/runs" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"run": "00000000-0000-4000-8000-000000000000",
"workspace": {},
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [],
"grants": []
}'POST/v2/runs
202 with the run's id, its Run document and its status. The client mints the run id, so a retried request is the same run. The request is durable - intent, captured context and Run document - before this answers; the start follows on the worker.
- Authorization
- Bearer token with
runs.write - Operation id
- runs_create_v2
Request body (required)
application/json CreateRunRequest
| Field | Type | Description |
|---|---|---|
| runrequired | RunId | |
| workspacerequired | WorkspaceId | The workspace the Run document is registered in. |
| requested_byrequired | ActorRef | |
| objectiverequired | Objective | What a person asked the agent to do (D9). The one field of a run that is a prompt, and therefore the one field that must never be reported. |
| agentrequired | SessionProfileKey | Stable identity for a launch profile. Built-ins remain readable across machines; user-created profiles are opaque UUIDs. |
| requested_model | DelegateModelName or null | Explicit model intent. New clients use the v2 create route when present. |
| scoperequired | WorkspaceScope | The working folder a run is admitted to (P1.5) and started in. Identity is a [ `None` is unreachable at admission. It exists so a request can be built before a scope is chosen and so the modal has a state to refuse; P1.5 makes it impossible to start a run with it. M4 adds git shapes - a worktree per run - as new variants, which is why this is an enum. |
| context | array of RunContextItem | Default |
| grants | array of WorkspaceId | The workspaces the run's tools may reach (D28). Empty denies all workspace access. Default |
{
"run": "00000000-0000-4000-8000-000000000000",
"workspace": {},
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [],
"grants": []
}Responses
| Status | Description | Body |
|---|---|---|
| 202 | See above. | CreateRunResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"run": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"status": {
"state": "created"
}
}curl -X POST "http://127.0.0.1:$PORT/v2/runs" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"run": "00000000-0000-4000-8000-000000000000",
"workspace": {},
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [],
"grants": []
}'GET/v1/runs/{run}
The header, what the answering device holds, the current state of every context pin, and a window of the timeline by index, oldest first (from, len up to 500). workspace names the workspace a run this device did not create is registered in - how a second device reads a run that reached it by sync.
- Authorization
- Bearer token with
runs.read - Operation id
- runs_run
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| runrequired | path | string (uuid) | |
| from | query | integer (uint64) | Default |
| len | query | integer (uint32, <= 500) | Default |
| workspace | query | string (uuid) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | RunView |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"document": "00000000-0000-4000-8000-000000000000",
"header": {
"run": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"version": "00000000-0000-4000-8000-000000000000",
"kind": "document"
}
],
"grants": [],
"status": {
"state": "created"
},
"failure_reason": "capability_not_negotiated",
"environment": {
"device": "string",
"kind": "local_device"
},
"artifacts": [],
"economics": {
"orchestrator_turns": 0,
"human_turns": 0,
"turns_with_usage": 0,
"input": {
"known": 0,
"unavailable_turns": 0
},
"output": {
"known": 0,
"unavailable_turns": 0
},
"cached_input": {
"known": 0,
"unavailable_turns": 0
},
"tool_calls": 0,
"interventions": 0,
"elapsed_ms": null,
"models": [],
"complete": false
},
"rating": {
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"rated_at_ms": 0
},
"origin": {
"origin": "manual"
}
},
"execution": {
"device": "string",
"session": "00000000-0000-4000-8000-000000000000",
"run_workspace": "string"
},
"context": [],
"timeline": {
"total": 0,
"from": 0,
"items": [
{
"id": "00000000-0000-4000-8000-000000000000",
"kind": {
"step": "run_created"
},
"refs": [],
"at_ms": 0
}
]
}
}curl "http://127.0.0.1:$PORT/v1/runs/$RUN" \
-H "Authorization: Bearer $KORU_TOKEN"POST/v1/runs/{run}/cancel
The header after the cancellation was asked for. A run mid-turn stays running until the provider answers the cancellation; the stream carries the end. Never a takeover - that is the session's own handover verb (D36).
- Authorization
- Bearer token with
runs.write - Operation id
- runs_cancel
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| runrequired | path | string (uuid) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | CancelRunResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"header": {
"run": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"version": "00000000-0000-4000-8000-000000000000",
"kind": "document"
}
],
"grants": [],
"status": {
"state": "created"
},
"failure_reason": "capability_not_negotiated",
"environment": {
"device": "string",
"kind": "local_device"
},
"artifacts": [],
"economics": {
"orchestrator_turns": 0,
"human_turns": 0,
"turns_with_usage": 0,
"input": {
"known": 0,
"unavailable_turns": 0
},
"output": {
"known": 0,
"unavailable_turns": 0
},
"cached_input": {
"known": 0,
"unavailable_turns": 0
},
"tool_calls": 0,
"interventions": 0,
"elapsed_ms": null,
"models": [],
"complete": false
},
"rating": {
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"rated_at_ms": 0
},
"origin": {
"origin": "manual"
}
}
}curl -X POST "http://127.0.0.1:$PORT/v1/runs/$RUN/cancel" \
-H "Authorization: Bearer $KORU_TOKEN"POST/v2/runs/{run}/resume
The header after the fresh attempt began. Refused with not_interrupted unless the run is interrupted, with attempt_live when the earlier attempt's session is still running, with source_in_trash or source_unavailable when a source the run was given no longer resolves for anything new (D48), and with prior_attempt_unknown when nothing proved the earlier attempt stopped - that one needs {"confirm": true} from a person. The body is optional and every field defaults.
- Authorization
- Bearer token with
runs.write - Operation id
- runs_resume_v2
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| runrequired | path | string (uuid) |
Request body
application/json ResumeRunRequest
| Field | Type | Description |
|---|---|---|
| confirm | boolean | Default |
{
"confirm": false
}Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | ResumeRunResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"header": {
"run": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"version": "00000000-0000-4000-8000-000000000000",
"kind": "document"
}
],
"grants": [],
"status": {
"state": "created"
},
"failure_reason": "capability_not_negotiated",
"environment": {
"device": "string",
"kind": "local_device"
},
"artifacts": [],
"economics": {
"orchestrator_turns": 0,
"human_turns": 0,
"turns_with_usage": 0,
"input": {
"known": 0,
"unavailable_turns": 0
},
"output": {
"known": 0,
"unavailable_turns": 0
},
"cached_input": {
"known": 0,
"unavailable_turns": 0
},
"tool_calls": 0,
"interventions": 0,
"elapsed_ms": null,
"models": [],
"complete": false
},
"rating": {
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"rated_at_ms": 0
},
"origin": {
"origin": "manual"
}
}
}curl -X POST "http://127.0.0.1:$PORT/v2/runs/$RUN/resume" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"confirm": false
}'POST/v1/runs/{run}/rate
The header carrying the rating. One gesture - good or not good - with an optional note that lives in the run's own content and reaches no event and no metric (D44). Refused with wrong_status while the run is still working.
- Authorization
- Bearer token with
runs.write - Operation id
- runs_rate
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| runrequired | path | string (uuid) |
Request body (required)
application/json RateRunRequest
| Field | Type | Description |
|---|---|---|
| ratingrequired | Rating | One gesture on a finished run (D44): good or not good. An unrated run is a normal state, which is why the header holds an |
| note | RatingNote or null | |
| rated_byrequired | ActorRef |
{
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
}
}Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | RateRunResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"header": {
"run": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"version": "00000000-0000-4000-8000-000000000000",
"kind": "document"
}
],
"grants": [],
"status": {
"state": "created"
},
"failure_reason": "capability_not_negotiated",
"environment": {
"device": "string",
"kind": "local_device"
},
"artifacts": [],
"economics": {
"orchestrator_turns": 0,
"human_turns": 0,
"turns_with_usage": 0,
"input": {
"known": 0,
"unavailable_turns": 0
},
"output": {
"known": 0,
"unavailable_turns": 0
},
"cached_input": {
"known": 0,
"unavailable_turns": 0
},
"tool_calls": 0,
"interventions": 0,
"elapsed_ms": null,
"models": [],
"complete": false
},
"rating": {
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"rated_at_ms": 0
},
"origin": {
"origin": "manual"
}
}
}curl -X POST "http://127.0.0.1:$PORT/v1/runs/$RUN/rate" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
}
}'POST/v1/runs/{run}/trash
The header and the Run document. This is half of the gesture: a run is a document of the workspace's manifest and putting it in the trash is that document's move into the workspace's bin, which is the caller's to make -- reversible, synced, and exactly what happens to every other document in Koru. What this does is the half only the worker can: refuse a run that is still working with wrong_status (cancel it first -- trashing something still writing into a folder is the one case where the reversible operation is not), and remember what the person said should happen to the run's results when the trash is emptied. Nothing on disk and nothing in the artifact store changes. The body is optional and its one field defaults to keep.
- Authorization
- Bearer token with
runs.write - Operation id
- runs_trash
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| runrequired | path | string (uuid) |
Request body
application/json TrashRunRequest
| Field | Type | Description |
|---|---|---|
| artifacts | ArtifactDisposition | Default |
{
"artifacts": "keep"
}Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | TrashRunResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"header": {
"run": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"version": "00000000-0000-4000-8000-000000000000",
"kind": "document"
}
],
"grants": [],
"status": {
"state": "created"
},
"failure_reason": "capability_not_negotiated",
"environment": {
"device": "string",
"kind": "local_device"
},
"artifacts": [],
"economics": {
"orchestrator_turns": 0,
"human_turns": 0,
"turns_with_usage": 0,
"input": {
"known": 0,
"unavailable_turns": 0
},
"output": {
"known": 0,
"unavailable_turns": 0
},
"cached_input": {
"known": 0,
"unavailable_turns": 0
},
"tool_calls": 0,
"interventions": 0,
"elapsed_ms": null,
"models": [],
"complete": false
},
"rating": {
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"rated_at_ms": 0
},
"origin": {
"origin": "manual"
}
},
"document": "00000000-0000-4000-8000-000000000000"
}curl -X POST "http://127.0.0.1:$PORT/v1/runs/$RUN/trash" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"artifacts": "keep"
}'POST/v1/runs/{run}/restore
The header and the Run document, which the caller moves back out of the workspace's bin. Nothing was deleted, so the run comes back whole; what this forgets is the decision about its results.
- Authorization
- Bearer token with
runs.write - Operation id
- runs_restore
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| runrequired | path | string (uuid) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | RestoreRunResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"header": {
"run": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"context": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"version": "00000000-0000-4000-8000-000000000000",
"kind": "document"
}
],
"grants": [],
"status": {
"state": "created"
},
"failure_reason": "capability_not_negotiated",
"environment": {
"device": "string",
"kind": "local_device"
},
"artifacts": [],
"economics": {
"orchestrator_turns": 0,
"human_turns": 0,
"turns_with_usage": 0,
"input": {
"known": 0,
"unavailable_turns": 0
},
"output": {
"known": 0,
"unavailable_turns": 0
},
"cached_input": {
"known": 0,
"unavailable_turns": 0
},
"tool_calls": 0,
"interventions": 0,
"elapsed_ms": null,
"models": [],
"complete": false
},
"rating": {
"rating": "good",
"note": "string",
"rated_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"rated_at_ms": 0
},
"origin": {
"origin": "manual"
}
},
"document": "00000000-0000-4000-8000-000000000000"
}curl -X POST "http://127.0.0.1:$PORT/v1/runs/$RUN/restore" \
-H "Authorization: Bearer $KORU_TOKEN"POST/v1/runs/{run}/purge
Everything this device holds about the run -- its ledger rows, its authority record, and its working folder when Koru made that folder. A run scoped to a project ran inside the person's own repository, and that directory is left exactly alone: folder says kept, removed or absent, because a trash that quietly did less than it offered teaches somebody that it did more. artifacts_retired is how many result families went, which is none unless the person asked for them to go with the run. Refused with run_folder_not_removed when the filesystem would not remove a folder Koru made -- nothing is changed and the run stays in the trash. The Run document is the caller's to remove once this has answered.
- Authorization
- Bearer token with
runs.write - Operation id
- runs_purge
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| runrequired | path | string (uuid) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | PurgeRunResponse |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
{
"run": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"folder": "removed",
"artifacts_retired": 0
}curl -X POST "http://127.0.0.1:$PORT/v1/runs/$RUN/purge" \
-H "Authorization: Bearer $KORU_TOKEN"GET/v1/runs/{run}/stream
text/event-stream of run_stream_item events: every history entry after after with its index, then live entries as they are written, every status change, and closed when the run ended. workspace names the workspace a run this device did not create is registered in.
- Authorization
- Bearer token with
runs.read - Operation id
- runs_stream
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| runrequired | path | string (uuid) | |
| after | query | integer (uint64) | |
| workspace | query | string (uuid) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | RunStreamItemtext/event-stream |
| 400 | The request body, query or path identity is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the operation's run scope | DelegateFailure |
| 404 | No run has that id on this device | DelegateFailure |
| 409 | The run is not in a status the operation applies to, its earlier attempt is still live, or its prior attempt is unknown and a person has not confirmed the resume | DelegateFailure |
| 413 | The request body exceeds the route limit | DelegateFailure |
| 422 | A context item could not be captured, or a source the run was given is now in the trash or unavailable (D48) | DelegateFailure |
| 503 | The delegate worker is not answering | DelegateFailure |
curl "http://127.0.0.1:$PORT/v1/runs/$RUN/stream" \
-N \
-H "Authorization: Bearer $KORU_TOKEN"POST/v1/schedules/pause
200 with the canonical paused schedule projection. A claimed Run is not cancelled.
- Authorization
- Bearer token with
runs.write - Operation id
- schedules_pause
Request body (required)
application/json PauseScheduleRequest
| Field | Type | Description |
|---|---|---|
| schedulerequired | ScheduleId | |
| workspacerequired | WorkspaceId | |
| expected_revisionrequired | integer (uint32, >= 0) |
{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"expected_revision": 0
}Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | PauseScheduleResponse |
| 400 | The request body or workspace query is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the required delegation scope | DelegateFailure |
| 404 | The schedule is missing or belongs to another workspace | DelegateFailure |
| 409 | The observed name is stale, or the schedule is retired or read-only | DelegateFailure |
| 413 | The schedule request exceeds the body limit | DelegateFailure |
| 503 | The delegate worker or schedule store is not answering | DelegateFailure |
{
"schedule": {
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"name": "string",
"header": {
"schedule": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"initial_owner": "string",
"definition": {
"revision": 0,
"effective_at_ms": 0,
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
},
"lifecycle": "active"
}
},
"state": {
"owner": "string",
"state": "active"
},
"next_firing": {
"at_ms": 0,
"kind": "exact"
},
"firings": [
{
"occurrence_ms": 0,
"revision": 0,
"outcome": "fired",
"run": "00000000-0000-4000-8000-000000000000",
"busy_holder": "00000000-0000-4000-8000-000000000000",
"at": 0
}
]
}
}curl -X POST "http://127.0.0.1:$PORT/v1/schedules/pause" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"expected_revision": 0
}'POST/v1/schedules/resume
200 with the canonical active schedule projection. Elapsed paused occurrences are not caught up.
- Authorization
- Bearer token with
runs.write - Operation id
- schedules_resume
Request body (required)
application/json ResumeScheduleRequest
| Field | Type | Description |
|---|---|---|
| schedulerequired | ScheduleId | |
| workspacerequired | WorkspaceId | |
| expected_revisionrequired | integer (uint32, >= 0) |
{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"expected_revision": 0
}Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | ResumeScheduleResponse |
| 400 | The request body or workspace query is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the required delegation scope | DelegateFailure |
| 404 | The schedule is missing or belongs to another workspace | DelegateFailure |
| 409 | The observed name is stale, or the schedule is retired or read-only | DelegateFailure |
| 413 | The schedule request exceeds the body limit | DelegateFailure |
| 503 | The delegate worker or schedule store is not answering | DelegateFailure |
{
"schedule": {
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"name": "string",
"header": {
"schedule": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"initial_owner": "string",
"definition": {
"revision": 0,
"effective_at_ms": 0,
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
},
"lifecycle": "active"
}
},
"state": {
"owner": "string",
"state": "active"
},
"next_firing": {
"at_ms": 0,
"kind": "exact"
},
"firings": [
{
"occurrence_ms": 0,
"revision": 0,
"outcome": "fired",
"run": "00000000-0000-4000-8000-000000000000",
"busy_holder": "00000000-0000-4000-8000-000000000000",
"at": 0
}
]
}
}curl -X POST "http://127.0.0.1:$PORT/v1/schedules/resume" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"expected_revision": 0
}'POST/v1/schedules/retire
200 with the canonical retired schedule projection. Existing Runs and their provenance remain unchanged.
- Authorization
- Bearer token with
runs.write - Operation id
- schedules_retire
Request body (required)
application/json RetireScheduleRequest
| Field | Type | Description |
|---|---|---|
| schedulerequired | ScheduleId | |
| workspacerequired | WorkspaceId |
{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000"
}Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | RetireScheduleResponse |
| 400 | The request body or workspace query is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the required delegation scope | DelegateFailure |
| 404 | The schedule is missing or belongs to another workspace | DelegateFailure |
| 409 | The observed name is stale, or the schedule is retired or read-only | DelegateFailure |
| 413 | The schedule request exceeds the body limit | DelegateFailure |
| 503 | The delegate worker or schedule store is not answering | DelegateFailure |
{
"schedule": {
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"name": "string",
"header": {
"schedule": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"initial_owner": "string",
"definition": {
"revision": 0,
"effective_at_ms": 0,
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
},
"lifecycle": "active"
}
},
"state": {
"owner": "string",
"state": "active"
},
"next_firing": {
"at_ms": 0,
"kind": "exact"
},
"firings": [
{
"occurrence_ms": 0,
"revision": 0,
"outcome": "fired",
"run": "00000000-0000-4000-8000-000000000000",
"busy_holder": "00000000-0000-4000-8000-000000000000",
"at": 0
}
]
}
}curl -X POST "http://127.0.0.1:$PORT/v1/schedules/retire" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000"
}'POST/v1/schedules/edit
200 with the canonical schedule projection after one durable revision-checked replacement of its editable definition and name.
- Authorization
- Bearer token with
runs.write - Operation id
- schedules_edit
Request body (required)
application/json EditScheduleRequest
| Field | Type | Description |
|---|---|---|
| schedulerequired | ScheduleId | |
| workspacerequired | WorkspaceId | |
| expected_revisionrequired | integer (uint32, >= 0) | |
| expected_namerequired | ScheduleName | A person-authored schedule label. It is presentation metadata, never schedule identity, and is redacted anywhere a derived |
| namerequired | ScheduleName | A person-authored schedule label. It is presentation metadata, never schedule identity, and is redacted anywhere a derived |
| templaterequired | DelegationTemplate | The reusable request fields. |
| recurrencerequired | RecurrenceRule | A persisted recurrence rule. The variants preserve Koru's existing floating-versus-zoned distinction without an optional timezone. |
{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"expected_revision": 0,
"expected_name": "string",
"name": "string",
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
}
}Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | EditScheduleResponse |
| 400 | The request body or workspace query is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the required delegation scope | DelegateFailure |
| 404 | The schedule is missing or belongs to another workspace | DelegateFailure |
| 409 | The observed name is stale, or the schedule is retired or read-only | DelegateFailure |
| 413 | The schedule request exceeds the body limit | DelegateFailure |
| 503 | The delegate worker or schedule store is not answering | DelegateFailure |
{
"schedule": {
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"name": "string",
"header": {
"schedule": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"initial_owner": "string",
"definition": {
"revision": 0,
"effective_at_ms": 0,
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
},
"lifecycle": "active"
}
},
"state": {
"owner": "string",
"state": "active"
},
"next_firing": {
"at_ms": 0,
"kind": "exact"
},
"firings": [
{
"occurrence_ms": 0,
"revision": 0,
"outcome": "fired",
"run": "00000000-0000-4000-8000-000000000000",
"busy_holder": "00000000-0000-4000-8000-000000000000",
"at": 0
}
]
}
}curl -X POST "http://127.0.0.1:$PORT/v1/schedules/edit" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"expected_revision": 0,
"expected_name": "string",
"name": "string",
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
}
}'GET/v1/schedules
Canonical definitions, reduced ownership/lifecycle state, truthful next-firing projections, and firing history. A firing carries a RunId only when it actually fired.
- Authorization
- Bearer token with
runs.read - Operation id
- schedules_list
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| workspacerequired | query | string (uuid) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | ListSchedulesResponse |
| 400 | The request body or workspace query is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the required delegation scope | DelegateFailure |
| 503 | The delegate worker or schedule store is not answering | DelegateFailure |
{
"schedules": [
{
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"name": "string",
"header": {
"schedule": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"initial_owner": "string",
"definition": {
"revision": 0,
"effective_at_ms": 0,
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
},
"lifecycle": "active"
}
},
"state": {
"owner": "string",
"state": "active"
},
"next_firing": {
"at_ms": 0,
"kind": "exact"
},
"firings": [
{
"occurrence_ms": 0,
"revision": 0,
"outcome": "fired",
"run": "00000000-0000-4000-8000-000000000000",
"busy_holder": "00000000-0000-4000-8000-000000000000",
"at": 0
}
]
}
],
"incomplete": false
}curl "http://127.0.0.1:$PORT/v1/schedules?workspace=$WORKSPACE" \
-H "Authorization: Bearer $KORU_TOKEN"POST/v1/schedules
201 with the canonical durable Schedule document projection. The client supplies the ScheduleId, workspace, reusable delegation template and recurrence rule; the worker stamps owner, revision, lifecycle and times.
- Authorization
- Bearer token with
runs.write - Operation id
- schedules_create
Request body (required)
application/json CreateScheduleRequest
| Field | Type | Description |
|---|---|---|
| schedulerequired | ScheduleId | |
| workspacerequired | WorkspaceId | |
| namerequired | ScheduleName | A person-authored schedule label. It is presentation metadata, never schedule identity, and is redacted anywhere a derived |
| templaterequired | DelegationTemplate | The reusable request fields. |
| recurrencerequired | RecurrenceRule | A persisted recurrence rule. The variants preserve Koru's existing floating-versus-zoned distinction without an optional timezone. |
{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"name": "string",
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
}
}Responses
| Status | Description | Body |
|---|---|---|
| 201 | See above. | CreateScheduleResponse |
| 400 | The request body or workspace query is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the required delegation scope | DelegateFailure |
| 409 | The schedule identity cannot be used in this workspace | DelegateFailure |
| 413 | The schedule request exceeds the body limit | DelegateFailure |
| 422 | The schedule definition is invalid | DelegateFailure |
| 503 | The delegate worker or schedule store is not answering | DelegateFailure |
{
"schedule": {
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"name": "string",
"header": {
"schedule": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"initial_owner": "string",
"definition": {
"revision": 0,
"effective_at_ms": 0,
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
},
"lifecycle": "active"
}
},
"state": {
"owner": "string",
"state": "active"
},
"next_firing": {
"at_ms": 0,
"kind": "exact"
},
"firings": [
{
"occurrence_ms": 0,
"revision": 0,
"outcome": "fired",
"run": "00000000-0000-4000-8000-000000000000",
"busy_holder": "00000000-0000-4000-8000-000000000000",
"at": 0
}
]
}
}curl -X POST "http://127.0.0.1:$PORT/v1/schedules" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"name": "string",
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
}
}'POST/v1/schedules/rename
200 with the canonical schedule projection after its durable owner-authorized name change.
- Authorization
- Bearer token with
runs.write - Operation id
- schedules_rename
Request body (required)
application/json RenameScheduleRequest
| Field | Type | Description |
|---|---|---|
| schedulerequired | ScheduleId | |
| workspacerequired | WorkspaceId | |
| expected_namerequired | ScheduleName | A person-authored schedule label. It is presentation metadata, never schedule identity, and is redacted anywhere a derived |
| namerequired | ScheduleName | A person-authored schedule label. It is presentation metadata, never schedule identity, and is redacted anywhere a derived |
{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"expected_name": "string",
"name": "string"
}Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | RenameScheduleResponse |
| 400 | The request body or workspace query is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the required delegation scope | DelegateFailure |
| 404 | The schedule is missing or belongs to another workspace | DelegateFailure |
| 409 | The observed name is stale, or the schedule is retired or read-only | DelegateFailure |
| 413 | The schedule request exceeds the body limit | DelegateFailure |
| 503 | The delegate worker or schedule store is not answering | DelegateFailure |
{
"schedule": {
"workspace": "00000000-0000-4000-8000-000000000000",
"document": "00000000-0000-4000-8000-000000000000",
"name": "string",
"header": {
"schedule": "00000000-0000-4000-8000-000000000000",
"created_at_ms": 0,
"initial_owner": "string",
"definition": {
"revision": 0,
"effective_at_ms": 0,
"template": {
"requested_by": {
"profile": "00000000-0000-4000-8000-000000000000",
"kind": "person"
},
"objective": "string",
"agent": {
"kind": "built_in",
"value": "string"
},
"requested_model": "string",
"scope": {
"kind": "none"
},
"grants": [],
"context": []
},
"recurrence": {
"cron": "string",
"type": "floating"
},
"lifecycle": "active"
}
},
"state": {
"owner": "string",
"state": "active"
},
"next_firing": {
"at_ms": 0,
"kind": "exact"
},
"firings": [
{
"occurrence_ms": 0,
"revision": 0,
"outcome": "fired",
"run": "00000000-0000-4000-8000-000000000000",
"busy_holder": "00000000-0000-4000-8000-000000000000",
"at": 0
}
]
}
}curl -X POST "http://127.0.0.1:$PORT/v1/schedules/rename" \
-H "Authorization: Bearer $KORU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"schedule": "00000000-0000-4000-8000-000000000000",
"workspace": "00000000-0000-4000-8000-000000000000",
"expected_name": "string",
"name": "string"
}'GET/v1/schedules/stream
A bounded text/event-stream of content-free schedule generations. Each item means to read the workspace list again; no objective, context, path, document id or schedule id travels in the event.
- Authorization
- Bearer token with
runs.read - Operation id
- schedules_stream
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| workspacerequired | query | string (uuid) | |
| after_instance | query | string (uuid) | |
| after_generation | query | integer (uint64) |
Responses
| Status | Description | Body |
|---|---|---|
| 200 | See above. | ScheduleChangetext/event-stream |
| 400 | The request body or workspace query is invalid | DelegateFailure |
| 401 | The gateway bearer is absent or invalid | DelegateFailure |
| 403 | The bearer lacks the required delegation scope | DelegateFailure |
| 503 | The delegate worker or schedule store is not answering | DelegateFailure |
curl "http://127.0.0.1:$PORT/v1/schedules/stream?workspace=$WORKSPACE" \
-N \
-H "Authorization: Bearer $KORU_TOKEN"POST/v1/runs/{run}/mcp
The endpoint a delegated provider is handed. Authenticated by the run's own bearer (issued through POST /v1/artifacts/authorities), resolved against the durable authority record on every call - never by a gateway session bearer. One JSON-RPC message per POST, answered as application/json; a notification is 202; GET and DELETE are 405. Exactly six tools: create, create_version, get, read, search, attach_to_run. Their definitions, as tools/list returns them, are in x-mcp-tools.
- Authorization
- A run's endpoint token, any scope
- Operation id
- runs_mcp
Request body (required)
application/json object
Type object
{}Responses
| Status | Description | Body |
|---|---|---|
| 200 | The JSON-RPC response | object |
| 202 | A notification was accepted; no body | |
| 400 | The body was not one JSON-RPC message | object |
| 401 | The bearer is absent, unknown (authority_unknown), belongs to an earlier attempt (stale_generation), or the run's authority was revoked (authority_revoked) | object |
| 405 | GET and DELETE: the endpoint is stateless and never speaks first | |
| 503 | artifacts.db did not open |
{}Behavior
- MCP tools
- [object Object], [object Object], [object Object], [object Object], [object Object], [object Object]
curl -X POST "http://127.0.0.1:$PORT/v1/runs/$RUN/mcp" \
-H "Authorization: Bearer $RUN_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'Generated from contract version 1. Last updated .
