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.

Overview

You have two ways to cancel. Use the cancel endpoint to drop a scheduled action by ID; it only works while the action is in scheduled state. Or use onConflict: "cancel_and_replace" on a fresh push to cancel the colliding action and apply the new one in a single round-trip.

Pattern A: Cancel a scheduled action by ID

Step 1: Schedule an action

curl -X POST https://api.amps.ai/battery/dev_abc123 \
  -H "x-api-key: sk_live_abc123xyz" \
  -H "Content-Type: application/json" \
  -d '{
    "action": {
      "command": "charge",
      "start": "2026-05-09T22:00:00Z",
      "end": "2026-05-10T05:00:00Z",
      "parameters": {
        "target": { "value": 100, "unit": "percent" }
      }
    }
  }'
{
  "actionId": "act_pending_001",
  "state": "scheduled",
  "type": "battery:set_operation_mode",
  "createdAt": "2026-05-08T08:00:00.000Z",
  "start": "2026-05-09T22:00:00.000Z"
}

Step 2: Cancel before it fires

curl -X POST https://api.amps.ai/actions/act_pending_001/cancel \
  -H "x-api-key: sk_live_abc123xyz"
You get back the action with state: cancelled. It will not fire.
{
  "id": "act_pending_001",
  "deviceId": "dev_abc123",
  "type": "battery:set_operation_mode",
  "state": "cancelled",
  "parameters": {
    "mode": "charge",
    "target": { "value": 100, "unit": "percent" }
  },
  "result": null,
  "errorCode": null,
  "errorMessage": null,
  "createdAt": "2026-05-08T08:00:00.000Z",
  "updatedAt": "2026-05-08T11:32:00.000Z",
  "acknowledgedAt": null,
  "completedAt": null,
  "start": "2026-05-09T22:00:00.000Z"
}

Cancellation only works in scheduled state

Once the action is in flight, cancel returns 409 ACTION_NOT_CANCELLABLE.
{
  "success": false,
  "error": {
    "code": "ACTION_NOT_CANCELLABLE",
    "message": "Action in state 'acknowledged' cannot be cancelled"
  },
  "meta": {
    "requestId": "req_4nF8bMqE",
    "timestamp": "2026-05-08T11:32:00.000Z",
    "path": "/actions/act_inflight_002/cancel",
    "latencyMs": 8
  }
}
If the action is already in flight, wait for it to reach completed or failed.

Pattern B: Cancel and replace in a single push

When the new intent is also a push, fold the cancellation into the new request. This avoids a race where the original fires between cancel and re-push.
curl -X POST https://api.amps.ai/battery/dev_abc123 \
  -H "x-api-key: sk_live_abc123xyz" \
  -H "Content-Type: application/json" \
  -d '{
    "action": {
      "command": "discharge",
      "start": "2026-05-09T22:00:00Z",
      "end": "2026-05-10T05:00:00Z",
      "parameters": {
        "target": { "value": 30, "unit": "percent" }
      }
    },
    "onConflict": "cancel_and_replace"
  }'
The colliding scheduled charge is cancelled and the new discharge is accepted in a single transaction.
{
  "actionId": "act_pending_002",
  "state": "scheduled",
  "type": "battery:set_operation_mode",
  "createdAt": "2026-05-08T11:32:00.000Z",
  "start": "2026-05-09T22:00:00.000Z"
}
The cancelled action remains visible by ID. A follow-up GET /actions/act_pending_001 returns state: cancelled.

When cancel_and_replace cannot help

If the colliding action is already acknowledged, the cancel half of cancel_and_replace fails. You get 409 CONFLICT with the in-flight action ID.
{
  "success": false,
  "error": {
    "code": "CONFLICT",
    "message": "The conflicting action is already in progress and cannot be cancelled. Wait for it to complete or fail.",
    "details": {
      "conflictingActionIds": ["act_inflight_002"]
    }
  },
  "meta": {
    "requestId": "req_3dC6hOsT",
    "timestamp": "2026-05-08T11:32:00.000Z",
    "path": "/battery/dev_abc123",
    "latencyMs": 18
  }
}
Poll the in-flight action. Once it reaches completed or failed, retry the push.

What next

Handle conflict 409s

Both onConflict strategies, plus SCHEDULER_ACTIVE behaviours.

Charge overnight

Recipe that creates the kind of action this page cancels.

Subscribe to webhooks

Detect terminal state transitions without polling.

Canonical actions

The action lifecycle and where cancellation fits.