> Source: https://wexa.ai/docs/sdks-and-apis/identifiers

# Which identifier goes where

You are holding an id and you want to know which argument takes it. That is this page.

Wexa issues opaque ids and validates their format before a tool runs, so an id in the wrong
argument is refused rather than quietly ignored. Two of them are worse than that: one has to be
**split** before a few places will accept it, and one field name means two different things on the
same object.

## The short version

| The id you hold | Where you got it | What takes it |
| --- | --- | --- |
| Agent id | `create-agent` → `agent_id`; `list-agents`; the console URL | `agent_id` on `get-agent`, `update-agent`, `delete-agent`, `agent-versions`, `rollback-agent-version`; `agentflow_id` on `run-agent` and `create-schedule`; `target_id` on `list-triggers` and `set-triggers` with `target_type: "agent"`; `agent_id` and `after_agent_id` on `update-process-flow`; `start_from_agent_id` on `run-agent` and `run-process-flow` |
| Agent id, **left half only** | the agent id up to the dot | `agentflow_id` on `list-schedules`; a trigger's `agentflow_id` inside `update-agent`; `{agentflowId}` in the [chat completions](/docs/sdks-and-apis/chat-completions) path |
| Process flow id | `create-process-flow` → `flow._id`; `get-process-flow` → `_id`; `flow-versions` → `process_flow_id` | `process_flow_id` on seven tools, `agentflow_id` on four — the same id under two names |
| Schedule id | `create-schedule` → `schedule_id` | `schedule_id` on `get-schedule`, `update-schedule`, `delete-schedule` |
| Execution id | `run-process-flow` — see the caveat below; the pairing is documented by the gateway, not captured here | `execution_id` on `get-execution` |
| Table id | `create-table` → `table_id`; `list-tables` → `tables[].table_id` | `table_id` on ten of the twelve Data Table tools — every one except `create-table` and `list-tables`, which do not address an existing table; `target_id` on `list-triggers` and `set-triggers` with `target_type: "table"` |
| Column id | `get-table` → `columns[].column_id` | `column_id` on `edit-column` and `delete-column`; the keys of `row` on `update-table-row` and of each `rows` entry on `insert-table-rows`, where a `column_name` is accepted too |
| Row id | `query-table-rows` → `rows[]._id` — **not** `rows[].row_id` | `row_id` on `update-table-row`; `row_ids` on `delete-table-rows` |
| Skill id | `list-skills` → `skills[]` — one entry per connector action | `skill_ids` on `create-agent`; `skills` inside `agent` on `update-agent`, which is the same list under a different name |
| Model id | `list-models` → `available[].model_name` or `registry[].id` | `model` on `create-agent` and `set-model` |
| Version number | `agent-versions` / `flow-versions` → `versions[]` and `live_version`; `promote-flow` → `version` | `version` on `rollback-agent-version` and `rollback-flow-version`; `from_version` and `to_version` on `agent-versions` — all integers, not ids |
| `lifecycle_id` | every response | nothing: it is the audit handle, not an argument |

## One object, three names

A process flow is addressed by three different spellings depending on where you are looking.

- **`process_flow_id`** is the argument name on `get-process-flow`, `update-process-flow`,
  `delete-process-flow`, `run-process-flow`, `flow-versions`, `promote-flow` and
  `rollback-flow-version` — seven tools.
- **`agentflow_id`** is the argument name on `run-agent`, `run-process-flow`, `create-schedule` and
  `list-schedules` — four tools. On `run-process-flow`, which takes both, the gateway's own schema
  calls `agentflow_id` an alias for `process_flow_id`.
- **`_id`** is what the flow itself is keyed by in output: `create-process-flow` returns it as
  `flow._id`, `get-process-flow` returns it as `_id`, and `promote-flow` returns the same value as
  `agentflowId` — camel case, on that one field only.

They are one value. Nothing needs converting between them; only the name changes.

## The compound agent id, and where to split it

`create-agent` does not return a plain id. It returns two ids joined by a dot:

```json
{
  "lifecycle_id": "qlc_000105",
  "result": {
    "agent_id": "6ab17f077566f41b5c28e2ae.6ab17f074a4bd3812ca5e968"
  }
}
```

The part **before** the dot is the container the agent lives in; the part **after** it is the agent
inside that container. Most tools take the whole thing, dot included, and split it themselves when
they need the container:

- every agent tool — `get-agent`, `update-agent`, `delete-agent`, `agent-versions`,
  `rollback-agent-version`
- `agentflow_id` on `run-agent` and on `create-schedule`
- `target_id` on `list-triggers` and `set-triggers`, for an agent target

Three places still need the left half today. Pass only the part before the dot:

- `agentflow_id` on `list-schedules`, which refuses the whole id as malformed
- a trigger's `agentflow_id` inside the `agent` you send to `update-agent`
- `{agentflowId}` in the [chat completions](/docs/sdks-and-apis/chat-completions) path

```json
{
  "agentflow_id": "6ab17f077566f41b5c28e2ae"
}
```

The difference is a fault, not a rule: these three places will take the whole id once it is fixed.

Never build an agent id yourself. Take it from `create-agent` or `list-agents`.

**Ids that are easy to confuse**

### Running an agent returns three ids, and only one of them polls

`run-agent` returns a large object. Three of its fields are identifiers, and they are easy to confuse:

- **`execution_id`** — a UUID, and the **only** id `get-execution` accepts.
- **`_id`** — the run record's own key, a 24-character hex string. `get-execution` answers a 404 for it.
- **`agentflow_id`** — the flow that ran: the same id you passed in.

Verified against a live deployment. One `run-agent` call returned
`_id` `6ab192bf7566f41b5c28e2e9` and `execution_id` `3c8cf2b5-612c-4700-be57-77b4d638ef37`:

| Passed to `get-execution` | Answer |
| --- | --- |
| `_id` | `404` — "Execution flow with ID 6ab192bf7566f41b5c28e2e9 not found" |
| `execution_id` | `200`, returning the execution record |

So an agent started with `run-agent` **does** have an execution record to poll. Read `execution_id`
from the response and pass that. The argument description on `get-execution` says "Execution id
returned by `run-process-flow`", which is true but incomplete: `run-agent` returns one too.

### `row_id` means two different things

A Data Table row carries two fields whose names both suggest an identifier, and only one of them is
one.

```json
{
  "_id": "6ab179ea7566f41b5c28e260",
  "row_id": 1,
  "customer": "AcmeC",
  "amount": 120
}
```

- **`_id`** is the row's identifier: an opaque string.
- **`row_id`** is the row's position in the table: an integer, and not unique across tables.

The `row_id` **argument** on `update-table-row` and the `row_ids` argument on `delete-table-rows`
both want `_id`, despite the name. Passing the integer is refused — and the refusal reports `row_id`
as *missing* rather than as the wrong type, so read it as "not a string" when you know you sent one.

### Column ids are sometimes names

`get-table` returns a `column_id` for every column, and for the columns the platform creates itself
that id *is* the name — `_id` and `row_id` come back with `column_id: "_id"` and
`column_id: "row_id"`. Columns you add get an opaque id instead:

```json
{ "column_id": "6ab17a6b3eecba4b44e58499", "column_name": "notes", "column_type": "String" }
```

Read the id from `get-table` rather than assuming either form. A `row` payload for
`update-table-row`, or a `rows` entry for `insert-table-rows`, may be keyed by either `column_id` or
`column_name`; a key that is neither is refused with the table's columns.

### Ids you choose yourself

Two arguments look like ids and are not issued by the platform:

- **`session_id`** on `run-agent` and `run-process-flow` is yours to pick. Reuse the same value
  across turns to get multi-turn memory and grouping; omit it for a one-shot run.
- **`after_id`** on `list-tables` is a pagination cursor, and it has to be a `table_id` you saw on a
  previous page. A value that is not one is refused as a `ValidationError`, not as a 404.

See also [How every tool call works](/docs/sdks-and-apis/how-every-tool-call-works) and [errors and retries](/docs/get-started/errors-and-retries).
