# Deploy

## Deploy a built agent image

**post** `/v5/agentex/deployments`

Deploy a successfully built agent image to Kubernetes as a Helm release.

Takes a completed build (referenced by `build_id`, or by `image_name` +
`image_tag`) together with the agent manifest and environment config, then
starts an asynchronous Temporal workflow that provisions the agent as a Helm
release. The call returns immediately with the deployment record in `PENDING`
status — it does not wait for the release to become healthy; poll
`GET /v5/agentex/deployments/{deployment_id}` for status and Kubernetes events
and `GET /v5/agentex/deployments/{deployment_id}/logs` for progress. This is the
deploy counterpart to `POST /v5/agentex/builds`: a build produces the container
image, a deployment runs that image. The referenced build must have finished
successfully, and the manifest's agent name must match the build's agent.

Set `preview=True` for an ephemeral deployment: it gets a globally unique Helm
release name (so concurrent redeploys never collide), an optional `preview_label`
for grouping, and an expiry (`expires_at`, defaulting to 8 hours from now);
`preview_label` and `expires_at` are rejected on non-preview deploys. A
non-preview (production) deploy instead supersedes any prior active deployment
that shares its Helm release name. Fails with a client error if the build is
missing or not in a successful state, if the manifest or environment YAML is
invalid or their agent names disagree, or if a secret referenced by the manifest
does not exist.

### Body Parameters

- `environment_config: string`

  YAML content of environment configuration from the environment config file.

- `manifest_file: string`

  YAML content of manifest configuration.

- `build_id: optional string`

  The build_id of the cloud build. Required if image_name and image_tag are not provided.

- `expires_at: optional string`

  ISO 8601 expiry timestamp. Only valid for preview deployments. If omitted on a preview deployment, defaults to 8 hours from now. Previews are always ephemeral and always have an expires_at.

- `image_name: optional string`

  Name of the image to deploy. Required if build_id is not provided.

- `image_tag: optional string`

  Tag of the image to deploy. Required if build_id is not provided.

- `preview: optional boolean`

  When True, creates a preview deployment with a unique deployment-id suffix appended to the helm release name.

- `preview_label: optional string`

  Non-unique grouping label for the preview (e.g. branch name, PR number). Persisted on the deployment record so callers can list all deploys for a given label via `GET /v5/agentex/deployments?preview_label=X&limit=1` (get the latest). Sanitized to lowercase alphanumeric + hyphens for K8s DNS-label compatibility (max 30 characters after sanitization). Each deploy still gets a unique helm release name regardless of label, so concurrent redeploys never share K8s resources. Only valid when preview=True.

### Returns

- `AgentexCloudDeploy object { id, account_id, created_at, 11 more }`

  - `id: string`

    The unique identifier of the deployment.

  - `account_id: string`

    The ID of the account that owns the given entity.

  - `created_at: string`

    The date and time when the entity was created in ISO format.

  - `created_by: Identity`

    The identity that created the entity.

    - `id: string`

    - `type: "user" or "service_account"`

      - `"user"`

      - `"service_account"`

    - `object: optional "identity"`

      - `"identity"`

  - `environment_config: string`

    YAML content of environment configuration from the environment config file.

  - `manifest_file: string`

    YAML content of manifest configuration.

  - `namespace: string`

    Kubernetes namespace where the deployment is deployed.

  - `status: string`

    Deployment status: pending, running, completed, failed, or cancelled.

  - `build_id: optional string`

    The build_id of the cloud build that produced the deployed image.

  - `deploy_events: optional array of AgentexCloudDeployEvent`

    Kubernetes events for this deployment.

    - `message: optional string`

      Full event message.

    - `reason: optional string`

      Short reason, e.g. 'Pulling', 'Scheduled'.

    - `timestamp: optional string`

      When the event was observed.

    - `type: optional string`

      Event type, e.g. 'Normal' or 'Warning'.

  - `expires_at: optional string`

    When this deployment will be cleaned up. Always set on preview deployments (defaults to 8 hours from creation if the request omits it). Null on non-preview deployments — they have no TTL.

  - `helm_release_name: optional string`

    Helm release name after successful deployment.

  - `object: optional "agentex_cloud_deploy"`

    - `"agentex_cloud_deploy"`

  - `preview_label: optional string`

    Non-unique grouping label for preview deployments. Filter `?preview_label=X&limit=1` returns the latest deploy for the label. Sanitized (lowercase alphanumeric + hyphens) and capped at 30 characters.

