Workflow Metrics
Operational endpoints for monitoring workflow health across the tenant. Use these to build dashboards, set up alerting thresholds, or identify stuck workflows.
Required Role
MEMBER
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
X-Tenant-ID | Tenant identifier string | Yes |
Aggregate Metrics
Retrieve a count of workflows grouped by status. This gives a high-level snapshot of the system's current operational state.
Endpoint
GET /api/v1/workflows/metrics
Response Body
json
{
"READY": 14,
"RUNNING": 203,
"COMPLETED": 98421,
"FAILED": 37,
"COMPENSATING": 2,
"COMPENSATED": 18,
"COMPENSATION_FAILED": 1
}The response is a flat object mapping each status to its current workflow count. All status keys are always present, with a value of 0 when no workflows exist in that state.
Status Values
| Status | Terminal | Description |
|---|---|---|
READY | No | Created but not yet started. |
RUNNING | No | Actively executing. |
COMPLETED | Yes | Finished successfully. |
FAILED | Yes | Terminated due to an unrecoverable error. |
COMPENSATING | No | Executing compensation (rollback) steps. |
COMPENSATED | Yes | Compensation completed successfully. |
COMPENSATION_FAILED | Yes | Compensation steps also failed. |
Examples
bash
curl -X GET "https://policy.aster-lang.dev/api/v1/workflows/metrics" \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-ID: acme-corp"js
const response = await fetch(
'https://policy.aster-lang.dev/api/v1/workflows/metrics',
{
headers: {
Authorization: 'Bearer <token>',
'X-Tenant-ID': 'acme-corp',
},
}
);
const metrics = await response.json();
// Alert if any workflows are stuck in a compensation failure state
if (metrics.COMPENSATION_FAILED > 0) {
console.warn(`${metrics.COMPENSATION_FAILED} workflow(s) require manual intervention`);
}List Workflows by Status
Retrieve a list of workflow IDs currently in a given status. Useful for drilling into specific workflows after identifying a concern from the aggregate metrics.
Endpoint
GET /api/v1/workflows/by-status/{status}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
status | string | The workflow status to filter by. Must be one of the values listed in the Status Values table above. |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | No | Maximum number of workflow IDs to return. Defaults to 100. The server may enforce its own maximum cap. |
Response Body
json
{
"status": "RUNNING",
"workflowIds": [
"wf-abc123",
"wf-def456",
"wf-ghi789"
],
"count": 3
}| Field | Type | Description |
|---|---|---|
status | string | The requested status (mirrors the path parameter). |
workflowIds | string[] | List of matching workflow identifiers, ordered by creation time descending. |
count | integer | Number of IDs returned in this response. May be less than the total if results were capped by limit. |
Examples
bash
# List up to 100 running workflows (default limit)
curl -X GET "https://policy.aster-lang.dev/api/v1/workflows/by-status/RUNNING" \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-ID: acme-corp"
# List up to 10 failed workflows
curl -X GET "https://policy.aster-lang.dev/api/v1/workflows/by-status/FAILED?limit=10" \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-ID: acme-corp"js
async function getWorkflowsByStatus(status, limit = 100) {
const params = new URLSearchParams({ limit: String(limit) });
const response = await fetch(
`https://policy.aster-lang.dev/api/v1/workflows/by-status/${status}?${params}`,
{
headers: {
Authorization: 'Bearer <token>',
'X-Tenant-ID': 'acme-corp',
},
}
);
return response.json();
}
// Inspect the first 10 failed workflows
const { workflowIds } = await getWorkflowsByStatus('FAILED', 10);
for (const id of workflowIds) {
const stateRes = await fetch(
`https://policy.aster-lang.dev/api/v1/workflows/${id}/state`,
{ headers: { Authorization: 'Bearer <token>', 'X-Tenant-ID': 'acme-corp' } }
);
const state = await stateRes.json();
console.log(id, state.updatedAt, state.lastEventSeq);
}HTTP Status Codes
| Status | Meaning |
|---|---|
200 OK | Request succeeded. |
400 Bad Request | Invalid status value or malformed limit parameter. |
401 Unauthorized | Missing or invalid bearer token. |
403 Forbidden | Token is valid but the caller lacks the MEMBER role. |
500 Internal Server Error | Unexpected engine failure. |