> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bland.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate Pathway

> Plan and build an agent from a legacy pathway graph.

### Overview

Takes an exported pathway graph and uses Bland's migration planner to re-architect it as an agent: the planner decides the scenario structure, and every legacy prompt, code snippet, and webhook body is carried over verbatim. By default the call is a dry run that returns the plan, the proposed agent snapshot, and a lint report for review; set `create` to `true` to also persist a new agent with its first version. A run takes several minutes; to receive progress events while it runs, use [Stream Pathway Migration](https://docs.bland.ai/api-v2/post/agents-migrate-stream.md). For a deterministic conversion with no planner, see [Migrate Pathways](https://docs.bland.ai/api-v2/post/agents-migrate-pathways.md).

Limited to 10 migration starts per hour per organization, counted together with [Stream Pathway Migration](https://docs.bland.ai/api-v2/post/agents-migrate-stream.md) and [Start Pathway Translation](https://docs.bland.ai/api-v2/post/agents-migrate-translations.md). Requires an admin, owner, operator, or prompter role.

### Headers

**authorization** `string` *required*

Your API key for authentication.

### Body Parameters

**pathway** `object` *required*

The legacy pathway graph, in the shape the pathway editor exports. Returns `400 INVALID_PATHWAY` if `nodes` or `edges` is missing or `nodes` is empty, and `400 PATHWAY_TOO_LARGE` beyond 500 nodes, 2,000 edges, or 2 MB serialized.

**pathway fields**

**nodes** `array` *required*

The pathway's nodes. Each has a string `id` and, typically, `type` and `data`. Must be non-empty.

**edges** `array` *required*

The pathway's edges. Each has `source` and `target` node IDs and optional `data`. May be empty.

**name** `string`

The pathway's name. Used to label the run and as the basis for the default agent name.

**globalPrompt** `string`

The pathway's global prompt, if it had one.

**name** `string`

Display name for the new agent when `create` is `true`. Whitespace is trimmed. Defaults to `<pathway.name> (migrated)`, or `unnamed pathway (migrated)` when the pathway has no name.

**create** `boolean` (default: false)

When `true`, the migrated snapshot is saved as a new agent with its first version and the response is `201`. Any other value is treated as `false` (dry run, `200`).

### Response

Returns `200` for a dry run and `201` when an agent was created. Returns `422` when the migrated snapshot fails validation or lint, or, in create mode, when the planner's report contains a blocking loss (`MIGRATION_BLOCKING_LOSS`), an open question (`MIGRATION_OPEN_QUESTION`), or a custom-code step with no saved snippet (`MIGRATION_CUSTOM_CODE_UNSUPPORTED`). In those cases review the dry-run output before creating.

**data.plan** `object`

The planner's migration plan. It references legacy nodes by ID rather than repeating their content.

**plan object**

**displayName** `string`

Proposed agent display name.

**hubPrompt** `string`

The prompt for the agent's central hub node, including a routing directory naming every scenario.

**languages** `array`

Spoken languages detected for the agent. Omitted when the planner did not set any.

**requestData** `array`

Request-data keys the pathway relied on, as `{ key, value }` pairs. Omitted when none.

**scenarios** `array`

Planned scenarios. Each has `kind` (`simple`, `complex`, or `auth-zone`), `name`, and `entry` (`mode` of `llm` or `deterministic`, `label`, and optional `description`, `alwaysPick`, `conditions`). A `simple` scenario carries `ruleParts` (text pieces, each either `{ text }` or `{ legacyPromptOf: <node id> }`) plus optional `variablesFrom`, `extraVariables`, `tools`, `carryToolsFrom`, and `settingsFrom`. A `complex` scenario carries `rule`, `steps`, and `edges`. An `auth-zone` carries `method`, `detail`, `steps`, `edges`, and `gates` (names of scenarios it protects).

**endCalls** `array`

Planned end-call nodes, each with `name`, `entry`, `promptParts`, and optional `variablesFrom` and `extraVariables`.

**report** `object`

The planner's accounting: `architectureSummary` (string), `dispositions` (one entry per legacy node group with `nodeIds`, `disposition`, `rationale`), `droppedOrApproximated` (entries with `item`, `severity` of `blocking`, `behavioral`, or `cosmetic`, and `note`), and `openQuestions` (strings).

**data.snapshot** `object`

The proposed agent configuration: `behavior` (`nodes` and `edges`), `settings`, `contact`, and optionally `knowledge`. This is the same shape [Create Agent Version](https://docs.bland.ai/api-v2/post/agents-id-versions.md) accepts, so you can edit it and save it to any agent. Abbreviated in the example below.

**data.lint** `object`

Structural checks on the snapshot: `errors` (array of strings; non-empty blocks creation) and `warnings` (array of strings).

**data.usage** `object`

Planner usage for the run: `inputTokens`, `outputTokens`, and `iterations`.

**data.created** `boolean`

`false` for a dry run, `true` when an agent and first version were saved.

**data.agent** `object`

Present only when `created` is `true`. The new agent record: `id`, `org_id`, `name`, `created_by` (`string | null`), `created_at`, `updated_at`, and `deleted_at` (`null`). Its `dev`, `staging`, and `production` environments are created unpinned; see [Get Agent](https://docs.bland.ai/api-v2/get/agents-id.md).

**data.version** `object`

Present only when `created` is `true`. The agent's first version: `id`, `org_id`, `agent_id`, `branch_id` (`null`), `snapshot` (identical to `data.snapshot`), `name` (`Migrated from pathway: <pathway name>`), `created_via` (`manual`), `revision` (`0`), `created_by` (`string | null`), and `created_at`.

**errors** `null | array`

`null` on success, or a list of error objects if the request failed.

```json Response theme={null}
{
  "data": {
    "plan": {
      "displayName": "Front desk",
      "hubPrompt": "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- \"Book appointment\": the caller wants to schedule a visit",
      "languages": ["english"],
      "scenarios": [
        {
          "kind": "simple",
          "name": "Book appointment",
          "entry": {
            "mode": "llm",
            "label": "Wants to book",
            "description": "The caller wants to schedule a visit"
          },
          "ruleParts": [
            { "legacyPromptOf": "73a855b4-7257-4c6e-bd7d-f151a763c9fa" }
          ],
          "variablesFrom": ["73a855b4-7257-4c6e-bd7d-f151a763c9fa"],
          "settingsFrom": "73a855b4-7257-4c6e-bd7d-f151a763c9fa"
        }
      ],
      "endCalls": [],
      "report": {
        "architectureSummary": "A two-node booking pathway collapsed into one hub and one booking scenario.",
        "dispositions": [
          {
            "nodeIds": ["73a855b4-7257-4c6e-bd7d-f151a763c9fa"],
            "disposition": "Became scenario \"Book appointment\"",
            "rationale": "Single dialogue step with variable extraction."
          },
          {
            "nodeIds": ["ddc0765a-8086-4826-bfaf-77b889fb3022"],
            "disposition": "Merged into the hub prompt",
            "rationale": "Greeting-only node with no branching."
          }
        ],
        "droppedOrApproximated": [],
        "openQuestions": []
      }
    },
    "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": "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- \"Book appointment\": the caller wants to schedule a visit",
              "loopWhile": "",
              "variables": []
            }
          },
          {
            "id": "545fe342-06be-4151-aae2-bd10bf128464",
            "type": "scenario",
            "position": { "x": 0, "y": 260 },
            "data": {
              "name": "Book appointment",
              "rule": "Ask which day and time works for the caller, then confirm the appointment back to them.",
              "target": { "kind": "dialogue", "label": "Book appointment" },
              "loopWhile": "",
              "variables": [
                {
                  "id": "78bf9689-57fb-4106-9402-34bce288b561",
                  "key": "appointment_time",
                  "value": "The date and time the caller chose",
                  "type": "string",
                  "accurateSpelling": false
                }
              ],
              "entry": {
                "mode": "llm",
                "label": "Wants to book",
                "description": "The caller wants to schedule a visit",
                "alwaysPick": false,
                "conditions": []
              }
            }
          }
        ],
        "edges": [
          { "id": "e-inbound-agent", "source": "inbound", "target": "agent" },
          {
            "id": "e-agent-book",
            "source": "agent",
            "target": "545fe342-06be-4151-aae2-bd10bf128464",
            "data": {
              "mode": "llm",
              "label": "Wants to book",
              "description": "The caller wants to schedule a visit",
              "alwaysPick": false,
              "conditions": []
            }
          }
        ]
      },
      "settings": {
        "displayName": "Front desk",
        "systemPrompt": "You are the front desk assistant for a dental office.",
        "voice": "",
        "languages": ["english"],
        "enableMemory": false,
        "interruptionSensitivity": 350,
        "backgroundNoise": "off"
      },
      "contact": { "inboundNumbers": [] }
    },
    "lint": {
      "errors": [],
      "warnings": []
    },
    "usage": {
      "inputTokens": 48211,
      "outputTokens": 6120,
      "iterations": 4
    },
    "created": false
  },
  "errors": null
}
```

```json Invalid Pathway theme={null}
{
  "data": null,
  "errors": [
    {
      "error": "INVALID_PATHWAY",
      "message": "body.pathway must be a legacy pathway graph with non-empty nodes[] and edges[]"
    }
  ]
}
```

```json Create Blocked theme={null}
{
  "data": null,
  "errors": [
    {
      "error": "MIGRATION_OPEN_QUESTION",
      "message": "open question: The transfer node has no phone number configured. Which number should the agent transfer to?"
    }
  ]
}
```

```json Rate Limited theme={null}
{
  "data": null,
  "errors": [
    {
      "error": "TOO_MANY_REQUESTS",
      "message": "Too many pathway migrations started for this organization — please wait before starting another."
    }
  ]
}
```

***

Docs for agents: [llms.txt](https://docs.bland.ai/llms.txt)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.