Warp Automation Platform HTTP API reference

Warp Agent API

API for creating, managing, and querying Warp cloud agent runs. These endpoints allow users to programmatically spawn agents, list runs, and retrieve detailed run information.

Base URL: https://app.warp.dev/api/v1

Authentication: Bearer token (Warp API key). Obtain from account settings. Pass as Authorization: Bearer YOUR_API_KEY.

Full machine-readable spec: openapi.json

GET /factory

List factories

List factories accessible to the authenticated principal. An optional team_uid query parameter restricts results to a single team, and an optional search query parameter filters by a case-insensitive substring match on the factory name or alias.

  • team_uid (query): Optional team UID to filter factories by ownership.
  • search (query): Case-insensitive substring search over the factory name and alias.
  • limit (query): Maximum number of factories to return (default 50, max 100).
  • cursor (query): Opaque cursor returned by a previous list response.

GET /factory/{uid}

Get a factory

Get a factory by its public UID.

  • uid (path, required): The public UID of the factory.

POST /factory/{uid}/runs

Dispatch a run to a factory

Dispatch a run to a factory by its UID, using prompt as the run's prompt and an optional title, ticket_ref, and ticket_url. Returns the created run; its factory task is created asynchronously and can be resolved afterwards with GET /factory/{uid}/task-by-run.

  • uid (path, required): The public UID of the factory.

GET /agent

List available agents

Retrieve a list of available agents (skills) that can be used to run tasks. Agents are discovered from environments or a specific repository.

  • repo (query): Optional repository specification to list agents from (format: "owner/repo"). If not provided, lists agents from all accessible environments.
  • refresh (query): When true, clears the agent list cache before fetching. Use this to force a refresh of the available agents.
  • sort_by (query): Sort order for the returned agents. - "name": Sort alphabetically by name (default) - "last_run": Sort by most recently used
  • include_malformed_skills (query): When true, includes skills whose SKILL.md file exists but is malformed. These variants will have a non-empty `error` field describing the parse failure. Defaults to false.

GET /agent/connected-self-hosted-workers

List connected self-hosted workers

Retrieve currently connected self-hosted workers for the authenticated principal's team. Worker presence is derived from worker websocket heartbeats and may be briefly stale.

GET /agent/runs/{runId}/transcript

Get run transcript

Retrieve the raw conversation transcript for an agent run. Returns a 302 redirect to a time-limited download URL for the transcript.

  • runId (path, required): The unique identifier of the run

POST /agent/run

Run an agent task

Spawn a cloud agent with a prompt and optional configuration. The agent will be queued for execution and assigned a unique run ID.

POST /agent/runs

Run a cloud agent

Spawn a cloud agent with a prompt and optional configuration. The agent will be queued for execution and assigned a unique run ID.

GET /agent/runs

List agent runs

