---
question: How do I call a workflow from Python or HTTP?
kind: task
via_web: na
via_cli: available
via_python: available
via_api: available
via_config: na
ref_cli: abi run script
ref_python: run(parameters)
ref_api: POST /workflows/{workflow_name}
prereq: You need a workflow whose `run` is implemented, in an in-engine module enabled in `config.yaml`.
next:
  - /capabilities/build/workflows/test-a-workflow
  - /capabilities/build/workflows/expose-as-a-tool
  - /capabilities/build/modules/module-jobs
---

# Run a workflow

A workflow runs when something calls its `run(parameters)`: your own code, a script the CLI loads with the engine, an HTTP call to its route, or an agent through its tools. On a schedule, a [module job](/user-guide/build/modules/module-jobs) calls it.

## Web UI

Not applicable. Nexus has no button that runs a workflow. An agent that carries the workflow's tools runs it from chat: see [Expose as a tool](/user-guide/build/workflows/expose-as-a-tool) and [Chat with an agent](/user-guide/build/agents/chat-with-an-agent).

## CLI

### Write a script

```python title="scripts/run_customers.py"
from my_module.workflows.CustomersWorkflow import (
    CustomersWorkflow,
    CustomersWorkflowConfiguration,
    CustomersWorkflowParameters,
)

workflow = CustomersWorkflow(CustomersWorkflowConfiguration())
print(workflow.run(CustomersWorkflowParameters(entity_id="42")))
```

### Run it with the engine

From the project root:

```bash
abi run script scripts/run_customers.py
```

`abi run script` loads the engine first, so the workflow can read its module's services. Arguments after the path are passed to the script. In a NATS project, the broker has to be up (`abi dev up`). The command is [`abi run script`](/user-guide/reference/cli#abi-run-script).

## Python

### Call `run`

Build the workflow and call `run` with its parameters model:

```python
from my_module.workflows.CustomersWorkflow import (
    CustomersWorkflow,
    CustomersWorkflowConfiguration,
    CustomersWorkflowParameters,
)

workflow = CustomersWorkflow(CustomersWorkflowConfiguration())
result = workflow.run(CustomersWorkflowParameters(entity_id="42"))
```

Inside the engine (an agent, another workflow, a `@job` handler), the module's services are already there. Outside it, load the engine first, as the CLI steps do.

### Or run it on a schedule

Call the workflow from a `@job` on the module's `ABIModule`, with a `Cron` or `Every` trigger. The example is on [Create a workflow](/user-guide/build/agents/creating-a-workflow#running-a-workflow-on-a-schedule).

## REST API

Once the engine has loaded the class, `run` is an HTTP call. Auth: the project's API key as a Bearer token.

### Call the route

The path is the class name in snake case. The body is the parameters model:

```bash
curl -X POST "http://localhost:9879/workflows/customers_workflow" \
  -H "Authorization: Bearer $ABI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "42"}'
```

With `abi dev up`, use the `api` port that `abi dev ports` prints. A class whose `run` is still the empty stub has no route. See [Expose as an API](/user-guide/build/workflows/expose-as-an-api).

## Config

Not applicable. `config.yaml` enables the module but does not run a workflow. A schedule is a `@job` in the module's Python code: see the Python steps.
