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)
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) → running → completed 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 AM0 */6 * * *— Every 6 hours0 9 * * 1-5— Weekdays at 9:00 AM0 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
| Method | Path | Description |
|---|---|---|
| GET | /api/tasks/schedules | List all scheduled tasks |
| POST | /api/tasks/schedules | Create a scheduled task |
| GET | /api/tasks/schedules/:id | Get task details |
| PUT | /api/tasks/schedules/:id | Update a task |
| DELETE | /api/tasks/schedules/:id | Delete a task |
| POST | /api/tasks/schedules/:id/run | Run task immediately |
| POST | /api/tasks/schedules/:id/toggle | Enable/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
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"
# }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...')}")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
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 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')}")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
# 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"
# }# Trigger immediate execution
execution = requests.post(
f"{base_url}/tasks/schedules/{task_data['id']}/run",
headers=headers
)
print(f"Execution started: {execution.json()['id']}")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
# 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 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 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']}")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
POSTto/api/tasks/scheduleswith the taskname,task_type,cron_expression,timezone, and type-specificparameters. 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), andagent_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_retriesandretry_delay_secondsin the task parameters. - Can I run a task immediately without waiting for the schedule?
- Yes. Call
POST /api/tasks/schedules/:id/runto trigger an immediate execution. The API returns202 Acceptedand the task runs in the background. - How do I disable a task without deleting it?
- Use the toggle endpoint:
POST /api/tasks/schedules/:id/togglewith{"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.
Related Features
- API Authentication — Obtain tokens for API access.
- Devices API — Manage the devices that tasks operate on.
- Error Codes — Reference for task-related errors.
- Scheduled Tasks — UI guide for creating and managing scheduled tasks.
- Cron Expressions — Guide to cron expression syntax and common patterns.