> Source: https://wexa.ai/docs/agents/get-execution

# get-execution

Poll one run of an agent or process flow. It returns the run's `status`, a Markdown `conclusion` and `last_agent_output`, the terminal agent's raw structured output. Needs the `fabric:orchestrate.read` grant.

**Read a run**

**Wexa MCP server**

```bash
curl -sS -X POST https://fabric.wexa.ai/mcp/$FABRIC_PROJECT_ID \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "Mcp-Session-Id: $MCP_SESSION_ID" \
  -H "content-type: application/json" -H "accept: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get-execution","arguments":{"execution_id":"d8b83fa9-afa7-4619-886f-55fafe5c9bc6"}}}'
```

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000186\",\"result\":{\"execution_id\":\"d8b83fa9-afa7-4619-886f-55fafe5c9bc6\",\"agentflow_id\":\"6ab1945e7566f41b5c28e308\",\"goal\":\"Reply OK.\",\"status\":\"running\",\"conclusion\":null}}"
    }
  ],
  "isError": false
}
```

**REST API**

```bash
curl -sS https://fabric.wexa.ai/v1/get-execution \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "content-type: application/json" \
  -d '{"execution_id":"d8b83fa9-afa7-4619-886f-55fafe5c9bc6"}'
```

```json
{
  "lifecycle_id": "qlc_000186",
  "result": {
    "execution_id": "d8b83fa9-afa7-4619-886f-55fafe5c9bc6",
    "agentflow_id": "6ab1945e7566f41b5c28e308",
    "goal": "Reply OK.",
    "status": "running",
    "conclusion": null
  }
}
```

**TypeScript SDK**

```ts
import { Fabric } from '@wexa-fabric/sdk'

const fabric = new Fabric()
const result = await fabric.getExecution({
  execution_id: 'd8b83fa9-afa7-4619-886f-55fafe5c9bc6'
})
```

```ts
// result is the payload itself, with no `.result` to read
{
  execution_id: 'd8b83fa9-afa7-4619-886f-55fafe5c9bc6',
  agentflow_id: '6ab1945e7566f41b5c28e308',
  goal: 'Reply OK.',
  status: 'running',
  conclusion: null
}
```

**Python SDK**

```python
from wexa import Fabric

fabric = Fabric()
out = fabric.get_execution(execution_id="d8b83fa9-afa7-4619-886f-55fafe5c9bc6")
```

```python
# out is the result, already unwrapped
{
    "execution_id": "d8b83fa9-afa7-4619-886f-55fafe5c9bc6",
    "agentflow_id": "6ab1945e7566f41b5c28e308",
    "goal": "Reply OK.",
    "status": "running",
    "conclusion": None
}
```

## Parameters

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `execution_id` | string | Required | Execution id returned by `run-agent` or `run-process-flow`. An execution in this project. |

**Show full response**

A real response, captured from a live call to `get-execution`:

**Result of get-execution**

**REST API**

```json
{
  "lifecycle_id": "qlc_000186",
  "result": {
    "agentflow_id": "6ab1945e7566f41b5c28e308",
    "conclusion": null,
    "execution_id": "d8b83fa9-afa7-4619-886f-55fafe5c9bc6",
    "files": [],
    "goal": "Reply OK.",
    "input_variables": null,
    "last_agent_output": null,
    "projectID": "6aa9beb7ec8121a43b6c791b",
    "start_from_agent_id": null,
    "status": "running",
    "task_id": "6ab196817566f41b5c28e31d"
  }
}
```

**Wexa MCP server**

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000186\",\"result\":{\"agentflow_id\":\"6ab1945e7566f41b5c28e308\",\"conclusion\":null,\"execution_id\":\"d8b83fa9-afa7-4619-886f-55fafe5c9bc6\",\"files\":[],\"goal\":\"Reply OK.\",\"input_variables\":null,\"last_agent_output\":null,\"projectID\":\"6aa9beb7ec8121a43b6c791b\",\"start_from_agent_id\":null,\"status\":\"running\",\"task_id\":\"6ab196817566f41b5c28e31d\"}}"
    }
  ],
  "isError": false
}
```

**TypeScript SDK**

```ts
// the object you get back IS the result — there is no `.result` to read
{
  agentflow_id: '6ab1945e7566f41b5c28e308',
  conclusion: null,
  execution_id: 'd8b83fa9-afa7-4619-886f-55fafe5c9bc6',
  files: [],
  goal: 'Reply OK.',
  input_variables: null,
  last_agent_output: null,
  projectID: '6aa9beb7ec8121a43b6c791b',
  start_from_agent_id: null,
  status: 'running',
  task_id: '6ab196817566f41b5c28e31d'
}

// The TS SDK names these camelCase — lifecycleId, traceId — where Python uses
// lifecycle_id and trace_id. Both are non-enumerable: readable, but omitted by
// Object.keys() and JSON.stringify(). `result.lifecycleId` here is undefined.
result.lifecycleId // 'qlc_000186'
```

