Skip to navigation

Managing Schedules programmatically

Create, change, pause, and run Schedules from your own code or tools instead of the dashboard. The Runtype API, the TypeScript SDK, the runtype CLI, and the Runtype MCP server all manage the same Schedules that appear on the Schedules page.

Before you begin

You need an API key that can manage Schedules. The following permissions apply:

  • Schedules (Read) (SCHEDULES:READ): list and get Schedules and their runs.
  • Schedules (Write) (SCHEDULES:WRITE): create, update, delete, pause, resume, and run Schedules.
  • Schedules (Full) (SCHEDULES:*): both.

Test keys can’t manage Schedules. For how to create a key, see Authentication.

You also need the ID of the Flow or Agent to schedule. Test it with a manual run before you automate it.

Choose an interface

Each interface covers a different part of the Schedule configuration. The following table compares them:

InterfaceFlow SchedulesAgent SchedulesRecord filters and inputsOne-time triggers
API and SDKYesYesYesYes
runtype CLIYesUpdate onlyThrough --from-fileThrough --from-file
Runtype MCP serverYesYesNoYes

Create a Schedule with the API

To create a Schedule, send a POST request to /v1/schedules. The following request creates a Flow Schedule that runs every day at 6:00 AM in Los Angeles:

curl -X POST https://api.runtype.com/v1/schedules \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"target": { "flowId": "YOUR_FLOW_ID" },
"trigger": {
"type": "recurring",
"cron": "0 6 * * *",
"timezone": "America/Los_Angeles"
},
"inputs": { "region": "emea" }
}'

Replace the following:

  • YOUR_API_KEY: your Runtype API key.
  • YOUR_FLOW_ID: the ID of the Flow to run.

The response contains the Schedule ID:

{ "id": "sched_01jv0000000000000000000001", "status": "created" }

The request body has the following fields:

  • target: exactly one of flowId or agentId. A Flow Schedule can add a Record target with recordType, recordFilter, or recordIds. For Record targets, see Automating batch processing.
  • trigger: type is recurring or one_time. A recurring trigger requires cron and an IANA timezone. A one-time trigger requires runAt as an ISO 8601 UTC timestamp, such as 2026-10-01T16:00:00Z.
  • messages: optional. For a Flow, a list of messages. For an Agent, a list of message sets.
  • inputs: optional Flow input values. Keys can’t start with _.
  • executionOptions: optional retry, concurrency, timeout, and model settings. For every field and range, see Create a schedule.

An Agent Schedule needs at least one of messages, recordType, recordFilter, or recordIds. The following body runs an Agent once on one message set:

{
"target": { "agentId": "YOUR_AGENT_ID" },
"trigger": { "type": "one_time", "runAt": "2026-10-01T16:00:00Z" },
"messages": [
{
"name": "Weekly summary",
"messages": [
{ "role": "user", "content": "Summarize this week's support tickets. Today is {{_now.date}}." }
]
}
]
}

Replace YOUR_AGENT_ID with the ID of the Agent to run. For the _now and _schedule variables, see What are Schedules?.

Manage existing Schedules with the API

The following endpoints act on an existing Schedule. Replace YOUR_SCHEDULE_ID with its ID, which starts with sched_.

TaskRequestResponse
List SchedulesGET /v1/schedulesdata and pagination
Get one ScheduleGET /v1/schedules/YOUR_SCHEDULE_IDThe Schedule
Update fieldsPUT /v1/schedules/YOUR_SCHEDULE_ID{ "status": "updated" } and id
PausePOST /v1/schedules/YOUR_SCHEDULE_ID/pause{ "status": "paused" }
ResumePOST /v1/schedules/YOUR_SCHEDULE_ID/resume{ "status": "resumed" }
Run immediatelyPOST /v1/schedules/YOUR_SCHEDULE_ID/run-nowstatus, runId, and error
List runsGET /v1/schedules/YOUR_SCHEDULE_ID/runsdata
DeleteDELETE /v1/schedules/YOUR_SCHEDULE_ID{ "success": true }

GET /v1/schedules accepts status=active or status=paused, search to match the Schedule name, and limit and cursor for pagination. limit is 50 by default and at most 100.

PUT is a partial update: only the fields that you send change. The following request moves a Schedule to 7:00 AM:

curl -X PUT https://api.runtype.com/v1/schedules/YOUR_SCHEDULE_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"trigger": {
"type": "recurring",
"cron": "0 7 * * *",
"timezone": "America/Los_Angeles"
}
}'

When you change the trigger, Runtype recalculates the next run time. When you change the Flow or Agent, the Schedule takes the name of the Flow or Agent that it now targets.

Resuming a Schedule doesn’t recalculate its next run time. If a recurring Schedule’s next run time passed while it was paused, it runs once within about a minute of the resume, then continues on its cadence.

Use the TypeScript SDK

The client.schedules namespace in @runtypelabs/sdk wraps the same endpoints: list, get, create, update, delete, pause, resume, runNow, and listRuns. The following example creates a Flow Schedule and handles a plan limit:

