Base URL http://localhost:3333/api/ · Authentication · Conventions

Schedule Routes

Base path: /api/schedules

The durable cron scheduler (PRD-091 Layer 1). Use when the user wants recurring execution of a goal. Survives backend restart, uses in-zone DST-correct timing, idempotent on last_run. Hangs on HeartbeatService — no separate process.

Schedule shape

{
  "id": "uuid",
  "user_id": "user-uuid",
  "target_type": "goal",
  "target_id": "goal-uuid",
  "cron": "0 9 * * MON-FRI",
  "timezone": "America/New_York",
  "next_run": "2026-06-22T13:00:00.000Z",
  "last_run": "2026-06-19T13:00:00.000Z",
  "enabled": true,
  "on_missed": "fire_once",
  "created_at": "..."
}

Supported cron syntax

5-field cron (minute hour dom month dow) plus macros:

  • Macros: @hourly, @daily, @midnight, @weekly, @monthly, @yearly, @annually
  • Fields: *, */N, A-B, A,B,C, day-of-week names (MONSUN), 7 aliases to 0 (Sunday)
  • Dom/dow OR semantics: when both restricted, the schedule fires when either matches (standard cron)
  • Timezone: IANA name (e.g. America/New_York, Europe/London). Defaults to UTC.

on_missed values

Value Behavior on backend restart
fire_once (default) If next_run is in the past, fire once then resume
fire_all Fire once for each missed slot (use sparingly — can cascade)
skip Skip missed firings; only resume forward

List Schedules

GET /

  • Authentication: Required
  • Response:
{ "success": true, "schedules": [ { ... } ] }

Get Schedules by Target

GET /target/:targetType/:targetId

  • Authentication: Required
  • Parameters:
    • targetType (path): goal (MVP currently only supports goal)
    • targetId (path): the goal ID
  • Description: Useful for the Goals UI to show "this goal is scheduled."
  • Response:
{ "success": true, "schedules": [ { ... } ] }

Preview Cron Firings (No Persist)

POST /preview

  • Authentication: Required
  • Body:
{
  "cron": "0 9 * * MON-FRI",
  "timezone": "America/New_York",
  "count": 5
}
  • Description: Validates the cron expression and returns the next count firing times (max 25). Persists nothing. Use this when surfacing "this schedule will next fire on..." in the UI before the user clicks Create.
  • Response:
{
  "success": true,
  "previews": [
    "2026-06-22T13:00:00.000Z",
    "2026-06-23T13:00:00.000Z",
    "2026-06-24T13:00:00.000Z"
  ]
}
  • Errors: 400 when cron is missing or invalid.

Create Schedule

POST /

  • Authentication: Required
  • Body:
{
  "targetType": "goal",
  "targetId": "goal-uuid",
  "cron": "0 9 * * MON-FRI",
  "timezone": "America/New_York",
  "enabled": true,
  "onMissed": "fire_once"
}
  • Description: Creates a schedule. next_run is computed from cron + timezone. enabled defaults to true. onMissed defaults to fire_once.
  • Response (201):
{ "success": true, "schedule": { ... } }
  • Errors:
    • 400 when targetType, targetId, or cron is missing
    • 400 when cron is invalid (per isValidCron)

Update Schedule

PATCH /:id

  • Authentication: Required
  • Body (any subset):
{
  "cron": "0 10 * * MON-FRI",
  "timezone": "Europe/London",
  "enabled": false,
  "onMissed": "skip"
}
  • Description: Updates schedule fields. When cron, timezone, or onMissed change, next_run is recomputed. Setting enabled: false pauses without deleting.
  • Response:
{ "success": true, "schedule": { ... } }
  • Errors: 404 not found, 403 forbidden, 400 invalid cron

Fire Schedule Now

POST /:id/fire-now

  • Authentication: Required
  • Description: Manually trigger the schedule's target (currently invokes TaskOrchestrator.executeGoalAutonomous). Does NOT update next_run — the regular cadence continues unaffected. Useful for "test run" or "I want it now."
  • Response:
{ "success": true, "result": { "executionId": "...", "status": "running" } }

Get Run History

GET /:id/runs

  • Authentication: Required
  • Parameters:
    • limit (query, optional): max 500, default 50
  • Response:
{
  "success": true,
  "runs": [
    {
      "id": "run-uuid",
      "schedule_id": "schedule-uuid",
      "fired_at": "2026-06-19T13:00:00.000Z",
      "execution_id": "exec-uuid",
      "status": "completed",
      "duration_ms": 4823
    }
  ]
}

Delete Schedule

DELETE /:id

  • Authentication: Required
  • Response:
{ "success": true, "deleted": true }

Email Listener Routes

Base path: /api/email-listeners

Get Email Listeners

GET /

  • Authentication: Required
  • Description: Get all workflows with receive-email trigger nodes for the authenticated user
  • Response:
{
  "success": true,
  "listeners": [
    {
      "id": "workflow-id",
      "workflow_id": "workflow-id",
      "workflow_name": "Email Handler Workflow",
      "workflow_status": "active",
      "email_address": "workflow-123@agnt.gg",
      "email_config": "Built-in Email",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-01T00:00:00Z"
    }
  ]
}