---
title: "Get the factory's most expensive PRs"
method: GET
path: "/factory/{uid}/costs/per-pr/top"
tags: ["Factories", "Metrics"]
---

# Get the factory's most expensive PRs

`GET /factory/{uid}/costs/per-pr/top`

## Request

- Base URL: `https://app.warp.dev/api/v1`
- URL: `https://app.warp.dev/api/v1/factory/{uid}/costs/per-pr/top`
- Auth: HTTP bearer

The costliest PRs first seen in the range, most expensive first, with
per-component cost breakdowns, attribution from each PR's earliest
live root run, and PR detail collected from code-forge webhooks.
PRs that predate webhook PR-fact collection still appear, with null
detail fields.

## Path parameters

- `uid` string, required

## Query parameters

- `start_date` string, date-time
- `end_date` string, date-time
- `limit` integer

## Response `200`

The factory's most expensive PRs for the requested range

- FactoryTopPRsResponse: Fields every factory-scoped metrics response carries alongside its data, so responses from several factories can be combined or told apart.
  - `as_of` string, date-time, required: The time the data is current as of. Data can lag live activity by a few minutes.
  - `team_uid` string, required: Public UID of the team that owns the factory.
  - `factory_uid` string, required: Public UID of the factory the response is scoped to.
  - `data` FactoryTopPR[], required: Most expensive first.
    - `url` string, required: Canonical PR URL; the listing's identity.
    - `dollars` FactoryDollarsBreakdown, required: US dollars the owning team was billed, split by source component: compute (run execution), platform, and inference (recorded per conversation and counted once per distinct conversation). total is the sum of the three. Each charge contributes its recorded billed amount; charges recorded before billed amounts were tracked fall back to an estimated cost.
      - `compute` number, double, required
      - `platform` number, double, required
      - `inference` number, double, required
      - `total` number, double, required
    - `creator` RunCreatorInfo
      - `type` 'user' | 'service_account': Type of the creator principal
      - `uid` string: Unique identifier of the creator
      - `display_name` string: Display name of the creator
      - `email` string: Email address of the creator
      - `photo_url` string, uri: URL to the creator's photo
    - `source` string, nullable: Public source name of the run that kicked off the PR (e.g. GITHUB_WEBHOOK, SLACK, API). New values may appear over time.
    - `requested_model_id` string, nullable: Model the kicking-off run was configured with; null means the server default was used.
    - `models` FactoryTopPRModel[], required: Models recorded in the PR's run trees' conversation usage metadata, most expensive first, each with its token-weighted share of the PR's inference dollars. Shares sum approximately to dollars.inference: conversations without per-model token counts contribute inference dollars but no shares. Empty when no per-model usage was recorded.
      - `model_id` string, required
      - `inference_dollars` number, double, required: The model's token-weighted share of the PR's inference dollars. Inference only; compute and platform costs have no model attribution.
    - `provider` 'GITHUB' | 'GITLAB' | 'AZURE_DEVOPS': The concrete source-control provider hosting a repository.
    - `repo_full_name` string, nullable: The repository as owner/repo.
    - `pr_number` integer, nullable: The provider's PR number.
    - `title` string, nullable: The PR title; null until the code host reports it.
    - `author_login` string, nullable: The code-host login that opened the PR.
    - `factory_uid` string, nullable: Public UID of the factory whose runs produced the PR.
    - `team_uid` string, nullable: Public UID of the team that owns the factory.
    - `state` 'open' | 'draft' | 'merged' | 'closed': The pull request's current state.
    - `opened_at` string, date-time, nullable: When the PR was opened; null when Warp did not see it being opened.
    - `first_human_review_at` string, date-time, nullable: The first review by a person; null when none was observed.
    - `merged_at` string, date-time, nullable: When the PR was merged; null while it is not merged.
    - `closed_at` string, date-time, nullable: When the PR was closed, by merging or otherwise; null while it is open or when the code host did not report it.
    - `updated_at` string, date-time, nullable: When the PR itself last changed.
    - `additions` integer, nullable: Lines added; null until the code host reports it.
    - `deletions` integer, nullable: Lines deleted; null until the code host reports it.
    - `changed_files` integer, nullable: Files changed; null until the code host reports it.
    - `num_commits` integer, nullable: Commits on the PR; null until the code host reports it.
    - `human_interactions` FactoryPullRequestHumanInteractions: Actions people took on the pull request, counted by type. A person is not a bot and not an app acting on a person's behalf. A review that was later dismissed is not counted. A follow-up a person sent to the run that produced the PR counts when it came through Slack, Linear, Jira, Teams, the web app, or the API; messages relayed through the Factory MCP or a local agent do not count, and a follow-up sent as a GitHub comment counts once, as a PR comment or review. total is the sum of every type.
      - `opened` integer, required: A person opened the PR.
      - `code_push` integer, required: A person pushed code to the PR. Pushes are attributed to whoever triggered them, so the code host's "update branch" button and rebases count.
      - `review_approved` integer, required: A person approved the PR.
      - `review_changes_requested` integer, required: A person requested changes.
      - `review_commented` integer, required: A person reviewed with comments only.
      - `comment` integer, required: A person commented on the PR.
      - `review_comment` integer, required: A person commented on a line of code.
      - `pr_action` integer, required: Other PR actions by a person, such as closed, reopened, or marked ready.
      - `follow_up_message` integer, required: A person sent a follow-up message to the run that produced the PR.
      - `total` integer, required: The sum of every interaction type.
    - `human_code_change` boolean, nullable: Whether a person changed the PR's code: any opened or code_push interaction. False only means autonomous when history_complete is true.
    - `history_complete` boolean, nullable: Whether Warp observed the PR from the moment it was opened. When false, interactions before Warp started watching the PR are missing from the counts.
    - `runs` FactoryPullRequestRun[], nullable: The factory's runs that produced the PR, earliest first.
      - `run_id` string, required
      - `root_run_id` string, required: The top-level run of the run's tree; equals run_id for a top-level run.
      - `created_at` string, date-time, required
    - `kickoff_at` string, date-time, nullable: When the earliest run that produced the PR was created.
    - `cycle_time` FactoryPullRequestCycleTime: The pull request's pipeline-stage durations in seconds. Each stage is null when either end was not observed, and never negative. Kickoff is when the earliest run that produced the PR was created; first review is the first review by a person.
      - `kickoff_to_pr` number, double, nullable, required
      - `pr_to_first_review` number, double, nullable, required
      - `first_review_to_merge` number, double, nullable, required
      - `kickoff_to_merge` number, double, nullable, required

