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

# Update Structure

<span class="badge--patch">PATCH</span> <code class="endpoint-url">/workflows/:id/structure</code>

Add or edit an agent's funnel statuses and custom lead fields. Rows are **upserted by `key`**: an unrecognized key is inserted, an existing key is updated. This endpoint never deletes — removing a status or field stays a deliberate dashboard action, so leads already sitting on a status are never orphaned.

## Path Parameters

| Parameter | Type          | Required | Description |
| --------- | ------------- | -------- | ----------- |
| `id`      | string (uuid) | **Yes**  | Agent ID    |

## Request Body

Provide `statuses`, `fields`, or both.

| Field      | Type  | Required | Description                                    |
| ---------- | ----- | -------- | ---------------------------------------------- |
| `statuses` | array | No       | Funnel statuses to upsert (see shape below)    |
| `fields`   | array | No       | Custom lead fields to upsert (see shape below) |

### `statuses[]` shape

| Field         | Type    | Required | Description                                                                                                                         |
| ------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `key`         | string  | **Yes**  | Stable identifier. Matches an existing status to update it, otherwise inserts a new one                                             |
| `label`       | string  | **Yes**  | Display label (`name` also accepted)                                                                                                |
| `is_initial`  | boolean | No       | Marks the funnel's entry status                                                                                                     |
| `is_terminal` | boolean | No       | Marks a funnel-ending status                                                                                                        |
| `sort_order`  | integer | No       | On insert, defaults to array index appended after the current max. Ignored on update — reordering existing statuses isn't done here |

### `fields[]` shape

| Field        | Type    | Required | Description                                                                                                                           |
| ------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `key`        | string  | **Yes**  | Stable identifier                                                                                                                     |
| `label`      | string  | **Yes**  | Display label                                                                                                                         |
| `type`       | string  | No       | One of: `text`, `number`, `date`, `datetime`, `boolean`, `select`, `multiselect`, `email`, `phone`, `url`, `currency`. Default `text` |
| `required`   | boolean | No       | Whether the agent must collect this field before advancing. Default `false`                                                           |
| `sort_order` | integer | No       | Same insert/update behavior as statuses                                                                                               |

## Responses

### `200` — Updated

```json theme={null}
{
  "success": true,
  "workflow_id": "123e4567-e89b-12d3-a456-426614174000",
  "statuses_upserted": 2,
  "fields_upserted": 1
}
```

`statuses_upserted` / `fields_upserted` are only present for the arrays you sent.

### `400` — Validation error

```json theme={null}
{
  "error": "Invalid input",
  "message": "Provide statuses and/or fields arrays"
}
```

Also returned as `"each status needs a key and a label"` or `"each field needs a key and a label"`.

### `401` — Authentication error

See [Authentication](/docs/en/api/authentication).

### `404` — Not found

```json theme={null}
{
  "error": "Not found",
  "message": "Workflow not found"
}
```

### `500` — Internal server error
