Skip to navigation

Agent versioning and publishing

Use Agent versioning to keep an immutable record of an Agent’s configuration at a point in time, and to return the Agent to one of those snapshots.

How versioning works

When you edit a saved Agent, you work on a draft. Saving records a version snapshot of the Agent’s configuration. Publishing marks a version as the Agent’s published version and deploys it to the Agent’s live release alias. Later edits create another draft.

The following table compares draft and published versions:

DraftPublished
Content that you can edit before publishingImmutable content that you can return to
Created when you save changes to an existing AgentCreated when you publish
Can become the published versionRemains in version history after replacement

Runtype assigns an increasing number to each version snapshot, and the dashboard displays labels such as v1 and v2. Saving creates a draft before you publish, so the first published version is not necessarily v1. A version entry can include a label, notes, a configuration summary, and a creation time.

Whether a save or a publish changes production traffic depends on your organization’s live-default setting. Read What runs when you do not name a version before you rely on either.

Save and publish from the dashboard

The Agent editor has a save button with an attached arrow, Save options, that opens the save menu.

  • Save version saves your changes and records a draft version. After a save, the button reads Saved.
  • Save & publish saves your changes and publishes the new version. It’s in the Save options menu.
  • Publish to live publishes changes you already saved. When that version is already live, it reads Published and is unavailable.

To make Save & publish the primary button, open Save options and turn on Publish on save. The setting is off by default. Runtype remembers it for this Agent in this browser, and changing it doesn’t save or publish anything. With Publish on save on, Save version only in the menu saves without publishing.

Publishing uses the exact version that the save created. If publishing fails, Retry publish retries that version without creating another one. The message stays in the editor after the notification closes. If someone else deployed to live while you were publishing, click Review deployment before you try again. An Agent managed in code asks you to confirm the overwrite first. For details, see Deploying an Agent managed in code.

What runs when you do not name a version

A request that names no agent.alias and no agent.versionId follows your organization’s live-default setting, which can differ between organizations. To find out which one applies, use either of these checks:

  • In the dashboard, open the Agent page. When the Agent has saved edits that live doesn’t run, the Live line reads Saved edits are not deployed to live with the setting on, and Unpublished edits are serving traffic with it off.
  • From code, read liveDefault on GET /v1/agents/{id}/aliases. true means live decides what runs. false means a save still changes what runs.

For background, see the changelog entry Running an agent without a version selector will follow its live alias.

With the live default off, a selector-less request runs the Agent’s saved configuration. A save reaches production immediately, whether or not you publish afterward.

With the live default on, a selector-less request runs the exact version that the live alias points at:

  • Saving stops changing what runs. A save records a candidate version, and live keeps serving until you deploy. The Agent page marks an Agent whose saved edits are not deployed.
  • Publish to live and Rollback move production, and each writes a deployment receipt.
  • An Agent that was never published doesn’t refuse. Its first selector-less run deploys its current configuration as its first version.
  • A conversation bound to a preview alias refuses a turn that names no selector, with 409 and code: "session_pointer_mismatch". A selector-less turn claims live.

Agents created from the dashboard, from a template, from quick start, or as part of a Product are deployed to live when they’re created. An Agent created by runtype ensure without publishing stays undeployed on purpose.

Three cases run their saved configuration under either setting: external Agents, Claude Managed Agents, and Agents in a personal account. Explicit selectors resolve the version they name under either setting.

If an Agent’s live alias has nothing runnable, a selector-less request refuses with 404 and code: "AGENT_NOT_DEPLOYED" instead of running a draft. Runtype reports this before a run, too. The create, read, and update responses of an eval suite that targets the Agent include a warnings entry with code: "AGENT_NOT_DEPLOYED", and a Flow whose execute-agent step names it reports EXECUTE_AGENT_TARGET_NOT_DEPLOYED at save time. To fix it, deploy a version to live.

View version history

To view version history, follow these steps:

  1. Open the Agent.
  2. Click the arrow beside the save button (Save options).
  3. Click View versions.

