NetStacksNetStacks

Tasks API

Schedule and monitor automated tasks including backups, health checks, agent tasks, and custom scripts with cron-based scheduling.

Overview

The Tasks API lets you create, manage, and monitor scheduled automation tasks. NetStacks supports several task types including backups, health checks, agent tasks (AI-driven automation), and custom scripts. Tasks run on cron schedules with timezone support and configurable retry logic.

Task endpoints are nested under /api/tasks and require authentication. The API provides two sub-routers:

  • /api/tasks/schedules — General scheduled tasks (all types: backup, health_check, custom_script, agent_task)
  • /api/tasks/agent-schedules — Agent task schedules specifically (simplified interface for AI-driven tasks)
Task Types

Available task types: backup, health_check, custom_script, agent_task. Each type has its own parameter schema passed in the parameters field.

How It Works

Task Lifecycle

Scheduled tasks follow this lifecycle: created scheduled (waiting for next cron trigger) → runningcompleted or failed. Each execution creates a separate execution record with start/end times, status, and results.

Cron Scheduling

Tasks use standard cron expressions with timezone support. Examples:

  • 0 2 * * * — Every day at 2:00 AM
  • 0 */6 * * * — Every 6 hours
  • 0 9 * * 1-5 — Weekdays at 9:00 AM
  • 0 0 1 * * — First day of each month at midnight

Retry Configuration

Tasks support automatic retries on failure with configurable max retries (default: 3) and retry delay (default: 60 seconds). Agent tasks default to a 1-hour timeout.

Endpoints Summary

MethodPathDescription
GET/api/tasks/schedulesList all scheduled tasks
POST/api/tasks/schedulesCreate a scheduled task
GET/api/tasks/schedules/:idGet task details
PUT/api/tasks/schedules/:idUpdate a task
DELETE/api/tasks/schedules/:idDelete a task
POST/api/tasks/schedules/:id/runRun task immediately
POST/api/tasks/schedules/:id/toggleEnable/disable a task

Step-by-Step Guide

1. Authenticate

Obtain a JWT token from the Authentication API.

2. Create a Scheduled Task

Send a POST with the task name, type, cron expression, timezone, and type-specific parameters.

3. List Scheduled Tasks

Use GET /api/tasks/schedules to view all tasks with their next run times and enabled status.

4. Monitor Executions

After a task runs, check its execution record for status, timing, and per-device results.

5. Run a Task Manually

Trigger an immediate execution with POST /api/tasks/schedules/:id/run. Returns 202 Accepted and the execution runs in the background.

6. Toggle or Delete Tasks

Disable a task without deleting it via the toggle endpoint, or delete it permanently.

Code Examples

Create a Scheduled Backup Task

create-backup-task.shbash
curl -X POST https://netstacks.example.net/api/tasks/schedules \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nightly DC1 Core Backup",
    "description": "Backup running configs for all DC1 core routers",
    "task_type": "backup",
    "cron_expression": "0 2 * * *",
    "timezone": "America/New_York",
    "parameters": {
      "device_ids": [
        "f47ac10b-58cc-4372-a567-0e02b2c3d479",
        "e36bd20a-47bb-3261-9456-1d13a1b2c368"
      ],
      "capture_running": true,
      "capture_startup": true
    },
    "enabled": true
  }'

# Response (201 Created):
# {
#   "id": "a9b8c7d6-e5f4-3210-9876-543210fedcba",
#   "name": "Nightly DC1 Core Backup",
#   "task_type": "backup",
#   "cron_expression": "0 2 * * *",
#   "timezone": "America/New_York",
#   "enabled": true,
#   "next_run_at": "2026-03-11T07:00:00Z",
#   "created_at": "2026-03-10T17:00:00Z"
# }
create-backup-task.pypython
import requests

base_url = "https://netstacks.example.net/api"
headers = {"Authorization": "Bearer eyJhbGciOiJIUzI1NiIs..."}

