Workflow automation

Agent Scheduler: Durable Cron Tasks for AI Agents

July 17, 2026 · Eric · 6 min read

Your AI agent generated a report at 3 AM. You want it scraped again tomorrow. And the day after. But your agent's chat session ended, the laptop went to sleep, or Claude Desktop is closed for the night.

The Agent Scheduler is a durable task runner that keeps working after your agent goes offline. You create a cron schedule, point it at a URL, and the platform fires POST requests on time — every time — whether your agent is running or not.

Current scope: Scheduler tasks are HTTP calls to public destinations you define. The platform handles timing, retries, and delivery history — it does not execute arbitrary server-side code, manage internal workflow steps, or invoke other Agent Media Tools endpoints directly.

Why your agent needs an offline task runner

AI agents are great at planning multi-step work. They're terrible at staying online. Every time you close Claude Desktop, finish a ChatGPT session, or restart Hermes, anything scheduled to happen next — a daily scrape, a weekly report, a midnight cleanup — simply doesn't run.

The Agent Scheduler solves this by decoupling scheduling from execution:

API overview

MethodRoutePurpose
POST/api/agent/schedulesCreate a one-time or recurring schedule
GET/api/agent/schedulesList your schedules
GET/api/agent/schedules/:idRead a single schedule
PATCH/api/agent/schedules/:idPause, resume, or update a schedule
DELETE/api/agent/schedules/:idDelete a schedule
POST/api/agent/schedules/:id/runManually trigger a run (outside the cron)
GET/api/agent/schedules/:id/historyRead delivery history for a schedule

All endpoints require an API key (Bearer token) and authenticate against your account's daily limits. Free accounts get 3 schedules, Pro gets 25, and Builder gets 100.

curl examples

💡 Windows users: Run these commands from Git Bash or WSL. PowerShell aliases curl to Invoke-WebRequest.

1. Create a daily scraping schedule

This schedule fires a POST to your public endpoint every morning at 6 AM Eastern:

curl -X POST https://agentmediatools.com/api/agent/schedules \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "name": "Daily HackerNews Scrape",
    "description": "Scrape HN top stories every morning",
    "method": "POST",
    "url": "https://your-domain.com/hook/scrape-hn",
    "headers": {
      "X-Auth": "your-hmac-secret",
      "Content-Type": "application/json"
    },
    "body": {
      "target": "https://news.ycombinator.com",
      "max_articles": 30
    },
    "schedule": {
      "type": "cron",
      "expression": "0 6 * * *",
      "timezone": "America/New_York"
    },
    "retry_on_failure": true,
    "max_retries": 3
  }'

The response returns the created schedule with its ID, the next scheduled run, and status:

{
  "id": "sch_a1b2c3d4e5f6",
  "name": "Daily HackerNews Scrape",
  "status": "active",
  "next_run": "2026-07-18T10:00:00Z",
  "created_at": "2026-07-17T14:00:00Z"
}

2. Create a one-time delayed task

Sometimes you don't need recurring — just a single future execution. Use type: "one_time" with an ISO datetime:

curl -X POST https://agentmediatools.com/api/agent/schedules \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "name": "Send weekly report at midnight",
    "method": "POST",
    "url": "https://your-domain.com/hook/send-report",
    "body": {"report_type": "weekly", "format": "pdf"},
    "schedule": {
      "type": "one_time",
      "run_at": "2026-07-24T00:00:00Z"
    }
  }'

One-time tasks auto-delete after their execution. Use the recurring cron type for ongoing work.

3. List all schedules

curl https://agentmediatools.com/api/agent/schedules \
  -H "Authorization: Bearer YOUR_API_KEY"

Response includes status (active, paused, completed for one-time), next run time, and the original configuration.

4. Pause and resume

Pausing stops future runs without deleting the schedule. Resume to reactivate:

curl -X PATCH https://agentmediatools.com/api/agent/schedules/sch_a1b2c3d4e5f6 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"status": "paused"}'
curl -X PATCH https://agentmediatools.com/api/agent/schedules/sch_a1b2c3d4e5f6 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{"status": "active"}'

5. View delivery history