The Version History panel lists version labels, status badges, alias badges, configuration summaries, creation times, and notes. The current published version has a live badge. A superseded published version has a previously published badge. A version that a preview alias points at shows that alias’s name.

When you have unsaved changes, the panel shows a Current draft entry with an unsaved badge. Its note says that loading or publishing another version discards those changes, but neither does. Load leaves the editor as it is, and publishing another version keeps your unsaved edits in the editor.

Publish an earlier version

Each version in the Version History panel has these actions:

  • Load fetches the version and confirms it in a notification. It doesn’t change the Agent or the editor. To see what a version contains, use Compare to live.
  • Compare to live opens a read-only comparison against the version that live points at. It isn’t offered on the version that’s already live.
  • Publish to live deploys the version to live and marks it as published. It’s unavailable on the version that’s already live.

To return an Agent to an earlier version, follow these steps:

  1. In the Agent editor, click Save options, then click View versions.
  2. Find the version that you want to return to.
  3. Click Publish to live beside it. On an organization Agent, click Publish in the confirmation dialog.

On an organization Agent, the confirmation names the version that live runs now and the version it switches to. The version changes for everything that runs this Agent.

The Deployments tab offers the same actions from the alias side. Rollback on the Deployment history card moves live back one deployment. Publish to live beside a preview alias deploys the version that preview runs.

The dashboard sends the alias revision it read. If someone else deployed in the meantime, the deploy is refused and a notification offers Reload. Reload reads the alias again and reopens the confirmation, and nothing changes until you confirm.

Publishing writes the version’s configuration back to the Agent, marks the version as published, and moves live in one step. The editor then reloads the saved Agent and keeps any unsaved edits you had open.

For Runtype and external Agents, the write covers the Agent’s name, description, icon, runtime configuration, capabilities, and external connection configuration recorded in the snapshot. Runtime configuration is replaced, not merged, so settings added after the version was saved don’t stay active.

Publishing also clears tool attachments that the version didn’t record: tools, MCP servers, runtime tools, subagent and code mode blocks, and approval settings. A tool that you attached after the version was saved doesn’t survive publishing that version.

A version without a stored configuration can’t be published. The dashboard reports this when you click Publish to live.

What publishing cannot restore

Publishing keeps these fields as they are and reports them in applied and warnings:

  • Claude Managed runtime settings and capabilities. Publishing an older version doesn’t change a Claude Managed Agent’s runtime configuration, hosted settings, credentials, or capabilities. To apply an older hosted definition, edit the Agent to match it and save.
  • Capabilities whose backing resource was deleted. If an older capability refers to a Flow, Agent, or tool that no longer exists, Runtype keeps the current capability set and names the missing capability in a warning.
  • Fields missing from older snapshots. An older snapshot without runtime configuration or capabilities keeps the current value and reports the gap.

Deploying an Agent managed in code

When ensure manages an Agent, the editor shows a Managed in code badge. Publishing a version from the dashboard is refused by default, so it can’t silently detach the Agent from code management. The dashboard opens a confirmation dialog. Clients that can’t show a dialog must select overwrite explicitly. The next ensure run then reports the change as an external modification. For the conflict options, see Manage agents as code.

When the deployment that put the current version on live came from code, the Live line on the Agent page offers Copy definition. Code means an ensure run, the CLI, or an SDK call. Copy definition copies the Agent’s definition to your clipboard, so you can add a dashboard edit to your repository before the next ensure run overwrites it.

Release aliases

A release alias is a named, movable pointer from an Agent to one of its immutable versions. Deploying moves the pointer and never rewrites the version. After the first mention, this page calls it an alias.

live is the built-in alias that production traffic follows. It can’t be archived and never expires. You can’t create an alias named live, latest, publish, or none. Every other name matches ^[a-z0-9][a-z0-9-]{0,62}$: up to 63 lowercase letters, digits, and hyphens, starting with a letter or digit.

