Overview
A 409 means the device already has an action booked for the requested window. The error response lists the colliding action IDs and the strategies that would resolve it. Two strategies,cancel_and_replace and queue_after, ride on the request body so you can resolve conflicts in a single round-trip.
A different kind of conflict comes from the device’s own scheduler. When an OEM has its native scheduler active, direct writes are rejected until it is cleared. You see this as SCHEDULER_ACTIVE on the action result.
Anatomy of a 409 CONFLICT
Push without anonConflict strategy when a colliding action exists:
409 with the conflicting action IDs and the strategies that would resolve the collision.
Strategy 1: cancel_and_replace
Use this when the new intent should win. The colliding action is cancelled and the new one is applied.- curl
- Node
act_pending_001 is cancelled and the new push is accepted.
Strategy 2: queue_after
Use this when the new intent should run as soon as the device is free, without losing the existing schedule. The new action is deferred until the active one terminates.When cancel_and_replace cannot help
cancel_and_replace only works while the conflicting action is scheduled. If the OEM has already accepted the write, you get a 409 with the in-flight IDs and no strategies that would resolve it.
completed, failed, or cancelled.
SCHEDULER_ACTIVE: a different kind of conflict
Some OEMs, FoxESS-class devices among them, require their native scheduler to be disabled before they will accept direct mode writes. When the scheduler is active, the action result carriesSCHEDULER_ACTIVE.
onConflict: "cancel_and_replace". The native scheduler is cleared, the direct command is applied, and the new action’s lifecycle reports back as normal. No separate cancel call is required.
What next
Cancel an action
The dedicated cancel endpoint and when to reach for it.
Schedule a charge for later
The kind of windowed action that triggers conflicts.
Auto modes
Hand control back to the platform after resolving a conflict.
Subscribe to webhooks
Detect SCHEDULER_ACTIVE failures without polling.