{
"openapi": "3.1.0",
"info": {
"title": "Moadim Server API",
"description": "REST API for managing routines",
"license": {
"name": "MIT",
"identifier": "MIT"
},
"version": "0.1.0"
},
"servers": [
{
"url": "/api/v1",
"description": "This server"
}
],
"paths": {
"/agents": {
"get": {
"tags": [
"crate::routines"
],
"summary": "`GET /agents` — list the agent registry keys a routine may target.",
"operationId": "list_agents",
"responses": {
"200": {
"description": "Available agent names",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"/echo": {
"post": {
"tags": [
"crate::routes::http"
],
"summary": "`POST /echo` — parse a JSON body and return the message with a server timestamp.",
"operationId": "echo",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EchoRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/EchoResponse"
}
}
}
},
"400": {
"description": "Invalid body"
}
}
}
},
"/health": {
"get": {
"tags": [
"crate::routes::http"
],
"summary": "`GET /health` — health check with uptime.",
"operationId": "health",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HealthResponse"
}
}
}
}
}
}
},
"/machine": {
"get": {
"tags": [
"crate::routes::http"
],
"summary": "`GET /machine` — the current machine's resolved identity.",
"description": "Returns the name this daemon uses to match `machines[]` targeting lists on routines. Useful for\nclients (e.g. the UI) that want to default their views to local entries only.",
"operationId": "get_current_machine",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MachineResponse"
}
}
}
}
}
},
"put": {
"tags": [
"crate::routes::http"
],
"summary": "`PUT /machine` — rename this machine's identity.",
"description": "Writes the new name to `machine.local.toml` and returns it trimmed. Returns `400` if the name\nis empty, `500` if the write fails. The `MOADIM_MACHINE` env var takes precedence at runtime;\nsetting the name here persists it for when the env var is absent.",
"operationId": "put_machine",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SetMachineRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MachineResponse"
}
}
}
},
"400": {
"description": "Empty name"
},
"500": {
"description": "Write failed"
}
}
}
},
"/machines": {
"get": {
"tags": [
"crate::routes::http"
],
"summary": "`GET /machines` — distinct machine names this daemon knows about.",
"description": "There is no central machine registry, so the \"known\" set is the union of every `machines`\ntargeting list declared by a routine, plus this machine's own resolved identity\n([`crate::machine::current_machine`]) so the local machine is always pickable even before\nanything targets it. Sorted and de-duplicated. Backs the UI machine picker; mirrors the\n`moadim machine list` CLI but reads the live in-memory store instead of disk.",
"operationId": "list_machines",
"responses": {
"200": {
"description": "Known machine names, sorted",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
},
"/restart": {
"post": {
"tags": [
"crate::routes::http"
],
"summary": "`POST /restart` — stop this server and start a fresh instance.",
"description": "The running server cannot rebind its own port, so it spawns a detached `moadim restart` helper\nthat stops it and starts a new process, mirroring the `moadim restart` CLI command and the\n`restart` MCP tool. Responds with the helper's PID before the restart completes.",
"operationId": "restart",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RestartResponse"
}
}
}
},
"500": {
"description": "could not spawn the restart helper"
}
}
}
},
"/routines": {
"get": {
"tags": [
"crate::routines"
],
"summary": "`GET /routines` — list routines, optionally filtered and sorted by repository.",
"operationId": "list",
"parameters": [
{
"name": "repository",
"in": "query",
"description": "Keep only routines with at least one repository whose URL contains this\nsubstring (case-insensitive). Empty or absent keeps every routine.",
"required": false,
"schema": {
"type": "string"
}
},
{
"name": "sort",
"in": "query",
"description": "Field to sort by (default: creation time).",
"required": false,
"schema": {
"$ref": "#/components/schemas/RoutineSort"
}
},
{
"name": "order",
"in": "query",
"description": "Sort direction (default: ascending).",
"required": false,
"schema": {
"$ref": "#/components/schemas/SortOrder"
}
},
{
"name": "local_only",
"in": "query",
"description": "When `true`, only return routines whose `machines` list includes the current machine.\nDefaults to `false` (return all routines, preserving backwards compatibility).",
"required": false,
"schema": {
"type": "boolean"
}
},
{
"name": "include_prompts",
"in": "query",
"description": "When `true`, include each routine's `prompt` in the response. Defaults to `false`:\nthe prompt (often the largest field) is omitted so listings stay compact. Fetch a\nsingle routine with `svc_get` / `GET /routines/{id}` to always see its prompt.",
"required": false,
"schema": {
"type": "boolean"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/RoutineResponse"
}
}
}
}
}
}
},
"post": {
"tags": [
"crate::routines"
],
"summary": "`POST /routines` — create a new routine.",
"operationId": "create",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateRoutineRequest"
}
}
},
"required": true
},
"responses": {
"201": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RoutineResponse"
}
}
}
},
"400": {
"description": "Invalid cron expression"
}
}
}
},
"/routines.ics": {
"get": {
"tags": [
"crate::routines"
],
"summary": "`GET /routines.ics` — iCalendar feed of every enabled routine's upcoming fire times.",
"description": "Returns a `text/calendar` body suitable for subscribing to in an external calendar\n(Google Calendar, Apple Calendar, …) so upcoming runs show up alongside other events.\nWith `?routine=<id>` the feed is scoped to a single routine (named after it); without\nit every enabled routine is rendered (issue #263).",
"operationId": "ical_feed",
"parameters": [
{
"name": "routine",
"in": "query",
"description": "Render only the fire times of the routine with this UUID. Absent (the default)\nrenders every enabled routine. An unknown or disabled id yields a well-formed\nempty calendar.",
"required": false,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "iCalendar (text/calendar) feed of upcoming routine fire times"
}
}
}
},
"/routines/cleanup": {
"post": {
"tags": [
"crate::routines"
],
"summary": "`POST /routines/cleanup` — reap finished, expired run workbenches on demand.",
"operationId": "cleanup",
"responses": {
"200": {
"description": "Number of workbenches removed",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CleanupResponse"
}
}
}
}
}
}
},
"/routines/lock": {
"get": {
"tags": [
"crate::routines"
],
"summary": "`GET /routines/lock` — return the current global lock status.",
"operationId": "get_lock_status",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LockStatus"
}
}
}
}
}
},
"post": {
"tags": [
"crate::routines"
],
"summary": "`POST /routines/lock` — create a lock sentinel, halting all routine scheduling and triggers.",
"operationId": "lock",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LockRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LockStatus"
}
}
}
},
"400": {
"description": "Unknown scope"
},
"500": {
"description": "IO error"
}
}
},
"delete": {
"tags": [
"crate::routines"
],
"summary": "`DELETE /routines/lock` — remove lock sentinel(s), restoring routine scheduling.",
"operationId": "unlock",
"parameters": [
{
"name": "scope",
"in": "query",
"description": "Which sentinel(s) to remove: `\"shared\"`, `\"local\"`, or `\"all\"`.",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/LockStatus"
}
}
}
},
"400": {
"description": "Unknown scope"
},
"500": {
"description": "IO error"
}
}
}
},
"/routines/{id}": {
"get": {
"tags": [
"crate::routines"
],
"summary": "`GET /routines/{id}` — retrieve a single routine by UUID.",
"operationId": "get",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Routine UUID",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RoutineResponse"
}
}
}
},
"404": {
"description": "Not found"
}
}
},
"put": {
"tags": [
"crate::routines"
],
"summary": "`PUT /routines/{id}` — fully replace a routine (behaves identically to PATCH).",
"operationId": "replace",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Routine UUID",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateRoutineRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RoutineResponse"
}
}
}
},
"400": {
"description": "Invalid"
},
"404": {
"description": "Not found"
}
}
},
"delete": {
"tags": [
"crate::routines"
],
"summary": "`DELETE /routines/{id}` — delete a routine by UUID.",
"operationId": "delete",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Routine UUID",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RoutineResponse"
}
}
}
},
"404": {
"description": "Not found"
}
}
},
"patch": {
"tags": [
"crate::routines"
],
"summary": "`PATCH /routines/{id}` — partially update a routine.",
"operationId": "update",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Routine UUID",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateRoutineRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/RoutineResponse"
}
}
}
},
"400": {
"description": "Invalid"
},
"404": {
"description": "Not found"
}
}
}
},
"/routines/{id}/logs": {
"get": {
"tags": [
"crate::routines"
],
"summary": "`GET /routines/{id}/logs` — return the newest workbench `agent.log` as plain text.",
"operationId": "get_logs",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Routine UUID",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Log file contents as plain text"
},
"404": {
"description": "Not found"
}
}
}
},
"/routines/{id}/scheduled-trigger": {
"post": {
"tags": [
"crate::routines"
],
"summary": "`POST /routines/{id}/scheduled-trigger` — run a routine on its schedule.",
"description": "The daemon-side endpoint the generated crontab line invokes (`moadim schedule trigger <id>`).\nUnlike [`trigger`] it does not record a manual trigger; the spawned command records the scheduled\ntimestamp itself. See [`svc_trigger_scheduled`].",
"operationId": "scheduled_trigger",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Routine UUID",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Routine"
}
}
}
},
"404": {
"description": "Not found"
}
}
}
},
"/routines/{id}/trigger": {
"post": {
"tags": [
"crate::routines"
],
"summary": "`POST /routines/{id}/trigger` — manually run a routine outside its schedule.",
"operationId": "trigger",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Routine UUID",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Routine"
}
}
}
},
"404": {
"description": "Not found"
}
}
}
},
"/shutdown": {
"post": {
"tags": [
"crate::routes::http"
],
"summary": "`POST /shutdown` — ask the server to stop gracefully.",
"description": "Used by the UI \"STOP\" button (and the `moadim stop` command) to kill a backgrounded server that\nhas no controlling terminal. The response is sent before the graceful shutdown completes.",
"operationId": "shutdown",
"responses": {
"200": {
"description": "",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ShutdownResponse"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"CleanupResponse": {
"type": "object",
"description": "Result of an on-demand workbench cleanup sweep.",
"required": [
"removed"
],
"properties": {
"removed": {
"type": "integer",
"description": "Number of finished, expired run workbenches removed by this sweep.",
"minimum": 0
}
}
},
"CreateRoutineRequest": {
"type": "object",
"description": "Request body for creating a new routine.",
"required": [
"schedule",
"title",
"agent",
"prompt"
],
"properties": {
"agent": {
"type": "string",
"description": "Agent registry key to launch."
},
"enabled": {
"type": "boolean",
"description": "Whether to create the routine enabled (defaults to `true`)."
},
"machines": {
"type": "array",
"items": {
"type": "string"
},
"description": "Machines to run this routine on (defaults to empty = runs nowhere until assigned)."
},
"max_runtime_secs": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Max wall-clock seconds a run may execute before the watchdog kills its hung\nsession. `None` uses the default cap (`MAX_RUNTIME_SECS`).",
"minimum": 0
},
"prompt": {
"type": "string",
"description": "Task prompt."
},
"repositories": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Repository"
},
"description": "Repositories to list as context (defaults to empty)."
},
"schedule": {
"type": "string",
"description": "Cron expression for the new routine. Evaluated in the host's local system\ntimezone (the OS crontab timezone), not UTC."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Free-form labels for the routine (defaults to empty). Each entry is trimmed\nand must be non-blank."
},
"title": {
"type": "string",
"description": "Human name for the routine."
},
"ttl_secs": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Workbench retention in seconds for finished runs; caps the cron-derived\nretention lower. `None` uses `min(MAX_TTL_SECS, cron interval)`.",
"minimum": 0
}
}
},
"DependencyHealth": {
"type": "object",
"description": "External-binary dependencies the daemon relies on at runtime, and whether each is resolvable on\nthe daemon's `PATH`. Surfaced in [`HealthResponse`] so the UI/CLI can flag a missing dependency\ninstead of having routine runs silently no-op.",
"required": [
"tmux"
],
"properties": {
"tmux": {
"type": "boolean",
"description": "Whether `tmux` (used to launch every routine agent) resolves on the daemon's `PATH`."
}
}
},
"EchoRequest": {
"type": "object",
"description": "Request body for `POST /echo`.",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"description": "Message to echo back."
}
}
},
"EchoResponse": {
"type": "object",
"description": "Response body for `POST /echo`.",
"required": [
"message",
"timestamp"
],
"properties": {
"message": {
"type": "string",
"description": "The echoed message."
},
"timestamp": {
"type": "integer",
"format": "int64",
"description": "Server timestamp (Unix seconds) when the echo was produced.",
"minimum": 0
}
}
},
"HealthResponse": {
"type": "object",
"description": "Response body for `GET /health`.",
"required": [
"status",
"uptime_secs",
"running",
"machine",
"dependencies",
"version",
"git_sha",
"build_date"
],
"properties": {
"build_date": {
"type": "string",
"description": "Committer date (`YYYY-MM-DD`) of the build commit, or `\"unknown\"` outside a git checkout."
},
"dependencies": {
"$ref": "#/components/schemas/DependencyHealth",
"description": "Presence of required external binaries on the daemon's `PATH`."
},
"git_sha": {
"type": "string",
"description": "Short git commit SHA the daemon was built from, or `\"unknown\"` outside a git checkout."
},
"machine": {
"type": "string",
"description": "Resolved name of this machine (from `MOADIM_MACHINE`, `~/.config/moadim/machine.local.toml`, or hostname)."
},
"running": {
"type": "boolean",
"description": "Whether the server is running."
},
"status": {
"type": "string",
"description": "Health status string (always `\"ok\"` when reachable)."
},
"uptime_secs": {
"type": "integer",
"format": "int64",
"description": "Seconds elapsed since the server started.",
"minimum": 0
},
"version": {
"type": "string",
"description": "Daemon version (from `CARGO_PKG_VERSION`)."
}
}
},
"LockRequest": {
"type": "object",
"description": "Request body for `POST /routines/lock`.",
"required": [
"scope"
],
"properties": {
"scope": {
"type": "string",
"description": "Which sentinel to create: `\"shared\"` (committed `.lock`) or `\"local\"` (gitignored `.local.lock`)."
}
}
},
"LockStatus": {
"type": "object",
"description": "Current state of both lock sentinels.",
"required": [
"shared",
"local",
"locked"
],
"properties": {
"local": {
"type": "boolean",
"description": "Whether the gitignored `.local.lock` file is present."
},
"locked": {
"type": "boolean",
"description": "`true` if either sentinel is present (all routine scheduling and triggers halted)."
},
"shared": {
"type": "boolean",
"description": "Whether the committed `.lock` file is present."
}
}
},
"MachineResponse": {
"type": "object",
"description": "Response body for `GET /machine`.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Resolved name of this machine (from `MOADIM_MACHINE`, `~/.config/moadim/machine.local.toml`, or hostname)."
}
}
},
"Repository": {
"type": "object",
"description": "A git repository made available to a routine's agent as prompt context (not cloned by moadim).",
"required": [
"repository"
],
"properties": {
"branch": {
"type": [
"string",
"null"
],
"description": "Branch to use, or `None` for the remote default branch."
},
"repository": {
"type": "string",
"description": "Git remote URL."
}
}
},
"RestartResponse": {
"type": "object",
"description": "Response body for `POST /restart`.",
"required": [
"status",
"helper_pid"
],
"properties": {
"helper_pid": {
"type": "integer",
"format": "int32",
"description": "PID of the detached helper process performing the stop-old-then-start-new restart.",
"minimum": 0
},
"status": {
"type": "string",
"description": "Acknowledgement status (always `\"restarting\"`)."
}
}
},
"Routine": {
"type": "object",
"description": "A persisted routine: a scheduled AI-agent task.",
"required": [
"id",
"schedule",
"title",
"agent",
"enabled",
"source",
"created_at",
"updated_at"
],
"properties": {
"agent": {
"type": "string",
"description": "Agent registry key (e.g. `\"claude\"`) resolved from `~/.config/moadim/agents/`."
},
"created_at": {
"type": "integer",
"format": "int64",
"description": "Unix timestamp (seconds) when the routine was created.",
"minimum": 0
},
"enabled": {
"type": "boolean",
"description": "Whether the routine is active."
},
"id": {
"type": "string",
"description": "Unique identifier (UUID v4)."
},
"last_manual_trigger_at": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Unix timestamp (seconds) when the routine was last manually triggered, if ever.\n\nOnly manual triggers (`trigger_routine`) update this; scheduled cron firings run the built\ncommand directly and do not. Accepts the legacy `last_triggered_at` key on deserialize.",
"minimum": 0
},
"last_scheduled_trigger_at": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Unix timestamp (seconds) when the routine was last fired by its cron schedule, if ever.\n\nThe mirror of [`Routine::last_manual_trigger_at`] for scheduled runs: a manual trigger\nupdates only the manual field, a scheduled firing updates only this one. The host OS crontab\nline runs `moadim schedule trigger <id>`, and the launch command the daemon spawns stamps this\ntimestamp into the gitignored `scheduled.local.toml` sidecar at fire time (via its `printf`\nstep); the daemon reads it back on load. The daemon never writes this field directly (it is\nabsent from `routine.toml` and the daemon-owned `state.local.toml`), so re-persisting a\nroutine can't clobber it.",
"minimum": 0
},
"machines": {
"type": "array",
"items": {
"type": "string"
},
"description": "Machines this routine runs on. Each daemon schedules a routine only when this list names its\nown machine identity ([`crate::machine::current_machine`]); an **empty list runs nowhere**, so\na routine is dormant until explicitly assigned. Lets one shared config repo drive different\nroutines on different machines."
},
"max_runtime_secs": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "Maximum wall-clock seconds a single run may execute before the cleanup watchdog force-kills\nits (hung) tmux session, after which the workbench is reaped under the normal TTL rules.\n`None` uses `min(MAX_RUNTIME_SECS, cron interval)`; an explicit value can only lower that. A\nsession still within this bound is never touched. The cap and\n[`Routine::effective_max_runtime_secs`] live in the cleanup module.",
"minimum": 0
},
"prompt": {
"type": "string",
"description": "The task prompt handed to the agent.\n\nOmitted from serialized output when empty. A persisted routine always has a\nnon-blank prompt (enforced by `validate_prompt`), so this never affects\n`routine.toml` persistence; it lets list responses drop the prompt by blanking\nit in-memory (see [`RoutineListQuery::include_prompts`] / `svc_list`)."
},
"repositories": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Repository"
},
"description": "Repositories listed in the prompt as context."
},
"schedule": {
"type": "string",
"description": "Cron expression defining when the routine runs, evaluated in the host's local\nsystem timezone (the OS crontab timezone), not UTC."
},
"source": {
"type": "string",
"description": "`\"managed\"` for routines owned by this server."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Free-form labels for grouping and filtering routines (e.g. `\"triage\"`, `\"nightly\"`).\nDefaults to empty; each entry is trimmed and must be non-blank."
},
"title": {
"type": "string",
"description": "Human name; slugified to name the workbench and tmux session."
},
"ttl_secs": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "How long (seconds) a finished run's workbench is retained before auto-cleanup removes it.\nCaps the cron-derived retention (`min(MAX_TTL_SECS, cron interval)`) lower; it can only\nshorten, never extend it. `None` uses the cron-derived value. Sessions still running are\nnever reaped. The cap and [`Routine::effective_ttl_secs`] live in the cleanup module.",
"minimum": 0
},
"updated_at": {
"type": "integer",
"format": "int64",
"description": "Unix timestamp (seconds) when the routine was last updated.",
"minimum": 0
}
}
},
"RoutineResponse": {
"allOf": [
{
"$ref": "#/components/schemas/Routine",
"description": "The underlying routine."
},
{
"type": "object",
"required": [
"agent_registered",
"file_path"
],
"properties": {
"agent_registered": {
"type": "boolean",
"description": "`true` if an agent config exists at `~/.config/moadim/agents/<agent>.toml`."
},
"file_path": {
"type": "string",
"description": "Absolute path to the routine's `routine.toml` file on disk."
},
"schedule_description": {
"type": [
"string",
"null"
],
"description": "Human-readable description of the schedule, including the timezone the\ncron expression is interpreted in, or `null` if it cannot be parsed."
},
"timezone": {
"type": [
"string",
"null"
],
"description": "IANA name of the local timezone the schedule is interpreted in (e.g.\n`\"Asia/Jerusalem\"`), or `null` if it cannot be determined. Cron\nexpressions are evaluated in this timezone, **not** UTC."
}
}
}
],
"description": "A [`Routine`] enriched with derived, non-persisted fields for API responses."
},
"RoutineSort": {
"type": "string",
"description": "Field to sort a routine listing by.",
"enum": [
"created",
"updated",
"title",
"repository"
]
},
"SetMachineRequest": {
"type": "object",
"description": "Request body for `PUT /machine`.",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"description": "New machine name. Trimmed; must be non-empty."
}
}
},
"ShutdownResponse": {
"type": "object",
"description": "Response body for `POST /shutdown`.",
"required": [
"status"
],
"properties": {
"status": {
"type": "string",
"description": "Acknowledgement status (always `\"shutting down\"`)."
}
}
},
"SortOrder": {
"type": "string",
"description": "Sort direction for a routine listing.",
"enum": [
"asc",
"desc"
]
},
"UpdateRoutineRequest": {
"type": "object",
"description": "Request body for partially updating an existing routine.",
"properties": {
"agent": {
"type": [
"string",
"null"
],
"description": "New agent key, or `None` to keep the existing value."
},
"enabled": {
"type": [
"boolean",
"null"
],
"description": "New enabled state, or `None` to keep the existing value."
},
"machines": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"description": "New machines targeting list, or `None` to keep the existing value."
},
"max_runtime_secs": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "New max runtime (seconds) for a single run, or `None` to keep the existing value.",
"minimum": 0
},
"prompt": {
"type": [
"string",
"null"
],
"description": "New prompt, or `None` to keep the existing value."
},
"repositories": {
"type": [
"array",
"null"
],
"items": {
"$ref": "#/components/schemas/Repository"
},
"description": "New repositories list, or `None` to keep the existing value."
},
"schedule": {
"type": [
"string",
"null"
],
"description": "New cron expression, or `None` to keep the existing value. Evaluated in the\nhost's local system timezone (the OS crontab timezone), not UTC."
},
"tags": {
"type": [
"array",
"null"
],
"items": {
"type": "string"
},
"description": "New tags list, or `None` to keep the existing value."
},
"title": {
"type": [
"string",
"null"
],
"description": "New title, or `None` to keep the existing value."
},
"ttl_secs": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "New workbench TTL (seconds), or `None` to keep the existing value.",
"minimum": 0
}
}
}
}
}
}