Aliases are an organization feature. An Agent in a personal account has no release aliases. A request to deploy one is refused with 400 and code: "alias_requires_organization".

Preview aliases

Any alias other than live is a preview. You can create one in two ways:

A typical name is the pull request that produced it, such as pr-482.

A preview selects configuration. It isn’t a sandbox: it shares the organization’s connections, Records, and secrets with live. To point one preview’s tools at its pull request’s own environment, use per-alias secret bindings.

A preview expires 14 days after the deploy that last touched it. Every successful deploy renews that expiry, including an ensure run that changed nothing, so a pull request that keeps building keeps its preview.

There is no limit on how many previews an organization or an Agent holds. Archive a preview when you no longer need it, for example when its pull request closes. A preview that nothing renews expires on its own.

Find a version ID

To deploy or run a specific version, you need its version ID. Use one of these reads:

ReadAPICLIMCP tool
List an Agent’s versionsGET /v1/agent-versions/{agentId}runtype agent-versions list AGENT_IDlist_agent_versions
Get one versionGET /v1/agent-versions/{agentId}/{versionId}runtype agent-versions get AGENT_ID VERSION_IDget_agent_version
Get the published versionGET /v1/agent-versions/{agentId}/publishedruntype agent-versions published AGENT_IDget_published_agent_version

The Aliases card on the Deployments tab also shows the version each alias points at.

Inspect aliases

GET /v1/agents/{id}/aliases lists an Agent’s aliases, with live first. GET /v1/agents/{id}/aliases/{alias} reads one. Archived aliases are left out unless you pass includeArchived=true. The CLI equivalents are runtype agents aliases list AGENT_ID and runtype agents aliases get AGENT_ID ALIAS, which take --include-archived.

Each alias carries these fields:

  • versionId and versionNumber: the version the alias points at.
  • revision: the number to send as If-Match when you deploy to the alias.
  • expiresAt: when a preview expires. It’s null for live.
  • archivedAt: when the alias was archived, or null.
  • bindingNames: the names of its per-alias secret bindings.

Deploy a version to an alias

Once live exists, a deploy to it must send the revision that you read as an If-Match header, so a deploy based on an old read can’t overwrite someone else’s. The first deploy to live has no revision to send. Previews accept the same header and don’t require it.

To deploy a version to live, follow these steps:

  1. Read the alias and note its revision:

    curl https://api.runtype.com/v1/agents/AGENT_ID/aliases/live \
    -H "Authorization: Bearer YOUR_API_KEY"
  2. Send the version with that revision in If-Match:

    curl -X PUT https://api.runtype.com/v1/agents/AGENT_ID/aliases/live \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -H "If-Match: REVISION" \
    -H "Idempotency-Key: IDEMPOTENCY_KEY" \
    -d '{"versionId": "VERSION_ID", "reason": "Fix refund wording"}'

Replace the following:

  • AGENT_ID: the Agent’s ID
  • YOUR_API_KEY: your Runtype API key
  • REVISION: the revision from step 1
  • IDEMPOTENCY_KEY: a unique string for this deploy, so a network retry doesn’t deploy twice
  • VERSION_ID: the version to deploy
  • reason: optional text recorded on the deployment receipt

The same deploy is available in the other clients:

  • CLI: runtype agents aliases activate AGENT_ID live --version-id VERSION_ID --revision REVISION --reason "Fix refund wording"
  • TypeScript SDK: client.agents.aliases.activate(agentId, 'live', { versionId, revision, idempotencyKey, reason })
  • MCP: activate_agent_alias

The deploy can fail with these responses:

  • 412 with code: "alias_revision_mismatch": someone deployed since you read the alias. actual holds the current revision. Read the alias again, check what changed, and retry.
  • 428: you omitted If-Match on a live alias that already exists.
  • 409 with code: "idempotency_key_reused": you reused an Idempotency-Key for a different deploy.
  • 422 with code: "alias_dependency_unresolved": the version references a saved tool, Flow, or Agent by a name that no longer exists or was renamed. refs lists the names. Restore or rename the dependency, then deploy again.

