> Source: https://wexa.ai/docs/agents/run-agent

# run-agent

[Can be held for approval](/docs/sdks-and-apis/how-every-tool-call-works#lifecycle-and-governance)

Run one agent that already exists in this project with a natural-language goal. It returns an `execution_id` straight away and does not wait for the run to finish. Needs the `fabric:agent.run` grant.

**Run an agent**

**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":"run-agent","arguments":{"agentflow_id":"6ab1945e7566f41b5c28e303","goal":"Reply with READY."}}}'
```

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000184\",\"result\":{\"execution_id\":\"8ba80297-9dfe-4ff6-9134-a1d9803355dd\",\"agentflow_id\":\"6ab1945e7566f41b5c28e303\",\"agentflow_name\":\"docs-fixture-agent\",\"goal\":\"Reply with READY.\",\"status\":\"running\"}}"
    }
  ],
  "isError": false
}
```

**REST API**

```bash
curl -sS https://fabric.wexa.ai/v1/run-agent \
  -H "authorization: Bearer $FABRIC_API_KEY" \
  -H "content-type: application/json" \
  -d '{"agentflow_id":"6ab1945e7566f41b5c28e303","goal":"Reply with READY."}'
```

```json
{
  "lifecycle_id": "qlc_000184",
  "result": {
    "execution_id": "8ba80297-9dfe-4ff6-9134-a1d9803355dd",
    "agentflow_id": "6ab1945e7566f41b5c28e303",
    "agentflow_name": "docs-fixture-agent",
    "goal": "Reply with READY.",
    "status": "running"
  }
}
```

**TypeScript SDK**

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

const fabric = new Fabric()
const result = await fabric.runAgent({
  agentflow_id: '6ab1945e7566f41b5c28e303',
  goal: 'Reply with READY.'
})
```

```ts
// result is the payload itself, with no `.result` to read
{
  execution_id: '8ba80297-9dfe-4ff6-9134-a1d9803355dd',
  agentflow_id: '6ab1945e7566f41b5c28e303',
  agentflow_name: 'docs-fixture-agent',
  goal: 'Reply with READY.',
  status: 'running'
}
```

**Python SDK**

```python
from wexa import Fabric

fabric = Fabric()
out = fabric.run_agent(
    agentflow_id="6ab1945e7566f41b5c28e303",
    goal="Reply with READY.",
)
```

```python
# out is the result, already unwrapped
{
    "execution_id": "8ba80297-9dfe-4ff6-9134-a1d9803355dd",
    "agentflow_id": "6ab1945e7566f41b5c28e303",
    "agentflow_name": "docs-fixture-agent",
    "goal": "Reply with READY.",
    "status": "running"
}
```

## Parameters

| Parameter | Type | Required | Notes |
| --- | --- | --- | --- |
| `agentflow_id` | string | Required | Id of the agent to run: the `agent_id` that `create-agent` or `list-agents` returns, unchanged. An agent in this project. There is no `agent_id` argument; a call that sends `agent_id` instead has no `agentflow_id` and is refused. An id that names a multi-agent process flow is refused: run that with [run-process-flow](/docs/automation/run-process-flow). |
| `files` | array | Optional | File ids to add to the execution context. See [known limitations](#known-limitations); do not pass it for now. |
| `goal` | string | Required | Natural-language goal or message for this run (this turn). This is not a one-off prompt: the agent must already exist. |
| `input_variables` | object | Optional | Input variables consumed by the agent. See [known limitations](#known-limitations). |
| `session_id` | string | Optional | Conversation id. Reuse the same value across turns for multi-turn memory and grouping. Omit for a one-shot run. |
| `start_from_agent_id` | string | Optional | Agent id to start the flow from. |

**Show full response**

A real response, captured from a live call to `run-agent`:

`agentflow` came back populated and is shown as `…` here, because the real value runs to thousands of characters. Read it from your own call rather than from this page.

**Result of run-agent**

**REST API**

```json
{
  "lifecycle_id": "qlc_000184",
  "result": {
    "_id": "6ab196817566f41b5c28e31a",
    "agent_type": "Task",
    "agent_version": null,
    "agentflow": "\u2026",
    "agentflow_id": "6ab1945e7566f41b5c28e303",
    "agentflow_name": "docs-fixture-agent",
    "agents_output": [],
    "anomaly_detected": null,
    "application_user_id": "6a79a770b6c128ccc24bfca7",
    "conclusion": null,
    "created_at": 1790023297.263668,
    "duration_ms": null,
    "end_time": null,
    "executed_by": {
      "_id": "6a79a770b6c128ccc24bfca7",
      "application_user_id": "6a79a770b6c128ccc24bfca7",
      "is_external_application": true,
      "metadata": null,
      "name": "6a79a770b6c128ccc24bfca7",
      "type": "api"
    },
    "execution_context": {},
    "execution_id": "8ba80297-9dfe-4ff6-9134-a1d9803355dd",
    "files": [],
    "goal": "Reply with READY.",
    "goal_template": null,
    "input_variables": {},
    "interop_ask": null,
    "interop_resume": null,
    "is_external_application": true,
    "kb_tags": [],
    "parent_execution_id": null,
    "previews": {},
    "projectID": "6aa9beb7ec8121a43b6c791b",
    "runtime_inputs": {},
    "schedule": null,
    "session_id": null,
    "simulation": false,
    "start_from_agent_id": null,
    "status": "running",
    "task_id": "6ab196817566f41b5c28e31b",
    "total_price": null,
    "total_tokens": null,
    "trigger_source": "api"
  }
}
```

**Wexa MCP server**

```json
{
  "content": [
    {
      "type": "text",
      "text": "{\"lifecycle_id\":\"qlc_000184\",\"result\":{\"_id\":\"6ab196817566f41b5c28e31a\",\"agent_type\":\"Task\",\"agent_version\":null,\"agentflow\":\"\\u2026\",\"agentflow_id\":\"6ab1945e7566f41b5c28e303\",\"agentflow_name\":\"docs-fixture-agent\",\"agents_output\":[],\"anomaly_detected\":null,\"application_user_id\":\"6a79a770b6c128ccc24bfca7\",\"conclusion\":null,\"created_at\":1790023297.263668,\"duration_ms\":null,\"end_time\":null,\"executed_by\":{\"_id\":\"6a79a770b6c128ccc24bfca7\",\"application_user_id\":\"6a79a770b6c128ccc24bfca7\",\"is_external_application\":true,\"metadata\":null,\"name\":\"6a79a770b6c128ccc24bfca7\",\"type\":\"api\"},\"execution_context\":{},\"execution_id\":\"8ba80297-9dfe-4ff6-9134-a1d9803355dd\",\"files\":[],\"goal\":\"Reply with READY.\",\"goal_template\":null,\"input_variables\":{},\"interop_ask\":null,\"interop_resume\":null,\"is_external_application\":true,\"kb_tags\":[],\"parent_execution_id\":null,\"previews\":{},\"projectID\":\"6aa9beb7ec8121a43b6c791b\",\"runtime_inputs\":{},\"schedule\":null,\"session_id\":null,\"simulation\":false,\"start_from_agent_id\":null,\"status\":\"running\",\"task_id\":\"6ab196817566f41b5c28e31b\",\"total_price\":null,\"total_tokens\":null,\"trigger_source\":\"api\"}}"
    }
  ],
  "isError": false
}
```

**TypeScript SDK**

```ts
// the object you get back IS the result — there is no `.result` to read
{
  _id: '6ab196817566f41b5c28e31a',
  agent_type: 'Task',
  agent_version: null,
  agentflow: '…',
  agentflow_id: '6ab1945e7566f41b5c28e303',
  agentflow_name: 'docs-fixture-agent',
  agents_output: [],
  anomaly_detected: null,
  application_user_id: '6a79a770b6c128ccc24bfca7',
  conclusion: null,
  created_at: 1790023297.263668,
  duration_ms: null,
  end_time: null,
  executed_by: {
    _id: '6a79a770b6c128ccc24bfca7',
    application_user_id: '6a79a770b6c128ccc24bfca7',
    is_external_application: true,
    metadata: null,
    name: '6a79a770b6c128ccc24bfca7',
    type: 'api'
  },
  execution_context: {},
  execution_id: '8ba80297-9dfe-4ff6-9134-a1d9803355dd',
  files: [],
  goal: 'Reply with READY.',
  goal_template: null,
  input_variables: {},
  interop_ask: null,
  interop_resume: null,
  is_external_application: true,
  kb_tags: [],
  parent_execution_id: null,
  previews: {},
  projectID: '6aa9beb7ec8121a43b6c791b',
  runtime_inputs: {},
  schedule: null,
  session_id: null,
  simulation: false,
  start_from_agent_id: null,
  status: 'running',
  task_id: '6ab196817566f41b5c28e31b',
  total_price: null,
  total_tokens: null,
  trigger_source: 'api'
}

// 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_000184'
```

**Python SDK**

```python
# a dict subclass; `result` is already unwrapped
{
 "_id": "6ab196817566f41b5c28e31a",
 "agent_type": "Task",
 "agent_version": None,
 "agentflow": "\u2026",
 "agentflow_id": "6ab1945e7566f41b5c28e303",
 "agentflow_name": "docs-fixture-agent",
 "agents_output": [],
 "anomaly_detected": None,
 "application_user_id": "6a79a770b6c128ccc24bfca7",
 "conclusion": None,
 "created_at": 1790023297.263668,
 "duration_ms": None,
 "end_time": None,
 "executed_by": {
  "_id": "6a79a770b6c128ccc24bfca7",
  "application_user_id": "6a79a770b6c128ccc24bfca7",
  "is_external_application": True,
  "metadata": None,
  "name": "6a79a770b6c128ccc24bfca7",
  "type": "api"
 },
 "execution_context": {},
 "execution_id": "8ba80297-9dfe-4ff6-9134-a1d9803355dd",
 "files": [],
 "goal": "Reply with READY.",
 "goal_template": None,
 "input_variables": {},
 "interop_ask": None,
 "interop_resume": None,
 "is_external_application": True,
 "kb_tags": [],
 "parent_execution_id": None,
 "previews": {},
 "projectID": "6aa9beb7ec8121a43b6c791b",
 "runtime_inputs": {},
 "schedule": None,
 "session_id": None,
 "simulation": False,
 "start_from_agent_id": None,
 "status": "running",
 "task_id": "6ab196817566f41b5c28e31b",
 "total_price": None,
 "total_tokens": None,
 "trigger_source": "api"
}

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

**More details**

The run is asynchronous: poll the execution by its `execution_id` with [get-execution](/docs/agents/get-execution) for status and the conclusion. Policy can refuse a run, and that refusal is an answer the call gives you, not a silent no-op. See [Policy and approvals](/docs/governance/policy-and-approvals).

In the console, open the agent and choose **Run now**.

### Before the first run

An agent with no skill runs only when it can answer without one. A Conversational or Voice agent can, when it has `has_knowledge_base: true` and at least one tag in `context`. Task, Proxy and Interop agents always need a skill, unless the run carries `files`; see the known limitation on `files` below. When an agent cannot run, the call still returns an `execution_id`, and the execution fails saying the agent `has no action or tool attached`. The whole rule is on [create-agent](/docs/agents/create-agent#running-without-a-skill).

### Session memory

With a `session_id`, the agent recalls earlier turns of the same session, and the runs are grouped together as one conversation. Only completed turns are recalled: a turn that failed, or is still running, is not. The agent gets the last six completed turns, oldest first, each answer cut to 350 characters and the whole block to 1,500 characters. A long conversation therefore keeps its recent turns, not its first ones.

### Known limitations

These are faults in the platform today, each with what to do instead.

**`files` makes the execution unreadable.** A run started with `files` is accepted, and every `get-execution` on it then fails with a `ValidationError` (422), so you cannot read its status or conclusion. Do not pass `files` for now. Add the content to the [knowledge base](/docs/context/knowledge-base-add) and give the agent its tags instead.

**`input_variables` does not fill an agent's prompt.** Input variables fill only a goal template (`goal_structure`) stored on the agent's container, and an agent made with `create-agent` has none, so they are ignored. A `{{name}}` placeholder in the agent's prompt is worse: the run stops in `awaiting_input`, only the console can supply the value, and no tool ends the run. Write the values into the `goal` instead, and keep `{{...}}` out of prompts for agents you run from code.

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