Skip to main content

Routines

Tags: automation, routines

Routines — the unified automation primitive (schedule, webhook, and system-event triggers)

Resources​

Request and response models used by the endpoints on this page.

CreateRoutineRequest​

FieldTypeRequiredDescription
agentIdMemberId
cronStringString
descriptionString
eventRulesArray<EventRuleData> | null
intervalSecondsInteger
limitIntegerDefault: 0
memberFilterIdInteger
nameString✓
promptString
repeatCountInteger
scheduleEnabledBooleanDefault: False
scheduleModeStringDefault: CRON
scheduledTimeString
skillsArray
startDateString
targetMemberIdInteger
timezoneString
visibilityStringDefault: workspace
webhookEnabledBooleanDefault: False
workflowIdInteger

Example:

{
"name": "string",
"scheduleEnabled": false,
"scheduleMode": "CRON",
"limit": 0,
"visibility": "workspace",
"webhookEnabled": false
}

EventRuleData​

FieldTypeRequiredDescription
actionParamsdict[str, Any]Parameters for the action
actionType<enum EventRuleActionType✓The action type to execute
activeBooleanWhether the rule is active (default: True)
conditionsStringCEL condition expression for conditional execution
delayIntegerDelay in seconds before executing the action (default: 0)
eventType<enum EventRuleEventType✓The event type that triggers this rule
nameStringDisplay name for the rule
objectTypeEventRuleObjectTypeThe object type this rule applies to (inferred from parent if not provided)
triggerParamsdict[str, Any]Parameters for the trigger (e.g., webhook config)
uuidString✓UUID for matching/creating event rules

Example:

{
"uuid": "string",
"eventType": null,
"actionType": null,
"active": true,
"delay": 0
}

EventRuleResponse​

FieldTypeRequiredDescription
actionParamsDict[str, Any]✓
actionSetLockedBooleanDefault: False
actionType<enum EventRuleActionType✓
activeBoolean✓
appConnectionIdInteger
calendarEventTypeIdInteger✓
calendarIdInteger✓
celBlockedAtDateTime
conditionsString✓
createdAtDateTime✓
dataTypeIdInteger✓
dataTypeNameString
delayInteger✓
errorString✓
errorMessageString✓
eventType<enum EventRuleEventType✓
failedAtDateTime✓
idInteger✓
journeyIdInteger
journeyStepIdInteger✓
nameString✓
objectType<enum EventRuleObjectType✓
orderInteger✓
routineIdInteger✓
taskIdInteger✓
taskNameString
taskWorkflowIdInteger
triggerParamsDict[str, Any]✓
updatedAtDateTime✓
uuidString✓
workflowRevisionIdInteger✓

Example:

{
"id": 0,
"uuid": "string",
"objectType": null,
"name": "string",
"eventType": null,
"conditions": "string",
"actionType": null,
"actionParams": {},
"triggerParams": {},
"active": false,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"taskId": 0,
"dataTypeId": 0,
"routineId": 0,
"workflowRevisionId": 0,
"calendarId": 0,
"calendarEventTypeId": 0,
"journeyStepId": 0,
"error": "string",
"errorMessage": "string",
"failedAt": "2024-01-01T00:00:00Z",
"delay": 0,
"order": 0,
"actionSetLocked": false
}

MemberSummary​

FieldTypeRequiredDescription
idInteger✓
nameString

Example:

{
"id": 0
}

PaginatedResponse[RoutineResponse]​

FieldTypeRequiredDescription
itemsArray<RoutineResponse>✓
pageInteger✓
pageSizeInteger✓
totalInteger✓
totalPagesInteger✓

Example:

{
"items": [],
"total": 0,
"page": 0,
"pageSize": 0,
"totalPages": 0
}

PaginatedResponse[RoutineRunResponse]​

FieldTypeRequiredDescription
itemsArray<RoutineRunResponse>✓
pageInteger✓
pageSizeInteger✓
totalInteger✓
totalPagesInteger✓

Example:

{
"items": [],
"total": 0,
"page": 0,
"pageSize": 0,
"totalPages": 0
}

RoutineConfigEventResponse​

FieldTypeRequiredDescription
actorMemberSummary | null
actorMemberIdInteger
actorType<enum RoutineConfigEventActorType✓
fieldsChangedArray
idInteger✓
occurredAtDateTime✓
reason<enum RoutineConfigEventReason✓
routineIdInteger✓
scheduleEnabledAfterBoolean
scheduleEnabledBeforeBoolean
scheduleTransitionedBoolean✓
uuidString✓
webhookEnabledAfterBoolean
webhookEnabledBeforeBoolean
webhookTransitionedBoolean✓