API keys carry two deploy scopes:

  • AGENTS:DEPLOY:PREVIEW deploys to and archives preview aliases. It can’t move live.
  • AGENTS:DEPLOY:LIVE deploys to and rolls back live.

A CI credential with only the preview scope can’t reach production, whatever the workflow asks it to do.

Archive a preview

Archive a preview when its pull request closes. See A pull-request workflow for the CI job. Expiry cleans up previews that nobody archived.

To archive one preview, use one of these:

  • Dashboard: on the Deployments tab, click the Archive button beside the alias, then confirm.
  • API: DELETE /v1/agents/{id}/aliases/{alias}
  • CLI: runtype agents aliases archive AGENT_ID ALIAS
  • MCP: archive_agent_alias

Archiving isn’t a delete. The alias keeps its deployment history, runs that already started finish, and a later deploy revives the same alias. New requests that name an archived alias are refused and don’t fall back to live. No request can archive live: the attempt answers 409 with code: "alias_archive_forbidden".

A request that names an alias or version that Runtype can’t run answers 404 with one of these codes: alias_not_found, alias_archived, alias_expired, version_not_found, or agent_not_found. None of them falls back to another version.

Deployment history

Every deploy appends an immutable deployment receipt. A receipt records the following:

  • The alias and its new revision.
  • The action: activate, rollback, archive, bind, or materialize.
  • The version deployed and the version it replaced.
  • Who deployed it.
  • Where the deploy came from: an ensure run, the dashboard, the CLI, an SDK, an MCP tool, an API call, or Runtype itself.
  • Any label, notes, commit, and reason sent with it.
  • Fingerprints of the named references the version used at that moment.

Receipts never record a secret value. Per-alias bindings appear on them as names only.

Read the history with GET /v1/agents/{id}/deployments, filtered to one alias with ?alias=, or with runtype agents deployments list AGENT_ID --alias live. In the dashboard, open the Agent and select the Deployments tab:

  • The Aliases card lists every alias with the version and revision it carries. Each alias offers Test this version, which runs a conversation against that alias without loading it into the editor. A preview also offers Compare to live, Publish to live, and an archive button.
  • The Deployment history card lists receipts newest first, marked Deployed, Rolled back, Archived, or Materialized.

A Materialized receipt is one Runtype wrote itself so that live names a runnable version. Its version carries a label such as agent-created, live-materialization, or live-default-cutover, and a note that explains why. A live-materialization version holds the configuration the Agent was already running when Runtype gave it a live alias, so behavior didn’t change.

Roll back an alias

Rollback moves an alias back to the version recorded before its most recent deploy and writes another receipt. Nothing is deleted and no version is rewritten. In the dashboard, Rollback moves live back one deploy.

From code, you can walk further back with steps (1 to 50, default 1). Only deploys, rollbacks, and materializations count as steps. Binding changes and archives don’t.

  • API: POST /v1/agents/{id}/aliases/{alias}/rollback with body {"steps": 2, "reason": "..."} and If-Match on live
  • CLI: runtype agents aliases rollback AGENT_ID live --steps 2 --revision REVISION
  • TypeScript SDK: client.agents.aliases.rollback(agentId, 'live', { steps, revision, reason })
  • MCP: rollback_agent_alias

Rollback follows the same scope, If-Match, and dependency rules as a deploy. It restores configuration only. It doesn’t undo external side effects, data written by the version you’re leaving, or edits made since to the tools and Flows that the version references by name.

Run a specific version

A request can name the version it wants instead of taking the saved configuration. On POST /v1/dispatch and POST /v1/agents/{agentId}/execute, supply exactly one selector beside the Agent identity:

  • agent.versionId runs that immutable version snapshot.
  • agent.alias runs the version that the release alias points at.

A selector runs a stored snapshot, so you can’t combine it with inline definition fields such as model, systemPrompt, or tools. Naming both alias and versionId is rejected. An alias that doesn’t exist answers 404 instead of falling back to the saved configuration. Selectors aren’t available for external or Claude Managed Agents.