### Example

```http
curl https://api.egp.scale.com/v5/agentex/deployments \
    -H 'Content-Type: application/json' \
    -H "x-api-key: $SGP_API_KEY" \
    -d '{
          "environment_config": "environment_config",
          "manifest_file": "manifest_file"
        }'
```

#### Response

```json
{
  "id": "id",
  "account_id": "account_id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "environment_config": "environment_config",
  "manifest_file": "manifest_file",
  "namespace": "namespace",
  "status": "status",
  "build_id": "build_id",
  "deploy_events": [
    {
      "message": "message",
      "reason": "reason",
      "timestamp": "2019-12-27T18:11:19.117Z",
      "type": "type"
    }
  ],
  "expires_at": "2019-12-27T18:11:19.117Z",
  "helm_release_name": "helm_release_name",
  "object": "agentex_cloud_deploy",
  "preview_label": "preview_label"
}
```

## Get an agent deployment

**get** `/v5/agentex/deployments/{deployment_id}`

Get a single agent deployment by ID, including its current status and Kubernetes events.

Returns the deployment record with its latest status and the associated
Kubernetes events (`deploy_events`) observed for the release, which are useful
for diagnosing why a deployment is still pending or unhealthy. Poll this after
`POST /v5/agentex/deployments` to track the asynchronous deploy to completion.
For the incremental log output rather than status and events, use
`GET /v5/agentex/deployments/{deployment_id}/logs`. Returns 404 if no deployment
with this ID exists for the caller's account.

### Path Parameters

- `deployment_id: string`

### Returns

- `AgentexCloudDeploy object { id, account_id, created_at, 11 more }`

  - `id: string`

    The unique identifier of the deployment.

  - `account_id: string`

    The ID of the account that owns the given entity.

  - `created_at: string`

    The date and time when the entity was created in ISO format.

  - `created_by: Identity`

    The identity that created the entity.

    - `id: string`

    - `type: "user" or "service_account"`

      - `"user"`

      - `"service_account"`

    - `object: optional "identity"`

      - `"identity"`

  - `environment_config: string`

    YAML content of environment configuration from the environment config file.

  - `manifest_file: string`

    YAML content of manifest configuration.

  - `namespace: string`

    Kubernetes namespace where the deployment is deployed.

  - `status: string`

    Deployment status: pending, running, completed, failed, or cancelled.

  - `build_id: optional string`

    The build_id of the cloud build that produced the deployed image.

  - `deploy_events: optional array of AgentexCloudDeployEvent`

    Kubernetes events for this deployment.

    - `message: optional string`

      Full event message.

    - `reason: optional string`

      Short reason, e.g. 'Pulling', 'Scheduled'.

    - `timestamp: optional string`

      When the event was observed.

    - `type: optional string`

      Event type, e.g. 'Normal' or 'Warning'.

  - `expires_at: optional string`

    When this deployment will be cleaned up. Always set on preview deployments (defaults to 8 hours from creation if the request omits it). Null on non-preview deployments — they have no TTL.

  - `helm_release_name: optional string`

    Helm release name after successful deployment.

  - `object: optional "agentex_cloud_deploy"`

    - `"agentex_cloud_deploy"`

  - `preview_label: optional string`

    Non-unique grouping label for preview deployments. Filter `?preview_label=X&limit=1` returns the latest deploy for the label. Sanitized (lowercase alphanumeric + hyphens) and capped at 30 characters.

### Example

```http
curl https://api.egp.scale.com/v5/agentex/deployments/$DEPLOYMENT_ID \
    -H "x-api-key: $SGP_API_KEY"
```

#### Response

```json
{
  "id": "id",
  "account_id": "account_id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "environment_config": "environment_config",
  "manifest_file": "manifest_file",
  "namespace": "namespace",
  "status": "status",
  "build_id": "build_id",
  "deploy_events": [
    {
      "message": "message",
      "reason": "reason",
      "timestamp": "2019-12-27T18:11:19.117Z",
      "type": "type"
    }
  ],
  "expires_at": "2019-12-27T18:11:19.117Z",
  "helm_release_name": "helm_release_name",
  "object": "agentex_cloud_deploy",
  "preview_label": "preview_label"
}
```

## List agent deployments

