Skip to main content
Schedules

Update a schedule

Update a Forward Schedule.

POST /api/v1/forward/schedules/{schedule_id} Uses merge-patch semantics. Fields present in the request are updated; omitted fields remain unchanged.

Headers

HeaderRequiredDescription
AuthorizationYesBearer <PAT or SAT>
Content-TypeYesapplication/json
Idempotency-KeyNoOptional idempotency key for unsafe requests.

Path parameters

ParameterTypeRequiredDescription
schedule_idstringYesForward Schedule ID.

Body parameters

ParameterTypeRequiredDescription
namestringNoNew Schedule name.
descriptionstringNoNew Schedule description.
template_idstringNoNew Forward Template ID.
initial_eventsarrayNoReplaces the initial event list.
executionobjectNoMerge updates the execution policy.
trigger_policyobject|nullNoUpdates the trigger policy. null changes it to manual.
environment_idstringNoNew execution environment.
sinksarray|nullNoOmission preserves the current Sink; null or [] clears it; one Pairing Sink replaces it.
metadataobjectNoMerge updates metadata. null values delete metadata keys.

Trigger policy

trigger_policy is a typed object. Create and update requests accept only configuration fields: type, expression, and timezone. Passing null changes the Schedule to {"type":"manual"}. upcoming_runs_at and last_run_at are response-only fields computed by Forward.
FieldTypeRequiredDescription
typestringYescron, once, interval, or manual.
expressionstringConditionalTrigger expression. Required for cron, once, and interval; not needed for manual.
timezonestringConditionalIANA timezone, such as Asia/Shanghai. Required for cron; required for once only when expression has no offset; optional for interval and manual.
upcoming_runs_atarrayResponse onlyUpcoming trigger times in UTC ISO 8601. The current implementation returns [] or the next scheduled time only.
last_run_atstring|nullResponse onlyMost recent trigger time.
typeRequired inputDescription
crontype, expression, timezoneRepeats by a 5-field cron expression in the given IANA timezone.
oncetype, expression, optional timezoneRuns once at an ISO 8601 time. timezone is required when the expression has no offset.
intervaltype, expressionRepeats by an ISO 8601 duration, such as PT15M.
manualtypeNever runs automatically. Trigger with the Run Schedule endpoint.
typeexpression formatExampleNotes
cronStandard 5-field cron0 9 * * *Minute-level calendar schedule. Seconds and 6-field cron are not supported.
onceISO 8601 absolute time2026-06-23T09:00:00 or 2026-06-23T01:00:00ZRuns once. The target time must be at least one minute in the future.
intervalISO 8601 durationPT15M, PT1H, P1DFixed interval schedule. Minimum interval is one minute.
manualOmitted or empty-Does not create scheduled runs.

Execution policy

execution is merge-updated. Omitted fields keep their current values.
FieldTypeDefaultDescription
session_modestringnew_sessionnew_session or reuse_session.
max_concurrent_runsinteger1Maximum concurrent runs for this Schedule.
max_attemptsinteger1Maximum actual attempts per Run. Allowed values: 1 or 2; values outside this range are rejected.
timeout_msinteger300000Timeout for one attempt.
session_modeDescription
new_sessionCreates a new execution Session for each trigger. Previous context is not reused.
reuse_sessionForward manages one fixed execution Session for this Schedule and reuses it across triggers. Callers cannot provide an arbitrary existing session_id.
max_attempts=2 means the server may automatically retry once after the first execution fails. Whether a retry actually happens depends on the failure type — parameter errors, permission errors, concurrency limits, timeouts, or connection interruptions are not guaranteed to be retried. Clients can check the attempt field on a Schedule Run to see how many attempts were made. Omitting execution, passing execution=null, passing an empty object, or passing a partial execution without max_attempts all preserve the current max_attempts value. Explicitly passing execution.max_attempts=null is treated as a type error and does not reset to default.

Update the IM sink

A non-empty sinks array may contain only one Pairing Sink, with only type=im_channel and channel_pairing_id:
{
  "sinks": [
    {
      "type": "im_channel",
      "channel_pairing_id": "pair_019eabc123"
    }
  ]
}
Request shapeResult
sinks omittedPreserves the current Sink without resolving the Pairing again.
"sinks": null or "sinks": []Clears the Sink and returns [].
One valid Pairing SinkReplaces the complete Sink and returns its normalized form.
Callers cannot submit channel_id, channel_type, an external channel user, Conversation, or other raw routing fields. The Pairing must belong to the current user, be active, and match the Schedule Identity and final Template. If template_id is changed while the existing Sink is a Pairing Sink, the request must also clear the Sink or replace it with one matching the new Template. Legacy Tool Sinks retain their compatibility behavior.

Example request

curl -s -X POST 'https://api.qoder.com/api/v1/forward/schedules/sched_019f00112233445566778899aabbccdd' \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Weekday tech brief",
  "trigger_policy": {
    "type": "cron",
    "expression": "0 9 * * 1-5",
    "timezone": "Asia/Shanghai"
  },
  "execution": {
    "max_attempts": 2
  },
  "sinks": [
    {
      "type": "im_channel",
      "channel_pairing_id": "pair_019eabc123"
    }
  ]
}'

Example response

HTTP 200 OK
{
  "id": "sched_019f00112233445566778899aabbccdd",
  "identity_id": "idn_019eabc123",
  "template_id": "tmpl_support",
  "name": "Weekday tech brief",
  "description": "Generate a daily technology news summary",
  "status": "active",
  "initial_events": [
    {
      "type": "user.message",
      "content": "Summarize current technology news in five bullet points."
    }
  ],
  "execution": {
    "session_mode": "new_session",
    "max_concurrent_runs": 1,
    "max_attempts": 2,
    "timeout_ms": 300000
  },
  "trigger_policy": {
    "type": "cron",
    "expression": "0 9 * * 1-5",
    "timezone": "Asia/Shanghai",
    "upcoming_runs_at": [
      "2026-06-23T01:00:00Z"
    ]
  },
  "environment_id": "env_019e64e01a137caf953ac2ac7b42ec5c",
  "sinks": [
    {
      "type": "im_channel",
      "channel_pairing_id": "pair_019eabc123"
    }
  ],
  "metadata": {},
  "created_at": "2026-06-22T10:00:00Z",
  "updated_at": "2026-06-22T10:30:00Z"
}

Response fields

Returns the updated Schedule object.

Errors

HTTPTypeCodeTrigger
400invalid_request_errorinvalid_trigger_policyTrigger policy is invalid.
400invalid_request_errorinvalid_requestexecution.max_attempts is not in the 1..2 range.
400invalid_request_errorunsupported_sinks_inputRequest body contains sinks.
404not_found_errorschedule_not_foundSchedule does not exist.
409invalid_request_errorschedule_archivedSchedule is archived.
401authentication_errorauthentication_requiredThe PAT or SAT is invalid or expired.

Notes

  • HTTP update requests do not support updating sinks.
  • reuse_session means Forward manages a fixed execution Session for this Schedule; callers cannot provide an arbitrary existing session_id.