← Back to Docs

API Reference

The RunLater API lets a script or app create and manage scheduled HTTP requests in your workspace. It is the same product as the dashboard: the same plan limits, the same scheduler, the same run log. For AI agents, the MCP server offers the same actions as tools.

Authentication

Create a key in Settings under API keys. The key is shown once; RunLater stores only its hash. Send it on every request. Revoking a key in Settings stops it right away.

Authorization: Bearer rl_sk_...

A key belongs to one workspace and only sees that workspace's schedules. A workspace with no plan can list and read, but creating or running a request returns 403 no_plan with the Settings link where the 14-day trial starts.

Schedule a request

One time, in a time zone:

curl https://runlater.app/api/v1/schedules \
  -H "Authorization: Bearer $RUNLATER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/reminder",
    "method": "POST",
    "headers": { "X-Secret": "abc123" },
    "body": { "user": 42 },
    "run_at": "2026-12-01T09:00:00",
    "timezone": "America/New_York"
  }'

Recurring, every Monday at 9:00:

curl https://runlater.app/api/v1/schedules \
  -H "Authorization: Bearer $RUNLATER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/hooks/report", "cron": "0 9 * * 1", "timezone": "Europe/London" }'

Fields

  • url (required): a public http(s) URL. Private and local addresses are refused.
  • run_at or cron (exactly one): an ISO date and time up to two years ahead, or a 5-field cron expression. Runs are at most once a minute.
  • timezone: IANA name, default UTC. Applies to cron and to a run_at with no offset.
  • method: GET, POST, PUT, PATCH or DELETE, default POST.
  • headers: an object, at most 30. Values are never returned by the API, only names.
  • body: a string or JSON, at most 64 KB. Not allowed on GET or DELETE.
  • content_type: default application/json.
  • name, description: labels for the dashboard.
  • retries: 0 to 10, default 3. retry_delay_seconds: 1 to 3600, default 60. timeout_seconds: 1 to 300, default 30.

Endpoints

All under https://runlater.app/api/v1.

  • POST /schedules: create. Returns 201 with the schedule.
  • GET /schedules: list, newest first. Query: status (scheduled, paused, finished), limit (at most 200).
  • GET /schedules/<id>: one schedule with recent_runs. Query: runs (0 to 100, default 10).
  • POST /schedules/<id>/pause and /resume: stop and restart it.
  • POST /schedules/<id>/run: send it once now without retries, and return the status code and response.
  • DELETE /schedules/<id>: delete it.
  • GET /schedules/<id>/runs and GET /runs: run history. Query: schedule_id (on /runs), status (success, failed, retrying, pending), limit (at most 100).
  • GET /account: plan, trial end date, limits and usage this month.

Errors

Every error has a code you can branch on and a sentence you can show someone:

{ "error": { "code": "no_plan", "message": "...", "next_url": "https://runlater.app/dashboard/settings" } }
  • 400 bad_params, bad_json, url_not_allowed: fix the request.
  • 401 unauthorized: missing or revoked key.
  • 403 no_plan: pick a plan in Settings to start the trial.
  • 403 schedule_limit_reached, run_limit_reached: the plan's limit. Delete schedules or move to a larger plan.
  • 404 not_found: no such schedule in this workspace.
  • 409 finished, time_passed: the schedule can't do that any more.

Limits

Scheduled requests held and runs per month come from your plan: Starter 250 and 25,000, Team 1,000 and 100,000, Pro 5,000 and 500,000. Every schedule in the workspace counts, however it was created. Only successful runs count toward the monthly limit. There is no SDK and requests are not signed yet.