Confluye Command
Enqueue, poll, confirm, cancel, and schedule Confluye Command jobs (legacy fluxus-command paths).
All routes below keep the path segment fluxus-command. That is a compatibility name.
JSON errors and UI copy say Confluye Command. Artifacts: Command artifacts.
Two HTTP families:
| Family | Auth | Success shape |
|---|---|---|
/api/fluxus-command | Session | Bare { job }, send payload, etc. |
/api/v1/fluxus-command/jobs | Workspace API key | api-contracts.v1 envelope |
/api/v1/fluxus-command/schedules | Any valid API key | Bare { schedules } / { schedule } |
Session endpoints
| Method | Path | Status | Notes |
|---|---|---|---|
| POST | /api/fluxus-command | 201 | Same send as chat without idempotency or attachmentFileIds |
| GET | /api/fluxus-command/jobs/{id} | 200 | { threadId, plan, job, result?, error?, attempt?, retryOfJobId? } or chat-message fallback |
| POST | /api/fluxus-command/jobs/{id}/confirm | 200 | Body { confirmationId } |
| POST | /api/fluxus-command/jobs/{id}/cancel | 200 | { job } |
| POST | /api/fluxus-command/jobs/{id}/retry | 202 | New job { job, queued } |
| GET | /api/fluxus-command/schedules | 200 | { schedules } |
| POST | /api/fluxus-command/schedules | 201 | { schedule } |
workspaceId query (jobs) or body (send/schedules) defaults to the session workspace. Membership
required. Send/confirm/cancel/retry use action create (Cannot create chat threads|command schedules for another workspace.).
GET job/schedules use access.
Empty send message: 400 Message is required. Missing job: 404 Confluye Command job not found
(confirm: ... or not awaiting confirmation). Other transition failures: 409 with the thrown message.
After same-origin and session authorization checks pass, confirmation validation and lifecycle failures
carry an errorCode next to error. Earlier request-integrity and authorization failures retain their
own error envelopes and may omit errorCode.
| Status | errorCode | When |
|---|---|---|
400 | request_malformed | Missing, non-string, or blank confirmationId |
404 | confirmation_not_found | Job without plan, unknown id, or a confirmation that never resumed this job. A single-use confirmation that was already consumed settles the job to failed and the response carries it, so Retry can issue a fresh confirmation |
409 | confirmation_mismatch | Another user's job, or an id that belongs to a different confirmation |
409 | confirmation_expired | The 300 s window closed; the response also carries the settled job (blocked) |
409 | confirmation_consumed | Consumed concurrently and the job never resumed (rare; a normal double click is 200) |
409 | execution_failed | The confirmed plan failed; the job is failed and the response carries it. The message is opaque and the raw exception stays in the server log |
500 | internal_error | Unexpected failure with no settled failed job; opaque message, no raw internal exception |
After an unexpected 500 or a lost response (network drop before any body), poll
GET /api/fluxus-command/jobs/{id} (session) or GET /api/v1/fluxus-command/jobs/{id} (API key) to
reconcile before deciding recovery. A 200 or a typed 409 with a settled job already establishes the
outcome. v1 confirm failures use the envelope in Errors (v1 jobs); the per-cause errorCode
and optional job payload above are the session-endpoint contract.
TTL when issued through Command: 300 seconds. Confirmation is single-use, but a replay of the same
confirmationId after it resumed the job (double click, retried request) answers 200 with the current job.
GET /api/fluxus-command/jobs/{id} settles an expired confirmation into a recoverable blocked job on read; the
worker also sweeps stale confirmations every scheduler tick so unattended threads are released.
No Idempotency-Key on session Command send/confirm/cancel/retry/schedules.
v1 job endpoints
Workspace API key only. 401 authentication_required / 403 authorization_failed (same
messages as Files). Query workspaceId on list is ignored; isolation is the key.
Viewer keys receive a workspace-safe.v1 job projection containing lifecycle metadata only.
Keys with workspace.secret.read or workspace.write retain the full job contract.
| Method | Path | Status | Idempotency |
|---|---|---|---|
| GET | /api/v1/fluxus-command/jobs | 200 { jobs, nextCursor } | No |
| POST | /api/v1/fluxus-command/jobs | 202 { job } | Required |
| GET | /api/v1/fluxus-command/jobs/{id} | 200 { job } | No |
| POST | /api/v1/fluxus-command/jobs/{id}/confirm | 200 { job } | Required |
| POST | /api/v1/fluxus-command/jobs/{id}/cancel | 200 { job } | Required |
| POST | /api/v1/fluxus-command/jobs/{id}/artifacts | 201 { job } | Required |
| POST | /api/v1/fluxus-command/jobs/{id}/artifacts/{fileId}/complete | 200 { job } | Required |
There is no v1 retry route.
List
Query: threadId optional, cursor optional (job id of the last item on the previous page),
limit optional default 50, integer 1–100. Bad limit/cursor: 400 request_malformed
(limit must be between 1 and 100 or Confluye Command cursor is invalid for this workspace and thread.).
Order: thread sequence desc when present, otherwise store order. nextCursor is the last job id
on the page, or null.
Create
{
"threadId": "existing-thread-id",
"message": "Query incidents",
"assistantContext": "optional",
"aiProvider": "optional",
"aiModel": "optional",
"attachmentFileIds": ["ready-file-id"]
}
threadId and message must be non-empty strings. attachmentFileIds if present must be unique
non-empty strings. Else 400 request_malformed
(threadId, message and valid attachmentFileIds are required.).
Does not append a user chat message. Job id is a random UUID. FIFO: if the thread already has
an active job, the new row stays queued. Ready attachments are validated then bound (423 if
not ready). Files service is not touched when the array is empty.
Confirm
{ "confirmationId": "cnf_…" }. Failures use the v1 error envelope below (409 conflict for an
expired, consumed, mismatched or failed confirmation); the per-cause errorCode and job payload
are a session-endpoint contract (see above). TTL when issued through Command: 300 seconds. Confirmation
is single-use, but a replay of the same confirmationId after it resumed the job (double click, retried
request) answers 200 with the current job. The worker sweeps stale confirmations every scheduler tick, so
an unattended thread is released as a recoverable blocked job.
Cancel
Queued jobs use FIFO cancelQueued (releases the thread slot). Otherwise the store cancels
non-terminal jobs. Terminal cancel: 409. Unknown: 404.
Job object (public)
| Field | Notes |
|---|---|
id | Session sends use command_ + UUID; v1 create uses UUID |
planId | Set after planning |
status | queued | running | waiting_confirmation | succeeded | failed | canceled | blocked |
traces | Per-action tool traces |
confirmation | { id, expiresAt } while waiting |
progress | { runId?, state, message, events } (events empty if no live buffer) |
attachments | Serialized ready file refs |
artifacts | Published outputs |
createdAt / updatedAt | ISO-8601 |
Session GET may also return plan, result (content, actions, citations, ragMode),
error, attempt, retryOfJobId. Each citation may include optional runId as an explicit run
target; when present, clients open Logs for that run. documentId remains the document target for
knowledge and other resources. Legacy run citations may carry only documentId with
knowledgeBaseName: "Runs" and a run_… id. If the durable row is gone, it falls back to the
assistant message that still embeds fluxusCommandJob.
Schedules
{
"title": "Morning failures",
"prompt": "summarize yesterday's failed runs",
"cron": "0 8 * * *",
"timezone": "UTC",
"threadId": "optional",
"workspaceId": "session-only"
}
Blank title/prompt: 400 Schedule title is required. / Schedule prompt is required. Invalid
cron/timezone fails in nextRunFromCron as 400. Default timezone UTC. Created enabled: true.
Serialized schedule: id, workspaceId, createdById, title, prompt, cron, timezone,
enabled, optional threadId, nextRunAt, lastRunAt, runCount, createdAt, updatedAt.
v1 GET/POST: 401 if no bearer; personal/copilot keys are accepted. No idempotency. No
envelope. No HTTP update/delete.
Due runner (not these routes): claims due rows, writes fluxusCommandScheduleRun, dispatches
sendWorkspaceChatMessage with the stored prompt.
Errors (v1 jobs)
| HTTP | error.code | Cause |
|---|---|---|
| 400 | idempotency_key_invalid | Missing/invalid key on mutations |
| 400 | request_malformed | Body, limit, cursor |
| 401 | authentication_required | Bearer |
| 403 | authorization_failed | Non-workspace key |
| 404 | resource_not_found | Job / artifact |
| 409 | conflict | Illegal transition, confirm consume |
| 409 | idempotency_replay_mismatch | Same key, different body |
| 423 | conflict | File not ready |
Gaps
- Session send is a second entry point beside
/api/chatwithout idempotency or attachments. - v1 create requires a pre-existing
threadIdand does not write the user line. - No v1 retry; session retry only from
failedorcanceled. - v1 GET job returns
{ job }only (noplan/resultwrapper used by the session GET). - Schedule HTTP is create/list only; v1 schedule auth is weaker than v1 jobs.