import { RuntypeClient, RuntypeApiError } from '@runtypelabs/sdk'
const client = new RuntypeClient({ apiKey: process.env.RUNTYPE_API_KEY })
try {
const { id } = await client.schedules.create({
target: { flowId: 'YOUR_FLOW_ID' },
trigger: {
type: 'recurring',
cron: '0 6 * * *',
timezone: 'America/Los_Angeles',
},
})
console.log(`Created ${id}`)
} catch (error) {
if (error instanceof RuntypeApiError && error.statusCode === 402) {
const { code, message } = error.data as { code?: string; message?: string }
console.error(code, message)
} else {
throw error
}
}

Replace YOUR_FLOW_ID with the ID of the Flow to run. The SDK doesn’t read RUNTYPE_API_KEY by itself, so pass the key in apiKey.

Use the CLI

The runtype schedules commands cover the common tasks. The following table lists them:

CommandEffect
runtype schedules listLists Schedules. Accepts --limit and --cursor.
runtype schedules get <schedule-id>Shows one Schedule.
runtype schedules create --flow <flow-id> --cron <cron> --timezone <time-zone>Creates a recurring Flow Schedule.
runtype schedules update <schedule-id>Changes the target, cron, time zone, or any field from a file.
runtype schedules pause <schedule-id>Pauses the Schedule.
runtype schedules resume <schedule-id>Resumes the Schedule.
runtype schedules run-now <schedule-id>Starts a run immediately.
runtype schedules runs <schedule-id>Lists the Schedule’s runs.
runtype schedules delete <schedule-id>Deletes the Schedule. In an interactive terminal, it asks you to confirm first.

create makes recurring Flow Schedules only, and all three of its flags are required. To add a Record target, messages, inputs, or a one-time trigger, create the Schedule, then save the fields in a JSON file and apply them with update:

runtype schedules update <schedule-id> --from-file schedule.json

Replace <schedule-id> with the Schedule ID. The file uses the same fields as a PUT request body. The --flow, --agent, --cron, and --timezone flags override the matching values in the file. Add --json to list, get, create, or update for machine-readable output.

Use the Runtype MCP server

The Runtype MCP server exposes Schedules to AI clients through these tools: list_schedules, get_schedule, create_schedule, update_schedule, delete_schedule, pause_schedule, resume_schedule, run_schedule_now, and list_schedule_runs.

The tools take snake_case fields, such as flow_id, agent_id, run_at, and execution_options. They don’t accept a Record Filter or Flow inputs. To set those, use the API. To connect a client, see Runtype MCP server.

Handle plan limits

Your plan limits how many Schedules can be active and how often a recurring Schedule can run. When a request exceeds a limit, the API returns 402 with a body like the following:

{
"error": "Limit Exceeded",
"message": "Active schedule limit reached (1). Upgrade your plan for more.",
"code": "ACTIVE_SCHEDULE_LIMIT",
"upgradeUrl": "/settings/billing"
}

The number in message is your plan’s limit. upgradeUrl is the dashboard path to your billing settings. Check code rather than message in your code.

The following table lists the two limit codes:

CodeReturned byCause
ACTIVE_SCHEDULE_LIMITCreate and resumeThe account already has as many active Schedules as the plan allows.
SCHEDULE_FREQUENCY_LIMITCreate, and update with a cronThe cron expression runs more often than the plan allows.

An active Schedule is one that isn’t paused, excluding one-time Schedules that already ran. Every new Schedule counts, including a one-time Schedule. To free a slot, pause or delete a Schedule that you don’t need.

For the frequency limit, Runtype measures the shortest gap between the next five runs of the cron expression. A gap under one hour counts as per-minute, under 24 hours as hourly, and under 28 days as daily. The message names the fastest frequency that your plan allows, such as Your plan allows Daily frequency or slower.

For plan details, see Rate limits and usage.

Troubleshoot common errors

The following table lists other errors that Schedule requests return:

StatusErrorFix
400Validation errorRead details for the field. For example, a recurring trigger without timezone.
400Invalid cron expression or Invalid timezoneUse a valid cron expression, such as 0 6 * * *, and an IANA time zone, such as Europe/Berlin.
400Invalid recordFilterFix the filter that message names. For operators, see Filtering and searching records.
400Agent cannot run on a schedule (SCHEDULE_AGENT_CONFIG_UNSUPPORTED)The Agent uses config that a schedule cannot supply, such as an end-user-isolated tenancyStrategy. Read details[].path and remove that config from the Agent, or run the Agent from dispatch instead.
400Flow cannot run on a schedule (RUNTIME_LANE_INELIGIBLE)The Flow has a step that batch can’t run, such as a top-level wait-until or crawl step, and the request would activate the Schedule: a create, a resume, or a change of target on an active Schedule. reasons names each step type. Remove or replace the step. You can still pause or delete the Schedule.
422RUNTIME_LANE_INELIGIBLE from Run nowThe Flow has a step that batch can’t run. Nothing is queued, and no executions are counted. Remove or replace the step that reasons names.
403Insufficient permissions. Required: SCHEDULES:WRITEUse an API key with the permission that the error names.
404Target not foundCheck that the Flow or Agent ID exists in your account.

Next steps

Continue with these guides: