# Builds

> Image builds (Railpack, Dockerfile or a pulled image) with scans, SBOM and signatures.

Image builds (Railpack, Dockerfile or a pulled image) with scans, SBOM and signatures.

| Operation | Method and path |
| --- | --- |
| [Get a build](#get-a-build) | `GET /v1/builds/{build_id}` |
| [Build logs](#build-logs) | `GET /v1/builds/{build_id}/logs` |
| [Cancel a running build](#cancel-a-running-build) | `POST /v1/builds/{build_id}/cancel` |

## Get a build

```http
GET /v1/builds/{build_id}
```

- **Operation:** `getBuild`
- **Scopes:** `projects:read`

**Parameters**

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `build_id` * | path | string |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` OK | OK. | [Build](/docs/api/objects/build/) |

**Errors:** `400`, `401`, `403`, `404`, `429`, `500`, as [problem+json](/errors/) with a stable `code`.

**Example**

```bash
curl https://api.guv.dev/v1/builds/bui_01jbx2m9k7q4r8t5v6w3y0z1pr \
  -H "Authorization: Bearer $GUV_TOKEN"
```

**Example response**

```json
{
  "id": "bld_01jbx2m9k7q4r8t5v6w3y0z1pr",
  "project_id": "string",
  "environment_id": "string",
  "service_id": "string",
  "deployment_id": "string",
  "status": "queued",
  "builder": "railpack",
  "detected": {
    "language": "node",
    "language_version": "22",
    "framework": "nextjs",
    "summary": "We'll build a Next.js app with Node 22."
  },
  "commit": {
    "sha": "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
    "branch": "string",
    "message": "string",
    "author": "string",
    "url": "https://guv.dev/"
  },
  "image": {
    "digest": "string",
    "size_bytes": 1,
    "signed": false,
    "sbom_url": "string",
    "provenance_url": "string"
  },
  "scan": {
    "secrets_found": 1,
    "secrets_in_bundle": 1,
    "vulnerabilities": {
      "critical": 1,
      "high": 1,
      "medium": 1,
      "low": 1,
      "kev": 1
    },
    "blocked": false,
    "block_reason": "string"
  },
  "cache_hit_ratio": 0.5,
  "created_at": "2026-10-22T13:05:00Z",
  "started_at": "2026-10-22T13:05:00Z",
  "finished_at": "2026-10-22T13:05:00Z",
  "duration_ms": 1
}
```

## Build logs

```http
GET /v1/builds/{build_id}/logs
```

JSON page by default; `Accept: text/event-stream` follows the build live.

- **Operation:** `getBuildLogs`
- **Scopes:** `logs:read`

**Parameters**

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `build_id` * | path | string |  |
| `follow` | query | boolean |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` OK | OK. | [LogQueryResult](/docs/api/objects/log-query-result/) |

**Errors:** `400`, `401`, `403`, `404`, `429`, `500`, as [problem+json](/errors/) with a stable `code`.

**Example**

```bash
curl https://api.guv.dev/v1/builds/bui_01jbx2m9k7q4r8t5v6w3y0z1pr/logs \
  -H "Authorization: Bearer $GUV_TOKEN"
```

**Example response**

```json
{
  "lines": [
    {
      "id": "lg_9f8e7d6c5b",
      "timestamp": "2026-10-23T14:04:02.123Z",
      "source": "runtime",
      "level": "error",
      "message": "TypeError: Cannot read properties of undefined (reading 'id')",
      "service": {
        "id": "svc_01jbx2m9k7q4r8t5v6w3y0z1sv",
        "name": "web"
      },
      "environment": "production",
      "deployment_id": "dep_01jbx2m9k7q4r8t5v6w3y0z1dp",
      "replica": "web-1",
      "http": null,
      "attributes": {},
      "redacted": false
    }
  ],
  "next_cursor": "string",
  "has_more": false,
  "query": "string",
  "dropped_lines": 1
}
```

## Cancel a running build

```http
POST /v1/builds/{build_id}/cancel
```

- **Operation:** `cancelBuild`
- **Scopes:** `projects:write`
- **Idempotency-Key:** required; supports `?dry_run=true`

**Parameters**

| Name | In | Type | Description |
| --- | --- | --- | --- |
| `build_id` * | path | string |  |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` OK | OK. With `dry_run=true`: a Plan (application/vnd.guv.plan+json) and nothing changes. | [Build](/docs/api/objects/build/) |

**Errors:** `400`, `401`, `403`, `404`, `409`, `422`, `429`, `500`, as [problem+json](/errors/) with a stable `code`.

**Example**

```bash
curl -X POST https://api.guv.dev/v1/builds/bui_01jbx2m9k7q4r8t5v6w3y0z1pr/cancel \
  -H "Authorization: Bearer $GUV_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"
```

**Example response**

```json
{
  "id": "bld_01jbx2m9k7q4r8t5v6w3y0z1pr",
  "project_id": "string",
  "environment_id": "string",
  "service_id": "string",
  "deployment_id": "string",
  "status": "queued",
  "builder": "railpack",
  "detected": {
    "language": "node",
    "language_version": "22",
    "framework": "nextjs",
    "summary": "We'll build a Next.js app with Node 22."
  },
  "commit": {
    "sha": "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
    "branch": "string",
    "message": "string",
    "author": "string",
    "url": "https://guv.dev/"
  },
  "image": {
    "digest": "string",
    "size_bytes": 1,
    "signed": false,
    "sbom_url": "string",
    "provenance_url": "string"
  },
  "scan": {
    "secrets_found": 1,
    "secrets_in_bundle": 1,
    "vulnerabilities": {
      "critical": 1,
      "high": 1,
      "medium": 1,
      "low": 1,
      "kev": 1
    },
    "blocked": false,
    "block_reason": "string"
  },
  "cache_hit_ratio": 0.5,
  "created_at": "2026-10-22T13:05:00Z",
  "started_at": "2026-10-22T13:05:00Z",
  "finished_at": "2026-10-22T13:05:00Z",
  "duration_ms": 1
}
```