**get** `/v5/agentex/deployments`

List the account's agent deployments, with pagination and optional filters.

Returns the deployments the caller is authorized to read. Optionally filter by
`build_id`, by `agent_name` (matched through each deployment's associated build),
or by `preview_label`. A `preview_label` is non-unique — many deployments can
share one (for example every deploy for a branch) — so combine it with `limit=1`
to fetch the latest deployment for that label. This lists deployments (the running
or attempted agent instances); to list the image builds they run, use the agentex
builds API.

### Query Parameters

- `agent_name: optional string`

  Filter deployments by agent name (via associated build)

- `build_id: optional string`

  Filter deployments by build ID

- `ending_before: optional string`

- `limit: optional number`

- `preview_label: optional string`

  Filter deployments by preview label (e.g. branch name). The label is non-unique — many deployments can share it. Combine with limit=1 to get the latest deploy for that label.

- `sort_by: optional string`

- `sort_order: optional SortOrder`

  - `"asc"`

  - `"desc"`

- `starting_after: optional string`

### Returns

- `has_more: boolean`

  Whether there are more items left to be fetched.

- `items: array of AgentexCloudDeploy`

  - `id: string`

    The unique identifier of the deployment.

  - `account_id: string`

    The ID of the account that owns the given entity.

  - `created_at: string`

    The date and time when the entity was created in ISO format.

  - `created_by: Identity`

    The identity that created the entity.

    - `id: string`

    - `type: "user" or "service_account"`

      - `"user"`

      - `"service_account"`

    - `object: optional "identity"`

      - `"identity"`

  - `environment_config: string`

    YAML content of environment configuration from the environment config file.

  - `manifest_file: string`

    YAML content of manifest configuration.

  - `namespace: string`

    Kubernetes namespace where the deployment is deployed.

  - `status: string`

    Deployment status: pending, running, completed, failed, or cancelled.

  - `build_id: optional string`

    The build_id of the cloud build that produced the deployed image.

  - `deploy_events: optional array of AgentexCloudDeployEvent`

    Kubernetes events for this deployment.

    - `message: optional string`

      Full event message.

    - `reason: optional string`

      Short reason, e.g. 'Pulling', 'Scheduled'.

    - `timestamp: optional string`

      When the event was observed.

    - `type: optional string`

      Event type, e.g. 'Normal' or 'Warning'.

  - `expires_at: optional string`

    When this deployment will be cleaned up. Always set on preview deployments (defaults to 8 hours from creation if the request omits it). Null on non-preview deployments — they have no TTL.

  - `helm_release_name: optional string`

    Helm release name after successful deployment.

  - `object: optional "agentex_cloud_deploy"`

    - `"agentex_cloud_deploy"`

  - `preview_label: optional string`

    Non-unique grouping label for preview deployments. Filter `?preview_label=X&limit=1` returns the latest deploy for the label. Sanitized (lowercase alphanumeric + hyphens) and capped at 30 characters.

- `total: number`

  The total of items that match the query. This is greater than or equal to the number of items returned.

- `limit: optional number`

  The maximum number of items to return.

- `object: optional "list"`

  - `"list"`

### Example

```http
curl https://api.egp.scale.com/v5/agentex/deployments \
    -H "x-api-key: $SGP_API_KEY"
```

#### Response

```json
{
  "has_more": true,
  "items": [
    {
      "id": "id",
      "account_id": "account_id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "created_by": {
        "id": "id",
        "type": "user",
        "object": "identity"
      },
      "environment_config": "environment_config",
      "manifest_file": "manifest_file",
      "namespace": "namespace",
      "status": "status",
      "build_id": "build_id",
      "deploy_events": [
        {
          "message": "message",
          "reason": "reason",
          "timestamp": "2019-12-27T18:11:19.117Z",
          "type": "type"
        }
      ],
      "expires_at": "2019-12-27T18:11:19.117Z",
      "helm_release_name": "helm_release_name",
      "object": "agentex_cloud_deploy",
      "preview_label": "preview_label"
    }
  ],
  "total": 0,
  "limit": 0,
  "object": "list"
}
```

## Get agent deployment logs

**get** `/v5/agentex/deployments/{deployment_id}/logs`

Get structured deployment log lines, with cursor-based pagination.

Returns the deployment's log lines in time order together with a `next_cursor`
and a `has_more` flag. Poll to stream logs incrementally: make the first call
without a cursor, then pass the previous response's `next_cursor` as `cursor` on
each subsequent call, stopping once the deployment reaches a terminal status.
Unlike `GET /v5/agentex/deployments/{deployment_id}`, which returns the
deployment's status and Kubernetes events, this returns the raw log output from
the deploy process. Returns 404 if no deployment with this ID exists for the
caller's account.

### Path Parameters

- `deployment_id: string`

### Query Parameters

- `cursor: optional string`

  Cursor from previous response's next_cursor field

- `limit: optional number`

  Maximum number of log lines to return

### Returns

- `deployment_id: string`

  The deployment ID

- `has_more: boolean`

  True if there may be more lines beyond this page (len(lines) == limit).

- `lines: optional array of object { id, message, log_level, timestamp }`

  Structured log lines

  - `id: string`

    Unique log line identifier (time-ordered)

  - `message: string`

    Log line content after the K8s timestamp

  - `log_level: optional string`

    Parsed log level (INFO, ERROR, WARN, DEBUG, FATAL)

  - `timestamp: optional string`

    Parsed K8s log timestamp

- `next_cursor: optional string`

  Cursor for the next page. Pass this as the after_id query parameter to get subsequent logs.

### Example

```http
curl https://api.egp.scale.com/v5/agentex/deployments/$DEPLOYMENT_ID/logs \
    -H "x-api-key: $SGP_API_KEY"
```

#### Response

```json
{
  "deployment_id": "deployment_id",
  "has_more": true,
  "lines": [
    {
      "id": "id",
      "message": "message",
      "log_level": "log_level",
      "timestamp": "2019-12-27T18:11:19.117Z"
    }
  ],
  "next_cursor": "next_cursor"
}
```

## Delete and tear down a deployment

**delete** `/v5/agentex/deployments/{deployment_id}`

Delete an agent deployment and tear down its Kubernetes resources.

Deletes the deployment's Kubernetes resources first, then marks the record as
`DELETED`; the underlying Helm release is subsequently uninstalled
asynchronously by FluxCD once the resource is removed. If the Kubernetes teardown
fails, the record is left unchanged and the call errors, so the delete can be
safely retried. Rejects the call with a client error if the deployment is already
in a terminal state (`DELETED`, `CANCELLED`, or `SUPERSEDED`) — a `SUPERSEDED`
record shares its Helm release with the deployment that replaced it, so deleting
it would tear down the live release. Returns 404 if no deployment with this ID
exists for the caller's account. This removes a running deployment, not the image
build behind it, which is managed separately through the agentex builds API.

### Path Parameters

- `deployment_id: string`

### Returns

- `AgentexCloudDeploy object { id, account_id, created_at, 11 more }`

  - `id: string`

    The unique identifier of the deployment.

  - `account_id: string`

    The ID of the account that owns the given entity.

  - `created_at: string`

    The date and time when the entity was created in ISO format.

  - `created_by: Identity`

    The identity that created the entity.

    - `id: string`

    - `type: "user" or "service_account"`

      - `"user"`

      - `"service_account"`

    - `object: optional "identity"`

      - `"identity"`

  - `environment_config: string`

    YAML content of environment configuration from the environment config file.

  - `manifest_file: string`

    YAML content of manifest configuration.

  - `namespace: string`

    Kubernetes namespace where the deployment is deployed.

  - `status: string`

    Deployment status: pending, running, completed, failed, or cancelled.

  - `build_id: optional string`

    The build_id of the cloud build that produced the deployed image.

  - `deploy_events: optional array of AgentexCloudDeployEvent`

    Kubernetes events for this deployment.

    - `message: optional string`

      Full event message.

    - `reason: optional string`

      Short reason, e.g. 'Pulling', 'Scheduled'.

    - `timestamp: optional string`

      When the event was observed.

    - `type: optional string`

      Event type, e.g. 'Normal' or 'Warning'.

  - `expires_at: optional string`

    When this deployment will be cleaned up. Always set on preview deployments (defaults to 8 hours from creation if the request omits it). Null on non-preview deployments — they have no TTL.

  - `helm_release_name: optional string`

    Helm release name after successful deployment.

  - `object: optional "agentex_cloud_deploy"`

    - `"agentex_cloud_deploy"`

  - `preview_label: optional string`

    Non-unique grouping label for preview deployments. Filter `?preview_label=X&limit=1` returns the latest deploy for the label. Sanitized (lowercase alphanumeric + hyphens) and capped at 30 characters.

### Example

```http
curl https://api.egp.scale.com/v5/agentex/deployments/$DEPLOYMENT_ID \
    -X DELETE \
    -H "x-api-key: $SGP_API_KEY"
```

#### Response

```json
{
  "id": "id",
  "account_id": "account_id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "environment_config": "environment_config",
  "manifest_file": "manifest_file",
  "namespace": "namespace",
  "status": "status",
  "build_id": "build_id",
  "deploy_events": [
    {
      "message": "message",
      "reason": "reason",
      "timestamp": "2019-12-27T18:11:19.117Z",
      "type": "type"
    }
  ],
  "expires_at": "2019-12-27T18:11:19.117Z",
  "helm_release_name": "helm_release_name",
  "object": "agentex_cloud_deploy",
  "preview_label": "preview_label"
}
```

## Domain Types

### Agentex Cloud Deploy

- `AgentexCloudDeploy object { id, account_id, created_at, 11 more }`

  - `id: string`

    The unique identifier of the deployment.

  - `account_id: string`

    The ID of the account that owns the given entity.

  - `created_at: string`

    The date and time when the entity was created in ISO format.

  - `created_by: Identity`

    The identity that created the entity.

    - `id: string`

    - `type: "user" or "service_account"`

      - `"user"`

      - `"service_account"`

    - `object: optional "identity"`

      - `"identity"`

  - `environment_config: string`

    YAML content of environment configuration from the environment config file.

  - `manifest_file: string`

    YAML content of manifest configuration.

  - `namespace: string`

    Kubernetes namespace where the deployment is deployed.

  - `status: string`

    Deployment status: pending, running, completed, failed, or cancelled.

  - `build_id: optional string`

    The build_id of the cloud build that produced the deployed image.

  - `deploy_events: optional array of AgentexCloudDeployEvent`

    Kubernetes events for this deployment.

    - `message: optional string`

      Full event message.

    - `reason: optional string`

      Short reason, e.g. 'Pulling', 'Scheduled'.

    - `timestamp: optional string`

      When the event was observed.

    - `type: optional string`

      Event type, e.g. 'Normal' or 'Warning'.

  - `expires_at: optional string`

    When this deployment will be cleaned up. Always set on preview deployments (defaults to 8 hours from creation if the request omits it). Null on non-preview deployments — they have no TTL.

  - `helm_release_name: optional string`

    Helm release name after successful deployment.

  - `object: optional "agentex_cloud_deploy"`

    - `"agentex_cloud_deploy"`

  - `preview_label: optional string`

    Non-unique grouping label for preview deployments. Filter `?preview_label=X&limit=1` returns the latest deploy for the label. Sanitized (lowercase alphanumeric + hyphens) and capped at 30 characters.

### Agentex Cloud Deploy Event

- `AgentexCloudDeployEvent object { message, reason, timestamp, type }`

  Slim event representation for the API response.

  - `message: optional string`

    Full event message.

  - `reason: optional string`

    Short reason, e.g. 'Pulling', 'Scheduled'.

  - `timestamp: optional string`

    When the event was observed.

  - `type: optional string`

    Event type, e.g. 'Normal' or 'Warning'.

### Deploy Logs Response

- `DeployLogsResponse object { deployment_id, has_more, lines, next_cursor }`

  Response containing structured deployment log lines with cursor-based pagination.

  The CLI can poll this endpoint to stream logs incrementally:

  1. First call: no after_id
  1. Subsequent calls: after_id=next_cursor from previous response
  1. Stop polling when has_more is False and the deployment reaches a terminal status

  - `deployment_id: string`

    The deployment ID

  - `has_more: boolean`

    True if there may be more lines beyond this page (len(lines) == limit).

  - `lines: optional array of object { id, message, log_level, timestamp }`

    Structured log lines

    - `id: string`

      Unique log line identifier (time-ordered)

    - `message: string`

      Log line content after the K8s timestamp

    - `log_level: optional string`

      Parsed log level (INFO, ERROR, WARN, DEBUG, FATAL)

    - `timestamp: optional string`

      Parsed K8s log timestamp

  - `next_cursor: optional string`

    Cursor for the next page. Pass this as the after_id query parameter to get subsequent logs.
