Skip to main content
An agent version identifies a deployed release of an agent. A release can change its prompt, model, voice, transcription settings, tools, or workflow. Two versions can have identical prompts and different pipelines. Experiments compare calls assigned to exactly two deployed versions of the same agent. Accurate version assignment is what makes the comparison meaningful: Zelto uses the version reported for the call, not a guess based on its transcript or the agent’s current configuration.

Three identifiers with different jobs

For example, support-agent can receive calls from both support-2026-09-a and support-2026-09-b. Keep agent.externalId the same for both. Giving each release a different agent ID creates separate agents that cannot be selected as the two versions of one experiment.

Declare versions in LiveKit or a custom integration

Send the top-level version field on every upload to POST https://ingest.zelto.ai/webhooks/calls. The wire field is version, not prompt_version, agent.version, or metadata.version. The API accepts a string of 1–255 characters after trimming surrounding whitespace. Labels are case-sensitive: release-a and Release-A are different. A release tag, immutable build ID, or hash of your complete versioned configuration works. A prompt-only hash cannot distinguish pipeline-only changes.
Use Authorization: Bearer $ZELTO_API_KEY, Content-Type: application/json, and X-Zelto-Provider: livekit for a LiveKit worker, or zelto for custom uploads. See the LiveKit example and call-upload contract. You can register a version before sending calls (see below). Otherwise, the first processed call with a new label creates the declared version; later calls with the same agent and label reuse it. A separate version-creation request is optional. Zelto also assigns a display number such as v1 or v2 in first-seen order. That number is separate from your label; send your release label, not a display number inferred from the dashboard.
version is optional for general call ingestion. For integrations intended to run experiments, send an explicit version on every call so attribution follows the release that handled it.

Keep a label tied to one release

  • Change the label for prompt, model, voice, transcription, tool, or workflow changes that should form a distinct version.
  • Keep it stable across calls on that release. Do not use a room ID, customer ID, per-call timestamp, or random UUID as the version label.
  • Capture the label and configuration from the session that handled the call. A deployment can happen while a call is running; do not label a delayed upload using whichever release is current at upload time.
  • On retry, resend the original call ID, version, and snapshots. Do not relabel old calls to make them join a different experiment arm.
  • For a rollback to an unchanged release, reuse that release’s label. If you need to distinguish two deployments of identical code, use separate release labels consistently.
Reusing a label after changing its configuration mixes those releases’ calls into one version. A label is supplied by your integration; Zelto does not verify that every call carrying it used an identical build.

Register a version in Zelto

Organization owners and admins can open Agents → your agent → Versions → Register version. Enter the release label, optional system prompt, and the LLM, STT, and TTS providers/models. TTS also has a voice ID field. Expand Additional configuration (JSON) to record tools, workflows, knowledge bases, runtime settings, or any custom context. Extra settings such as llm.temperature can go here; the provider/model fields above take precedence when both specify the same key. Registration records context; it does not deploy or run this configuration. Draft prompt candidates remain separate.

Register a version through the API

Use an organization API key owned by an owner or admin. The agent must already exist in that organization. On the platform API host, call POST /v1/agents/{id}/versions, using the Zelto agent UUID:
version.json
A new registration returns HTTP 201 with { "id": "<version UUID>", "created": true }. Retrying with the same label and configuration returns HTTP 200 with created: false. A supplied prompt or configuration that differs from an existing version returns 409 Conflict: create a new release label instead of rewriting history. Omitted fields on a retry leave existing values alone. Internal prefixes draft: and generated: are reserved. The call-upload endpoint remains on https://ingest.zelto.ai/webhooks/calls. Registering a release does not make it the fallback for unversioned calls. It becomes observed when a processed call explicitly reports its label. Registration uses config; call upload uses versionConfig alongside version. Both write the same version configuration. After registration, report that label on each call. Do not substitute the returned UUID or Zelto’s display number for your release label.

Version identity and configuration are separate

version assigns calls to a release. The configuration is context supplied by your organization: it can describe everything that release uses, including provider/model choices, voice, tools, retrieval, workflow, deployment settings, and custom components. All supplied JSON fields are preserved and available in the version detail and comparison, including experiment setup. Supply a JSON object, up to 64 KiB when serialized as UTF-8. The keys llm, stt, and tts are conventions matching the form, not a closed list. Other keys and nested objects/arrays are supported. Include configuration, not API keys or other credentials. This is descriptive context; Zelto does not execute workflows, configure providers, or discover missing settings for you. Send the actual prompt as systemPrompt, or in a leading system transcript turn for call uploads. A version label alone does not supply a prompt. A first call can create the version with versionConfig. Existing snapshots are not replaced by later call uploads; a missing snapshot can be filled. Send complete configuration from the start, and register a new label when it changes. A configuration already captured from legacy call metadata is also an existing snapshot: later uploads do not merge a new versionConfig into it. For older versions without explicitly supplied configuration, Zelto shows only the captured model, transcription, and voice settings from call metadata. Missing snapshots are unavailable, not evidence of identical pipelines. Full workflow and tool context is available when your integration or the form supplies it; it is not collected automatically.

Provider-managed and automatic versions

For LiveKit/custom calls with no explicit version, Zelto creates an initial generated version if necessary, then assigns subsequent calls to the latest deployed version. A weekly job can create another generated version when the generalized prompt changes. It does not detect pipeline-only changes, and it does not immediately distinguish two releases running concurrently. Use explicit labels for experiments. A draft candidate created in Zelto is for simulations. It has not handled real calls and cannot be selected as an experiment arm. Deploy the release in your own stack and upload calls with its version label to make it available.

Verify before launching an experiment

  1. Send a call from release A and another from release B with the same agent ID, distinct call IDs, and distinct version labels.
  2. Wait for processing. HTTP 200 with { "received": true } acknowledges acceptance; it does not mean the call and version are already visible.
  3. Open the agent’s Versions tab. Confirm both labels and inspect which calls belong to each. Check prompt/configuration snapshots where available.
  4. Open Experiments → New experiment and select that agent and those two versions. Review the captured differences and recent call counts.
  5. Choose configured monitors and use Check recent traffic. Historical traffic checks the setup; it does not backfill the new experiment’s results.
  6. Enter a name and launch. Keep reporting the actual version on each future call and route callers consistently in your own platform. Send a stable endUserId where available for caller-level analysis.
The experiment’s selected versions are fixed at launch. Calls from a third release do not automatically replace A or B. A new comparison needs a new experiment. Zelto observes traffic; it does not deploy releases or route calls.

Troubleshooting