Schemas
Every request and response type in the API.
App
objectstring (date-time)string,nullstring (uri)stringstringstring (date-time)AuditEntry
object"api_key.rotated" | "signing_secret.revealed" | "signing_secret.rotated"string"operator" | "app" | "user"What sort of actor: user for a person (actor is user:<clerk id>), app for an app's own key (actor is app:<id>), operator for any other recorded name, which is an operator token's configured name. Taken from the recorded actor, never from actorName.
stringWhat to show for the actor: a person's name where one is known, otherwise the same text as actor. Always present. A person chooses their own name, so it is a label and never an identity: show it with actorKind.
string (date-time)string,nullstring (uuid)string,nullBulkAction
object"redrive" | "rewind" | "cancel"What to do to every matching run.
booleanAnswer with just a count, and start nothing.
default false
objectstringredrive only: restart from this step rather than where the run failed.
stringRecorded on every run this touches.
max length 1000
stringrewind only, and required: the step to rewind to.
integer (int64)rewind only: the workflow version to rewind onto.
min 1 · max 2147483647
BulkActionJob
object"redrive" | "rewind" | "cancel"stringstringstring,nullstring (date-time)integer (int64)string,nullinteger (int64)string,null (date-time)string (uuid)"pending" | "running" | "completed" | "cancelled" | "failed"integer (int64)Cancel
objectstringmax length 1000
Duration
string | numberA length of time, written the way people say it: "10s", "3d", "1h30m", "250ms". A bare number is milliseconds.
The ceiling is 9223372036854 ms, about 292 years — what a 64-bit nanosecond counter holds. Anything longer is refused, in either spelling. It is stated here because a limit the server enforces and the document omits is a client that validates, complies, and is rejected anyway.
EditState
objectmap of anystringmax length 1000
Error
objectEvery error the server emits, including the framework’s own validation failures. code is the closed enum above and is what a client should branch on. details is present only on a 4xx, where it describes what the CALLER got wrong; a 5xx never carries it, because the only thing it could carry is an internal message.
objectMetricDefinition
objectstringstring[]Every label a series of this metric carries, in order. Always starts with app and workflow.
stringPrometheus-compatible: snake_case with a foliot_ prefix; a counter ends in _total.
"rollup" | "live"rollup: counted into minute, hour and day buckets from Foliot's own tables, so it has history; live: read at the moment it is asked, so it has none yet.
"counter" | "gauge" | "distribution"counter: a count per bucket, which only adds up; gauge: a value at an instant.
stringWhat one unit of the value is: runs, attempts, seconds.
MetricPoint
objectstring (date-time)The start of the bucket (UTC), or for a live gauge the moment it was read.
number (double)A counter's running total from the first bucket of the range through this one. Absent for a gauge.
number (double)A counter's count in this bucket; a gauge's value.
MetricSeries
objectmap of stringThe value of each of the metric's labels.
For a rollup metric, one point for every bucket in the range, zero where nothing was counted. For a live gauge, one point.
number (double)A counter's sum over the whole range. Absent for a gauge.
MyWorkspace
objectA workspace the signed-in person belongs to, and their role in it.
string (uuid)string"owner" | "operator" | "viewer"stringPrincipal
Who a bearer token belongs to.
PrincipalApp
objectstring"app"PrincipalOperator
object"operator"stringThe operator's name, from FOLIOT_OPERATOR_TOKENS.
PrincipalUser
objectA signed-in person. workspaces is read from the database on every call, never from the token, and is empty for someone who has signed in but belongs to none (they can see nothing). name and email are absent until the profile has been mirrored. truncated is true only when the person belongs to more workspaces than are listed (the first 200 by slug): the list is then not the whole of it. canCreateWorkspace says whether they may make their own first workspace.
booleanWhether this person may make their own first workspace with POST /me/workspaces: they have never belonged to one. false for a person who belongs to a workspace and for one who was removed from theirs, so a screen offers the form only to someone the server will accept. Read now, after any invitation has joined them.
string"user"stringbooleanstring (uuid)Reason
objectstringWhy. Optional; recorded with the action.
max length 1000
Redrive
objectstringDefaults to the run's current step.
stringmax length 1000
RegisterApp
objectstringmax length 500
string (uri)Where tasks are pushed.
stringThe app's name. With POST /apps it also becomes the app's id; in a workspace the id is generated and the name only has to be unique in that workspace. Lower-case kebab.
min length 1 · max length 100 · pattern ^[a-z0-9][a-z0-9-]*$
RegisteredWorkflow
objectstring (date-time)integer (int64)stringinteger (int64)Rewind
objectstringmax length 1000
stringmin length 1
integer (int64)min 1 · max 2147483647
Run
objectstringinteger (int64)string,nullbooleanstring (date-time)string,nullstring,null (date-time)integer (int64)string (uuid)string,nullanystring,null (date-time)map of anystring[]string (date-time)null | "paused" | "signal" | "task"string,nullstringinteger (int64)RunError
objectintegerstringMatched against a retry policy's retryOn. Engine-set classes include timeout, wait_timeout, run_timeout and cancelled; handlers may set their own.
stringbooleanstringRunEvent
RunEventRunStarted | RunEventStepStarted | RunEventTaskDispatched | RunEventTaskAcked | RunEventTaskCompleted | RunEventTaskFailed | RunEventTaskTimedOut | RunEventStepCompleted | RunEventStepExhausted | RunEventStepSkipped | RunEventStepParked | RunEventStepReleased | RunEventRunSleeping | RunEventRunWaiting | RunEventSignalReceived | RunEventWaitTimedOut | RunEventChoiceEvaluated | RunEventRunSucceeded | RunEventRunFailed | RunEventRunCancelled | RunEventRunStuck | RunEventRunRedriven | RunEventRunRewound | RunEventRunRepinned | RunEventStateEdited | RunEventRunCompactedOne entry of a run’s history. payload varies by type; every variant was observed from a real run (see go/internal/acceptance/captures/_event-payloads.json).
RunEventChoiceEvaluated
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for choice.evaluated.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"choice.evaluated"RunEventRunCancelled
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.cancelled.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.cancelled"RunEventRunCompacted
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.compacted.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.compacted"RunEventRunFailed
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.failed.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.failed"RunEventRunRedriven
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.redriven.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.redriven"RunEventRunRepinned
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.repinned.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.repinned"RunEventRunRewound
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.rewound.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.rewound"RunEventRunSleeping
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.sleeping.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.sleeping"RunEventRunStarted
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.started.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.started"RunEventRunStuck
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.stuck.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.stuck"RunEventRunSucceeded
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
map of anyPayload written for run.succeeded.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.succeeded"RunEventRunWaiting
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for run.waiting.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"run.waiting"RunEventSignalReceived
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for signal.received.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"signal.received"RunEventStateEdited
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for state.edited.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"state.edited"RunEventStepCompleted
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for step.completed.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"step.completed"RunEventStepExhausted
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for step.exhausted.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"step.exhausted"RunEventStepParked
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for step.parked.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"step.parked"RunEventStepReleased
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for step.released.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"step.released"RunEventStepSkipped
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for step.skipped.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"step.skipped"RunEventStepStarted
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
map of anyPayload written for step.started.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"step.started"RunEventTaskAcked
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for task.acked.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"task.acked"RunEventTaskCompleted
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for task.completed.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"task.completed"RunEventTaskDispatched
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for task.dispatched.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"task.dispatched"RunEventTaskFailed
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for task.failed.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"task.failed"RunEventTaskTimedOut
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for task.timed_out.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"task.timed_out"RunEventWaitTimedOut
objectstringfoliot for engine actions, otherwise the operator name.
string (date-time)integer,nullintegerBumped by redrive and rewind, so re-runs of a step stay distinguishable.
integerMonotonic across the engine; use seq for per-run ordering.
objectPayload written for wait.timed_out.
string (uuid)integerPosition within this run's history, starting at 1.
string,null"wait.timed_out"RunStatus
"running" | "sleeping" | "waiting" | "succeeded" | "failed" | "cancelled" | "stuck"running is being worked on; sleeping and waiting are parked and cost nothing; stuck means the run outlived its runTimeout. Succeeded, failed and cancelled are terminal.
SecretAction
objectstringWhy. Required, and recorded.
min length 8 · max length 1000
Signal
objectstringDedupe key. A repeat with the same key is reported duplicate, not delivered again.
max length 200
stringmin length 1 · max length 100
anySignalByKey
objectstringmin length 1
stringDedupe key. A repeat with the same key is reported duplicate, not delivered again.
max length 200
stringmin length 1 · max length 100
anystringmin length 1
SignalResult
objectbooleanbooleanbooleanSkip
objectanyOverrides the placeholder, for a step whose output the next one needs.
stringmin length 1 · max length 1000
StartRun
objectstringYour own identifier, for signalling later without tracking run ids.
max length 200
stringmax length 200
anystring[]max 20 items
integer (int64)min 1 · max 2147483647
stringmin length 1
StepControl
objectbooleanstringmax length 1000
number (double)min 0.1 · max 10000
StepControlState
objectstring,nullstringbooleanstring,nullstringstring (date-time)stringStepOccupancy
objectinteger (int64)Being worked on right now.
integer (int64)Parked on a sleep step.
stringinteger (int64)Unfinished runs sitting at this step.
integer (int64)Parked on a wait step, or on an async task.
TaskComplete
objectstringOverride the definition's next step. Must name a real step or a sentinel.
max length 100
anyTaskFail
objectobjectTaskPayload
objectstringinteger (int64)string,nullstring (date-time)After this the attempt is abandoned as timed out.
integer (int64)string{runId}:{generation}:{step}:{attempt}.
anyThe run's input.
string (uuid)map of anyEarlier steps' outputs, keyed by step name.
stringstring (uuid)Complete or fail the task with this.
stringW3C traceparent whose trace id is the run id.
stringinteger (int64)UpdateApp
objectstringmax length 500
string (uri)WorkflowDefinition
objectstringmax length 1000
stringmin length 1 · max length 100 · pattern ^[a-z0-9][a-z0-9-]*$
objectobject[]min 1 items · max 200 items
integermin 1 · max 2147483647
WorkflowDefinitionNode
objectA condition tree. and, or and not may nest at most 32 levels deep; a deeper tree is refused. A node has exactly one shape (a comparison, and, or or not); one carrying more than one is refused. A schema cannot express either rule, so they are stated here instead.
WorkflowHealth
objectmap of integer (int64)Run counts keyed by status; statuses with no runs are absent.
integer (int64)Runs that reached failed in the last 24 hours.
number,null (double)Age of the oldest due-but-unprocessed run. The scheduler-lag signal.
number,null (double)number,null (double)string[]integer (int64)integer (int64)[]stringWorkflowSummary
objectstring,nullinteger (int64)stringstring[]string[]integer (int64)[]WorkspaceMember
objectstringThe person's Clerk user id (user_...): what the credential history records as user:<id>.
stringAbsent until the person's profile has been mirrored from Clerk.
string (date-time)stringAbsent until the person's profile has been mirrored from Clerk.
"owner" | "operator" | "viewer"string (uuid)Foliot's id for the person: the id the role and removal routes take.
WorkspaceSummary
objectinteger (int64)How many apps it holds.
string (date-time)string (uuid)integer (int64)How many people belong to it, in any role.
stringinteger (int64)How many of them are owners.
string