A conversation binds to the first alias or version it runs. A later turn on the same conversationId that names a different version or alias is refused with 409 and code: "session_pointer_mismatch". Start a new conversation for the other alias or version.

Evaluate a version before deploying it

An eval run can name the version it evaluates, so the version you grade is the version you deploy. Supply the same selector on the eval request:

curl -X POST https://api.runtype.com/v1/eval/suites/YOUR_SUITE_ID/run \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent": {"alias": "pr-482"}}'

Replace the following:

  • YOUR_SUITE_ID: the eval suite you want to run
  • YOUR_API_KEY: your Runtype API key
  • pr-482: the release alias you want to evaluate

POST /v1/eval/suites/{suiteId}/run, POST /v1/eval/run, and POST /v1/eval/submit all accept agent.alias or agent.versionId. The MCP run_eval_suite and submit_eval tools expose them as agent_alias and agent_version_id. The CLI’s runtype eval run takes --alias ALIAS or --version-id VERSION_ID.

The run resolves the selector once, before its first case. Deploying to the alias while the run is in progress doesn’t change what its later cases run, and a retry runs the same version again. The selector belongs to the run, not to the suite. A suite is a fixed case set, and you choose the version when you run it.

Every run records what it evaluated, and the eval read surfaces return it:

  • agentVersionId: the exact version every case ran.
  • agentTargetResolution: alias, version, or legacy-live-row. legacy-live-row means the run named no selector and ran the Agent’s saved configuration.
  • agentTargetAlias: the release alias the run resolved through.
  • caseManifestHash: SHA-256 over the case set the run used, so you can tell an edited or reordered suite from the one that produced the evidence.
  • evaluatorFingerprint: SHA-256 over the judges and grading configuration the run scored with.

Runtype records that evidence but doesn’t enforce it. You don’t need a passing run to deploy a version, and a failing run doesn’t block or reverse a deploy. Decide with the evidence, then deploy. A run that resolved a single target gives you the exact version ID to deploy.

Selectors aren’t available for external or Claude Managed Agents on evals either. An eval request that names one answers 422 with code: "selector_unsupported_agent_type". A suite that targets a Flow has no version selector and answers 400.

Per-alias secret bindings

A preview alias shares its organization’s credentials and configuration by default. That doesn’t work when a preview needs to call its own environment. For example, an Agent whose tools make HTTP calls into your application has to call the environment that its pull request deployed, not the one live calls.

Bind the value to the alias instead of putting it in the definition. A binding is a {{secret:NAME}} value that runs reaching this Agent through this alias use ahead of the organization secret of the same name. The version’s content stays identical to what live runs, so any evaluation evidence on that version still applies.

await client.agents.ensure(definition, {
deploy: {
alias: `pr-${pullRequest}`,
bindings: { RRX_TOOLS_BASE_URL: `https://pr-${pullRequest}.example.com` },
},
})

To set bindings on an alias that already exists, send the complete set:

curl -X PUT https://api.runtype.com/v1/agents/$AGENT_ID/aliases/pr-482/bindings \
-H "Authorization: Bearer $RUNTYPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"bindings": {"RRX_TOOLS_BASE_URL": "https://pr-482.example.com"}}'

Bindings behave as follows:

  • Whole-set replacement. Each write states the complete set the alias carries, so a name you stop sending stops resolving. DELETE on the same path clears every binding.
  • Write-only values. Values are encrypted at rest, and no read returns one. GET .../bindings, the alias itself (bindingNames), the deployment receipt, and the audit log carry names only.
  • Bindings belong to the alias, not the version. Changing them increases the alias revision and appends a bind deployment receipt without changing the version. Archiving or expiring the alias removes them with it.
  • Limits. An alias carries at most 25 bindings, and each value is at most 4096 characters. Each name uses uppercase letters, digits, and underscores, starts with a letter, ends with a letter or digit, and is 2 to 100 characters long.
  • Provider and platform names are refused. Runtype resolves these names itself, so a binding would have no effect. A name that starts with RUNTYPE_, PLATFORM_, CLOUDFLARE_, or INTERNAL_ is rejected with code: "alias_binding_invalid". So are provider credential names such as ANTHROPIC_API_KEY, OPENAI_API_KEY, and AWS_ACCESS_KEY_ID.
  • Bindings apply to the Agent the request named. A nested sub-Agent, a Claude Managed session, and a detached sub-Agent run resolve their own aliases, so they read organization secrets instead of the parent’s bindings.

