Skip to content

Factories > Integrations

Use the factory API

Open in ChatGPT ↗
Ask ChatGPT about this page
Open in Claude ↗
Ask Claude about this page
Copied!

Discover factories and dispatch tasks by UID with the public factory API, without learning the foreman agent's internals.

Use the factory API to find a factory and start work from a custom integration without managing agent details. Build it into a chat bot, script, or service for any tool Warp doesn’t connect to directly.

  • Discover factories by name - Search factories your account can access by name or alias, so your integration doesn’t need to hardcode factory UIDs.
  • Dispatch by UID, not by agent - Start a run with only a factory’s UID. The server resolves the factory’s foreman agent for you.
  • Ticket metadata built in - Attach a ticket_ref (and optional ticket_url) to a dispatched run so the factory’s task ties back to your own tracker from the start.
  • Continue with the existing Oz API & SDK - Once a run is dispatched, every other Agent API operation (retrieving status, sending follow-ups) works on it unchanged.

Earlier integrations that sent work to a factory had to call the lower-level Agent API and pass the factory’s foreman agent as an agent_identity_uid - an implementation detail a caller had to look up and store out of band. The factory API removes that step: program against the factory, not the foreman.

A factory exposes a public UID, the same UID shown in the factory dashboard and used by Factory MCP. Two endpoints work with that UID:

  • GET /factory - list factories your account can access, optionally filtered with a search parameter that matches the factory’s name or alias, case-insensitively.
  • GET /factory/{uid} - retrieve a single factory by UID.

Dispatching work is a single call:

  • POST /factory/{uid}/runs - creates a run on the factory’s foreman agent. The server looks up the foreman for you, so the request body only needs a prompt, a title, and optionally a ticket_ref/ticket_url pair identifying the originating ticket in your own tracker.

The response is an ordinary run: a run_id, a run_url, and a state. From there, the run behaves like any other cloud agent run - list it, retrieve it, or send it follow-ups through the same Agent API endpoints you’d use for a run started any other way. The factory API only changes how a run gets started; everything downstream is unchanged. See the Agents API Reference for full parameters and error codes on those run-management endpoints.

When to use the factory API vs the Agent API

Section titled “When to use the factory API vs the Agent API”

Use the factory API to start work whenever the destination is a factory. Reach for the lower-level Agent API only when you’re working with a standalone cloud agent that isn’t part of a factory, or when you need a capability the factory API doesn’t expose yet, such as full orchestration control.

TaskRecommended API
Find a factory by name before dispatching to itfactory API - GET /factory?search=
Start a new task on a factoryfactory API - POST /factory/{uid}/runs
Continue, monitor, or cancel a run (factory or standalone)Agent API - GET /agent/runs/{runId}, POST /agent/runs/{runId}/followups, POST /agent/runs/{runId}/cancel
Run a standalone cloud agent with no factory involvedAgent API - POST /agent/run
Build a multi-agent orchestrationAgent API - see multi-agent orchestration

The Agent API isn’t deprecated. Every factory run is still an ordinary run under the hood, so status, follow-ups, and cancellation all go through the same Agent API endpoints regardless of which API started the run. The factory API only replaces the dispatch step for factory work.

Before dispatching work, find the factory’s UID. If your integration already stores the UID (for example, from when it was configured), skip ahead to dispatching a run.

import os
from oz_agent_sdk import OzAPI
client = OzAPI(api_key=os.environ.get("WARP_API_KEY"))
# Find a factory by name or alias — no UIDs needed up front
page = client.factories.list(search="payments")
factory = page.factories[0]
# With the pagination scheme wired, iteration auto-pages
for f in client.factories.list(search="payments"):
print(f.uid, f.name)

The REST equivalent:

GET /api/v1/factory?search=payments
Authorization: Bearer YOUR_API_KEY

Retrieve a factory when the UID is already known

Section titled “Retrieve a factory when the UID is already known”
factory = client.factories.retrieve(factory.uid)
GET /api/v1/factory/YOUR_FACTORY_UID
Authorization: Bearer YOUR_API_KEY

Dispatching a run only needs the factory’s UID, a prompt, and a title. Foreman resolution happens server-side, so there’s no separate lookup step.

run = client.factories.runs.create(
factory.uid,
prompt="Investigate and fix the flaky payment webhook retry test",
title="Fix flaky payment webhook retry test",
ticket_ref="linear:PAY-123", # optional; omitted -> adhoc ref
)
print(run.run_id, run.run_url, run.state)
POST /api/v1/factory/YOUR_FACTORY_UID/runs
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"prompt": "Investigate and fix the flaky payment webhook retry test",
"title": "Fix flaky payment webhook retry test",
"ticket_ref": "linear:PAY-123"
}

ticket_ref identifies the originating ticket in <source>:<id> form (for example linear:PAY-123 or jira:PROJ-456). Pass an optional ticket_url alongside it so the factory’s task record links straight back to your tracker. Omit both to let the server mint an adhoc reference.

A dispatched run is an ordinary run, so the rest of the Oz API & SDK works on it unchanged:

# Check status the same way you would for any other run
status = client.agent.runs.retrieve(run.run_id)

To steer the run instead of just checking on it, send a follow-up the same way you would for a run started with POST /agent/run:

POST /api/v1/agent/runs/YOUR_RUN_ID/followups
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"prompt": "Also add a regression test for the retry backoff"
}

See key endpoints for the full set of run-management operations, including cancellation.

If your integration currently dispatches to a factory with the lower-level Agent API, replace the foreman lookup and agent_identity_uid with a single factory API call.

Before - the caller has to already know the foreman’s agent UID:

client.agent.run(prompt="Fix the flaky test", agent_identity_uid="YOUR_FOREMAN_AGENT_UID")

After - the caller only needs the factory’s UID; the server resolves the foreman:

run = client.factories.runs.create(
factory.uid,
prompt="Fix the flaky test",
title="Fix the flaky test",
)

The run executes exactly the same way, and existing run-management APIs keep working on it. The agent_identity_uid path still works for existing integrations, but new integrations should dispatch through the factory API instead of looking up and storing a foreman agent UID.

  • Connect your factory - Every way work can enter a factory, including the factory API alongside Slack, GitHub, and Factory MCP.
  • Build a Mattermost bot for Warp Factories - A worked example that discovers a factory and dispatches and continues a task from a custom chat integration.
  • Factory MCP - Connect a local coding agent to a factory instead of calling the REST API directly.
  • Oz API & SDK - Full endpoint reference, SDKs, and error codes for the underlying Agent API.
  • How Warp Factories work - The stages a dispatched task moves through after the foreman picks it up.