# Add a version to a program

POST /v1/programs/{id}/versions: Add a version to a program

```http
POST /v1/programs/{id}/versions
```

|  |  |
|---|---|
| Operation id | `createProgramVersion` |
| Key scope | `run`: keys that run jobs (and `admin` keys) |
| Section | [Programs](https://docs.kaab.ist/reference/api#programs) |

## Parameters

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes | min length 1 |

## Request body

| Field | Type | Required | Description |
|---|---|---|---|
| `definition` | [ProgramDefinition](https://docs.kaab.ist/reference/api/schemas/program-definition) | yes |  |
| `notes` | string |  | max length 1000 |
| `publish` | boolean |  | default `true` |
| `draft_id` | string |  | The builder draft this version was built from; its picker confirmations move to it. · pattern `^dft_[0-9a-hjkmnp-tv-z]{26}$` |

## Example request

```bash
curl -X POST "https://api.kaab.ist/v1/programs/{id}/versions" \
  -H "Authorization: Bearer $KAAB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"definition":{"kaab":"1","steps":[{"goto":"https://shop.example.com/p/1"},{"extract":{"title":"h1"}}]},"notes":"healing: relocate price","publish":false}'
```

## Responses

### 201

Version

[ProgramVersion](https://docs.kaab.ist/reference/api/schemas/program-version)

```json
{
  "id": "pv_01j9zqk3q7m4n5p6r7s8t9v0wx",
  "object": "program_version",
  "program_id": "prg_01j9zqk3q7m4n5p6r7s8t9v0wx",
  "version": 3,
  "status": "published",
  "definition": {
    "kaab": "1",
    "steps": [
      {
        "goto": "https://shop.example.com/p/1"
      },
      {
        "extract": {
          "title": "h1"
        }
      }
    ]
  },
  "definition_hash": "sha256:9ab1",
  "lint": {
    "errors": [],
    "warnings": [
      {
        "code": "W001",
        "path": "steps[0]",
        "message": "`goto` without `expect`"
      }
    ]
  },
  "notes": "healing: relocate price",
  "source": "proposal",
  "created_at": "2026-09-18T10:00:00Z",
  "published_at": "2026-09-18T10:00:00Z"
}
```

## Errors

Every error answers with the [error envelope](https://docs.kaab.ist/reference/api/schemas/error-response); its `code` is one of the [error codes](https://docs.kaab.ist/reference/codes#errors).

| Status | When |
|---|---|
| 400 | `request_invalid`: request validation failed |
| 401 | Missing or invalid API key |
| 402 | `insufficient_credits`: top up to continue |
| 403 | The key's scope does not cover this operation |
| 404 | Resource not found |
| 409 | Conflicting state (see `error.code`) |
| 422 | Semantically invalid request (see `error.code`) |
| 429 | Rate limited; see `Retry-After` |
| 500 | `internal`: unexpected server error |
