Tasks
Poll for due tasks, run them, and report results
Task lifecycle
When a task is due, Nod pushes a task_due event to your agent via WebSocket (or webhook if offline). The server creates the run automatically — your agent just executes the prompt and reports the result. Polling endpoints are available as a fallback for agents without a persistent connection.
Receiving due tasks
When a scheduled task is due, Nod pushes it to your agent. The run is already created — just execute the prompt and complete the run.
task_due eventPushed via WebSocket or POSTed to your webhook_url when a scheduled task is due.
task_idrun_idtask_nametask_promptschedule{
"type": "task_due",
"task_id": "tsk_abc123",
"run_id": "run_xyz789",
"task_name": "Daily standup summary",
"task_prompt": "Summarize yesterday's git commits.",
"schedule": "0 9 * * 1-5"
}Polling (fallback)
If your agent doesn't have a WebSocket or webhook, you can poll for due tasks.
/api/agent/tasks/dueFallback: get tasks that are due to run now.
GET /api/agent/tasks/due X-Nod-Agent-Id: agt_abc123 X-Nod-Secret: nod_abc123...
[
{
"id": "tsk_abc123",
"name": "Daily standup summary",
"prompt": "Summarize yesterday's git commits.",
"schedule": "0 9 * * 1-5",
"trigger_type": "scheduled",
"enabled": true
}
]/api/agent/tasks/triggers/pendingGet queued webhook trigger events that arrived while the agent was offline.
GET /api/agent/tasks/triggers/pending X-Nod-Agent-Id: agt_abc123 X-Nod-Secret: nod_abc123...
[
{
"id": "evt_abc123",
"task_id": "tsk_xyz",
"task_name": "Process push",
"task_prompt": "Analyze the push event.",
"payload": { "ref": "refs/heads/main" },
"run_id": "run_abc123",
"received_at": "2025-09-01T10:30:00Z"
}
]/api/agent/tasks/:task_id/run/startStart a task run. Returns a run_id to track progress.
POST /api/agent/tasks/tsk_abc123/run/start X-Nod-Agent-Id: agt_abc123 X-Nod-Secret: nod_abc123...
{
"run_id": "run_abc123"
}/api/agent/tasks/runs/:run_id/completeMark a task run as completed or failed. For interactive agents, this automatically creates a task message in the chat — no separate message call needed.
statusrequiredsummaryChat message is created automatically
POST /api/agent/tasks/runs/run_abc123/complete
X-Nod-Agent-Id: agt_abc123
X-Nod-Secret: nod_abc123...
{
"status": "completed",
"summary": "## Daily Summary\n\n- **12 commits** across 3 PRs\n- 2 issues closed"
}{
"status": "completed",
"run_id": "run_abc123"
}/api/agent/tasks/runs/:run_idFetch a specific task run's details, including its output summary.
run_idrequiredsummary field contains the full task deliverable — this is the content that was set via nod-task-output during the task run, or the agent's text output. Use this endpoint when you need to programmatically access a task's results.GET /api/agent/tasks/runs/run_abc123 X-Nod-Agent-Id: agt_abc123 X-Nod-Secret: nod_abc123...
{
"id": "run_abc123",
"task_id": "tsk_abc123",
"agent_id": "agt_abc123",
"status": "completed",
"summary": "# Daily Standup Summary\n\n## PRs Merged\n- Fix login bug (#234)...",
"started_at": "2025-09-01T09:00:00Z",
"finished_at": "2025-09-01T09:02:30Z"
}/api/agent/tasksList all tasks assigned to this agent.
[
{
"id": "tsk_abc123",
"name": "Daily standup",
"prompt": "Summarize git activity.",
"schedule": "0 9 * * 1-5",
"trigger_type": "scheduled",
"next_run_at": "2025-09-02T09:00:00Z",
"last_run_status": "completed",
"enabled": true
},
{
"id": "tsk_xyz",
"name": "Process push",
"prompt": "Analyze the push event.",
"schedule": "event",
"trigger_type": "event",
"trigger_id": "a1b2c3d4...64chars",
"enabled": true
}
]/api/agent/tasksCreate a task directly from the agent (without a proposal flow).
namerequiredpromptrequiredschedulerequiredPOST /api/agent/tasks
X-Nod-Agent-Id: agt_abc123
X-Nod-Secret: nod_abc123...
{
"name": "Health check",
"prompt": "Run the test suite and report failures.",
"schedule": "0 */6 * * *"
}{
"id": "tsk_new123",
"name": "Health check",
"schedule": "0 */6 * * *",
"trigger_type": "scheduled",
"next_run_at": "2025-09-01T18:00:00Z",
"enabled": true
}Real-time task triggers
If your agent is connected via WebSocket and an external webhook fires, you receive a task_trigger event immediately — no polling needed.
task_trigger eventPushed via WebSocket when a webhook triggers a task.
task_idrun_idtask_nametask_promptpayload{
"type": "task_trigger",
"task_id": "tsk_xyz",
"run_id": "run_abc123",
"task_name": "Process push",
"task_prompt": "Analyze the push event.",
"payload": {
"ref": "refs/heads/main",
"commits": [{ "message": "Fix login bug" }]
}
}Task context (scratchpad)
For multi-step tasks that pause for user input (e.g., a decision request mid-execution), the context scratchpad lets you persist intermediate state between webhook invocations. Context blocks are auto-cleared when the task run completes.
/api/agent/tasks/runs/:run_id/contextAppend a context block to a task run's scratchpad.
run_idrequiredtextrequiredPOST /api/agent/tasks/runs/run_abc123/context
X-Nod-Agent-Id: agt_abc123
X-Nod-Secret: nod_abc123...
{
"run_id": "run_abc123",
"text": "Fetched daily goals: stand-up 9am, review PRs, ship invoice module"
}{
"status": "ok",
"block_id": 1
}/api/agent/tasks/runs/:run_id/contextRead all context blocks for a task run, ordered chronologically.
{
"run_id": "run_abc123",
"blocks": [
{ "id": 1, "text": "Fetched daily goals: ...", "created_at": "2025-09-01T09:00:05Z" },
{ "id": 2, "text": "User selected: review PRs first", "created_at": "2025-09-01T09:01:30Z" }
]
}Context is cleared on completion
POST /api/agent/tasks/runs/:run_id/complete, all context blocks for that run are automatically deleted. You don't need to clean up manually.Cron schedule examples
| Expression | Meaning |
|---|---|
| 0 9 * * 1-5 | Every weekday at 9:00 AM |
| 0 */6 * * * | Every 6 hours |
| 30 8 * * 1 | Every Monday at 8:30 AM |
| */15 * * * * | Every 15 minutes |