Skip to main content

DIAL Scheduler API

This reference covers the Scheduler API for platform engineers verifying a configured service. It describes the HTTP API, schedule definition, run lifecycle, and MCP interface. All resource operations are scoped to the caller resolved through DIAL Core.

Paths and authentication​

Container paths begin with /v1. Through the upstream application definition, the Core route prefix is:

<DIAL_URL>/v1/deployments/applications/public/dial_scheduler__1.0.0/route

Append /v1/schedules/ or another container path to that prefix. Public Core requests use DIAL authentication; Core forwards an Api-Key for the Scheduler's caller lookup. Direct container requests require Api-Key; the Scheduler resolves it through Core's /v1/user/info. A bearer token alone does not satisfy that direct header dependency.

Sources: caller authentication, router prefixes, and application route definition.

Operations​

MethodContainer pathInputSuccess response
POST/v1/schedules/Schedule definition201, full schedule
GET/v1/schedules/Pagination and optional filters200, paginated schedules
GET/v1/schedules/{schedule_id}Path ID200, full schedule, including soft-deleted records
PUT/v1/schedules/{schedule_id}Complete replacement definition200, full schedule
POST/v1/schedules/{schedule_id}/pauseNo body200, paused schedule
POST/v1/schedules/{schedule_id}/resumeNo body200, resumed schedule
DELETE/v1/schedules/{schedule_id}Path ID204, empty body
POST/v1/schedules/{schedule_id}/runNo body or overrides202, newly created run
GET/v1/schedules/{schedule_id}/runsPagination and run ordering200, paginated run summaries
GET/v1/schedules/{schedule_id}/runs/{run_id}Path IDs200, run detail and result
GET/v1/sign-in/statusRequired service_id query parameter200, sign-in state

The trailing slash on collection paths is significant: the API disables automatic slash redirects. Full schedule responses include id, display_name, service_id, description, next_run_time, trigger, properties, metadata, is_deleted, created_by, created_at, and updated_at.

Sources: schedule routes, run routes, and schedule response schema.

Schedule definition​

POST and PUT accept the same body. PUT replaces all writable fields; it is not a partial update.

FieldRequiredDefaultDescription
display_nameYes—Non-empty name; whitespace-only values are rejected.
service_idYes—Registered external service used to obtain the owner's credentials, normally dial-native.
descriptionNonullNotes, up to 1000 characters.
triggerYes—Exactly one cron or date trigger.
propertiesYes—Target configuration described below.
metadataNo{}String-keyed tags; only string-valued entries support list filtering.

The server supplies ownership and timestamps. is_deleted is read-only and ignored if supplied in a create or replace body. Definitions are validated by the request schemas.

Triggers​

trigger.date is an ISO-8601 datetime for one execution. trigger.cron contains required fields and optional start_date and end_date bounds. Supplying both trigger types, or neither, returns 422.

Cron fields are year, month, day, week, day_of_week, hour, minute, and second. Each accepts a string cron expression, an integer, or null. Non-null fields are passed to APScheduler's CronTrigger; omitted values follow that library's cron semantics.

Triggers use UTC. An every-weekday-at-09:00 example is:

{
"cron": {
"fields": {
"day_of_week": "mon-fri",
"hour": 9,
"minute": 0,
"second": 0
}
}
}

Source: trigger construction.

Target properties​

FieldDefaultDescription
target_type—Required: chat_completion, responses, rest, or sse.
url—Required HTTP/HTTPS URL. Model targets use a base URL, such as http://dial-core:8080/openai/; HTTP targets use the endpoint URL.
methodnullRequired for rest and sse: GET, POST, or PUT. Must be absent or null for model targets.
payload{}Target request body. Model targets require payload.model; their stream defaults to false.
extra_headers{}Additional request headers. REST and SSE executors merge these with the owner's delegated authentication header.
api_versionnullRequired for model targets; must be absent or null for REST and SSE.
timeoutProcess defaultPositive absolute duration ceiling per attempt, in seconds.
idle_timeoutProcess defaultPositive maximum gap between parsed stream events, in seconds. Used for SSE and streamed model calls; must not exceed an explicitly supplied timeout.
retrynullOptional retry policy; no Scheduler policy retries when omitted.
create_conversationfalseSave a successful run as a DIAL conversation. true is allowed only for chat_completion.

For model targets, url is the API base and payload.model selects the deployment. It is not the full deployment-specific completion URL. Conversation creation is best effort; failure is logged without changing a successful target run to an error.

Sources: property validation, chat executor, and conversation persistence. The upstream configuration document omits idle_timeout; this table follows code.

Retries​

When present, retry requires both fields:

FieldConstraintMeaning
interval_sequenceNon-empty array of positive numbersSeconds to wait before each successive retry; [5, 30] allows three total attempts.
retryable_errorsNon-empty array of integers from 100 to 599HTTP status codes eligible for policy retries.

Credential lookup happens before target execution. A credentials-stage failure never dispatches the target or consumes this retry policy. Duration expiry, idle expiry, and transport failures without an HTTP status are terminal for Scheduler's policy. See retry implementation.

Sign-in status​

Create and replace require state=signed_in for the requested service_id before writing the schedule. The API reads Core's application details with the caller's key and examines the external service's auth_settings:

StateMeaningCreate or replace
signed_inApplication approval and user sign-in both report SIGNED_INContinues
not_signed_inApplication approval exists, but user sign-in does not403
unknownApplication approval is missing, or status could not be determined502

The status response includes service_id, state, signed_in, and detail. signed_in is a derived boolean; inspect state to distinguish missing user sign-in from an unresolved state.