# Create a nightly backup task
task = requests.post(f"{base_url}/tasks/schedules", headers=headers, json={
    "name": "Nightly DC1 Core Backup",
    "description": "Backup running configs for all DC1 core routers",
    "task_type": "backup",
    "cron_expression": "0 2 * * *",
    "timezone": "America/New_York",
    "parameters": {
        "device_ids": [
            "f47ac10b-58cc-4372-a567-0e02b2c3d479",
            "e36bd20a-47bb-3261-9456-1d13a1b2c368"
        ],
        "capture_running": True,
        "capture_startup": True
    },
    "enabled": True
})
task_data = task.json()
print(f"Created task: {task_data['id']}")
print(f"Next run: {task_data.get('next_run_at', 'calculating...')}")
create-backup-task.tstypescript
const BASE_URL = "https://netstacks.example.net/api";
const headers = {
  Authorization: "Bearer eyJhbGciOiJIUzI1NiIs...",
  "Content-Type": "application/json",
};

const taskResp = await fetch(`${BASE_URL}/tasks/schedules`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    name: "Nightly DC1 Core Backup",
    description: "Backup running configs for all DC1 core routers",
    task_type: "backup",
    cron_expression: "0 2 * * *",
    timezone: "America/New_York",
    parameters: {
      device_ids: [
        "f47ac10b-58cc-4372-a567-0e02b2c3d479",
        "e36bd20a-47bb-3261-9456-1d13a1b2c368",
      ],
      capture_running: true,
      capture_startup: true,
    },
    enabled: true,
  }),
});
const task = await taskResp.json();
console.log(`Created task: ${task.id}`);
console.log(`Next run: ${task.next_run_at}`);

List Scheduled Tasks

list-tasks.shbash
curl "https://netstacks.example.net/api/tasks/schedules?limit=20" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

# Response:
# {
#   "tasks": [
#     {
#       "id": "a9b8c7d6-e5f4-3210-9876-543210fedcba",
#       "name": "Nightly DC1 Core Backup",
#       "task_type": "backup",
#       "cron_expression": "0 2 * * *",
#       "timezone": "America/New_York",
#       "enabled": true,
#       "last_run_at": "2026-03-10T07:00:00Z",
#       "next_run_at": "2026-03-11T07:00:00Z"
#     }
#   ],
#   "total": 5,
#   "limit": 20,
#   "offset": 0
# }
list-tasks.pypython
# List all scheduled tasks
tasks = requests.get(
    f"{base_url}/tasks/schedules",
    headers=headers,
    params={"limit": 20}
).json()
for t in tasks["tasks"]:
    status = "enabled" if t["enabled"] else "disabled"
    print(f"{t['name']} ({t['task_type']}) - {status} - next: {t.get('next_run_at', 'N/A')}")
list-tasks.tstypescript
const listResp = await fetch(`${BASE_URL}/tasks/schedules?limit=20`, {
  headers: { Authorization: "Bearer eyJhbGciOiJIUzI1NiIs..." },
});
const taskList = await listResp.json();
taskList.tasks.forEach((t: any) => {
  const status = t.enabled ? "enabled" : "disabled";
  console.log(`${t.name} (${t.task_type}) - ${status} - next: ${t.next_run_at ?? "N/A"}`);
});

Run a Task Immediately

run-task.shbash
# Trigger immediate execution (returns 202 Accepted)
curl -X POST https://netstacks.example.net/api/tasks/schedules/a9b8c7d6-.../run \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

# Response (202 Accepted):
# {
#   "id": "exec-uuid",
#   "task_id": "a9b8c7d6-...",
#   "status": "running",
#   "trigger": "manual",
#   "started_at": "2026-03-10T17:30:00Z"
# }
run-task.pypython
# Trigger immediate execution
execution = requests.post(
    f"{base_url}/tasks/schedules/{task_data['id']}/run",
    headers=headers
)
print(f"Execution started: {execution.json()['id']}")
run-task.tstypescript
const runResp = await fetch(`${BASE_URL}/tasks/schedules/${task.id}/run`, {
  method: "POST",
  headers,
});
const execution = await runResp.json();
console.log(`Execution started: ${execution.id}`);