Bindings override configuration for one preview. They don’t isolate it: everything else about a preview, including its data, credentials, and memory, still comes from the organization.

Memory namespaces and release pointers

Agent memory is keyed by the subject it’s about, never by the Agent’s configuration version. A new version, a preview alias, and a request pinned to a versionId all read and write the same memory the Agent already had. Sharing is the default, and it works until a preview alias starts writing memory that live traffic shouldn’t see.

You choose the isolation. Three read-only variables pass the alias or version that a run resolved through into the memory profile template:

VariableValuePresent when
{{_agent.alias}}The release alias the request named, including liveThe request supplied agent.alias
{{_agent.versionId}}The immutable version the run is pinned toThe request supplied agent.alias or agent.versionId
{{_agent.version}}That version’s human label, when the version carries one. Display only: free text, not unique, absent on an unlabelled versionThe pinned version has a label

All three are absent when the request named no selector. {{_agent.alias}} is also absent when the request pinned a bare agent.versionId, because a version ID belongs to no particular alias. A template variable that Runtype can’t resolve turns memory off for that run instead of falling back to a shared bucket. Write a fallback ({{_agent.alias || "live"}}) unless you want memory off on those runs.

The namespace ladder

Climb one rung only when the product needs it. Each rung shows the value the template resolves to for an end user dana on an Agent whose live alias and pr-482 preview both run. Runtype then prefixes that value with the owning organization to form the stored profile ID, so the values shown are the part you control.

1. Shared. Omit profileTemplate. Every version, alias, and pinned request shares one bucket per Agent.

profileTemplate: (unset, defaults to {{_agent.id}})
live -> agent_01j...
pr-482 -> agent_01j... (the same bucket)

Move on when the Agent serves more than one end user.

2. Per end user. Required on any Product Surface that serves many end users. Runtype turns memory off when a multi-end-user Surface resolves a template with no end-user identity.

profileTemplate: {{_endUser.id}}
live -> dana
pr-482 -> dana (the same bucket)

Move on when a preview alias starts writing memory.

3. Previews isolated, live shared. Each preview alias gets its own bucket. live keeps the one it already had, so preview traffic doesn’t touch production memory.

profileTemplate: {{_endUser.id}}/{{_agent.alias || "live"}}
live -> dana/live
pr-482 -> dana/pr-482
no selector -> dana/live
agent.versionId -> dana/live

Changing the template changes the bucket. The memory an Agent already built on rung 2 stays under the old profile, and live starts empty at dana/live. Move up the ladder before the Agent has memory you care about, or copy the old bucket forward with the memory tools.

The || "live" fallback keeps ordinary traffic on one bucket: a request with no selector and a request pinned to a bare agent.versionId both resolve the fallback. To keep production traffic that’s pinned to an exact version on the shared bucket, deploy that version to an alias and select the alias instead of sending a raw versionId.

Move on when behavior has to be reproducible per version.

4. Per version. Every version starts empty. Use this for regulated or evaluation-driven setups where a version’s behavior must not depend on memory another version wrote.

profileTemplate: {{_endUser.id}}/{{_agent.versionId || "live"}}
live -> dana/agentver_01j...
pr-482 -> dana/agentver_01k...
no selector -> dana/live
agent.versionId -> dana/agentver_01j...

