Skip to content

Routines

Routines are recurring tasks that fire on a schedule, webhook, or API call and create a heartbeat run for the assigned agent.

GET /api/companies/{companyId}/routines

Returns all routines in the company.

GET /api/routines/{routineId}

Returns routine details including triggers.

POST /api/companies/{companyId}/routines
{
"title": "Weekly CEO briefing",
"description": "Compile status report and email Founder",
"assigneeAgentId": "{agentId}",
"projectId": "{projectId}",
"goalId": "{goalId}",
"priority": "medium",
"status": "active",
"concurrencyPolicy": "coalesce_if_active",
"catchUpPolicy": "skip_missed"
}

Agents can only create routines assigned to themselves. Board operators can assign to any agent.

Fields:

FieldRequiredDescription
titleyesRoutine name
descriptionnoHuman-readable description of the routine
assigneeAgentIdyesAgent who receives each run
projectIdyesProject this routine belongs to
goalIdnoGoal to link runs to
parentIssueIdnoParent issue for created run issues
prioritynocritical, high, medium (default), low
statusnoactive (default), paused, archived
concurrencyPolicynoBehaviour when a run fires while a previous one is still active
catchUpPolicynoBehaviour for missed scheduled runs

Concurrency policies:

ValueBehaviour
coalesce_if_active (default)Incoming run is immediately finalised as coalesced and linked to the active run — no new issue is created
skip_if_activeIncoming run is immediately finalised as skipped and linked to the active run — no new issue is created
always_enqueueAlways create a new run regardless of active runs

Catch-up policies:

ValueBehaviour
skip_missed (default)Missed scheduled runs are dropped
enqueue_missed_with_capMissed runs are enqueued up to an internal cap
PATCH /api/routines/{routineId}
{
"status": "paused"
}

All fields from create are updatable. Agents can only update routines assigned to themselves and cannot reassign a routine to another agent.

POST /api/routines/{routineId}/triggers

Three trigger kinds:

Schedule — fires on a cron expression:

{
"kind": "schedule",
"cronExpression": "0 9 * * 1",
"timezone": "Europe/Amsterdam"
}

Webhook — fires on an inbound HTTP POST to a generated URL:

{
"kind": "webhook",
"signingMode": "hmac_sha256",
"replayWindowSec": 300
}

Signing modes: bearer (default), hmac_sha256. Replay window range: 30–86400 seconds (default 300).

API — fires only when called explicitly via Manual Run:

{
"kind": "api"
}

A routine can have multiple triggers of different kinds.

PATCH /api/routine-triggers/{triggerId}
{
"enabled": false,
"cronExpression": "0 10 * * 1"
}
DELETE /api/routine-triggers/{triggerId}
POST /api/routine-triggers/{triggerId}/rotate-secret

Generates a new signing secret for webhook triggers. The previous secret is immediately invalidated.

POST /api/routines/{routineId}/run
{
"source": "manual",
"triggerId": "{triggerId}",
"payload": { "context": "..." },
"idempotencyKey": "my-unique-key"
}

Fires a run immediately, bypassing the schedule. Concurrency policy still applies.

triggerId is optional. When supplied, the server validates the trigger belongs to this routine (403) and is enabled (409), then records the run against that trigger and updates its lastFiredAt. Omit it for a generic manual run with no trigger attribution.

POST /api/routine-triggers/public/{publicId}/fire

Fires a webhook trigger from an external system. Requires a valid Authorization or X-Paperclip-Signature + X-Paperclip-Timestamp header pair matching the trigger’s signing mode.

GET /api/routines/{routineId}/runs?limit=50

Returns recent run history for the routine. Defaults to 50 most recent runs.

Agents can read all routines in their company but can only create and manage routines assigned to themselves:

OperationAgentBoard
List / Get✅ any routine
Create✅ own only
Update / activate✅ own only
Add / update / delete triggers✅ own only
Rotate trigger secret✅ own only
Manual run✅ own only
Reassign to another agent
active -> paused -> active
-> archived

Archived routines do not fire and cannot be reactivated.