Exports
Export endpoints expose workflow state and execution history. The execution history endpoint produces structured, typed events for debugging, auditing and data migration.
Auth: Every endpoint requires builder access (superadmin or the engineer role), except GET /api/workflow-states/:workflowId/execution. That endpoint is open to builders and to the person who started the run or the account it runs as (read from the run’s start envelope: lt.userId, or lt.initiatedBy when it runs under execute_as); others receive 403.
Every endpoint resolves the workflow from the workflowId alone.
List workflow jobs
Section titled “List workflow jobs”GET /api/workflow-states/jobsLists workflow jobs with optional filtering and pagination. Requires a namespace.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
app_id |
string |
Yes | Application namespace (alias: namespace) |
entity |
string |
No | Filter by entity name |
search |
string |
No | Search by workflow ID substring |
status |
string |
No | Filter by status: running, completed, failed |
sort_by |
string |
No | Sort field |
order |
string |
No | Sort direction: asc or desc |
registered |
string |
No | Filter by registration status |
limit |
integer |
No | Max results |
offset |
integer |
No | Pagination offset |
Example request
curl "https://lt.acme.dev/api/workflow-states/jobs?app_id=durable&status=running&limit=25" \ -H "Authorization: Bearer $LT_TOKEN"Response 400: Missing app_id.
Raw workflow state
Section titled “Raw workflow state”GET /api/workflow-states/:workflowIdExports the full workflow state using HotMesh’s durable export. The response includes facets (data, state, status, timeline, transitions) that can be filtered.
Path parameters
| Parameter | Type | Description |
|---|---|---|
workflowId |
string |
Workflow id |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
allow |
string |
no | Comma-separated allowlist of facets: data, state, status, timeline, transitions |
block |
string |
no | Comma-separated blocklist of facets |
values |
string |
no | Set to false to omit timeline values |
allow and block are mutually exclusive. If both are provided, allow takes precedence.
Example request (only data and status):
curl "https://lt.acme.dev/api/workflow-states/reviewContent-a1b2c3d4?allow=data,status" \ -H "Authorization: Bearer $LT_TOKEN"Response 200: Raw workflow state object from HotMesh. The structure follows the facet selection.
Response 404
{ "error": "No task found for workflow \"unknown-id\"" }Execution history
Section titled “Execution history”GET /api/workflow-states/:workflowId/executionExports the workflow’s execution history as structured, typed events (workflow_execution_started, activity_task_scheduled, activity_task_completed and so on) with ISO timestamps, durations and cross-references.
Path parameters
| Parameter | Type | Description |
|---|---|---|
workflowId |
string |
Workflow id |
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
excludeSystem |
string |
no | false |
Set to true to omit LT interceptor activities (lt*) |
omitResults |
string |
no | false |
Set to true to strip activity result payloads |
mode |
string |
no | sparse |
sparse (flat events) or verbose (includes nested child workflow executions) |
maxDepth |
integer |
no | 5 |
Recursion depth limit for verbose mode |
Example request (execution history without system activities):
curl "https://lt.acme.dev/api/workflow-states/reviewContent-a1b2c3d4/execution?excludeSystem=true" \ -H "Authorization: Bearer $LT_TOKEN"Response 200
{ "workflowId": "reviewContent-a1b2c3d4", "workflowName": "reviewContent", "taskQueue": "long-tail", "events": [ { "eventId": 1, "eventType": "workflow_execution_started", "timestamp": "2025-01-15T10:00:00.000Z", "details": { "input": { "data": { "contentId": "post-456" }, "metadata": {} } } }, { "eventId": 2, "eventType": "activity_task_scheduled", "timestamp": "2025-01-15T10:00:00.050Z", "details": { "activityType": "analyzeContent", "taskQueue": "long-tail" } }, { "eventId": 3, "eventType": "activity_task_completed", "timestamp": "2025-01-15T10:00:02.300Z", "details": { "scheduledEventId": 2, "duration": "2.250s", "result": { "confidence": 0.92 } } }, { "eventId": 4, "eventType": "workflow_execution_completed", "timestamp": "2025-01-15T10:00:02.350Z", "details": { "result": { "approved": true } } } ], "summary": { "totalEvents": 4, "duration": "2.350s", "status": "completed" }}Verbose mode includes nested children arrays for orchestrator workflows, each holding the child workflow’s full event sequence. Use maxDepth to limit recursion for deeply nested orchestrations.
Workflow status
Section titled “Workflow status”GET /api/workflow-states/:workflowId/statusReturns the numeric status semaphore from HotMesh.
Path parameters
| Parameter | Type | Description |
|---|---|---|
workflowId |
string |
Workflow id |
Example request
curl https://lt.acme.dev/api/workflow-states/reviewContent-a1b2c3d4/status \ -H "Authorization: Bearer $LT_TOKEN"Response 200
{ "workflow_id": "reviewContent-a1b2c3d4", "status": 0 }| Value | Meaning |
|---|---|
0 |
Complete |
| Positive | Running |
| Negative | Interrupted |
Workflow state
Section titled “Workflow state”GET /api/workflow-states/:workflowId/stateReturns the current job state of the workflow: the internal HotMesh representation of where the workflow is in its execution.
Path parameters
| Parameter | Type | Description |
|---|---|---|
workflowId |
string |
Workflow id |
Example request
curl https://lt.acme.dev/api/workflow-states/reviewContent-a1b2c3d4/state \ -H "Authorization: Bearer $LT_TOKEN"Response 200: HotMesh job state object. Its structure follows the workflow’s current execution point.
Programmatic access
Section titled “Programmatic access”The same data is available through the Durable client:
const client = new Durable.Client({ connection });const handle = await client.workflow.getHandle( taskQueue, workflowName, workflowId,);
// Execution historyconst execution = await handle.exportExecution({ exclude_system: true,});
// Raw state exportconst state = await handle.export({ allow: ['data', 'status'],});