Retrieve a paginated list of agent runs with optional filtering. Results default to `sort_by=updated_at` and `sort_order=desc`.

  • limit (query): Maximum number of runs to return
  • cursor (query): Pagination cursor from previous response
  • sort_by (query): Sort field for results. - `updated_at`: Sort by last update timestamp (default) - `created_at`: Sort by creation timestamp - `title`: Sort alphabetically by run title - `agent`: Sort alphabetically by skill. Runs without a skill are grouped last.
  • sort_order (query): Sort direction
  • state (query): Filter by run state. Can be specified multiple times to match any of the given states.
  • name (query): Filter by agent config name
  • model_id (query): Filter by model ID
  • creator (query): Filter by creator UID (user or service account)
  • executor (query): Filter by the user or agent that executed the run. This will often be the same as the creator, but not always: users may delegate tasks to agents.
  • source (query): Filter by run source type
  • execution_location (query): Filter by where the run executed
  • created_after (query): Filter runs created after this timestamp (RFC3339 format)
  • created_before (query): Filter runs created before this timestamp (RFC3339 format)
  • updated_after (query): Filter runs updated after this timestamp (RFC3339 format)
  • environment_id (query): Filter runs by environment ID. Passing the literal value `empty-environment` matches runs with no environment configured, rather than omitting the parameter, which applies no environment filter at all. `empty-environment` can never collide with a real environment ID: every environment ID is exactly 22 characters drawn from `[A-Za-z0-9]`, while this sentinel contains a hyphen and is a different length.
  • skill (query): Filter runs by skill spec (e.g., "owner/repo:path/to/SKILL.md"). Alias for skill_spec.
  • skill_spec (query): Filter runs by skill spec (e.g., "owner/repo:path/to/SKILL.md")
  • schedule_id (query): Filter runs by the scheduled agent ID that created them
  • ancestor_run_id (query): Filter runs by ancestor run ID. The referenced run must exist and be accessible to the caller.
  • metadata (query): Filter by exact metadata key/value pairs using object notation (e.g. `metadata[ticket_id]=VIS-238`), combining multiple pairs with AND semantics, up to 5 per request. Returns `feature_not_available` when metadata filtering is not enabled.
  • artifact_type (query): Filter runs by artifact type
  • q (query): Fuzzy search query across run title, prompt, and skill_spec

GET /agent/run-by-external-reference

Find the run that produced a given external reference URL

Reverse-looks up the agent run that created an EXTERNAL_REFERENCE artifact with the given URL. The URL is matched against the canonical locator stored when the artifact was reported via POST /harness-support/report-artifact with artifact_type EXTERNAL_REFERENCE. Returns 404 when no matching run exists or when the caller lacks access, to avoid leaking run existence.

  • url (query, required): The canonical URL of the external reference artifact to look up.

GET /agent/runs/{runId}

Get run details

Retrieve detailed information about a specific agent run, including the full prompt, session link, and resolved configuration.

  • runId (path, required): The unique identifier of the run

GET /agent/runs/{runId}/timeline

Get run timeline

Retrieve chronological setup and lifecycle timeline events for an agent run.

  • runId (path, required): The unique identifier of the run

GET /agent/runs/{runId}/conversation

Get normalized run conversation

Retrieve a run's conversation as a normalized sequence of messages and nested steps. The response groups text, tool activity, and event content into structured blocks.

  • runId (path, required): The unique identifier of the run

POST /agent/runs/{runId}/cancel

Cancel a run

Cancel an agent run that is currently queued or in progress; once cancelled, the run transitions to a cancelled state. Not all runs can be cancelled: a run already in a terminal state, in PENDING, or of an unsupported type (self-hosted, local, GitHub Action) is rejected instead — see the error responses below for each case.

  • runId (path, required): The unique identifier of the run to cancel

POST /agent/runs/{runId}/followups

Submit a follow-up message for a run

Send a follow-up message to an existing run. The server transparently routes the message based on the current state of the run (still queued, actively running, or ended). A 200 response means the follow-up was accepted; updated run state can be observed via `GET /agent/runs/{runId}`.

  • runId (path, required): The unique identifier of the run

GET /agent/conversations/{conversation_id}

Get normalized conversation

Retrieve a conversation directly by conversation ID in Warp's normalized task/message format.

  • conversation_id (path, required): The unique identifier of the conversation

POST /agent/schedules

Create a scheduled agent

Create a new scheduled agent that runs on a cron schedule. The agent will be triggered automatically based on the cron expression.

GET /agent/schedules

List scheduled agents

Retrieve all scheduled agents accessible to the authenticated user. Results are sorted alphabetically by name.

GET /agent/schedules/{scheduleId}

Get scheduled agent details

Retrieve detailed information about a specific scheduled agent, including its configuration, history, and next scheduled run time.

  • scheduleId (path, required): The unique identifier of the scheduled agent

PUT /agent/schedules/{scheduleId}

Update a scheduled agent