When X-DIAL-CLIENT-CHANNEL-ID is forwarded, a check that is not signed in can request an interactive sign-in through Core's client channel. It then rechecks status after a successful interaction. The check does not modify schedules, but it can initiate that user interaction.

The upstream README and API contract describe an OBO-probe check and a read-only status endpoint. The implemented sign-in service instead uses application auth status and supports the client-channel interaction.

Verification request​

Through Core, with the upstream application path:

curl --fail-with-body \
-H 'Api-Key: <YOUR_DIAL_API_KEY>' \
'https://<YOUR_DIAL_HOST>/v1/deployments/applications/public/dial_scheduler__1.0.0/route/v1/sign-in/status?service_id=dial-native'

An example response after approval and user sign-in is:

{
"service_id": "dial-native",
"state": "signed_in",
"detail": "Signed in to dial-native.",
"signed_in": true
}

Create and verify a schedule​

The following request uses an existing deployment ID and a URL reachable from the Scheduler containers. The model must support the requested Chat Completions API version. The schedule fires every weekday at 09:00 UTC and saves successful runs as conversations.

curl --fail-with-body \
-H 'Api-Key: <YOUR_DIAL_API_KEY>' \
-H 'Content-Type: application/json' \
-X POST \
'https://<YOUR_DIAL_HOST>/v1/deployments/applications/public/dial_scheduler__1.0.0/route/v1/schedules/' \
--data '{
"display_name": "Weekday summary",
"service_id": "dial-native",
"trigger": {
"cron": {
"fields": {"day_of_week": "mon-fri", "hour": 9, "minute": 0, "second": 0}
}
},
"properties": {
"target_type": "chat_completion",
"url": "http://dial-core:8080/openai/",
"api_version": "2025-01-01-preview",
"payload": {
"model": "<DEPLOYMENT_ID>",
"messages": [{"role": "user", "content": "Summarize the latest project updates."}],
"stream": true
},
"timeout": 300,
"idle_timeout": 60,
"create_conversation": true
}
}'

Use the returned id for an immediate verification run:

curl --fail-with-body \
-H 'Api-Key: <YOUR_DIAL_API_KEY>' \
-X POST \
'https://<YOUR_DIAL_HOST>/v1/deployments/applications/public/dial_scheduler__1.0.0/route/v1/schedules/<SCHEDULE_ID>/run'

It returns 202 with this shape; the ID and timestamp are illustrative:

{
"id": "2d816fac-83a2-464e-9d69-84d84efca623",
"status": "in_progress",
"start_time": "2026-11-09T15:00:00Z",
"end_time": null,
"conversation_id": null
}

Poll /v1/schedules/<SCHEDULE_ID>/runs/<RUN_ID> through the same Core route prefix until it completes. This run executes in the API process, can overlap other runs, and does not change next_run_time. Acceptance is not execution success; credential failures are recorded later on the run.

Listing and run results​

List responses contain count, limit, offset, results, next, and previous. limit defaults to 20 and must be at least 1; offset defaults to 0 and must be non-negative.

Schedule filters include case-insensitive name and model substrings, metadata__<KEY>=<VALUE> string matches, and is_deleted (default false). Filters combine with AND. is_deleted=true lists only soft-deleted records, not both states. Ordering accepts order_by=created_at|next_run_time|name and order_dir=asc|desc; the default is created_at desc. Schedules without a next run sort last when ordering by next_run_time.

Run lists support order_by=created_at and order_dir=asc|desc, defaulting to descending creation time. Run detail includes id, status, start_time, end_time, result, schedule, and conversation_id. schedule summarizes the schedule's current name, trigger, and target properties, not the definition the run executed; after a replacement, earlier runs show the new definition. Status values are in_progress, success, and error.

ResultMeaning
{"result": {...}}Model response from a chat-completion or Responses target
{"status_code": 200, "body": ...}REST result; JSON is decoded when possible, otherwise text is stored
{"events": [...]}Collected SSE event data
{"error_text": "..."}Target execution failed
{"stage": "credentials", "error_text": "...", "credentials_response": {...}}Owner credentials could not be obtained; target dispatch did not occur

conversation_id is populated after successful conversation storage for opted-in chat completions; otherwise it remains null. Sources: list routes, run schemas, run detail, and target executors.

Deletion and errors​

Deletion unregisters future execution. A schedule without runs is removed; one with any run history is retained with is_deleted=true. Its details and history stay readable, but update, pause, resume, run-now, and repeat deletion return 409. There is no restore operation. See deletion implementation.

StatusMeaning
401Core accepted the Api-Key, but its user-info response did not resolve a caller identity.
403Required user sign-in is missing on create or replace.
404Resource does not exist or is not owned by the caller.
409Operation conflicts with a soft-deleted schedule.
422Missing required header or parameter, invalid schedule definition, or invalid list parameter.
502Core rejected or did not answer the caller lookup, including for an invalid or expired Api-Key; sign-in state is unresolved; or job registration or removal failed.

Errors raised by the endpoint handlers use FastAPI's {"detail": ...} envelope. Sign-in rejection places service_id, state, signed_in, and detail inside that envelope. The upstream API contract's bare-string error examples differ from the implemented handlers.

MCP interface​

With MCP_ENABLED=true, the API exposes HTTP MCP at MCP_PATH (default /mcp). It generates tools from schedule, run, and sign-in routes; health and diagnostic routes are excluded. run_schedule_now and get_sign_in_status are explicit tool operation IDs.

The MCP adapter forwards incoming Api-Key and X-DIAL-CLIENT-CHANNEL-ID to the in-process HTTP operations. Both headers are removed from tool input schemas because clients provide them through the request context. The DIAL application definition enables per-request key forwarding for this connection.

Sources: MCP server and header forwarding.

Further reading​