> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gp.scale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API and SDK

> Programmatic access to Agentex cloud builds and deployments via the REST API and Python/TypeScript SDKs.

## Overview

The Build and Deploy API and SDKs give you programmatic control over Agentex cloud builds and deployments. You can create builds, poll for status, stream logs, create deployments, and tear them down through REST endpoints under `/v5/builds` and `/v5/agentex/deployments`, or through the equivalent Python and TypeScript SDK methods.

The API and SDKs expose the same underlying resources as the UI, CLI, and CI/CD interfaces, so anything you create or modify programmatically is visible everywhere else. Use them when you need to integrate builds and deployments into custom automation or tooling.

For full SDK documentation, see the [Python SDK reference](https://sgp-dev.stldocs.app/api/python) and [TypeScript SDK reference](https://sgp-dev.stldocs.app/api/typescript).

## Authentication

Every request to the Build and Deploy API requires two headers:

| Header                  | Description                                                               |
| ----------------------- | ------------------------------------------------------------------------- |
| `x-api-key`             | Your SGP API key. Found in the IAM or admin section of the SGP dashboard. |
| `x-selected-account-id` | Your SGP account ID. Found in the admin section of the SGP dashboard.     |

<CodeGroup>
  ```bash curl theme={null}
  curl -s $SGP_CLIENT_BASE_URL/v5/builds \
    -H "x-api-key: $SGP_API_KEY" \
    -H "x-selected-account-id: $SGP_ACCOUNT_ID"
  ```

  ```python Python theme={null}
  from scale_gp_beta import SGPClient

  client = SGPClient(
      api_key="your-api-key",
      account_id="your-account-id",
  )
  ```

  ```typescript TypeScript theme={null}
  import SGPClient from 'scale-gp';

  const client = new SGPClient({
    apiKey: process.env.SGP_API_KEY,
    accountId: process.env.SGP_ACCOUNT_ID,
  });
  ```
</CodeGroup>

<Note>
  The Python and TypeScript SDKs handle authentication headers automatically once you initialize the client. The examples in the rest of this page assume you have already created a `client` instance as shown above.
</Note>

## Build lifecycle

A build packages your agent source code into a container image. The lifecycle is: **create** the build, **poll** its status until it reaches a terminal state, and optionally **stream logs** or **cancel** it. See the [build status lifecycle](/docs/v5/agents/agentex/cloud-build-and-deploy/overview#build) for the full state diagram.

### Create a build

To create a build, send a multipart form request with your build context archive (a `.tar.gz` of your agent source code), the target image name and tag, and the agent name.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST $SGP_CLIENT_BASE_URL/v5/builds \
    -H "x-api-key: $SGP_API_KEY" \
    -H "x-selected-account-id: $SGP_ACCOUNT_ID" \
    -F "context_archive=@build-context.tar.gz" \
    -F "image_name=my-agent" \
    -F "image_tag=v1.2.0" \
    -F "agent_name=my-agent"
  ```

  ```python Python theme={null}
  build = client.build.create(
      context_archive="./build-context.tar.gz",
      image_name="my-agent",
      image_tag="v1.2.0",
      agent_name="my-agent",
  )
  print(f"Build created: {build.id} (status: {build.status})")
  ```

  ```typescript TypeScript theme={null}
  const build = await client.build.create({
    context_archive: "./build-context.tar.gz",
    image_name: "my-agent",
    image_tag: "v1.2.0",
    agent_name: "my-agent",
  });
  console.log(`Build created: ${build.id} (status: ${build.status})`);
  ```
</CodeGroup>

The response includes the build ID and an initial status of `queued`. Use the build ID to poll for status updates and retrieve logs.

Optional parameters:

| Parameter    | Description                                               |
| ------------ | --------------------------------------------------------- |
| `build_args` | Key-value pairs passed as Docker build arguments          |
| `platform`   | Target platform for the image build (e.g., `linux/amd64`) |

### Get build status

Poll `GET /v5/builds/{build_id}` to check the current status of a build.

<CodeGroup>
  ```bash curl theme={null}
  curl -s $SGP_CLIENT_BASE_URL/v5/builds/$BUILD_ID \
    -H "x-api-key: $SGP_API_KEY" \
    -H "x-selected-account-id: $SGP_ACCOUNT_ID"
  ```

  ```python Python theme={null}
  build = client.build.retrieve("build_abc123")
  print(f"Status: {build.status}")
  ```

  ```typescript TypeScript theme={null}
  const build = await client.build.retrieve("build_abc123");
  console.log(`Status: ${build.status}`);
  ```
</CodeGroup>

### Cancel a build

You can cancel a build that is in `queued` or `running` state.

```bash theme={null}
curl -X POST $SGP_CLIENT_BASE_URL/v5/builds/$BUILD_ID/cancel \
  -H "x-api-key: $SGP_API_KEY" \
  -H "x-selected-account-id: $SGP_ACCOUNT_ID"
```

## Deploy lifecycle

A deployment takes a successfully built container image and rolls it out to a Kubernetes cluster. The lifecycle is: **create** the deployment, **poll** its status until it becomes `healthy` or `failed`, and inspect **logs** for debugging. See the [deployment status lifecycle](/docs/v5/agents/agentex/cloud-build-and-deploy/overview#deployment) for the full state diagram.

### Create a deployment

To create a deployment, provide the `manifest_file` (your `manifest.yaml` content as a string), the `environment_config` (your `environments.yaml` content as a string), and a `build_id` referencing a successful build.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST $SGP_CLIENT_BASE_URL/v5/agentex/deployments \
    -H "x-api-key: $SGP_API_KEY" \
    -H "x-selected-account-id: $SGP_ACCOUNT_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "manifest_file": "name: my-agent\nversion: 1.0\n...",
      "environment_config": "environment: production\nnamespace: agents\n...",
      "build_id": "build_abc123"
    }'
  ```

  ```python Python theme={null}
  deployment = client.deploy.create(
      manifest_file="name: my-agent\nversion: 1.0\n...",
      environment_config="environment: production\nnamespace: agents\n...",
      build_id="build_abc123",
  )
  print(f"Deployment created: {deployment.id} (status: {deployment.status})")
  ```

  ```typescript TypeScript theme={null}
  const deployment = await client.deploy.create({
    manifest_file: "name: my-agent\nversion: 1.0\n...",
    environment_config: "environment: production\nnamespace: agents\n...",
    build_id: "build_abc123",
  });
  console.log(`Deployment created: ${deployment.id} (status: ${deployment.status})`);
  ```
</CodeGroup>

Instead of a `build_id`, you can supply `image_name` and `image_tag` directly to deploy a pre-existing image.

To create a **preview deployment** (ephemeral, with automatic teardown), add the following optional parameters:

| Parameter       | Description                                                      |
| --------------- | ---------------------------------------------------------------- |
| `preview`       | Set to `true` to create a preview deployment                     |
| `preview_label` | A label for the preview (e.g., `pr-482`). Maximum 30 characters. |
| `expires_at`    | ISO 8601 timestamp for when the preview should be torn down      |

### Get deployment status

Poll `GET /v5/agentex/deployments/{deployment_id}` to check the current status and view deployment events.

<CodeGroup>
  ```bash curl theme={null}
  curl -s $SGP_CLIENT_BASE_URL/v5/agentex/deployments/$DEPLOYMENT_ID \
    -H "x-api-key: $SGP_API_KEY" \
    -H "x-selected-account-id: $SGP_ACCOUNT_ID"
  ```

  ```python Python theme={null}
  deployment = client.deploy.retrieve("deploy_xyz789")
  print(f"Status: {deployment.status}")
  ```

  ```typescript TypeScript theme={null}
  const deployment = await client.deploy.retrieve("deploy_xyz789");
  console.log(`Status: ${deployment.status}`);
  ```
</CodeGroup>

### Delete a deployment

To tear down a deployment and release its cluster resources:

```bash theme={null}
curl -X DELETE $SGP_CLIENT_BASE_URL/v5/agentex/deployments/$DEPLOYMENT_ID \
  -H "x-api-key: $SGP_API_KEY" \
  -H "x-selected-account-id: $SGP_ACCOUNT_ID"
```

## Polling pattern

Builds and deployments are asynchronous operations. After creating either resource, poll the status endpoint until the resource reaches a terminal state.

**Build statuses:** `queued` → `running` → `success` | `failed` | `cancelled` | `timed_out` | `error`

**Deploy statuses:** `pending` → `in_progress` → `healthy` | `failed` | `cancelled`

<CodeGroup>
  ```bash curl theme={null}
  # Poll a build until it reaches a terminal state
  while true; do
    STATUS=$(curl -s $SGP_CLIENT_BASE_URL/v5/builds/$BUILD_ID \
      -H "x-api-key: $SGP_API_KEY" \
      -H "x-selected-account-id: $SGP_ACCOUNT_ID" \
      | jq -r '.status')
    echo "Build status: $STATUS"
    case $STATUS in
      success|failed|cancelled|timed_out|error) break ;;
    esac
    sleep 5
  done
  ```

  ```python Python theme={null}
  import time

  build = client.build.retrieve("build_abc123")
  terminal_statuses = {"success", "failed", "cancelled", "timed_out", "error"}

  while build.status not in terminal_statuses:
      time.sleep(5)
      build = client.build.retrieve("build_abc123")
      print(f"Build status: {build.status}")

  if build.status != "success":
      raise RuntimeError(f"Build ended with status: {build.status}")
  ```

  ```typescript TypeScript theme={null}
  const terminalStatuses = new Set(["success", "failed", "cancelled", "timed_out", "error"]);

  let build = await client.build.retrieve("build_abc123");

  while (!terminalStatuses.has(build.status)) {
    await new Promise((r) => setTimeout(r, 5000));
    build = await client.build.retrieve("build_abc123");
    console.log(`Build status: ${build.status}`);
  }

  if (build.status !== "success") {
    throw new Error(`Build ended with status: ${build.status}`);
  }
  ```
</CodeGroup>

<Note>
  A polling interval of 5 seconds is a reasonable default. Builds typically take 2-10 minutes depending on image complexity. Deployments typically take 1-5 minutes depending on image size and cluster capacity.
</Note>

## Log streaming

Build logs and deployment logs use different retrieval mechanisms.

### Build logs (SSE)

Build logs are streamed via Server-Sent Events (SSE) from `GET /v5/builds/{build_id}/logs`. Each event contains a log line from the image build process.

```bash theme={null}
curl -N $SGP_CLIENT_BASE_URL/v5/builds/$BUILD_ID/logs \
  -H "x-api-key: $SGP_API_KEY" \
  -H "x-selected-account-id: $SGP_ACCOUNT_ID"
```

The response is a stream of `text/event-stream` data. Each line is a log entry from the build. The stream closes when the build completes.

### Deployment logs (cursor-based pagination)

Deployment logs are retrieved with cursor-based pagination from `GET /v5/agentex/deployments/{deployment_id}/logs`. Each response includes a page of log lines, a `next_cursor` for fetching the next page, and a `has_more` flag.

<CodeGroup>
  ```bash curl theme={null}
  # Fetch the first page of deployment logs
  CURSOR=""
  while true; do
    RESPONSE=$(curl -s "$SGP_CLIENT_BASE_URL/v5/agentex/deployments/$DEPLOYMENT_ID/logs?limit=100&cursor=$CURSOR" \
      -H "x-api-key: $SGP_API_KEY" \
      -H "x-selected-account-id: $SGP_ACCOUNT_ID")
    echo "$RESPONSE" | jq -r '.lines[]'
    HAS_MORE=$(echo "$RESPONSE" | jq -r '.has_more')
    if [ "$HAS_MORE" != "true" ]; then
      break
    fi
    CURSOR=$(echo "$RESPONSE" | jq -r '.next_cursor')
  done
  ```

  ```python Python theme={null}
  cursor = None

  while True:
      params = {"limit": 100}
      if cursor:
          params["cursor"] = cursor

      response = client.deploy.logs(
          "deploy_xyz789",
          **params,
      )

      for line in response.lines:
          print(line)

      if not response.has_more:
          break
      cursor = response.next_cursor
  ```

  ```typescript TypeScript theme={null}
  let cursor: string | undefined;

  while (true) {
    const response = await client.deploy.logs("deploy_xyz789", {
      limit: 100,
      cursor,
    });

    for (const line of response.lines) {
      console.log(line);
    }

    if (!response.has_more) break;
    cursor = response.next_cursor;
  }
  ```
</CodeGroup>

## Listing and filtering

Use the list endpoints to retrieve builds and deployments for an agent, filtered by common criteria.

### List builds

Retrieve builds filtered by agent name, with control over result count and sort order.

<CodeGroup>
  ```bash curl theme={null}
  curl -s "$SGP_CLIENT_BASE_URL/v5/builds?agent_name=my-agent&limit=10&sort_order=desc" \
    -H "x-api-key: $SGP_API_KEY" \
    -H "x-selected-account-id: $SGP_ACCOUNT_ID"
  ```

  ```python Python theme={null}
  builds = client.build.list(
      agent_name="my-agent",
      limit=10,
      sort_order="desc",
  )
  for build in builds:
      print(f"{build.id}: {build.status} ({build.image_tag})")
  ```

  ```typescript TypeScript theme={null}
  const builds = await client.build.list({
    agent_name: "my-agent",
    limit: 10,
    sort_order: "desc",
  });
  for (const build of builds) {
    console.log(`${build.id}: ${build.status} (${build.imageTag})`);
  }
  ```
</CodeGroup>

### List deployments

Retrieve deployments, optionally filtered by preview label to find the latest deployment for a specific branch or PR.

<CodeGroup>
  ```bash curl theme={null}
  # Get the latest deployment for a specific PR
  curl -s "$SGP_CLIENT_BASE_URL/v5/agentex/deployments?preview_label=pr-482&limit=1" \
    -H "x-api-key: $SGP_API_KEY" \
    -H "x-selected-account-id: $SGP_ACCOUNT_ID"
  ```

  ```python Python theme={null}
  deployments = client.deploy.list(
      preview_label="pr-482",
      limit=1,
  )
  if deployments:
      latest = deployments[0]
      print(f"Latest PR deploy: {latest.id} ({latest.status})")
  ```

  ```typescript TypeScript theme={null}
  const deployments = await client.deploy.list({
    preview_label: "pr-482",
    limit: 1,
  });
  if (deployments.length > 0) {
    const latest = deployments[0];
    console.log(`Latest PR deploy: ${latest.id} (${latest.status})`);
  }
  ```
</CodeGroup>

### Undeployed builds

To find agents that have completed builds but no healthy deployment, use the undeployed builds endpoint:

```bash theme={null}
curl -s $SGP_CLIENT_BASE_URL/v5/builds/undeployed \
  -H "x-api-key: $SGP_API_KEY" \
  -H "x-selected-account-id: $SGP_ACCOUNT_ID"
```

This is useful for identifying agents that may have been built but never deployed, or agents whose deployments have failed and need attention.

## API and SDK reference

For full request and response schemas, see the generated API reference and SDK documentation:

**API reference:**

* [Agentex Cloud Build](/reference/v5/agentex-cloud-build): endpoints for creating, listing, polling, and cancelling builds
* [Agentex Cloud Deploy](/reference/v5/agentex-cloud-deploy): endpoints for creating, listing, inspecting, and deleting deployments
* [SGP Cloud Secrets](/reference/v5/sgp-cloud-secrets): endpoints for managing account-level secrets

**SDK reference:**

* [Python SDK](https://sgp-dev.stldocs.app/api/python): `scale_gp_beta` package (`client.build`, `client.deploy`, `client.secrets`)
* [TypeScript SDK](https://sgp-dev.stldocs.app/api/typescript): `scale-gp` package (`client.build`, `client.deploy`, `client.secrets`)

<Note>
  The Build and Deploy API does not support webhooks or push notifications. You must poll the status endpoints to track build and deployment progress. There is no callback mechanism to notify your system when a build completes or a deployment becomes healthy.
</Note>

## Next steps

* [sgpctl CLI](/docs/v5/agents/agentex/cloud-build-and-deploy/sgpctl): the same operations from the terminal with a simpler interface
* [CI/CD with Gitea Actions](/docs/v5/agents/agentex/cloud-build-and-deploy/ci-cd): automate builds triggered by git push
* [Secrets](/docs/v5/agents/agentex/cloud-build-and-deploy/secrets): manage credentials via API/SDK or the dashboard
* [Preview Deployments](/docs/v5/agents/agentex/cloud-build-and-deploy/preview-deployments): ephemeral deployments for branch and PR testing
