---
title: "ktm ci build"
description: "Generate a local-only campaign JSON template with ktm ci build using test IDs or a saved Tests campaign, then pipe it into ci run."
sidebarTitle: "build"
lastUpdated: "2026-09-23"
---

> **For AI agents:** the complete documentation index is at [llms.txt](/llms.txt). Append `.md` to any page URL for its markdown version.

{/* GENERATED FILE: do not edit by hand. Regenerate with: node scripts/generate.mjs */}

Generate a campaign JSON template from test IDs or a saved Tests campaign (local-only, no execution)

## Usage

```bash
ktm ci build [flags]
```

## Examples

```bash
# Build template for two tests (no variant pinning — group defaults are used)
ktm ci build --test-ids 16480,16838

# Pin a single group's variant
ktm ci build --product acme~web --test-ids 16480 \
  --variant "API:Staging"

# Multi-group pinning
ktm ci build --product acme~web --test-ids 16480 \
  --variant "API:Staging" --variant "Database:Replica" --variant "Frontend:Canary"

# Numeric variant id (when stable across environments)
ktm ci build --product acme~web --test-ids 16480 --variant 691

# Build from a saved Tests campaign (product auto-derived from the campaign)
ktm ci build --test-campaign 42

# Build from a Tests campaign and pin a variant
ktm ci build --test-campaign 42 --variant "API:Staging"

# Full Tests-campaign pipeline: build → run with one-off override
ktm ci build --test-campaign 42 --variant "API:Staging" | \
  ktm ci run --stdin --set-var "GLOBAL_VAR=override-value"

# Full pipeline: build → fill values → run
ktm ci build --product acme~web --test-ids 16480 --variant "API:Staging" | \
  jq '.tests[0].input_variables.TODO_INDEX.value = "42"' | \
  ktm ci run --stdin
```

## Flags

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `--name` | string |  | Campaign name (optional, defaults to empty) |
| `--product` | string |  | Product slug (format: operator~product). Required with --test-ids (resolves V3 variable buckets); not needed with --test-campaign (auto-derived). |
| `--test-campaign` | int |  | Saved Tests campaign id (mutually exclusive with --test-ids; product auto-derived) |
| `--test-ids` | string |  | Comma-separated test IDs (from 'tests list'); mutually exclusive with --test-campaign |
| `--variant` | string[] |  | Pin a variant per variable group. Repeatable. Forms: '5' (numeric variant ID) or 'API:Staging' (group:variant by name). Variables in unpinned groups use that group's default variant. |

## Details

Build a campaign JSON template by fetching test details and emitting a
self-documenting structure ready to be piped into "ci run --stdin".

The output is a JSON template with a "_meta" key that tells an AI agent what
kind each variable is and what resource type each owner expects. The agent
fills in values and pipes the result to "ci run --stdin".

The "_meta" key is stripped automatically by "ci run --stdin". The "_meta" key
provides test names that appear in per-test result output when the campaign is
executed via "ci run --stdin".

--variant is repeatable, per-group. Each spec pins one variable group.
Globals always emit a "global" bucket. Variables in unpinned groups use
that group's default variant. The legacy single-scope --variable-group
flag has been removed.

Campaign JSON schema:
  name              — campaign name (optional)
  run_origin        — 1 (from test IDs) or 2 (from a saved Tests campaign)
  tests[]           — array of test entries:
    id              — test ID (from tests list)
    input_variables — key/value map of variable names to \{value, bucket\} pairs
    direct_owners   — key/value map of owner labels to resource identifiers

## Notes

- Builds a campaign template locally and prints JSON — it does **not** execute anything. Fill in the values, then pipe it to [`ktm ci run`](/cli/commands/ci/run) with `--stdin`.

## Related

- [`ktm ci`](/cli/commands/ci)
- [`ktm tests list`](/cli/commands/tests/list)

<Note>
  Global flags (`--output`, `--debug`, `--host`, …) apply to every command. See the [command reference overview](/cli/commands/overview).
</Note>

## What's next?

<Columns cols={2}>
  <Card title="All commands" icon="terminal" href="/cli/commands/overview">
    Browse the full CLI reference.
  </Card>
  <Card title="Get started" icon="rocket" href="/cli/getting-started">
    Install the CLI and authenticate.
  </Card>
</Columns>