Update an existing scheduled agent's configuration. All fields except agent_config are required.

  • scheduleId (path, required): The unique identifier of the scheduled agent

DELETE /agent/schedules/{scheduleId}

Delete a scheduled agent

Delete a scheduled agent. This will stop all future scheduled runs.

  • scheduleId (path, required): The unique identifier of the scheduled agent

POST /agent/schedules/{scheduleId}/pause

Pause a scheduled agent

Pause a scheduled agent. The agent will not run until resumed.

  • scheduleId (path, required): The unique identifier of the scheduled agent

POST /agent/schedules/{scheduleId}/resume

Resume a scheduled agent

Resume a paused scheduled agent. The agent will start running according to its cron schedule.

  • scheduleId (path, required): The unique identifier of the scheduled agent

GET /agent/environments

List environments

Retrieve cloud environments accessible to the authenticated principal. Returns environments the caller owns, has been granted guest access to, or has accessed via link sharing.

  • sort_by (query): Sort order for the returned environments. - `name`: alphabetical by environment name - `last_updated`: most recently updated first (default)

GET /agent/models

List available models

Retrieve the list of LLM models available to the authenticated user for agent runs. The response includes which model is the default, as well as per-model metadata such as provider, cost, and whether the model is currently disabled (and why).

GET /agent/artifacts/{artifactUid}

Get artifact details

Retrieve an artifact by its UUID: a time-limited signed download URL for downloadable file-like artifacts, or the current plan content inline for plan artifacts. Public artifacts can be read without authentication; private artifacts require the caller to be authenticated and authorized.

  • artifactUid (path, required): The unique identifier (UUID) of the artifact

GET /agent/artifacts/{artifactUid}/download

Download an artifact

Redirect to a temporary signed download URL for a downloadable artifact. Public artifacts can be downloaded without authentication; private artifacts require the caller to be authenticated and authorized.

  • artifactUid (path, required): The unique identifier (UUID) of the artifact

PATCH /factory/scorers/{scorer_id}

Update a scorer's definition

Apply a partial update to a scorer's definition; omitted fields are left unchanged, but at least one field must be provided, and the owning factory is immutable. Each update bumps the scorer's version without invalidating any scoring judge already in flight, since judges validate against the definition snapshot taken at dispatch time, and historical scores keep their recorded classification values. Supplying `scope_mode` or `agent_uids` replaces the scorer's scope in full.

  • scorer_id (path, required): The scorer identifier

DELETE /factory/scorers/{scorer_id}

Delete a scorer

Permanently delete a scorer. This is not reversible and it is not an archive: the scorer's scoring attempts, scores, judge reasoning, self-improvement config, and self-improvement triage results go with it, and the scorer stops being readable through this API as soon as the call returns. The underlying rows and the judge-reasoning blobs stored outside the database are destroyed shortly afterwards by the deletion sweep, which removes each blob before the record that references it and retries until both are gone.

  • scorer_id (path, required): The scorer identifier

POST /agent/identities

Create an agent

Create a new agent for the caller's team. Agents can be used as the execution principal for team-owned runs.

GET /agent/identities

List agents

List all agents for the caller's team. Each agent includes an `available` flag indicating whether it is within the team's plan limit and may be used for runs.

POST /factory/scorers

Create a scorer

Create an active run scorer for a factory with either selected-agent or all-agent scope. Creating a scorer does not start scoring. Pass self_improvement_enabled to also turn on self-improvement for the new scorer in the same request; the scorer and its self-improvement config are created atomically, so a failure leaves neither behind.

GET /factory/scorers

List agent scorers

List the scorers owned by the caller's team, including scope agents and aggregate scoring stats. Pass factory_uid to narrow the result to a single factory.

GET /factory/scorers/{scorer_id}/results

List recent results for an scorer

List the scorer's most recent scoring attempts, newest first. A failed attempt carries no classification. Pagination is a keyset cursor over attempted_at with the attempt id as a stable tiebreak.

  • scorer_id (path, required): The scorer identifier
  • limit (query): Maximum number of results to return (1-100, default 50)
  • cursor (query): Opaque cursor returned by a previous list response.