Example:

{
"id": 0,
"uuid": "string",
"routineId": 0,
"occurredAt": "2024-01-01T00:00:00Z",
"actorType": null,
"reason": null,
"scheduleTransitioned": false,
"webhookTransitioned": false
}

RoutineResponse​

FieldTypeRequiredDescription
agentIdInteger
createdAtDateTime✓
cronStringString
descriptionString
eventRulesArray<EventRuleResponse>Default: []
idInteger✓
intervalSecondsInteger
limitInteger✓
memberFilterIdInteger
memberFilterNameString
nameString✓
nextRunDateTime
ownerIdInteger✓
promptString
repeatCountInteger
scheduleEnabledBoolean✓
scheduleModeString✓
scheduledTimeDateTime
skillsArray
startDateDateTime
targetMemberIdInteger
timezoneString
updatedAtDateTime✓
uuidString✓
visibilityString✓
webhookEnabledBooleanDefault: False
webhookSecretPlaintextString
workflowIdInteger

Example:

{
"id": 0,
"uuid": "string",
"name": "string",
"scheduleEnabled": false,
"scheduleMode": "string",
"limit": 0,
"visibility": "string",
"ownerId": 0,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"eventRules": [],
"webhookEnabled": false
}

RoutineRunResponse​

FieldTypeRequiredDescription
assignmentIdInteger
chatIdInteger
completedAtDateTime
completionMessageIdInteger
createdAtDateTime✓
errorMessageString
failureCodeString
idInteger✓
jobIdString
memberMemberSummary | null
memberIdInteger
parentRunIdInteger
routineIdInteger✓
skipReasonString
startedAtDateTime
statusString✓
updatedAtDateTime✓
uuidString✓

Example:

{
"id": 0,
"uuid": "string",
"routineId": 0,
"status": "string",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z"
}

RoutineVoiceReadinessPreviewRequest​

FieldTypeRequiredDescription
eventRulesArray<EventRuleData> | null
memberFilterIdInteger
nameString
routineIdInteger
targetMemberIdInteger

Example:

{}

RoutineVoiceReadinessPreviewResponse​

FieldTypeRequiredDescription
totalWarningsInteger✓
warningsArray<RoutineVoiceReadinessWarningResponse>✓

Example:

{
"warnings": [],
"totalWarnings": 0
}

RoutineVoiceReadinessWarningResponse​

FieldTypeRequiredDescription
actionTypeString✓
affectedMemberCountInteger✓
audienceSizeInteger✓
codeLiteral['audience_empty', 'audience_filter_not_authorized', 'audience_voice_disabled', 'audience_missing_phone', 'phone_number_missing', 'phone_number_unresolved', 'phone_number_archived', 'phone_number_voice_disabled']✓
eventRuleIdInteger
eventRuleUuidString
phoneNumberIdInteger
phoneNumberNameString
routineIdInteger
routineNameString
targetKindLiteral['member', 'member_filter', 'owner', 'none']✓

Example:

{
"actionType": "string",
"code": "audience_empty",
"targetKind": "member",
"audienceSize": 0,
"affectedMemberCount": 0
}

SchedulePreviewRequest​

FieldTypeRequiredDescription
countIntegerDefault: 5
cronStringString✓
timezoneString

Example:

{
"cronString": "string",
"count": 5
}

SchedulePreviewResponse​

FieldTypeRequiredDescription
nextRunsArray✓

Example:

{
"nextRuns": []
}

UpdateRoutineRequest​

FieldTypeRequiredDescription
agentIdMemberId
cronStringString
descriptionString
eventRulesArray<EventRuleData> | null
intervalSecondsInteger
limitInteger
memberFilterIdInteger
nameString
promptString
repeatCountInteger
rotateWebhookSecretBoolean
scheduleEnabledBoolean
scheduleModeString
scheduledTimeString
skillsArray
startDateString
targetMemberIdInteger
timezoneString
visibilityString
webhookEnabledBoolean
workflowIdInteger

Example:

{}

Endpoints​

List​

GET /api/v2/w/{workspace_uuid}/routines

Description:

List all Routines for the workspace with pagination.

Visibility rules, owner/ownerId composition and the query itself: lib/services/routine_read_service.py.

Authorization: Requires automations:read scope

Parameters:

  • page (Integer) — min: 1
  • pageSize (Integer) — min: 1, max: 100
  • sortBy (RoutineSortField)
  • sortOrder (SortOrder)
  • owner (String)
  • ownerId (Integer)
  • agentId (Integer) — min: 1
  • agentOnly (Boolean)