## Other responses

- `400`: Invalid date range or limit
- `401`: Authentication required
- `403`: Factory access is not enabled for the authenticated principal
- `404`: Factory not found or not accessible
- `429`: The caller has used up the request budget shared by the factory metrics endpoints. Wait the number of seconds in Retry-After, then retry.
- `500`: Internal server error

## Changes

- **2026-10-21** `7ee3ba55debc`: 2 info
  - api tag `factory-metrics` added
  - api tag `factory` removed
- **2026-10-19** `2c45dcc0a13e`: 5 breaking, 5 info
  - added `#/components/schemas/FactoryPullRequestCycleTime, subschema #2` to the `allOf[subschema #2]/data/items/cycle_time` response property `oneOf` list for the response status `200`
  - added `#/components/schemas/FactoryPullRequestHumanInteractions, subschema #2` to the `allOf[subschema #2]/data/items/human_interactions` response property `oneOf` list for the response status `200`
  - added `#/components/schemas/FactoryPullRequestState, subschema #2` to the `allOf[subschema #2]/data/items/state` response property `oneOf` list for the response status `200`
  - added `#/components/schemas/FactoryRepositoryCodeForge, subschema #2` to the `allOf[subschema #2]/data/items/provider` response property `oneOf` list for the response status `200`
  - …6 more
- **2026-10-15** `f4630aae17ba`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/warp/apis/oz-agent-api/changes/factory/:uid/costs/per-pr/top/get.md)

---

[API](https://skmtc.dev/warp/apis/oz-agent-api.md) - [All operations](https://skmtc.dev/warp/apis/oz-agent-api/llms.txt) - [OpenAPI document](https://skmtc.dev/warp/apis/oz-agent-api/revisions/4b5d145669be?raw)
