Documentation

Actions & Execution

Start and stop operations executed against cloud resources — triggered by schedules or by manual API calls — with idempotent retries, structured state history, and bulk dispatch.

Actions are start/stop operations executed against cloud resources — either triggered automatically by schedules or manually through the API.

How Execution Works

  1. An action intent is created (by scheduler or manual API call)
  2. The intent is queued in Redis for processing
  3. The executor picks up the intent and calls the cloud provider API
  4. The result (success/failure) is recorded as an execution log
  5. State transitions are tracked in the state history

Action Statuses

StatusDescription
pendingAction is queued, waiting to be processed
runningAction is being executed against the cloud provider
succeededAction completed successfully
failedAction failed — check errorMessage for details

Manual Action

Trigger a start or stop action on a specific resource outside of any schedule.

POST/actions

Submit a manual start or stop action.

Request · bash
curl -X POST https://zopnight.com/api/actions \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
  "type": "stop",
  "resourceUID": "i-0abc123def456",
  "provider": "aws",
  "resourceType": "aws-ec2",
  "cloudAccountID": "ca_abc123",
  "region": "us-east-1"
}'
Response · json
{
"data": {
  "actionID": "act_xyz789",
  "status": "queued"
}
}

Bulk Action

Start or stop all resources in a resource group with a single request. Resources are processed according to their execution tier and order.

POST/actions/bulk

Submit a bulk action for a resource group.

Request · bash
curl -X POST https://zopnight.com/api/actions/bulk \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
  "type": "start",
  "groupID": "grp_abc123"
}'
Response · json
{
"data": {
  "bulkActionID": "bulk_xyz789",
  "status": "queued",
  "total": 4
}
}

Get Action Status

GET/actions/{actionID}

Check the status of a submitted action.

Response · json
{
"data": {
  "id": "act_xyz789",
  "resourceUID": "i-0abc123def456",
  "provider": "aws",
  "cloudAccountID": "ca_abc123",
  "region": "us-east-1",
  "action": "stop",
  "reason": "manual",
  "status": "succeeded",
  "startedAt": "2025-01-20T10:00:05Z",
  "completedAt": "2025-01-20T10:00:12Z",
  "createdAt": "2025-01-20T10:00:00Z"
}
}

Get Bulk Action Status

GET/actions/bulk/{bulkActionID}

Check the status of a bulk action.

Response · json
{
"data": {
  "id": "bulk_xyz789",
  "groupID": "grp_abc123",
  "type": "start",
  "status": "completed",
  "total": 4,
  "completed": 4,
  "failed": 0,
  "createdAt": "2025-01-20T10:00:00Z"
}
}

Latest Bulk Action

Returns the most recent bulk action for the org. Useful for "is there still something running?" indicators that don't already have a bulk ID to look up.

GET/actions/bulk/latest

Get the most recent bulk action submitted by this org.

Response · json
{
"data": {
  "id": "bulk_xyz789",
  "groupID": "grp_abc123",
  "type": "start",
  "status": "running",
  "total": 12,
  "completed": 7,
  "failed": 0,
  "createdAt": "2026-04-29T10:00:00Z"
}
}

State History

Query the state transition history for resources. This provides an audit trail of when resources were started or stopped and why.

GET/state-history

Get resource state transition history with pagination.

Query Parameters

ParameterDescription
resource_uidFilter by specific resource
changed_by_typeFilter by source: schedule, manual, bulk, override, override_expired
pagePage number
limitItems per page
Response · json
{
"data": {
  "items": [
    {
      "id": "sh_001",
      "resourceUid": "i-0abc123def456",
      "state": "stopped",
      "changedAt": "2025-01-20T18:00:00Z",
      "changedBy": "schedule:nightly-shutdown:cron_xyz",
      "scheduleId": "sch_abc123",
      "executionState": { "step": "stop-instance", "status": "succeeded" }
    },
    {
      "id": "sh_002",
      "resourceUid": "i-0abc123def456",
      "state": "failed",
      "changedAt": "2025-01-21T08:00:00Z",
      "changedBy": "schedule:nightly-shutdown:cron_xyz",
      "scheduleId": "sch_abc123",
      "errorMessage": "InsufficientCapacity: m6i.large not available in us-east-1a"
    }
  ],
  "total": 2,
  "page": 1,
  "limit": 50
}
}