Yukta is pre-beta (
0.0.1-SNAPSHOT). Paths, fields and status codes may change before v0.1.0.Base path and discovery
All endpoints live under/api on the server address, http://localhost:8080 by default. There is no version segment in the path.
The server publishes an OpenAPI description at /v3/api-docs and interactive documentation at /swagger-ui.html. Both list every endpoint with its schemas. The same description is rendered in the Endpoint reference tab of this site, where every endpoint has its parameters, request and response schemas and a request playground. Use these guides for behaviour and the endpoint reference for exact shapes.
Authentication
A fresh server listens on loopback only and requires no key. When you configureyukta.api-key or yukta.api-keys, every request under /api must carry a key in one of two headers:
401 and a WWW-Authenticate: Bearer header. A valid key that is not allowed to make the request gets 403. Only /actuator/health is reachable without a key. The other management endpoints need an ADMIN key that is not limited to sessions. See Security for how to configure keys.
Roles
yukta.api-key defines one key with the ADMIN role. yukta.api-keys defines named keys, each with a role and an optional list of sessions.
Each endpoint page names the role it needs. When keys are configured, a request path that uses
.. segments, encoded separators or path parameters is refused with 400, so no spelling of a path bypasses the check.
Keys limited to sessions
A key can be limited to a list of sessions. It then reaches only/api/sessions/{sessionId}/... and /api/workflow/{sessionId}/... for its own sessions, and /api/executions/{executionId}/... for runs of its sessions. Every other path answers 403: the session listings, the plugin catalogue, the event stream and the control-bus views. POST /api/workflow/start names its session in the body rather than the path, so a session-limited key cannot call it. The MCP start_workflow tool accepts such a key.
With named keys, the control commands a request sends are recorded under the actor key:<name> in the control audit.
Servers without a key
When no key is configured the server checks theHost and Origin headers instead. A request whose Host is not localhost, 127.0.0.1, [::1] or listed in yukta.allowed-hosts is refused with 403. A request that changes state and carries an Origin header must come from the same site or from an origin listed in yukta.allowed-origins. Both rules stop a web page in your browser from driving a local server. They are switched off as soon as a key is configured.
The server does not send CORS headers. A browser application must be served from the same origin as the API, as the built-in web UI is, or reach it through a proxy.
Request and response format
- Request bodies are JSON with
Content-Type: application/json. - Responses are JSON, except the event streams, which use
text/event-stream. - Unknown fields in a request body are rejected with
400and the field name, so a misspelt option never passes silently. - Timestamps are ISO-8601 strings without a zone offset for run times, and with
Zfor instants such assavedAt. - Identifiers in path segments must be URL-encoded.
X-Request-ID header. Send your own value (letters, digits and hyphens, up to 64 characters) to correlate calls; otherwise the server generates one. X-Correlation-ID works the same way. Quote the request ID when you report a server error.
Response envelope
Most endpoints wrap their result in one envelope.
Empty fields are left out. Error responses use the same envelope with
error, path and, for validation problems, errors instead of data; see Errors.
Two kinds of response do not use the envelope: the event streams, and GET /api/sessions/{sessionId}/executions/{executionId}/results, which returns the results object directly.
Paging
List endpoints that can grow large are paged with a cursor.
When more items remain, the response carries an
X-Next-Cursor header holding the cursor for the next page. When the header is absent, you have the last page. A cursor that matches no item returns the first page again.
Paged endpoints: GET /api/sessions, GET /api/sessions/summaries, GET /api/workflow/{sessionId}/history and GET /api/sessions/{sessionId}/workflows/{workflowId}/executions. Two other lists take only a limit and no cursor: GET /api/executions (default 100, maximum 1000) and GET /api/control/audit (default 100, maximum 500).
Idempotent start
POST /api/workflow/start accepts an optional Idempotency-Key header. A repeat of the request with the same key, for the same session and workflow, within the window returns the execution id of the first start instead of starting a second run. A start that failed is forgotten, so retrying it runs again.
yukta.start.idempotency-ttl (default 10m) and the server remembers at most yukta.start.idempotency-max-keys keys (default 100000). Keys survive a restart only when the execution log is kept on disk.
Server-sent event streams
Streams share these conventions; the Streams page has the details of each.- Each event has an
idthat counts from 0 within the stream. - A client that reconnects sends the last id it saw in the
Last-Event-IDheader. The stream then skips what the client already received. - An idle stream sends a comment line (
: ping) every 15 seconds so proxies keep the connection open. - Status, log and result streams end when the execution ends. The event feed (
/api/events/stream) never ends on its own.
Request size
The server reads request bodies up to1MB. A larger body is answered with 413. Set YUKTA_LIMITS_MAX_BODY to change the limit, for example 4MB.
Deprecated aliases
Execution endpoints exist at two paths. The/api/executions/{executionId}/... form is current. The older /api/workflow/... form still works and is marked deprecated; where it names a session, it also checks that the execution belongs to that session.
Retry, breakpoint, signal and priority exist only at the current path. The execution index behind
/api/executions/{executionId} keeps a finished run for yukta.tracker.cleanup-ttl (default 10m). To read an older run from the session history, use the status alias that names the session.