Serve flows with LFX
lfx serve starts a FastAPI server that exposes your flows as HTTP API endpoints at POST /flows/{flow_id}/run.
A LANGFLOW_API_KEY is required because lfx serve starts a publicly accessible server.
To execute a flow once and stream results to stdout instead, see Run flows with LFX.
Both lfx serve and lfx run accept a .json flow file or a .py Python script.
Prerequisites
-
A flow JSON file. Download the Simple Agent starter flow from the repository:
curl -o simple-agent-flow.json "https://raw.githubusercontent.com/langflow-ai/langflow/main/src/backend/base/langflow/initial_setup/starter_projects/Simple%20Agent.json" -
The flow's required API keys. The Simple Agent flow uses OpenAI, which requires
OPENAI_API_KEY.
Install flow dependencies
uv pip install lfx and uvx lfx install the LFX engine only. Before running a flow, install the extensions that provide the flow's components.
If a component is missing, LFX reports component-not-found with a hint naming the bundle to install, for example:
component-not-found-with-hint: DuckDuckGoSearchComponent not found.
Hint: try ext:duckduckgo:DuckDuckGoSearchComponent@official
Use the bundle name from the hint to find the pip package in the Bundle list.
For more information, see Install LFX with bundle components.
Generate requirements.txt
Extension packages cover component code. Some flows still need additional Python packages at runtime (third-party SDKs imported by those components).
To list them from a flow JSON file, use lfx requirements:
lfx requirements simple-agent-flow.json
Install the reported packages in the same environment before running the flow.
Start the server
-
Generate a Langflow API key.
For LFX, generate a secure token locally:
uv run python -c "import secrets; print(secrets.token_urlsafe(32))"This is different from creating an API key through the Langflow UI or CLI, which stores the key in the Langflow database. LFX only needs a secure token string to authenticate requests.
-
Set your environment variables. Use a
.envfile or export directly:.envfile:LANGFLOW_API_KEY="sk..."OPENAI_API_KEY="sk-..."Export:
export LANGFLOW_API_KEY="sk..."export OPENAI_API_KEY="sk-..." -
Start the server with your flow:
With a
.envfile:uv run lfx serve simple-agent-flow.json --env-file .envWith exported variables:
uv run lfx serve simple-agent-flow.json -
Copy the
flow_idfrom the startup output:LFX ServerFlow loaded: simple-agent-flow.json (c1dab29d-3364-58ef-8fef-99311d32ee42)Server: http://127.0.0.1:8000Run flows at: POST /flows/{flow_id}/runAPI key: x-api-key header or ?x-api-key= query parameter
Call the server
In a new terminal, set your API key and flow ID, then send a test request:
export LANGFLOW_API_KEY="sk..."
export FLOW_ID="c1dab29d-3364-58ef-8fef-99311d32ee42"
- Python
- JavaScript
- curl
import os
import requests
flow_id = os.environ["FLOW_ID"]
api_key = os.environ["LANGFLOW_API_KEY"]
url = f"http://localhost:8000/flows/{flow_id}/run"
headers = {
"Content-Type": "application/json",
"x-api-key": api_key,
}
payload = {
"input_value": "Hello, world!",
}
response = requests.post(url, headers=headers, json=payload, timeout=60)
response.raise_for_status()
print(response.text)
const flowId = process.env.FLOW_ID;
const apiKey = process.env.LANGFLOW_API_KEY;
const options = {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": apiKey,
},
body: JSON.stringify({
input_value: "Hello, world!",
}),
};
fetch(`http://localhost:8000/flows/${flowId}/run`, options)
.then(async (response) => {
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
console.log(await response.text());
})
.catch((error) => console.error(error));
curl -X POST http://localhost:8000/flows/$FLOW_ID/run \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-d '{"input_value": "Hello, world!"}'
Supply variables and credentials per request
The run and stream request bodies accept global_vars, a map of variables applied to a deep copy of the graph for that request only.
Use it to send an API key or a connection credential without putting it in the server's environment, where it would become an ambient default for every other caller:
curl -X POST http://localhost:8000/flows/$FLOW_ID/run \
-H "Content-Type: application/json" \
-H "x-api-key: $LANGFLOW_API_KEY" \
-d '{
"input_value": "Hello, world!",
"global_vars": {"LF_CONNECTION__GOOGLE__WORK": "{\"access_token\":\"ya29.a0-example\",\"scopes\":[\"https://www.googleapis.com/auth/drive.readonly\"]}"}
}'
Request-scoped values are consulted before the process environment, so a caller's value always wins.
With the built-in environment resolver, start the server with --no-env-fallback to prevent process-environment fallback. Custom resolvers retain their own credential lookup behavior:
uv run lfx serve ./flows/ --no-env-fallback
Add --reset-environ to also restore os.environ after each run, so a flow that mutates the process environment cannot affect the next request on the same worker.
For connection references, the LF_CONNECTION__* key derivation, the credential JSON format, and how to plug in your own resolver, see Resolve connections in headless LFX.
Serve multiple flows
To serve multiple flows, pass a directory to lfx serve to load all .json flows at server startup:
uv run lfx serve ./flows/
Control which components load
LFX loads all component categories by default. Use environment variables to restrict which categories are available when loading flows.
| Variable | Description |
|---|---|
LANGFLOW_COMPONENT_CATEGORY_ALLOWLIST | Comma-separated list of category names to include. If empty, all categories are included. |
LANGFLOW_COMPONENT_CATEGORY_BLOCKLIST | Comma-separated list of category names to exclude. Applied after the allowlist. |
Category names are case-insensitive. The virtual keyword core in the allowlist or blocklist expands to all core component categories.
Component category names don't always match the labels displayed in the Langflow visual editor. To view the component categories, see Bundle list.
To restrict components to specific categories:
export LANGFLOW_COMPONENT_CATEGORY_ALLOWLIST="openai,anthropic,processing,input_output"
uv run lfx serve my_flow.json
To exclude specific categories:
export LANGFLOW_COMPONENT_CATEGORY_BLOCKLIST="prototypes,langchain_utilities"
uv run lfx run my_flow.json "Hello"
To allow only core categories:
export LANGFLOW_COMPONENT_CATEGORY_ALLOWLIST="core"
uv run lfx serve my_flow.json
See also
Was this page helpful?