Publish Agent to Staging
curl --request POST \
--url https://api.bland.ai/v2/agents/{agent_id}/publish \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"snapshot": {},
"version_id": "<string>",
"bump": "<string>"
}
'import requests
url = "https://api.bland.ai/v2/agents/{agent_id}/publish"
payload = {
"snapshot": {},
"version_id": "<string>",
"bump": "<string>"
}
headers = {
"authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({snapshot: {}, version_id: '<string>', bump: '<string>'})
};
fetch('https://api.bland.ai/v2/agents/{agent_id}/publish', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bland.ai/v2/agents/{agent_id}/publish",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'snapshot' => [
],
'version_id' => '<string>',
'bump' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bland.ai/v2/agents/{agent_id}/publish"
payload := strings.NewReader("{\n \"snapshot\": {},\n \"version_id\": \"<string>\",\n \"bump\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bland.ai/v2/agents/{agent_id}/publish")
.header("authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"snapshot\": {},\n \"version_id\": \"<string>\",\n \"bump\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v2/agents/{agent_id}/publish")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"snapshot\": {},\n \"version_id\": \"<string>\",\n \"bump\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"version": {
"id": "5bf56fc0-6ad5-4cd9-bb96-90cb63121526",
"org_id": "cee059fe-ac03-4fb4-acb1-6e8ef9dc4c39",
"agent_id": "9e676162-cf94-4d38-b9e7-4f2e8528989b",
"branch_id": null,
"snapshot": {
"behavior": {
"nodes": [],
"edges": []
},
"settings": {
"displayName": "Front desk",
"systemPrompt": "You answer calls for Northwind Dental and book appointments."
},
"contact": {
"inboundNumbers": []
}
},
"name": null,
"created_via": "manual",
"revision": 0,
"created_by": "68140a61-70e5-4a16-a5dc-70a0b923f52b",
"created_at": "2026-09-10T19:02:44.310Z"
},
"semver": "1.4.0",
"environments": [
{
"id": "a8e0f34d-0d4a-421e-b13e-26dd1bbd5161",
"env_type": "dev",
"current_version_id": null
},
{
"id": "c0835434-da77-4691-8452-bcfd7a2e6bee",
"env_type": "staging",
"current_version_id": "5bf56fc0-6ad5-4cd9-bb96-90cb63121526"
},
{
"id": "95e84904-2fe9-45e8-bb2a-137eb5bb40eb",
"env_type": "production",
"current_version_id": "65039217-bb14-4b1a-85b4-bfde372485a3"
}
]
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "INVALID_SNAPSHOT",
"message": "settings.systemPrompt must be a string"
},
{
"error": "INVALID_SNAPSHOT",
"message": "contact.inboundNumbers must be an array"
}
]
}
{
"data": null,
"errors": [
{
"error": "NO_VERSIONS",
"message": "Save a version before publishing to staging"
}
]
}
{
"data": null,
"errors": [
{
"error": "PUBLISH_IN_PROGRESS",
"message": "Another publish is in progress for this agent, please retry"
}
]
}
Environments and Releases
Publish Agent to Staging
Publish a version to the staging environment.
POST
/
v2
/
agents
/
{agent_id}
/
publish
Publish Agent to Staging
curl --request POST \
--url https://api.bland.ai/v2/agents/{agent_id}/publish \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"snapshot": {},
"version_id": "<string>",
"bump": "<string>"
}
'import requests
url = "https://api.bland.ai/v2/agents/{agent_id}/publish"
payload = {
"snapshot": {},
"version_id": "<string>",
"bump": "<string>"
}
headers = {
"authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({snapshot: {}, version_id: '<string>', bump: '<string>'})
};
fetch('https://api.bland.ai/v2/agents/{agent_id}/publish', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bland.ai/v2/agents/{agent_id}/publish",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'snapshot' => [
],
'version_id' => '<string>',
'bump' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bland.ai/v2/agents/{agent_id}/publish"
payload := strings.NewReader("{\n \"snapshot\": {},\n \"version_id\": \"<string>\",\n \"bump\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bland.ai/v2/agents/{agent_id}/publish")
.header("authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"snapshot\": {},\n \"version_id\": \"<string>\",\n \"bump\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v2/agents/{agent_id}/publish")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"snapshot\": {},\n \"version_id\": \"<string>\",\n \"bump\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"version": {
"id": "5bf56fc0-6ad5-4cd9-bb96-90cb63121526",
"org_id": "cee059fe-ac03-4fb4-acb1-6e8ef9dc4c39",
"agent_id": "9e676162-cf94-4d38-b9e7-4f2e8528989b",
"branch_id": null,
"snapshot": {
"behavior": {
"nodes": [],
"edges": []
},
"settings": {
"displayName": "Front desk",
"systemPrompt": "You answer calls for Northwind Dental and book appointments."
},
"contact": {
"inboundNumbers": []
}
},
"name": null,
"created_via": "manual",
"revision": 0,
"created_by": "68140a61-70e5-4a16-a5dc-70a0b923f52b",
"created_at": "2026-09-10T19:02:44.310Z"
},
"semver": "1.4.0",
"environments": [
{
"id": "a8e0f34d-0d4a-421e-b13e-26dd1bbd5161",
"env_type": "dev",
"current_version_id": null
},
{
"id": "c0835434-da77-4691-8452-bcfd7a2e6bee",
"env_type": "staging",
"current_version_id": "5bf56fc0-6ad5-4cd9-bb96-90cb63121526"
},
{
"id": "95e84904-2fe9-45e8-bb2a-137eb5bb40eb",
"env_type": "production",
"current_version_id": "65039217-bb14-4b1a-85b4-bfde372485a3"
}
]
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "INVALID_SNAPSHOT",
"message": "settings.systemPrompt must be a string"
},
{
"error": "INVALID_SNAPSHOT",
"message": "contact.inboundNumbers must be an array"
}
]
}
{
"data": null,
"errors": [
{
"error": "NO_VERSIONS",
"message": "Save a version before publishing to staging"
}
]
}
{
"data": null,
"errors": [
{
"error": "PUBLISH_IN_PROGRESS",
"message": "Another publish is in progress for this agent, please retry"
}
]
}
Overview
Moves the agent’sstaging pointer. The body picks one of three modes: send snapshot to save a new version and publish it, send version_id to publish an existing dev-timeline version, or send neither to publish the newest saved dev version. A version published for the first time is given a semver using bump; republishing a version that already has one re-records its original number. Move it on to production with Promote Agent to Production.
Requires an admin, owner, operator, or prompter role.
Headers
string
required
Your API key for authentication.
Path Parameters
string
required
The agent’s unique identifier.
Body Parameters
object
A full agent configuration to save as a new version and publish, the same object accepted by Create Agent Version. Top-level keys:
behavior ({ nodes, edges }), settings (displayName and systemPrompt strings, optional guardrails with at most 5 custom entries), contact (inboundNumbers array), and optional knowledge ({ kbIds: string[] }). Serialized size must not exceed 2 MB. Returns 400 INVALID_SNAPSHOT with one error entry per problem. Custom guardrails require an enterprise plan: a snapshot that adds one on another plan returns 403 ENTERPRISE_REQUIRED. When present, version_id is ignored.string
ID of an existing version on the agent’s dev timeline to publish without saving anything new. Versions saved on a branch are not accepted; merge the branch first. Returns
404 VERSION_NOT_FOUND if the ID is not on the dev timeline. Ignored when snapshot is present.string
default:"patch"
Which component to increment when this publish mints a new version number:
patch, minor, or major. The increment is applied to the highest number ever minted for the agent, so a first publish yields 0.0.1, 0.1.0, or 1.0.0. Ignored when the version already has a number. Returns 400 INVALID_BUMP for any other value.Response
Returns201 on success. Returns 200 instead when version_id names the version already pinned to staging; nothing changes and the current number is returned.
object
The published version, including its full
snapshot.Show version object
Show version object
string
Unique identifier for the version.
string
The organization that owns the version.
string
The agent the version belongs to.
null
Always
null; only dev-timeline versions can be published.object
The agent configuration stored in this version.
string | null
The version’s saved name, or
null.string
manual or autosave, depending on how the version was originally saved. A version created by this call is manual.integer
Rewrite counter for autosaved versions.
0 for a version created by this call.string | null
ID of the user who saved the version, or
null when saved with an org-level key.string
ISO 8601 timestamp the version was saved.
string
The version number recorded on this deployment, for example
1.4.0.array
The agent’s three environments after the publish. Each has
id, env_type (dev, staging, or production), and current_version_id (the pinned version, or null if unpinned).string[]
Non-blocking advisories about the saved snapshot (for example a transfer step with no target). Only present in
snapshot mode and only when there is at least one.array
Present alongside
warnings. Each entry has message and, when the advisory concerns a single step, nodeId.null | array
null on success, or a list of error objects if the request failed. Returns 404 NOT_FOUND for an unknown agent, 400 NO_VERSIONS when the body has neither snapshot nor version_id and the agent has no saved versions, and 409 PUBLISH_IN_PROGRESS when another publish for the same agent is still running; retry after a moment.{
"data": {
"version": {
"id": "5bf56fc0-6ad5-4cd9-bb96-90cb63121526",
"org_id": "cee059fe-ac03-4fb4-acb1-6e8ef9dc4c39",
"agent_id": "9e676162-cf94-4d38-b9e7-4f2e8528989b",
"branch_id": null,
"snapshot": {
"behavior": {
"nodes": [],
"edges": []
},
"settings": {
"displayName": "Front desk",
"systemPrompt": "You answer calls for Northwind Dental and book appointments."
},
"contact": {
"inboundNumbers": []
}
},
"name": null,
"created_via": "manual",
"revision": 0,
"created_by": "68140a61-70e5-4a16-a5dc-70a0b923f52b",
"created_at": "2026-09-10T19:02:44.310Z"
},
"semver": "1.4.0",
"environments": [
{
"id": "a8e0f34d-0d4a-421e-b13e-26dd1bbd5161",
"env_type": "dev",
"current_version_id": null
},
{
"id": "c0835434-da77-4691-8452-bcfd7a2e6bee",
"env_type": "staging",
"current_version_id": "5bf56fc0-6ad5-4cd9-bb96-90cb63121526"
},
{
"id": "95e84904-2fe9-45e8-bb2a-137eb5bb40eb",
"env_type": "production",
"current_version_id": "65039217-bb14-4b1a-85b4-bfde372485a3"
}
]
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "INVALID_SNAPSHOT",
"message": "settings.systemPrompt must be a string"
},
{
"error": "INVALID_SNAPSHOT",
"message": "contact.inboundNumbers must be an array"
}
]
}
{
"data": null,
"errors": [
{
"error": "NO_VERSIONS",
"message": "Save a version before publishing to staging"
}
]
}
{
"data": null,
"errors": [
{
"error": "PUBLISH_IN_PROGRESS",
"message": "Another publish is in progress for this agent, please retry"
}
]
}
Docs for agents: llms.txt
Was this page helpful?