**Python SDK**

```python
# a dict subclass; `result` is already unwrapped
{
 "agentflow_id": "6ab1945e7566f41b5c28e308",
 "conclusion": None,
 "execution_id": "d8b83fa9-afa7-4619-886f-55fafe5c9bc6",
 "files": [],
 "goal": "Reply OK.",
 "input_variables": None,
 "last_agent_output": None,
 "projectID": "6aa9beb7ec8121a43b6c791b",
 "start_from_agent_id": None,
 "status": "running",
 "task_id": "6ab196817566f41b5c28e31d"
}

out.lifecycle_id  # 'qlc_000186' — an attribute, not a key
```

## A run waiting on an external agent

An [external agent node](/docs/automation/update-process-flow) hands its step to an agent on another platform. That agent can take hours, and it can stop to ask a question of its own. A run in that state answers `status: "interop_pending"` and carries `waiting_on_external_agent`, so you can tell a run that is waiting from one that is merely slow, and from one that failed. In every other status the field is `null`, including a finished run that was cancelled while a question was open.

| Field | Type | Notes |
| --- | --- | --- |
| `agent_id` | string | The external agent node the run is parked on. Empty when the external agent asked over MCP elicitation, which carries no node id. |
| `registration_id` | string | The peer agent connection the task was handed to, the same id [list-peer-agents](/docs/agents/list-peer-agents) returns. |
| `question` | string \| null | What the external agent asked before it will continue. `null` means it is still working and nobody has to do anything. |
| `question_schema` | object \| null | The shape the external agent wants its answer in, when it declared one. An A2A pause carries prose and no schema; an MCP elicitation carries both. |
| `question_mechanism` | string \| null | `a2a_pending` or `mcp_elicitation`: which of the two ways it asked. |

**A question is answered in the console and nowhere else.** No surface gains a way to answer one: the answer is reviewed there first, helped by a context graph suggestion that is never sent for you. Nothing here returns that suggestion, nor the tokens the platform uses to resume the run.

How long a question waits depends on how it was asked. An MCP question (`mcp_elicitation`) waits 3 minutes for a person in the console, and with no answer by then it is cancelled. An A2A question (`a2a_pending`) has no time limit: the run stays `interop_pending` until a person answers it. No tool cancels a parked run from the SDKs, the REST API or the Wexa MCP server. A process flow with a parked run cannot be deleted until the run ends, so plan for a person to answer.

A real response, captured from a live run parked on an external agent:

```json
{
  "agentflow_id": "6ab36485f19beb4f0ed39e9a",
  "execution_id": "2b0cf9a7-9be7-4142-a578-8695372db913",
  "goal": "Settle the outstanding invoice for ACME-7.",
  "status": "interop_pending",
  "waiting_on_external_agent": {
    "agent_id": "",
    "question": "Which account should I settle, and who owns it?",
    "question_mechanism": "mcp_elicitation",
    "question_schema": {
      "description": "What the external agent needs before it can act.",
      "properties": {
        "account_code": {
          "description": "The customer's account code",
          "title": "Account Code",
          "type": "string"
        },
        "owner_email": {
          "description": "Who owns that account",
          "title": "Owner Email",
          "type": "string"
        }
      },
      "required": [
        "account_code",
        "owner_email"
      ],
      "title": "AccountAnswer",
      "type": "object"
    },
    "registration_id": "6ab36477825fc7bd72f3324b"
  }
}
```

**More details**

Two fields carry the result, and they are not interchangeable. `conclusion` is a Markdown summary of the run, written for a reader: always prose, never parse it as JSON, because code that treats it as structured data breaks on the first run that phrases itself differently. `last_agent_output` is the terminal agent's raw structured output, whatever that step actually produced, under `input_data` and `output_data`. Read it when a program needs the answer.

If that output is shaped like a Process Flow Manifest (flow, agents, wiring), pass it directly to [create-process-flow](/docs/automation/create-process-flow) as its `manifest`: one run's output becomes the next process flow's definition.

An execution is the record of what happened; a definition says what should happen, and only the execution answers the first. You start a run with [run-agent](/docs/agents/run-agent) or [run-process-flow](/docs/automation/run-process-flow), which return an `execution_id` and finish, then read the execution by id until it is done. An execution belongs to exactly one project, filled in from your credential rather than your arguments.

In the console, open **Orchestrate**, then **Executions**. Filter by status, source, agent type or date range, search by agent name or execution id, and open a row to see its trace. To list runs instead of reading one, use [list-executions](/docs/agents/list-executions); to ship a change safely, see [agent-versions](/docs/agents/agent-versions).

A run parked on an external agent node answers status `interop_pending`; the field that says why is under Show full response.

Every tool call works the same way: [How every tool call works](/docs/sdks-and-apis/how-every-tool-call-works).
