Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.amps.ai/llms.txt

Use this file to discover all available pages before exploring further.

Scheduling on Amps has one execution primitive: a push. A push fires immediately, at a future instant, or across a window. Schedules sit on top as a thin coordination layer that groups pushes into slots and recurrence patterns. There is no separate schedule execution engine. Understand the push and you understand scheduling.

Push is the primitive

A push targets a single device. start and end declare temporal intent:
ShapeBodyBehaviour
ImmediateNo startFire on receipt.
Scheduledstart onlyPersist; fire at start.
Windowedstart and endRun from start, revert at end.
The same canonical body works for all three, defined on canonical actions. Each command on a device declares an execution array stating which of these shapes it accepts.
{
  "action": {
    "command": "charge",
    "parameters": { "power": { "value": 5, "unit": "kw" } },
    "start": "2026-06-01T00:30:00+01:00",
    "end":   "2026-06-01T05:30:00+01:00"
  }
}
start accepts ISO 8601 with explicit timezone or a relative duration (30m, 1.5h, 2h). Naive datetimes are rejected. start must be in the future. The horizon is 30 days; further-out submissions return 422 START_OUT_OF_RANGE.

Lifecycle states

Every action moves through a small state machine:
StateMeaning
scheduledPersisted, queued to fire at start.
acknowledgedThe platform has dispatched the command to the OEM. Initial state for an immediate push.
completedThe OEM accepted the command.
failedThe OEM rejected the command, or a transient failure exhausted retries.
cancelledPOST /actions/{id}/cancel was called before dispatch.
completed records that the OEM accepted the command, not that the device verified end-state. To confirm physical state, subscribe to push.completed and read the device on the webhook. The API does not retry a failed push; you decide whether to re-submit, and with what. Subscribe to push.completed and push.failed via webhooks, or poll the action endpoint. Both are first-class.

Cancellation

POST /actions/{id}/cancel transitions a scheduled action to cancelled and removes it from the queue. Already-executing actions cannot be cancelled: a 409 ACTION_NOT_CANCELLABLE comes back. Amps does not attempt to recall in-flight OEM calls.

Internal dispatch guarantees

Exactly-once dispatch is guaranteed; a redelivered dispatch event never invokes the OEM twice.

Schedules as coordinators

The /schedules resource is in development. Action-level scheduling via start and end on push is available today. The conceptual model below describes what the resource will deliver when it ships; until then, group your own pushes client-side.
A schedule groups pushes:
{
  "deviceId": "device_abc123",
  "timezone": "Europe/London",
  "slots": [
    { "time": "00:30", "command": "charge",        "parameters": { "power": { "value": 5, "unit": "kw" } } },
    { "time": "05:30", "command": "auto.balanced" }
  ],
  "recurrence": { "type": "daily" }
}
Two slot variants exist: at (absolute ISO 8601) and time (wall-clock HH:mm plus a schedule-level timezone). A schedule will not mix the two; mixed payloads will be rejected. The schedule’s slots field is the authoritative record of what you asked for. Child actions and OEM-native programs are derived from it.

Recurrence

A schedule with a recurrence field will expand into slot instances on a rolling horizon (default 7 days, bounded 1-30). A daily cron tops up the horizon. Excluded weekdays and date ranges are honoured when slots are expanded.

DST handling

Time-variant slots will respect DST. Spring-forward: a slot that resolves to the skipped wall-clock hour skips that day. Fall-back: a slot in the repeated wall-clock hour fires once, at the first occurrence. Skipping rather than shifting prevents double-fires on recurrence patterns.

Schedule lifecycle

Schedules will carry their own state machine: pending to active (first slot fires) to completed (no further instances and all child actions terminal). A cancel route will transition to cancelled and stop further expansion. An update route will atomically replace slot definitions and recreate the affected child actions while preserving the schedule ID.

Two paths, one contract

Schedules will route over two execution paths depending on the OEM:
The OEM has an imperative push API. Amps creates one child action per slot instance on the rolling horizon and queues each to fire at its start.
The split will be invisible to you. The same /schedules resource and response shape applies to both. The capability response carries a read-only hint, but no request field selects a path.

Conflict and overlap

A new action that overlaps an existing pending or active action on the same device returns 409 CONFLICT with conflictingActionIds[], unless onConflict resolves it. Amps does not auto-cancel existing schedules on a conflicting submission. Read conflict resolution for the full model, including foreign-state preflight against device-side schedulers.
Amps does not poll devices to detect drift between scheduled intent and physical state. Schedules are declarative on submission; execution is queue-driven (Path A) or device-owned (Path B).

What scheduling does not do

  • No price or tariff inputs. Slots carry absolute or wall-clock times. Tariff optimisation stays on your side, and the control plane stays decoupled from market data feeds.
  • No pause and resume. The paused state is reserved in the enum but unused. Cancel and re-create instead.
  • No priorities or preemption. Conflicts surface as 409, and you drive resolution.
  • No fleet or multi-device actions. Every action targets one deviceId. Aggregation across devices is the caller’s responsibility.

Frequently asked questions

What states can a scheduled action be in?

Five: scheduled (persisted, queued to fire at start), acknowledged (the platform is talking to the OEM), completed (the OEM accepted), failed (the OEM rejected, or transient retries exhausted), and cancelled (a client cancelled before dispatch). scheduled and acknowledged are non-terminal. The other three are terminal. Actions never move backward through the state machine.

Can I cancel a scheduled action?

Yes, while it is in scheduled. POST /actions/{id}/cancel transitions the action to cancelled and removes it from the queue. Already-executing actions (acknowledged) cannot be cancelled and return 409 ACTION_NOT_CANCELLABLE. Amps does not attempt to recall in-flight OEM calls. When the schedules resource ships, POST /schedules/{id}/cancel will cancel the parent and every pending child action.

What happens if my schedule conflicts with another scheduled action?

The new action returns 409 CONFLICT with conflictingActionIds[] if onConflict is absent. Supply cancel_and_replace to drop the conflicting action and run the new one, or queue_after to defer the new action until the conflicting one’s end. Window-overlap predicates are not part of the test: two scheduled discharges for the same device collide on submission even with disjoint times. The model trades flexibility for an unambiguous one-action-per-device invariant.

How does recurrence work?

Recurrence ships with the /schedules resource (in development). A schedule with a recurrence field expands into slot instances on a rolling horizon (default 7 days, bounded 1-30). A daily cron tops up the horizon. Each expanded slot becomes a child action that moves through the same lifecycle as a direct push. Excluded weekdays and date ranges are honoured at expansion time. Cancelling the parent schedule cancels every pending child action.

How will the platform handle DST transitions?

When the schedules resource ships, time-variant slots (time plus timezone) will respect daylight saving. Spring-forward: a slot resolving to the skipped wall-clock hour is skipped that day, and the schedule emits schedule.slot_skipped. Fall-back: a slot in the repeated wall-clock hour fires once, at the first occurrence. Skipping rather than shifting prevents double-fires on recurrence patterns; the webhook keeps the skip visible.

Canonical Actions

The shape every push uses.

Conflict Resolution

onConflict, 409 envelopes, foreign-state preflight.

Webhooks

Action and schedule lifecycle events delivered to your endpoint.

Error Envelope

START_IN_PAST, START_OUT_OF_RANGE, EXECUTION_NOT_SUPPORTED.
For worked examples, see the cookbook: charge overnight and discharge during a peak window.