# Compute API

> REST endpoints for compute inventory, schedules, and remediation actions across EC2, GCE, Azure VMs, ASGs, MIGs, and VMSS.

Source: https://zop.dev/docs/zopnight/api/compute

---

## Base URL and auth

```
https://api.zop.dev/v1
```

All requests require a personal access token in the `Authorization: Bearer …` header. See [Authentication](https://zop.dev/docs/zopnight/authentication) for how to mint one.

Read-only PATs can call every endpoint in this section except `POST /compute/:id/actions` (requires `compute:write` scope).

## List compute resources

```
GET /compute
```

### Query parameters

| Name | Type | Description |
|---|---|---|
| `account` | string | Filter by cloud account ID. |
| `provider` | enum | `aws`, `gcp`, `azure`. |
| `type` | string | Resource type, e.g. `ec2`, `gce-vm`, `azure-vm`, `asg`. |
| `environment` | string | `prod`, `stage`, `uat`, `dev`. |
| `team` | string | Owning team slug. |
| `state` | enum | `running`, `stopped`, `pending`, `terminated`. |
| `page` | int | 1-indexed. |
| `pageSize` | int | Max 200, default 50. |

### Example

```bash
curl "https://api.zop.dev/v1/compute?provider=aws&environment=dev&state=running" \
  -H "Authorization: Bearer $ZOPNIGHT_PAT"
```

### Response

```json
{
  "data": [
    {
      "id": "i-0abc12340def56789",
      "provider": "aws",
      "type": "ec2",
      "account": "123456789012",
      "region": "us-east-1",
      "state": "running",
      "environment": "dev",
      "team": "payments-platform",
      "tags": { "env": "dev", "owner": "payments-platform" },
      "instanceType": "m5.xlarge",
      "launchedAt": "2026-04-12T08:14:00Z",
      "cost": {
        "monthlyProjected": 124.32,
        "currency": "USD",
        "reconciledTo": "aws-cost-explorer"
      },
      "schedule": {
        "id": "sched_dev_night_shift",
        "nextAction": "stop",
        "nextActionAt": "2026-06-01T14:30:00Z"
      }
    }
  ],
  "pagination": { "page": 1, "pageSize": 50, "total": 412 }
}
```

## Get a compute resource

```
GET /compute/:id
```

Returns the full resource document including dependency edges (security-group references, target-group memberships, attached volumes).

## List recommendations for a compute resource

```
GET /compute/:id/recommendations
```

Returns the open recommendations for this resource (idle, right-size, schedule, orphan) each with the rule ID, the observed metric, the threshold, the action, and the projected dollar.

## Apply an action

```
POST /compute/:id/actions
```

### Body

```json
{
  "action": "stop",
  "reason": "manual-test",
  "reviewerNote": "Confirmed with team-payments on Slack",
  "dryRun": false
}
```

Supported actions: `stop`, `start`, `reboot`, `terminate`, `resize`, `apply-schedule`, `remove-schedule`. Each action runs through the standard four-step gate: **precondition → approval → cloud call → validate**.

### Response

```json
{
  "actionId": "act_01HK3F2V8X7QZP",
  "status": "applied",
  "appliedAt": "2026-06-01T05:01:23Z",
  "validation": {
    "preCondition": "pass",
    "approval": "auto",
    "cloudResult": "EC2 stop-instances completed",
    "postValidation": "instance state = stopped"
  }
}
```

If `dryRun: true`, the response shows what would have happened without making the cloud call.

## Errors

Errors use standard HTTP status codes. The body carries a machine-readable `code`, a human-readable `message`, and the numeric `status`.

| Status | Meaning |
|---|---|
| `400` | Invalid or malformed parameters (bad enum value, missing required field). |
| `401` | Missing or invalid token. |
| `403` | Token lacks the required scope (e.g. `compute:write` on `POST /compute/:id/actions`). |
| `404` | Resource not found, or not visible to the token's role. |
| `429` | Rate limited; see [Rate limits](#rate-limits). |
| `5xx` | Server error; safe to retry with backoff. |

```json
{
  "error": {
    "code": "forbidden",
    "message": "token is missing the compute:write scope",
    "status": 403
  }
}
```

## Rate limits

- **Read endpoints**: 600 requests/min per workspace.
- **Action endpoints**: 60 requests/min per workspace.

Headers `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` are returned on every response.