GET /factory/scorers/{scorer_id}/results/reasons

Read judge reasons for a page of scorer results

Read the judge's reasoning for the given runs in one request, so a page of results can show reasons alongside classifications. Reasons are stored outside the database and read per run with bounded concurrency; a run whose reason is missing or unreadable is reported individually so one unavailable reason never fails the request.

  • scorer_id (path, required): The scorer identifier
  • run_id (query, required): Runs to read reasons for. Repeat the parameter once per run; at most 100 distinct runs (the results page maximum) per request.

GET /factory/scorers/{scorer_id}/metrics/pass-rate

Get a scorer's pass-rate metric over a date range

Returns a period-aligned pass-rate series plus a full-range aggregate for the scorer's dashboard chart, computed directly from every live score in [start_date, end_date) rather than the capped, unfiltered recent-attempts list /results returns. The headline pass_rate and the series describe the same window and denominator, so they cannot disagree. Binning follows the same day/week/month rules and 365-period cap as GET /factory/{uid}/metrics.

  • scorer_id (path, required): The scorer identifier
  • start_date (query): RFC3339 UTC range start, inclusive. Defaults to 30 days before end_date.
  • end_date (query): RFC3339 UTC range end, exclusive. Defaults to now.
  • group_by_period (query): Binning granularity for the series. Defaults to day.

GET /factory/scorers/{scorer_id}/self-improvement-config

Get a scorer's self-improvement config

Retrieve the self-improvement configuration for a scorer: whether self-improvement is enabled for it.

  • scorer_id (path, required): The scorer identifier

PUT /factory/scorers/{scorer_id}/self-improvement-config

Enable self-improvement for a scorer

Turn self-improvement on for a scorer, marking its config active. Self-improvement acts on runs the scorer itself already scores as failing (scored label's score below the scorer's threshold); this endpoint carries no classification data of its own.

  • scorer_id (path, required): The scorer identifier

DELETE /factory/scorers/{scorer_id}/self-improvement-config

Disable self-improvement for a scorer

Turn self-improvement off for a scorer by removing its config.

  • scorer_id (path, required): The scorer identifier

POST /factory/run-scoring/dispatches

Manually dispatch scoring for one or more runs

Immediately dispatch judge runs for the named (run, scorer) pairs, bypassing the two-hour idle cool-down, automatic sampling, and the scorer-created-after-run gate, since the caller selected the exact run — even a 0% sampling rate still accepts a manual dispatch. The full target set is validated before dispatch begins, and each pair's outcome (dispatched, already in flight, or failed) is reported independently.

GET /factory/runs/{run_id}/scores

Read a run's current scores

List the current live attempt for each evaluation that has attempted the given run, most recent attempt first. Excludes a deleted evaluation's data. Requires only view access to the run, since reading scores is part of viewing the run.

  • run_id (path, required): The run identifier

POST /agent/runs/{runId}/scores

Report evaluation scores for a run

Report one or more evaluation verdicts for a run, called by the judge run dispatched to score it and authenticated with that judge run's API key. Each verdict is processed independently — the response reports per-verdict acceptance, and a rejected verdict does not block the others — so reporting a subset of the run's evaluations is valid.

  • runId (path, required): The run being scored

GET /agent/identities/{uid}

Retrieve an agent

Retrieve a single agent by its unique identifier. The response includes an `available` flag indicating whether the agent is within the team's plan limit and may be used for runs.

  • uid (path, required): The unique identifier of the agent

PUT /agent/identities/{uid}

Update an agent

Update an existing agent.

  • uid (path, required): The unique identifier of the agent

DELETE /agent/identities/{uid}

Delete an agent

Delete an agent. All API keys associated with the agent are deleted atomically.

  • uid (path, required): The unique identifier of the agent