Service Reference
Scheduler — Amazon EventBridge Scheduler
EventBridge Scheduler is served as a REST-JSON API at AWS's own paths, so an unmodified SDK or aws scheduler CLI call reaches it. This implementation focuses on schedule groups,...
Scheduler — Amazon EventBridge Scheduler
AWS docs: https://docs.aws.amazon.com/scheduler/latest/APIReference/Welcome.html
EventBridge Scheduler is served as a REST-JSON API at AWS’s own paths, so an
unmodified SDK or aws scheduler … call reaches it. This implementation focuses
on schedule groups, schedules, tagging, and clock-driven target dispatch to
every target type EventBridge rules reach.
Behavior Notes
-
Request paths — AWS’s own bindings, taken from the pinned Smithy model:
| Operation | Binding | | --- | --- | |
CreateSchedule|POST /schedules/{Name}—GroupNamein the body | |GetSchedule|GET /schedules/{Name}?groupName=| |UpdateSchedule|PUT /schedules/{Name}—GroupNamein the body | |DeleteSchedule|DELETE /schedules/{Name}?groupName=| |ListSchedules|GET /schedules?ScheduleGroup=| |CreateScheduleGroup|POST /schedule-groups/{Name}| |GetScheduleGroup|GET /schedule-groups/{Name}| |DeleteScheduleGroup|DELETE /schedule-groups/{Name}| |ListScheduleGroups|GET /schedule-groups| |TagResource/UntagResource/ListTagsForResource|POST/DELETE/GET /tags/{ResourceArn}|A schedule is addressed by name alone; its group is never a path segment.
/tags/{ResourceArn}is shared with API Gateway, EKS and Pipes, and is dispatched on theschedulersegment of the resource ARN.Releases up to and including
0.0.1-alpha.33served these operations under an emulator-invented/_scheduler/prefix instead, so every SDK and CLI call answered501. That prefix has been removed rather than kept as an alias. -
Default schedule group:
defaultis auto-seeded and cannot be deleted.DeleteScheduleGroupdeletes the schedules inside the group, as AWS does.
-
Supported schedule expressions:
rate(...)at(...)cron(...)(AWS-style 6-field form). Each field takes*,?, a value, a comma-separated list, a range (9-17) or a step (*/5,0/15,9-17/4); a step over a range walks that range. TheL,Wand#day specifiers and the three-letter month and day names are not supported, and an expression using one is refused byCreateSchedule.- A cron expression is evaluated by advancing field by field, so a sparse schedule — yearly, say — costs the same per tick as a frequent one.
-
Validation on
CreateScheduleandUpdateSchedule:- The schedule and group names must match the model’s constraint — 1–64
characters of
[0-9a-zA-Z-_.]. - The
ScheduleExpressionmust be one the engine can evaluate. An expression it cannot parse is refused up front rather than accepted and reported as an engine error on every tick, which would leave a schedule that reads correctly inGetScheduleand never fires. FlexibleTimeWindow.Modeis required and must beOFForFLEXIBLE;Statemust beENABLEDorDISABLED.
- The schedule and group names must match the model’s constraint — 1–64
characters of
-
UpdateSchedulereplaces, as AWS’s does. The request carries the whole schedule, so any optional member the caller omits —Description,ScheduleExpressionTimezone,State,StartDate,EndDate, or anything insideTarget— ends up unset, andStatereturns to itsENABLEDdefault. Read the schedule, change what you mean to change, and send the result back. What survives is the schedule’s identity, again as on AWS: its name, group, ARN andCreationDate.Releases up to and including
0.0.1-alpha.33merged instead, keeping an omitted member at its stored value. -
Pagination and filtering:
ListSchedulesandListScheduleGroupshonourMaxResults(1–100, a full page when omitted) andNextToken.ListSchedulesfilters onNamePrefixandState;ListScheduleGroupsfilters onNamePrefix.- A
NextTokenthat cannot be decoded is answered with aValidationExceptionrather than silently restarting at the first page, which an SDK paginator would read as a legitimate page and loop on. - Both operations return the full stored object rather than AWS’s
ScheduleSummary/ScheduleGroupSummaryshape. That is a superset, so an SDK deserialises it unchanged.
-
Background scheduler engine:
- Polls on a 1-second clock ticker.
- Uses the injected clock, so integration tests can advance time quickly.
- A tick hands each due schedule to a pool of delivery workers rather than
delivering it on the tick itself, so a target that is slow, unreachable or
working through its
RetryPolicydelays only its own schedule. A schedule is never in flight twice, so its firings stay in order; a tick that finds a schedule still mid-delivery leaves it due and skips it.
-
Target dispatch:
- Delivery goes through the same internal dispatcher EventBridge rules and Pipes use, so a target ARN behaves identically on a schedule and on a rule. A firing is replayed against the emulator’s own API, which means a missing function, queue, topic, stream or state machine produces that service’s own AWS error rather than a silent no-op.
- Supported target types: Lambda (async invoke), SQS, SNS,
Step Functions, Kinesis, Firehose, ECS (
RunTask) and EventBridge event buses (PutEvents). - Target parameters honoured:
SqsParameters.MessageGroupId,KinesisParameters.PartitionKey,EventBridgeParameters(SourceandDetailType), andEcsParameters(TaskDefinitionArn,TaskCount,LaunchType,PlatformVersion,Group,NetworkConfiguration). The remainder of AWS’sEcsParametersshape — tags, placement constraints and strategy, capacity provider strategy — is accepted and ignored. Target.Inputis delivered verbatim. A target with noInputreceives a generated{"source":"aws.scheduler","time":…,"id":…}envelope.- A target type Overcast cannot fire is rejected at
CreateScheduleandUpdateSchedulewith aValidationException, rather than being accepted and dropped at fire time. This is stricter than AWS, which delivers to ~270 services through templated and universal (arn:aws:scheduler:::aws-sdk:…) targets; the refusal fails locally and loudly instead of leaving a schedule that looks correct and never fires. An ECS target withoutEcsParameters.TaskDefinitionArn, and an event-bus target withoutEventBridgeParameters, are refused for the same reason.
-
Retries and dead-lettering:
RetryPolicy.MaximumRetryAttemptsis honoured, capped at 6 total attempts. Retries run back to back on the delivery worker that owns the firing, with no backoff, so AWS’s default of 185 attempts is not replayed: a target with noRetryPolicyis attempted once. Other schedules are unaffected while a firing retries. EventBridge rule targets behave the same way.RetryPolicy.MaximumEventAgeInSecondsis honoured — once the payload is older than the budget, no further attempt is made.DeadLetterConfig.Arnis honoured for SQS queues, which is the only dead-letter target AWS supports. The payload is sent to the queue after the final failed attempt.- A firing that cannot be delivered and has no dead-letter queue is logged at
ERRORwith the sink’s own message — it is never dropped silently.
-
Not implemented:
FlexibleTimeWindowis stored and returned, but a schedule always fires at its exact due tick rather than being jittered across the window.ScheduleExpressionTimezoneis stored and returned, butcron(...)andat(...)are evaluated against the emulator’s own clock rather than the named zone.KmsKeyArnis stored and returned, but nothing is encrypted with it — the emulator holds schedule data in plaintext, so noDecryptcall is ever made against the key.
Summary
| Category | ✅ Supported |
|---|---|
| Schedule Groups | 4 |
| Schedules | 5 |
| Tags | 3 |
Endpoints
Schedule Groups
| Operation | Status | Notes | AWS Docs |
|---|---|---|---|
CreateScheduleGroup | ✅ Supported | Creates a named group | docs |
GetScheduleGroup | ✅ Supported | Returns group metadata | docs |
ListScheduleGroups | ✅ Supported | Lists groups in region | docs |
DeleteScheduleGroup | ✅ Supported | Deletes group (except default) | docs |
Schedules
| Operation | Status | Notes | AWS Docs |
|---|---|---|---|
CreateSchedule | ✅ Supported | POST /schedules/{Name}; GroupName in the body, defaulting to default; rejects a target type Overcast cannot fire | docs |
GetSchedule | ✅ Supported | GET /schedules/{Name}; ?groupName selects the group | docs |
UpdateSchedule | ✅ Supported | PUT /schedules/{Name}; GroupName in the body; replaces the whole schedule, so an omitted member is unset; rejects a target type Overcast cannot fire | docs |
DeleteSchedule | ✅ Supported | DELETE /schedules/{Name}; ?groupName selects the group | docs |
ListSchedules | ✅ Supported | GET /schedules; optional ?ScheduleGroup filter | docs |
Tags
| Operation | Status | Notes | AWS Docs |
|---|---|---|---|
TagResource | ✅ Supported | Merges tags on ARN, at the shared /tags/{ResourceArn} path; refuses the keys and values AWS refuses | docs |
UntagResource | ✅ Supported | Removes ?TagKeys from ARN | docs |
ListTagsForResource | ✅ Supported | Returns the modeled TagList, ordered by key | docs |