API Reference
Runs
API reference for execution runs and their lifecycle.
ExecutionRun
Represents a single execution of a plan for a contact.
interface ExecutionRun {
id: string;
planId: string;
planVersion: number;
contactId: string;
status: RunStatus;
currentStep: string | null;
stepsCompleted: number;
stepsRemaining: number;
startTick: number;
currentTick: number;
startedAt: Date;
completedAt: Date | null;
outcome: string | null;
variables: Record<string, unknown>;
}
type RunStatus =
| 'pending'
| 'active'
| 'waiting'
| 'paused'
| 'completed'
| 'failed'
| 'cancelled';Listing Runs
engine.listRuns(filters)
const runs = await engine.listRuns(filters?: {
status?: RunStatus | RunStatus[];
planId?: string;
contactId?: string;
startedAfter?: Date;
startedBefore?: Date;
limit?: number;
offset?: number;
}): Promise<{ runs: ExecutionRun[]; total: number }>;Examples
// All active runs
const active = await engine.listRuns({ status: 'active' });
// Runs for a specific contact
const contactRuns = await engine.listRuns({ contactId: 'contact_123' });
// Failed runs in the last 24 hours
const failed = await engine.listRuns({
status: 'failed',
startedAfter: new Date(Date.now() - 86400000),
});Run Lifecycle
Starting a Run
const run = await engine.execute(plan, {
contact: { id: 'contact_123', email: 'jane@example.com' },
});
// run.status === 'active'Pausing and Resuming
await engine.pauseRun(run.id);
// run.status === 'paused'
await engine.resumeRun(run.id);
// run.status === 'active'Cancelling
await engine.cancelRun(run.id, 'Contact requested removal');
// run.status === 'cancelled'
// Recorded in audit log with reasonCompletion
Runs complete automatically when they reach an end step:
// After final step executes:
// run.status === 'completed'
// run.outcome === 'replied' (from the end step definition)Bulk Operations
engine.bulkExecute(plan, contacts)
Enroll multiple contacts into a plan:
const results = await engine.bulkExecute(plan, {
contacts: Contact[],
variables?: Record<string, unknown>, // shared variables
batchSize?: number, // default: 100
});
// results: { created: 950, skipped: 50, errors: 0 }
// Skipped = already enrolled or suppressedengine.bulkCancel(filters, reason)
Cancel runs matching filters:
await engine.bulkCancel(
{ planId: 'old-plan', status: 'active' },
'Plan deprecated'
);