Response: See PaginatedResponse[RoutineResponse]


Create​

POST /api/v2/w/{workspace_uuid}/routines

Description:

Create a new Routine.

Authorization: Requires automations:write scope

Parameters:

Response: See RoutineResponse


Preview Schedule​

POST /api/v2/w/{workspace_uuid}/routines/preview-schedule

Description:

Preview the next N run times for a cron expression.

An omitted/blank timezone falls back to the workspace's, then UTC — the same precedence the schedulers apply, so the preview cannot promise a wall-clock the dispatcher will not honour. This is what the editor already does client-side; sending the fallback through the server too keeps a direct API/CLI caller from getting a different answer.

Authorization: Requires automations:read scope

Parameters:

Response: See SchedulePreviewResponse


Preview Voice Readiness​

POST /api/v2/w/{workspace_uuid}/routines/preview-voice-readiness

Description:

Non-blocking preview of what would stop this Routine placing its calls.

Warn-not-block authoring assist, read-only and non-persisting. It evaluates the draft's target audience and its phone:call actions against the prerequisites the dispatch path actually enforces — the Member voice opt-out, a reachable member phone, and a resolvable, unarchived, voice-enabled workspace number.

Every one of those failures is silent today: the opt-out makes the action skip, which leaves the RoutineRun COMPLETED, so the schedule looks like it ran and no call was placed (CS-173). This endpoint is the surface that says so before the schedule fires.

There is no hard create/update sibling to this check: an unready audience is a transient member-data condition, not a structural one, so blocking the save would refuse a Routine that becomes correct the moment someone toggles a Member preference. Advisory is the right and only posture here.

No PHI reaches the response: the audience is aggregated in SQL and comes back as counts, never rows. (The predicates do read Member.phone and Member.notify_voice — that is the question being asked; no value from either column crosses the wire, a log, or a breadcrumb.)

The counts are an upper bound over the whole matched cohort and do not honour Routine.limit, which caps how many members a single run dispatches to. A capped Routine can therefore be warned about members it would not have reached on the next slot; it is never silent about members it would.

Authorization: Requires automations:write scope

Parameters:

Response: See RoutineVoiceReadinessPreviewResponse


Runs​

GET /api/v2/w/{workspace_uuid}/routines/runs

Description:

List all Routine runs for the workspace with pagination.

Only runs for Routines the caller can see are returned. The visibility join and the routineId/status filters live in lib/services/routine_read_service.py.

Authorization: Requires automations:read scope

Parameters:

  • page (Integer) — min: 1
  • pageSize (Integer) — min: 1, max: 100
  • sortBy (EventRunSortField)
  • sortOrder (SortOrder)
  • routineId (Integer)
  • status (String)

Response: See PaginatedResponse[RoutineRunResponse]


Delete Event Id​

DELETE /api/v2/w/{workspace_uuid}/routines/{event_id}

Description:

Delete a Routine.

Authorization: Requires automations:admin scope

Parameters:

  • event_id (Integer)

Response: dict[str, str]


Get Event Id​

GET /api/v2/w/{workspace_uuid}/routines/{event_id}

Description:

Get a specific Routine by ID.

Authorization: Requires automations:read scope

Parameters:

  • event_id (Integer)

Response: See RoutineResponse


Update Event Id​

PUT /api/v2/w/{workspace_uuid}/routines/{event_id}

Description:

Update an existing Routine.

Authorization: Requires automations:write scope

Parameters:

Response: See RoutineResponse


History​

GET /api/v2/w/{workspace_uuid}/routines/{event_id}/history

Description:

Config-change history for one Routine, newest first (GH #22937).

Access rules and rationale: lib/services/routine_history_service.py.

Authorization: Requires automations:read scope

Parameters:

  • event_id (Integer)
  • limit (Integer)
  • before_id (Integer)
  • transitions_only (Boolean)

Response: List of RoutineConfigEventResponse


Run​

POST /api/v2/w/{workspace_uuid}/routines/{event_id}/run

Description:

Run a Routine manually.

Authorization: Requires automations:write scope

Parameters:

  • event_id (Integer)
  • member_id (Integer)
  • member_filter_id (Integer)

Response: dict[str, str]


Delete Runs​

DELETE /api/v2/w/{workspace_uuid}/routines/{event_id}/runs

Description:

Reset/clear all runs for a Routine.

Orchestration, ordering and rationale: lib/services/routine_reset_service.py.

Authorization: Requires automations:admin scope

Parameters:

  • event_id (Integer)

Response: dict[str, str | int]