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_atorcron(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 arun_atwith 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: defaultapplication/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. Returns201with the schedule.GET /schedules: list, newest first. Query:status(scheduled, paused, finished),limit(at most 200).GET /schedules/<id>: one schedule withrecent_runs. Query:runs(0 to 100, default 10).POST /schedules/<id>/pauseand/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>/runsandGET /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.