Toggle Task Enabled/Disabled

toggle-task.shbash
# Disable a task
curl -X POST https://netstacks.example.net/api/tasks/schedules/a9b8c7d6-.../toggle \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

Create an Agent Task Schedule

create-agent-task.shbash
# Create a scheduled AI agent task
curl -X POST https://netstacks.example.net/api/tasks/agent-schedules \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly Config Audit",
    "description": "AI agent reviews config changes and flags anomalies",
    "prompt": "Review all config backups from the past 7 days. Flag any unauthorized changes, security policy violations, or BGP route leaks.",
    "cron_expression": "0 9 * * 1",
    "timezone": "America/Chicago",
    "enabled": true
  }'
create-agent-task.pypython
# Create a weekly AI agent audit task
agent_task = requests.post(f"{base_url}/tasks/agent-schedules", headers=headers, json={
    "name": "Weekly Config Audit",
    "description": "AI agent reviews config changes and flags anomalies",
    "prompt": "Review all config backups from the past 7 days. Flag any unauthorized changes, security policy violations, or BGP route leaks.",
    "cron_expression": "0 9 * * 1",
    "timezone": "America/Chicago",
    "enabled": True
})
print(f"Agent task created: {agent_task.json()['id']}")
create-agent-task.tstypescript
const agentResp = await fetch(`${BASE_URL}/tasks/agent-schedules`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    name: "Weekly Config Audit",
    description: "AI agent reviews config changes and flags anomalies",
    prompt: "Review all config backups from the past 7 days. Flag any unauthorized changes, security policy violations, or BGP route leaks.",
    cron_expression: "0 9 * * 1",
    timezone: "America/Chicago",
    enabled: true,
  }),
});
const agentTask = await agentResp.json();
console.log(`Agent task created: ${agentTask.id}`);

Questions & Answers

How do I create a scheduled task?
Send a POST to /api/tasks/schedules with the task name, task_type, cron_expression, timezone, and type-specific parameters. The task will execute automatically on the defined schedule.
What task types are available?
NetStacks supports four task types: backup (configuration backup), health_check (device connectivity and status checks), custom_script (user-defined scripts), and agent_task (AI-driven automation with a natural language prompt).
How do I monitor a running task?
After triggering a task (manually or via schedule), the execution record is created with a status of running. Check the task details endpoint to see execution history and current status.
How do I set up retry logic for failed tasks?
Tasks default to 3 retries with a 60-second delay between attempts. You can customize these when creating or updating a task by setting max_retries and retry_delay_seconds in the task parameters.
Can I run a task immediately without waiting for the schedule?
Yes. Call POST /api/tasks/schedules/:id/run to trigger an immediate execution. The API returns 202 Accepted and the task runs in the background.
How do I disable a task without deleting it?
Use the toggle endpoint: POST /api/tasks/schedules/:id/toggle with {"enabled": false}. The task remains in the system but will not execute on its cron schedule.

Troubleshooting

Task Not Firing on Schedule

Verify the cron expression is correct and the timezone matches your expectations. Use a cron expression validator to confirm the next run time. Ensure the task is enabled (enabled: true).

Task Failing Immediately

Check device connectivity before scheduling tasks. Use the Devices API credential test endpoint to verify the Controller can reach the target devices.

Invalid Cron Expression (400 Bad Request)

The cron expression syntax is invalid. NetStacks uses standard 5-field cron format: minute hour day-of-month month day-of-week. Extended expressions with seconds are not supported.

Invalid Timezone (400 Bad Request)

The timezone string is not a valid IANA timezone identifier. Use full names like America/New_York or Europe/London, not abbreviations like EST or GMT.

409 Conflict (Duplicate Name)

A task with the same name already exists. Task names must be unique within your organization.