curl https://agentmediatools.com/api/agent/schedules/sch_a1b2c3d4e5f6/history \
  -H "Authorization: Bearer YOUR_API_KEY"

Each history entry shows the run timestamp, HTTP status code returned by your endpoint, response body (truncated if large), and any error message:

{
  "schedule_id": "sch_a1b2c3d4e5f6",
  "total_runs": 4,
  "history": [
    {
      "run_id": "run_abc123",
      "triggered_at": "2026-07-17T10:00:00Z",
      "status": 200,
      "response_preview": "{\"ok\":true,\"articles_scraped\":30}",
      "duration_ms": 1247
    },
    {
      "run_id": "run_def456",
      "triggered_at": "2026-07-16T10:00:00Z",
      "status": 0,
      "error": "Connection refused",
      "retry_of": "run_def456",
      "retry_count": 2
    }
  ]
}

Python example: agent-managed schedules

Here's a complete Python script that lets an agent create, inspect, and manage schedules programmatically — useful for a coordinator agent or an n8n workflow:

import requests
import json
import sys

API_KEY = "YOUR_API_KEY"
BASE = "https://agentmediatools.com"
HEADERS = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {API_KEY}"
}

# ── Create a daily schedule ─────────────────────────────────
def create_daily_scrape(name, target_url, hook_url, cron_expr, tz="UTC"):
    """Create a recurring schedule that POSTs scrape instructions to your hook."""
    payload = {
        "name": name,
        "description": f"Scrape {target_url} on cron",
        "method": "POST",
        "url": hook_url,
        "headers": {"Content-Type": "application/json"},
        "body": {"target": target_url},
        "schedule": {
            "type": "cron",
            "expression": cron_expr,
            "timezone": tz
        },
        "retry_on_failure": True,
        "max_retries": 3
    }
    r = requests.post(f"{BASE}/api/agent/schedules",
        headers=HEADERS, json=payload)
    return r.json()

# ── Create a one-time schedule ──────────────────────────────
def create_one_time_task(name, hook_url, body, run_at_iso):
    """Fire a POST once at a specific future time."""
    payload = {
        "name": name,
        "method": "POST",
        "url": hook_url,
        "body": body,
        "schedule": {
            "type": "one_time",
            "run_at": run_at_iso
        }
    }
    r = requests.post(f"{BASE}/api/agent/schedules",
        headers=HEADERS, json=payload)
    return r.json()

# ── List active schedules ──────────────────────────────────
def list_schedules():
    r = requests.get(f"{BASE}/api/agent/schedules", headers=HEADERS)
    return r.json()

# ── Read schedule history ──────────────────────────────────
def get_history(schedule_id):
    r = requests.get(f"{BASE}/api/agent/schedules/{schedule_id}/history",
        headers=HEADERS)
    return r.json()

# ── Pause / resume ─────────────────────────────────────────
def set_status(schedule_id, new_status):
    r = requests.patch(f"{BASE}/api/agent/schedules/{schedule_id}",
        headers=HEADERS,
        json={"status": new_status})
    return r.json()

# ── Manual run ─────────────────────────────────────────────
def trigger_now(schedule_id):
    r = requests.post(
        f"{BASE}/api/agent/schedules/{schedule_id}/run",
        headers=HEADERS)
    return r.json()

# ── Delete ─────────────────────────────────────────────────
def delete_schedule(schedule_id):
    r = requests.delete(
        f"{BASE}/api/agent/schedules/{schedule_id}",
        headers=HEADERS)
    return r.json()

# ── Demo ───────────────────────────────────────────────────
if __name__ == "__main__":
    action = sys.argv[1] if len(sys.argv) > 1 else "create"

    if action == "create":
        sched = create_daily_scrape(
            name="Daily HN Top Stories",
            target_url="https://news.ycombinator.com",
            hook_url="https://my-worker.example.com/hooks/scrape",
            cron_expr="0 8 * * 1-5",
            tz="America/New_York"
        )
        print(f"✅ Created: {sched['name']} (id={sched['id']})")
        print(f"   Next run: {sched['next_run']}")

    elif action == "list":
        data = list_schedules()
        for s in data.get("schedules", []):
            print(f"  [{s['status']}] {s['name']} — id={s['id']}")

    elif action == "history" and len(sys.argv) > 2:
        hist = get_history(sys.argv[2])
        for entry in hist.get("history", []):
            status = entry.get("status", "N/A")
            print(f"  {entry['triggered_at']} → HTTP {status}")

    elif action == "trigger" and len(sys.argv) > 2:
        result = trigger_now(sys.argv[2])
        print(f"Triggered: {result}")

    else:
        print("""Usage:
  python scheduler.py create
  python scheduler.py list
  python scheduler.py history SCHEDULE_ID
  python scheduler.py trigger SCHEDULE_ID
  python scheduler.py pause SCHEDULE_ID
  python scheduler.py resume SCHEDULE_ID
  python scheduler.py delete SCHEDULE_ID""")

Via MCP (for Claude Desktop / Hermes)

If you use the Agent Media Tools MCP server, your agent can manage schedules through natural language:

"Create a daily scrape schedule that fires at 6 AM Eastern and POSTs to my webhook"

The MCP server exposes these scheduler tools:

💡 Cron expression reference: Standard 5-field UNIX cron (minute hour day month weekday). 0 6 * * * = daily at 6 AM. */15 * * * * = every 15 minutes. 0 9 * * 1-5 = weekdays at 9 AM. TZ defaults to UTC if not specified.

Real-world patterns

1. Daily data ingestion

Your agent sets up a schedule that POSTs to a Vercel Edge Function or Cloudflare Worker every morning. The worker fetches API data, transforms it, and pushes it to your database. Your agent checks the schedule history when it comes online to verify today's ingestion ran.

2. Weekly report generation

A one-time schedule fires every Sunday at midnight, triggering a script that generates a PDF report and emails it to stakeholders. The schedule is re-created each week by the agent with the updated parameters — or you keep a cron schedule pointing at the same endpoint.

3. Heartbeat / uptime monitoring

Set a cron schedule that fires every 5 minutes to a health-check endpoint. If the endpoint fails to respond, the platform's retry mechanism gives you visibility into delivery failures — the history shows exactly which runs failed and when.

4. Midnight cleanup + one-time override

Keep a recurring cron for daily temp-file cleanup. When something urgent needs immediate cleanup, trigger a manual run via POST /api/agent/schedules/:id/run without waiting for the next cron tick. The manual run doesn't interfere with the cron schedule.

Scheduler vs. Pipeline Builder vs. Webhooks

Agent Media Tools has three systems for executing work over time. Here's how they differ:

FeatureAgent SchedulerPipeline BuilderWebhooks
TriggerCron or future timeManual (human or API)External event (job done, etc.)
ExecutionHTTP call to your endpointServer-side step executionHTTP POST to your endpoint
RetriesAutomatic (configurable)Manual via on_error policyUp to 5 retries, exp backoff
HistoryFull delivery logRun history per pipelineDelivery receipts
Auth requiredAPI keyBrowser sessionAPI key for management
Free limit3 schedulesUnlimited self-serve1 webhook URL

Use the Scheduler when you need time-based execution and your agent needs to stay offline. Use Pipelines for synchronous multi-step media workflows. Use Webhooks to get notified when something finishes.

Pricing and limits

Getting started

  1. Sign up at agentmediatools.com — free account
  2. Generate an API key from your account settings
  3. Decide what runs — set up a simple webhook receiver or a serverless function
  4. Create your first schedule with the curl command above
  5. Check the history after the first run — inspect delivery status and response

Your agent stays focused on planning and decision-making. The Scheduler handles the execution, retries, and timing — whether your agent is online or not.

⏰ Keep your agent working while it's asleep

Create a schedule in under 30 seconds. Free accounts get 3 schedules — enough for daily scrapes, weekly reports, and one-off tasks.

Open Agent Scheduler →  ·  API docs →  ·  💬 Discord

Tags: cron, scheduled tasks, agent scheduler, durable execution, offline agent, periodic HTTP, cron schedule API, AI agent scheduling, background jobs for AI agents