Keep the fallback unless you mean it. Written as a bare {{_endUser.id}}/{{_agent.versionId}}, this rung turns memory off for every request that selects no version, which is most ordinary traffic. Validation reports MEMORY_POINTER_TEMPLATE_UNGUARDED when a pointer variable has no fallback.

Key on {{_agent.versionId}}, never {{_agent.version}}. The label is free text, isn’t unique across versions, and is absent on a version nobody labeled, so it makes a poor bucket key.

5. Environment-mapped. When one Agent serves several environments, map the alias to the namespace you want instead of adding a rung. {{_endUser.id}}/{{_agent.alias || "live"}} already does this when each environment has its own alias. A per-dispatch agentInput.memory.profileTemplate override lets a CI run choose its own bucket without editing the Agent. Two separate Agents give the strongest separation, because they share nothing.

Runtype doesn’t copy live memory into a preview bucket. Copy it yourself with the memory tools.

What happens on rollback and alias changes

The bucket follows the template:

  • Rollback (moving live back to an earlier version) keeps the same bucket on rungs 1 to 3. On rung 4 it moves back to that version’s own bucket, where the earlier version reads what it wrote before.
  • Deploying a newer version to an alias (for example, to pr-482) keeps the alias’s bucket on rungs 1 to 3 and starts a fresh bucket on rung 4.
  • Archiving or expiring a preview alias doesn’t delete what it wrote. The bucket stays until you remove it.

Agents with a Tenancy Strategy

When an Agent sets a tenancyStrategy, Runtype builds the namespace from the resolved tenant and end user and ignores profileTemplate. The template variables have no effect. Set memory.pointerScope instead:

  • "shared" (the default) keeps one bucket across every version and alias.
  • "alias" gives each release alias its own bucket.
  • "version" gives each version its own bucket.

pointerScope applies only to an Agent that sets a tenancyStrategy. On any other Agent the field has no effect, because memory there uses the template. Runtype reports MEMORY_POINTER_SCOPE_IGNORED so the field doesn’t look like isolation. A run that resolved no alias or version, such as a request with no selector, uses the shared bucket.

The pointer scope separates memory. It doesn’t restrict access: preview aliases still share the organization’s credentials, Records, and integration connections.

The validators report MEMORY_SHARED_ACROSS_POINTERS as a recommendation when an Agent turns on memory and keys it on neither the variables nor pointerScope.

Publish from the API

POST /v1/agent-versions/{agentId}/publish applies the stored snapshot to the Agent and marks that version as published, in one step. Send versionId in the request body. The TypeScript SDK exposes the same operation:

const result = await client.agentVersions.publish(agentId, versionId)
console.log(result.applied, result.warnings, result.lastModifiedSource)

For an Agent managed in code, the default returns 409 with code: "managed_by_code_conflict". After explicit confirmation, use the option for your client:

  • REST and TypeScript SDK: onConflict: "overwrite"
  • CLI: runtype agent-versions publish AGENT_ID --version VERSION_ID --overwrite-managed
  • MCP: publish_agent_version with on_conflict: "overwrite"
  • Code Mode: { onConflict: "overwrite" }

Inspect applied and warnings to see which parts of the snapshot were restored.

POST /v1/agents/{id}/publish snapshots the Agent’s current saved configuration as a new published version.

On an organization Agent, both routes also deploy the published version to live in the same step and append a deployment receipt. An Agent in a personal account has no release aliases, so those routes only record the published version. To deploy to a preview alias, see Deploy a version to an alias.

Best practices

Use these practices to manage Agent changes:

  • Save small, incremental changes so each version snapshot is a short step back.
  • Know which step reaches production for your organization, from What runs when you do not name a version. Test the Agent first either way. Try a change on a non-production Product before you put it on an Agent that production traffic uses.
  • Review conversations and activity after you deploy.
  • Give the version a label when you deploy from CI, so the deployment history shows which commit produced what is running.
  • To go back to an earlier configuration, click Publish to live beside that version in Version History. Then read the notification for anything the deploy couldn’t restore.

Next steps

Continue with these Agent guides: