Migrate Persona
curl --request POST \
--url https://api.bland.ai/v2/agents/migrate/persona \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"persona_id": "<string>",
"name": "<string>",
"pathway_modes": [
{}
]
}
'import requests
url = "https://api.bland.ai/v2/agents/migrate/persona"
payload = {
"persona_id": "<string>",
"name": "<string>",
"pathway_modes": [{}]
}
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({persona_id: '<string>', name: '<string>', pathway_modes: [{}]})
};
fetch('https://api.bland.ai/v2/agents/migrate/persona', 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/migrate/persona",
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([
'persona_id' => '<string>',
'name' => '<string>',
'pathway_modes' => [
[
]
]
]),
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/migrate/persona"
payload := strings.NewReader("{\n \"persona_id\": \"<string>\",\n \"name\": \"<string>\",\n \"pathway_modes\": [\n {}\n ]\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/migrate/persona")
.header("authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"persona_id\": \"<string>\",\n \"name\": \"<string>\",\n \"pathway_modes\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v2/agents/migrate/persona")
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 \"persona_id\": \"<string>\",\n \"name\": \"<string>\",\n \"pathway_modes\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"agent": {
"id": "3096f27e-d17c-4fe8-a469-dac7da1d8d57",
"org_id": "45794f66-94ca-44a2-9248-202c5ff22717",
"name": "Support line",
"created_by": "bd8ae00b-c51d-4364-b1b3-245ad579c44a",
"created_at": "2026-09-10T19:02:15.907Z",
"updated_at": "2026-09-10T19:02:15.907Z",
"deleted_at": null
},
"version": {
"id": "d24c0c2b-ea67-4ad2-97f7-aad1c9aef52f",
"org_id": "45794f66-94ca-44a2-9248-202c5ff22717",
"agent_id": "3096f27e-d17c-4fe8-a469-dac7da1d8d57",
"branch_id": null,
"snapshot": {
"behavior": {
"nodes": [
{
"id": "inbound",
"type": "inbound",
"position": { "x": 360, "y": -180 },
"data": { "number": "" }
},
{
"id": "agent",
"type": "agent",
"position": { "x": 192, "y": 0 },
"data": {
"prompt": "You are the support line for Acme Utilities. Greet the caller and find out what they need.\n\n## Routing\n\nAfter each user turn, enter the scenario that matches where the conversation is now. The scenarios you can enter:\n\n- \"Report an outage\": the caller has lost service",
"loopWhile": "",
"variables": []
}
},
{
"id": "67a8c229-341e-423f-8295-e837e301134b",
"type": "complex-scenario",
"position": { "x": 0, "y": 260 },
"data": {
"name": "Report an outage",
"rule": "The caller has lost service",
"target": { "kind": "dialogue", "label": "Report an outage" },
"entry": {
"mode": "llm",
"label": "Report an outage",
"description": "The caller has lost service",
"alwaysPick": false,
"conditions": []
},
"flow": {
"nodes": [
{ "id": "start", "type": "start", "position": { "x": 0, "y": 0 }, "data": {} },
{
"id": "08e7085c-e318-42d8-a071-a5cd91f202cc",
"type": "prompt",
"position": { "x": 0, "y": 160 },
"data": {
"name": "Collect address",
"prompt": "Ask for the service address and when the outage started.",
"useStaticText": false,
"loopWhile": "",
"variables": [],
"useAudioExtraction": false,
"ignorePreviousExtractions": false,
"settings": {}
}
},
{ "id": "end", "type": "end", "position": { "x": 0, "y": 320 }, "data": {} }
],
"edges": [
{ "id": "e-start-address", "source": "start", "target": "08e7085c-e318-42d8-a071-a5cd91f202cc" },
{ "id": "e-address-end", "source": "08e7085c-e318-42d8-a071-a5cd91f202cc", "target": "end" }
]
}
}
}
],
"edges": [
{ "id": "e-inbound-agent", "source": "inbound", "target": "agent" },
{
"id": "e-agent-outage",
"source": "agent",
"target": "67a8c229-341e-423f-8295-e837e301134b",
"data": {
"mode": "llm",
"label": "Report an outage",
"description": "The caller has lost service",
"alwaysPick": false,
"conditions": []
}
}
]
},
"settings": {
"displayName": "Support line",
"systemPrompt": "Be concise and empathetic. Never promise a restoration time.",
"voice": "maya",
"languages": ["english"],
"enableMemory": true,
"interruptionSensitivity": 350,
"backgroundNoise": "off"
},
"contact": { "inboundNumbers": [] },
"knowledge": { "kbIds": ["53156238-c466-459f-8057-1f88c256d55b"] }
},
"name": "Migrated from persona: Support line",
"created_via": "manual",
"revision": 0,
"created_by": "bd8ae00b-c51d-4364-b1b3-245ad579c44a",
"created_at": "2026-09-10T19:02:15.907Z"
},
"warnings": [],
"lint": {
"errors": [],
"warnings": []
}
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "PERSONA_NOT_FOUND",
"message": "persona not found in this organization"
}
]
}
{
"data": null,
"errors": [
{
"error": "TRANSLATE_NOT_SUPPORTED",
"message": "AI-translated persona pathways run as a job — POST /v2/agents/migrate/translations with the persona_id, or switch those pathways to 1:1 to migrate synchronously"
}
]
}
Migration
Migrate Persona
Build an agent from a persona and its attached pathways.
POST
/
v2
/
agents
/
migrate
/
persona
Migrate Persona
curl --request POST \
--url https://api.bland.ai/v2/agents/migrate/persona \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"persona_id": "<string>",
"name": "<string>",
"pathway_modes": [
{}
]
}
'import requests
url = "https://api.bland.ai/v2/agents/migrate/persona"
payload = {
"persona_id": "<string>",
"name": "<string>",
"pathway_modes": [{}]
}
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({persona_id: '<string>', name: '<string>', pathway_modes: [{}]})
};
fetch('https://api.bland.ai/v2/agents/migrate/persona', 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/migrate/persona",
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([
'persona_id' => '<string>',
'name' => '<string>',
'pathway_modes' => [
[
]
]
]),
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/migrate/persona"
payload := strings.NewReader("{\n \"persona_id\": \"<string>\",\n \"name\": \"<string>\",\n \"pathway_modes\": [\n {}\n ]\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/migrate/persona")
.header("authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"persona_id\": \"<string>\",\n \"name\": \"<string>\",\n \"pathway_modes\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v2/agents/migrate/persona")
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 \"persona_id\": \"<string>\",\n \"name\": \"<string>\",\n \"pathway_modes\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"agent": {
"id": "3096f27e-d17c-4fe8-a469-dac7da1d8d57",
"org_id": "45794f66-94ca-44a2-9248-202c5ff22717",
"name": "Support line",
"created_by": "bd8ae00b-c51d-4364-b1b3-245ad579c44a",
"created_at": "2026-09-10T19:02:15.907Z",
"updated_at": "2026-09-10T19:02:15.907Z",
"deleted_at": null
},
"version": {
"id": "d24c0c2b-ea67-4ad2-97f7-aad1c9aef52f",
"org_id": "45794f66-94ca-44a2-9248-202c5ff22717",
"agent_id": "3096f27e-d17c-4fe8-a469-dac7da1d8d57",
"branch_id": null,
"snapshot": {
"behavior": {
"nodes": [
{
"id": "inbound",
"type": "inbound",
"position": { "x": 360, "y": -180 },
"data": { "number": "" }
},
{
"id": "agent",
"type": "agent",
"position": { "x": 192, "y": 0 },
"data": {
"prompt": "You are the support line for Acme Utilities. Greet the caller and find out what they need.\n\n## Routing\n\nAfter each user turn, enter the scenario that matches where the conversation is now. The scenarios you can enter:\n\n- \"Report an outage\": the caller has lost service",
"loopWhile": "",
"variables": []
}
},
{
"id": "67a8c229-341e-423f-8295-e837e301134b",
"type": "complex-scenario",
"position": { "x": 0, "y": 260 },
"data": {
"name": "Report an outage",
"rule": "The caller has lost service",
"target": { "kind": "dialogue", "label": "Report an outage" },
"entry": {
"mode": "llm",
"label": "Report an outage",
"description": "The caller has lost service",
"alwaysPick": false,
"conditions": []
},
"flow": {
"nodes": [
{ "id": "start", "type": "start", "position": { "x": 0, "y": 0 }, "data": {} },
{
"id": "08e7085c-e318-42d8-a071-a5cd91f202cc",
"type": "prompt",
"position": { "x": 0, "y": 160 },
"data": {
"name": "Collect address",
"prompt": "Ask for the service address and when the outage started.",
"useStaticText": false,
"loopWhile": "",
"variables": [],
"useAudioExtraction": false,
"ignorePreviousExtractions": false,
"settings": {}
}
},
{ "id": "end", "type": "end", "position": { "x": 0, "y": 320 }, "data": {} }
],
"edges": [
{ "id": "e-start-address", "source": "start", "target": "08e7085c-e318-42d8-a071-a5cd91f202cc" },
{ "id": "e-address-end", "source": "08e7085c-e318-42d8-a071-a5cd91f202cc", "target": "end" }
]
}
}
}
],
"edges": [
{ "id": "e-inbound-agent", "source": "inbound", "target": "agent" },
{
"id": "e-agent-outage",
"source": "agent",
"target": "67a8c229-341e-423f-8295-e837e301134b",
"data": {
"mode": "llm",
"label": "Report an outage",
"description": "The caller has lost service",
"alwaysPick": false,
"conditions": []
}
}
]
},
"settings": {
"displayName": "Support line",
"systemPrompt": "Be concise and empathetic. Never promise a restoration time.",
"voice": "maya",
"languages": ["english"],
"enableMemory": true,
"interruptionSensitivity": 350,
"backgroundNoise": "off"
},
"contact": { "inboundNumbers": [] },
"knowledge": { "kbIds": ["53156238-c466-459f-8057-1f88c256d55b"] }
},
"name": "Migrated from persona: Support line",
"created_via": "manual",
"revision": 0,
"created_by": "bd8ae00b-c51d-4364-b1b3-245ad579c44a",
"created_at": "2026-09-10T19:02:15.907Z"
},
"warnings": [],
"lint": {
"errors": [],
"warnings": []
}
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "PERSONA_NOT_FOUND",
"message": "persona not found in this organization"
}
]
}
{
"data": null,
"errors": [
{
"error": "TRANSLATE_NOT_SUPPORTED",
"message": "AI-translated persona pathways run as a job — POST /v2/agents/migrate/translations with the persona_id, or switch those pathways to 1:1 to migrate synchronously"
}
]
}
Overview
Deterministically converts a persona into a new agent, with no AI planning involved. The persona’s prompts, voice, and call settings become the agent’s settings, each attached pathway becomes a complex scenario holding a one-to-one conversion of its graph, and the persona’s skills become simple scenarios. The persona’s published version is used, falling back to its draft. The agent and its first version are always created; the response is201. To have the planner re-architect the persona’s pathways instead, use Start Pathway Translation with the same body.
Requires an admin, owner, operator, or prompter role.
Headers
string
required
Your API key for authentication.
Body Parameters
string
required
UUID of a persona in your organization. Returns
400 INVALID_PERSONA_ID if it is not a UUID, 404 PERSONA_NOT_FOUND if no such persona exists in your organization, and 422 PERSONA_HAS_NO_VERSION if the persona has neither a published nor a draft version.string
Display name for the new agent. Whitespace is trimmed. Defaults to the persona’s name.
array
One entry per pathway attached to the persona, in the persona’s order, each
one_to_one or translate. The length must match the persona’s pathway count or the request returns 400 INVALID_PATHWAY_MODES. This endpoint only performs one_to_one; any translate entry returns 400 TRANSLATE_NOT_SUPPORTED. Omit the field to convert every pathway one-to-one.Response
Returns201 on success. Returns 422 with INVALID_MIGRATED_SNAPSHOT or MIGRATION_LINT_FAILED when the converted agent does not validate, and 422 PERSONA_MIGRATION_FAILED when a referenced pathway cannot be loaded (for example, it was deleted or belongs to another organization).
object
The new agent record.
Show agent object
Show agent object
string
Unique identifier for the agent.
string
The organization that owns the agent.
string
The agent’s display name.
string | null
ID of the user who ran the migration, or
null when run with an org-level key.string
ISO 8601 timestamp of creation.
string
ISO 8601 timestamp of the last update.
null
Always
null on a live agent.object
The agent’s first version, saved on the dev timeline.
Show version object
Show version object
string
Unique identifier for the version.
string
The organization that owns the version.
string
The agent this version belongs to.
null
Always
null; migrations save to the dev timeline, not a branch.object
The full agent configuration (
behavior, settings, contact, and knowledge when the persona had knowledge bases). Same shape as Create Agent Version accepts. Abbreviated in the example below.string
Migrated from persona: <persona name>.string
Always
manual.integer
Always
0 on a new version.string | null
ID of the user who ran the migration, or
null when run with an org-level key.string
ISO 8601 timestamp of creation.
array
Human-readable notes about constructs the one-to-one conversion could not carry faithfully. Review each before publishing the agent.
object
Structural checks on the saved snapshot:
errors (always empty on a 201) and warnings (array of strings).null | array
null on success, or a list of error objects if the request failed.{
"data": {
"agent": {
"id": "3096f27e-d17c-4fe8-a469-dac7da1d8d57",
"org_id": "45794f66-94ca-44a2-9248-202c5ff22717",
"name": "Support line",
"created_by": "bd8ae00b-c51d-4364-b1b3-245ad579c44a",
"created_at": "2026-09-10T19:02:15.907Z",
"updated_at": "2026-09-10T19:02:15.907Z",
"deleted_at": null
},
"version": {
"id": "d24c0c2b-ea67-4ad2-97f7-aad1c9aef52f",
"org_id": "45794f66-94ca-44a2-9248-202c5ff22717",
"agent_id": "3096f27e-d17c-4fe8-a469-dac7da1d8d57",
"branch_id": null,
"snapshot": {
"behavior": {
"nodes": [
{
"id": "inbound",
"type": "inbound",
"position": { "x": 360, "y": -180 },
"data": { "number": "" }
},
{
"id": "agent",
"type": "agent",
"position": { "x": 192, "y": 0 },
"data": {
"prompt": "You are the support line for Acme Utilities. Greet the caller and find out what they need.\n\n## Routing\n\nAfter each user turn, enter the scenario that matches where the conversation is now. The scenarios you can enter:\n\n- \"Report an outage\": the caller has lost service",
"loopWhile": "",
"variables": []
}
},
{
"id": "67a8c229-341e-423f-8295-e837e301134b",
"type": "complex-scenario",
"position": { "x": 0, "y": 260 },
"data": {
"name": "Report an outage",
"rule": "The caller has lost service",
"target": { "kind": "dialogue", "label": "Report an outage" },
"entry": {
"mode": "llm",
"label": "Report an outage",
"description": "The caller has lost service",
"alwaysPick": false,
"conditions": []
},
"flow": {
"nodes": [
{ "id": "start", "type": "start", "position": { "x": 0, "y": 0 }, "data": {} },
{
"id": "08e7085c-e318-42d8-a071-a5cd91f202cc",
"type": "prompt",
"position": { "x": 0, "y": 160 },
"data": {
"name": "Collect address",
"prompt": "Ask for the service address and when the outage started.",
"useStaticText": false,
"loopWhile": "",
"variables": [],
"useAudioExtraction": false,
"ignorePreviousExtractions": false,
"settings": {}
}
},
{ "id": "end", "type": "end", "position": { "x": 0, "y": 320 }, "data": {} }
],
"edges": [
{ "id": "e-start-address", "source": "start", "target": "08e7085c-e318-42d8-a071-a5cd91f202cc" },
{ "id": "e-address-end", "source": "08e7085c-e318-42d8-a071-a5cd91f202cc", "target": "end" }
]
}
}
}
],
"edges": [
{ "id": "e-inbound-agent", "source": "inbound", "target": "agent" },
{
"id": "e-agent-outage",
"source": "agent",
"target": "67a8c229-341e-423f-8295-e837e301134b",
"data": {
"mode": "llm",
"label": "Report an outage",
"description": "The caller has lost service",
"alwaysPick": false,
"conditions": []
}
}
]
},
"settings": {
"displayName": "Support line",
"systemPrompt": "Be concise and empathetic. Never promise a restoration time.",
"voice": "maya",
"languages": ["english"],
"enableMemory": true,
"interruptionSensitivity": 350,
"backgroundNoise": "off"
},
"contact": { "inboundNumbers": [] },
"knowledge": { "kbIds": ["53156238-c466-459f-8057-1f88c256d55b"] }
},
"name": "Migrated from persona: Support line",
"created_via": "manual",
"revision": 0,
"created_by": "bd8ae00b-c51d-4364-b1b3-245ad579c44a",
"created_at": "2026-09-10T19:02:15.907Z"
},
"warnings": [],
"lint": {
"errors": [],
"warnings": []
}
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "PERSONA_NOT_FOUND",
"message": "persona not found in this organization"
}
]
}
{
"data": null,
"errors": [
{
"error": "TRANSLATE_NOT_SUPPORTED",
"message": "AI-translated persona pathways run as a job — POST /v2/agents/migrate/translations with the persona_id, or switch those pathways to 1:1 to migrate synchronously"
}
]
}
Docs for agents: llms.txt
Was this page helpful?