> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trunk.io/llms.txt
> Use this file to discover all available pages before exploring further.

# List a merge queue's pull requests

> Lists the pull requests in a queue, **most recently enqueued first**.

**This is not queue order** — do not infer position from this list's index. For the order the engine will consider, use `GET /v2/merge-queues/{id}/order`. `state` accepts a comma-separated list of queue-entry states. `readiness.hasImpactedTargets` is omitted on this list read, because resolving it costs a storage lookup per entry; read a single pull request to get it. `sort` and `direction` are not configurable yet: each accepts only the value this list already uses (`createdAt`, `desc`) and rejects anything else with `400`. Neither is ignored, so a client cannot silently receive an ordering it did not ask for.

`concludedAfter` and `concludedBefore` keep pull requests that reached `merged`, `failed` or `cancelled` inside that window, both bounds inclusive — v1's `since`/`until`. That is a fact about the entry's history, not its current state: an entry that failed in the window and was later resubmitted still matches, so pair them with `state` to filter on where it is now.



## OpenAPI

````yaml /openapi-v2.json get /v2/merge-queues/{id}/pull-requests
openapi: 3.1.0
info:
  title: Trunk API
  version: 2.0.0
  description: >-
    The Trunk public API. Every endpoint is scoped to a single organization and
    requires a credential.


    ## Authentication


    For automation, send an API key as `Authorization: Bearer <key>`. An
    organization admin creates one in the Trunk app under **Settings → Developer
    → API Keys**, and chooses the merge-queue permissions it holds. A key with
    no permissions can read merge queues but change nothing. Those permissions
    scope merge queue only: every key can use the Flaky Tests and Dynamic CI
    endpoints, including their writes, whatever permissions it holds.


    A short-lived first-party token in the `x-trunk-token` header is what the
    `trunk` CLI sends after `trunk auth login`.


    A GitHub Actions job can upload impacted targets with no Trunk secret: the
    `trunk-io/login` action exchanges the run's own GitHub credential (its OIDC
    token, or on a pull request from a fork its `GITHUB_TOKEN`) for a
    short-lived first-party token. That token is accepted only by `PUT
    /v2/impacted-targets`, for the run's own repository — and on a fork pull
    request, only for that pull request and its head sha.


    ## Errors


    Every 4xx and 5xx response is a `ErrorResponse`: `{ "error": { "code",
    "message" } }`. Switch on `code`, which is stable; `message` is prose and
    may change at any time.


    **An authorization denial on a read is reported as `404`, not `403`** —
    whether a resource exists must not leak across organizations, so a resource
    in another organization is indistinguishable from one that does not exist.
    `403 INSUFFICIENT_PERMISSIONS` means the credential is valid but is not
    permitted the action (or carries no organization).


    Every response carries an `X-Request-Id` header. Quote it in support
    requests.


    ## Rate limiting


    Requests are limited per organization (currently 100 requests/second).
    Exceeding it returns `429` with `RATE_LIMIT_EXCEEDED`; retry with backoff.
    Note that the limit is enforced at the edge, which does not yet wrap its
    `429` in the `ErrorResponse` envelope described above — treat any `429` as
    rate limiting regardless of body.


    ## Compatibility


    Within v2, Trunk may add: new endpoints, new **optional** response fields,
    new members to any enum (including new `code` values, new queue-entry
    states, and new providers), and new optional request parameters. **Clients
    must tolerate values and fields they do not recognize** rather than failing
    closed — a client that switches exhaustively over an enum will break when a
    member is added. Removals and semantic changes require a new major version.


    ## Provider support


    Merge queues, verification runs and checks are **GitHub-only** today;
    `Check.provider` has a single member for that reason. Impacted-target
    uploads additionally require a `github.com` repository named `owner/repo`.
    The `Provider` enum lists values the repository index can store, not
    surfaces that are fully supported.


    ## Not yet available


    A pull request's numeric **position** in its queue is not exposed, and list
    responses are not ordered by queue position. `GET
    /v2/merge-queues/{id}/order` returns the order the engine will consider pull
    requests in, but an array index there is not a wait: use a pending entry's
    `directlyAhead` rather than counting, and `GET
    /v2/pull-requests/{id}/queue-entry-estimate` for when it is expected to
    merge (on queues that serve estimates). This API delivers no events of its
    own — poll it, or subscribe to [Merge Queue's
    webhooks](https://docs.trunk.io/merge-queue/webhooks). `Idempotency-Key` is
    not yet honored, so a mutation that times out must be reconciled by reading
    the resource back rather than blindly retried.
  contact:
    name: Trunk Support
    url: https://docs.trunk.io
servers:
  - url: https://api.trunk.io
    description: Production
security:
  - apiKey: []
  - trunkToken: []
tags:
  - name: mergeQueues
    x-group: Merge Queues
  - name: pullRequests
    x-group: Pull Requests
  - name: mergeQueueVerificationRuns
    x-group: Verification Runs
  - name: impactedTargets
    x-group: Impacted Targets
  - name: repositories
    x-group: Repositories
  - name: dynamicCi
    x-group: Dynamic CI
  - name: ciJobs
    x-group: CI Jobs
  - name: ciWorkflowRuns
    x-group: CI Workflow Runs
  - name: ciFailureClusters
    x-group: CI Failure Clusters
  - name: testCollections
    x-group: Test Collections
  - name: tests
    x-group: Tests
  - name: testUploads
    x-group: Test Uploads
paths:
  /v2/merge-queues/{id}/pull-requests:
    get:
      tags:
        - mergeQueues
      summary: List a merge queue's pull requests
      description: >-
        Lists the pull requests in a queue, **most recently enqueued first**.


        **This is not queue order** — do not infer position from this list's
        index. For the order the engine will consider, use `GET
        /v2/merge-queues/{id}/order`. `state` accepts a comma-separated list of
        queue-entry states. `readiness.hasImpactedTargets` is omitted on this
        list read, because resolving it costs a storage lookup per entry; read a
        single pull request to get it. `sort` and `direction` are not
        configurable yet: each accepts only the value this list already uses
        (`createdAt`, `desc`) and rejects anything else with `400`. Neither is
        ignored, so a client cannot silently receive an ordering it did not ask
        for.


        `concludedAfter` and `concludedBefore` keep pull requests that reached
        `merged`, `failed` or `cancelled` inside that window, both bounds
        inclusive — v1's `since`/`until`. That is a fact about the entry's
        history, not its current state: an entry that failed in the window and
        was later resubmitted still matches, so pair them with `state` to filter
        on where it is now.
      operationId: mergeQueues.listPullRequests
      parameters:
        - schema:
            type: string
            description: The merge queue's id.
            example: xK9mP2nQ
          required: true
          description: The merge queue's id.
          name: id
          in: path
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
            description: Page size, between 1 and 100.
            example: 25
          required: false
          description: Page size, between 1 and 100.
          name: limit
          in: query
        - schema:
            type: string
            description: >-
              Opaque cursor from a previous response's `nextCursor`. A cursor is
              bound to the operation and filter it was minted for.
            example: AQEKZm9vYmFy
          required: false
          description: >-
            Opaque cursor from a previous response's `nextCursor`. A cursor is
            bound to the operation and filter it was minted for.
          name: cursor
          in: query
        - schema:
            type: boolean
            default: false
            description: >-
              Set true to include `total` in the response. Costs an extra COUNT
              query, so it is off by default.
            example: false
          required: false
          description: >-
            Set true to include `total` in the response. Costs an extra COUNT
            query, so it is off by default.
          name: includeTotal
          in: query
        - schema:
            type: string
            minLength: 1
            description: Comma-separated queue-entry states, e.g. `testing,pending`.
            example: testing,pending
          required: false
          description: Comma-separated queue-entry states, e.g. `testing,pending`.
          name: state
          in: query
        - schema:
            type: string
            minLength: 1
            description: Only pull requests opened by this author.
            example: octocat
          required: false
          description: Only pull requests opened by this author.
          name: author
          in: query
        - schema:
            type: string
            format: date-time
            description: Only entries that concluded at or after this instant (ISO-8601).
            example: '2026-09-01T00:00:00Z'
          required: false
          description: Only entries that concluded at or after this instant (ISO-8601).
          name: concludedAfter
          in: query
        - schema:
            type: string
            format: date-time
            description: Only entries that concluded at or before this instant (ISO-8601).
            example: '2026-09-08T00:00:00Z'
          required: false
          description: Only entries that concluded at or before this instant (ISO-8601).
          name: concludedBefore
          in: query
      responses:
        '200':
          description: A page of pull requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PullRequestList'
        '400':
          description: '`VALIDATION_FAILED` | `INVALID_CURSOR`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                VALIDATION_FAILED:
                  summary: VALIDATION_FAILED
                  value:
                    error:
                      code: VALIDATION_FAILED
                      message: 'Invalid input: expected string, received undefined'
                INVALID_CURSOR:
                  summary: INVALID_CURSOR
                  value:
                    error:
                      code: INVALID_CURSOR
                      message: Invalid or expired cursor.
        '401':
          description: '`AUTHENTICATION_REQUIRED` | `INVALID_TOKEN`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AUTHENTICATION_REQUIRED:
                  summary: AUTHENTICATION_REQUIRED
                  value:
                    error:
                      code: AUTHENTICATION_REQUIRED
                      message: No credential was supplied
                INVALID_TOKEN:
                  summary: INVALID_TOKEN
                  value:
                    error:
                      code: INVALID_TOKEN
                      message: The supplied token failed verification
        '404':
          description: '`MERGE_QUEUE_NOT_FOUND`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                MERGE_QUEUE_NOT_FOUND:
                  summary: MERGE_QUEUE_NOT_FOUND
                  value:
                    error:
                      code: MERGE_QUEUE_NOT_FOUND
                      message: Merge queue not found
        '429':
          description: '`RATE_LIMIT_EXCEEDED`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                RATE_LIMIT_EXCEEDED:
                  summary: RATE_LIMIT_EXCEEDED
                  value:
                    error:
                      code: RATE_LIMIT_EXCEEDED
                      message: Rate limit exceeded; retry after the Retry-After delay
        '500':
          description: '`INTERNAL_ERROR`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                INTERNAL_ERROR:
                  summary: INTERNAL_ERROR
                  value:
                    error:
                      code: INTERNAL_ERROR
                      message: An unexpected error occurred
components:
  schemas:
    PullRequestList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/PullRequest'
          maxItems: 100
        nextCursor:
          type:
            - string
            - 'null'
          description: >-
            Opaque cursor for the next page, or null on the last page. Pass it
            back verbatim as `cursor`; do not construct or inspect one.
          example: AQEKZm9vYmFy
        hasMore:
          type: boolean
          description: True when another page is available.
          example: true
        total:
          type: integer
          description: >-
            Total rows matching the filter. Present only when the request set
            `includeTotal=true`.
          example: 1247
      required:
        - data
        - nextCursor
        - hasMore
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
              description: >-
                Human-readable description of what went wrong. Not stable — do
                not parse.
              example: An unexpected error occurred
          required:
            - code
            - message
      required:
        - error
      description: >-
        The uniform error envelope. Every 4xx and 5xx response in this API has
        this shape.
    PullRequest:
      type: object
      properties:
        id:
          type: string
          example: 0f8fad5b-d9cb-469f-a165-70867728950e
        repositoryId:
          type: string
          example: 7c9e6679-7425-40de-944b-e07fc1f90ae7
        number:
          type: integer
          example: 4901
        title:
          type: string
          example: 'feat: terminate /v2 at the gateway'
        branch:
          type: string
          example: phil/implement-remaining-apis
        sha:
          type: string
          description: >-
            The head commit of the pull request as Trunk last indexed it.
            Compare against a verification run's `testedPullRequests[].sha` to
            tell whether a run tested the current head or a superseded one — a
            mismatch means the branch moved after that run started.
          example: 9c58bf40e5c1a2b3d4e5f60718293a4b5c6d7e8f
        baseBranch:
          type: string
          description: >-
            The branch this pull request targets. Must match the queue's
            `targetBranch` to be enqueueable — `readiness.doesBaseBranchMatch`
            reports that check.
          example: main
        author:
          type: string
          example: octocat
        url:
          type: string
          description: Omitted until the provider sync has populated it.
          example: https://github.com/acme/widgets/pull/4901
        state:
          $ref: '#/components/schemas/PullRequestState'
        isCurrentlySubmittedToQueue:
          type: boolean
          description: True when this pull request's queue entry is non-terminal.
          example: true
        queueEntry:
          $ref: '#/components/schemas/QueueEntry'
        createdAt:
          type: string
          format: date-time
          example: '2026-07-28T10:55:00.000Z'
        htmlUrl:
          type: string
          description: >-
            The pull request's page in the Trunk web app. Absent when the
            repository has no keyed organization.
          example: https://app.trunk.io/acme/pull/4901?repo=1a2b3c4d
        viewerIsAuthor:
          type: boolean
          description: >-
            Whether the authenticated user authored this pull request. Provided
            on the queue pull-request list (`GET
            /merge-queues/{id}/pull-requests`); absent elsewhere and when the
            caller is not a signed-in user.
          example: true
        ci:
          anyOf:
            - $ref: '#/components/schemas/PullRequestCi'
            - type: 'null'
          description: >-
            CI on the head commit. Null when the repository has no CI data.
            Absent from lists, from a lookup of more than one pull request, and
            when the CI read failed.
      required:
        - id
        - repositoryId
        - number
        - title
        - branch
        - sha
        - baseBranch
        - author
        - isCurrentlySubmittedToQueue
        - createdAt
      description: >-
        A pull request Trunk has indexed. There is no nested repository object —
        resolve `repositoryId` with `GET /v2/repositories/{id}`.
    ErrorCode:
      type: string
      enum:
        - AUTHENTICATION_REQUIRED
        - INVALID_TOKEN
        - INSUFFICIENT_PERMISSIONS
        - INTERNAL_ERROR
        - VALIDATION_FAILED
        - NOT_FOUND
        - INVALID_CURSOR
        - MERGE_QUEUE_NOT_FOUND
        - PR_ALREADY_ENQUEUED
        - PR_NOT_ENQUEUEABLE
        - UPSTREAM_ERROR
        - VERIFICATION_RUN_NOT_FOUND
        - PR_NOT_FOUND
        - REPOSITORY_NOT_FOUND
        - IMPACTED_TARGETS_UNSUPPORTED
        - QUEUE_ALREADY_EXISTS
        - QUEUE_HAS_ACTIVE_ENTRIES
        - MODE_CHANGE_IN_PROGRESS
        - PR_NOT_IN_ACTIVE_STATE
        - MERGE_QUEUE_NOT_CREATABLE
        - PR_TESTS_NOT_RESTARTABLE
        - ALLOWED_BOT_SUBMITTERS_FROZEN
        - ESTIMATE_NOT_ENABLED
        - PROVIDER_URL_NOT_FOUND
        - CI_HOST_UNSUPPORTED
        - CI_SCOPE_NOT_FOUND
        - CI_JOB_NOT_FOUND
        - CI_FAILURE_CLUSTER_NOT_FOUND
        - TEST_COLLECTION_NOT_FOUND
        - TEST_NOT_FOUND
        - TEST_UPLOAD_NOT_FOUND
        - TICKETING_NOT_CONFIGURED
        - TICKETING_CREDENTIALS_INVALID
        - TICKETING_SITE_REFUSED
        - TICKET_NOT_FOUND
        - TICKET_LINK_CONFLICT
        - TEST_ALREADY_LINKED
        - TICKET_FIELDS_REJECTED
        - TICKET_CONTENT_UNAVAILABLE
        - TICKETING_CREATE_REFUSED
        - RATE_LIMIT_EXCEEDED
      description: >-
        Stable machine-readable error identifier. Switch on this, never on
        `message`. A shipped code's meaning never changes, but **new codes may
        be added within v2** — treat an unrecognized code as a generic failure
        of its HTTP status rather than failing closed.
      example: INTERNAL_ERROR
    PullRequestState:
      type: string
      enum:
        - open
        - closed
        - merged
      description: >-
        The pull request's state at the provider, as Trunk last indexed it — not
        its queue state, which is `QueueEntry.state`.
      example: open
    QueueEntry:
      type: object
      properties:
        id:
          type: string
          description: >-
            This membership's own id — the merge item, not the pull request. A
            pull request has at most one entry at a time, and an ordinary
            resubmission after a cancellation reuses it. It is not a permanent
            handle on the pull request, though: an entry the queue tears down is
            replaced, so a pull request whose base branch moves it to a
            different queue gets a new id on its next submission.
          example: 6f1c2d3e-4a5b-4c6d-8e9f-0a1b2c3d4e5f
        mergeQueueId:
          type: string
          example: xK9mP2nQ
        state:
          $ref: '#/components/schemas/QueueEntryState'
        stateChangedAt:
          type: string
          format: date-time
          description: >-
            When the entry entered its current `state` — the newest `changedAt`
            in its queue-entry history, or `createdAt` before any transition was
            recorded.
          example: '2026-07-28T11:40:02.000Z'
        priorityValue:
          type: integer
          description: >-
            The entry's numeric priority. 0 means skip the line. A submit body
            carries this OR `priorityName`, never both — but the queue usually
            resolves a submitted name to a value, so a read normally returns
            both and they agree. Either may still be absent on its own: some
            entries carry a value the queue never named, and some a name it
            never resolved.
          example: 100
        priorityName:
          type: string
          description: >-
            The entry's named priority. A submit body carries this OR
            `priorityValue`, never both; a read normally returns both, since the
            queue stores the value it resolved this name to. Either may still be
            absent on its own — do not infer one from the presence of the other.
          example: high
        usedDefaultPriorityName:
          type: string
          description: >-
            The default priority name the engine applied because a submission
            supplied no priority. It records this when the entry enters the
            queue proper, not at submission, and a resubmission does not clear
            it — so an entry can carry the value from an earlier cycle,
            including beside an explicitly-supplied `priorityValue`. A `PATCH
            /v2/pull-requests/{id}/queue-entry` on an already-enqueued entry
            does clear it, because that patch resupplies the priority
            explicitly.
          example: medium
        skipsTheLine:
          type: boolean
          description: >-
            Read-only — derived from `priorityValue === 0`. To set it, send
            `priorityValue: 0`.
          example: false
        allowBatching:
          type: boolean
          description: >-
            Whether this entry may be verified in a batch with others. The
            queue's own `config.allowBatching` is the ceiling — an entry cannot
            batch when the queue forbids it.
          example: true
        direct:
          type: boolean
          description: >-
            Whether the entry was sent directly to the queue past an unmet
            readiness condition (`direct` on submit or on `PATCH
            /v2/pull-requests/{id}/queue-entry`). It did not skip the queue's
            own tests.
          example: false
        verifiedByVerificationRunId:
          type: string
          description: >-
            The verification run whose pass the queue merged this entry on.
            Present only for an entry the queue itself merged straight out of
            `testsPassed`; absent for a force merge, a direct merge, a merge
            made on the provider, or any unmerged entry. For an optimistically
            merged entry it is the successor's run — the one that vouched. Read
            it with `GET /v2/merge-queue-verification-runs/{id}`.
          example: a1b2c3d4-e5f6-4718-9a0b-1c2d3e4f5061
        readiness:
          $ref: '#/components/schemas/Readiness'
        createdAt:
          type: string
          format: date-time
          description: >-
            When this queue entry was created — the pull request's FIRST
            submission. The entry is reused across resubmissions (a cancelled or
            failed pull request submitted again keeps it), so on a pull request
            that took several trips this is not the start of the trip that
            merged. For that, read the oldest `notReady` transition of the trip
            you care about from `GET
            /v2/pull-requests/{id}/queue-entry-history`.
          example: '2026-07-28T11:02:31.000Z'
        updatedAt:
          type: string
          format: date-time
          description: >-
            When the entry row last changed, including an attribute-only write
            (priority, batching) that records no transition. For the last state
            change specifically, read `stateChangedAt`.
          example: '2026-07-28T11:40:02.000Z'
      required:
        - id
        - mergeQueueId
        - state
        - stateChangedAt
        - skipsTheLine
        - allowBatching
        - direct
        - readiness
        - createdAt
        - updatedAt
      description: >-
        A pull request's queue membership. There is at most one ever —
        re-submitting the same pull request mutates this record rather than
        adding another.
    PullRequestCi:
      type: object
      properties:
        headSha:
          type: string
          description: 'The commit the counts describe: the pull request''s head.'
          example: a0de7a77e8d758a346f83ed19209a5a25814bb17
        observedAt:
          type: string
          format: date-time
          example: '2026-09-29T15:12:25.000Z'
        pollAfterSeconds:
          type:
            - integer
            - 'null'
          description: >-
            When to read again: 10 while a job is queued or running, 30 while a
            failure's analysis is on its way, null when nothing on this commit
            will change.
          example: 10
        jobs:
          $ref: '#/components/schemas/CiJobCounts'
        jobsUrl:
          type: string
          description: >-
            The jobs on `headSha`: `GET /v2/ci-jobs`, already filtered.
            Root-relative: resolve it against the host you called.
          example: >-
            /v2/ci-jobs?pullRequestId=0f8fad5b-d9cb-469f-a165-70867728950e&commitSha=a0de7a77e8d758a346f83ed19209a5a25814bb17
        workflowRunsUrl:
          type: string
          description: >-
            The workflow runs on `headSha`: `GET /v2/ci-workflow-runs`, already
            filtered. Root-relative, like `jobsUrl`.
          example: >-
            /v2/ci-workflow-runs?pullRequestId=0f8fad5b-d9cb-469f-a165-70867728950e&commitSha=a0de7a77e8d758a346f83ed19209a5a25814bb17
      required:
        - headSha
        - observedAt
        - pollAfterSeconds
        - jobs
        - jobsUrl
        - workflowRunsUrl
      description: >-
        CI on the pull request's head commit, counted. The lists are one request
        away through `jobsUrl` and `workflowRunsUrl`.
    QueueEntryState:
      type: string
      enum:
        - notReady
        - pending
        - testing
        - testsPassed
        - merged
        - failed
        - cancelled
        - pendingFailure
      description: >-
        Where a pull request sits in its queue's lifecycle.


        | Value | Meaning |

        | --- | --- |

        | `notReady` | Enqueued but not yet eligible to test — a readiness
        condition is unmet (see `QueueEntry.readiness`). |

        | `pending` | Ready and waiting for a test slot, or waiting on an
        earlier entry. |

        | `testing` | A verification run is in flight for this entry. |

        | `testsPassed` | Verification succeeded; waiting to merge. |

        | `merged` | Terminal — merged into the target branch. |

        | `failed` | Terminal — verification or the merge itself failed. |

        | `cancelled` | Terminal — removed from the queue (dequeued, or
        cancelled by the engine). |

        | `pendingFailure` | A failure is expected because an entry ahead
        failed, but this entry has not been re-tested yet. Not terminal: it
        usually returns to `pending` or `testing`. |


        New members may be added within v2.
      example: testing
    Readiness:
      type: object
      properties:
        requiresImpactedTargets:
          type: boolean
          description: >-
            Whether this queue gates the entry on an impacted-target upload.
            When true and `hasImpactedTargets` is false, the entry stays
            `notReady` until CI uploads them (`impactedTargets.upload`).
          example: true
        hasImpactedTargets:
          type: boolean
          description: >-
            Whether impacted targets are uploaded for the entry's commit — for a
            stacked pull request, for every pull request its queued stack covers
            — or not needed (queue mode, or a pull request predating the queue's
            switch to graph mode). ABSENT, not false, in two cases: on a list
            read (which includes a coordinates lookup addressed by more than one
            `number`), and on the response to a write whose post-write lookup
            failed. Absence means 'not answered here' — never 'no targets'.
          example: true
        doesBaseBranchMatch:
          type: boolean
          description: >-
            Whether the pull request's `baseBranch` still equals the queue's
            `targetBranch`. False means it was retargeted after being enqueued
            and cannot merge through this queue.
          example: true
        mergeability:
          $ref: '#/components/schemas/Mergeability'
        mergeabilityDetails:
          $ref: '#/components/schemas/MergeabilityDetails'
      required:
        - requiresImpactedTargets
        - doesBaseBranchMatch
        - mergeability
      description: >-
        Whether the pull request currently satisfies what the queue needs of it.
        Recomputed at read time, NOT a snapshot of the entry's state change — so
        a `merged` entry can report `notMergeable` (its branch has since moved,
        or the provider now says so), which is a fact about the pull request
        today rather than a contradiction of the merge.
    CiJobCounts:
      type: object
      properties:
        total:
          type: integer
          example: 209
        queued:
          type: integer
          example: 0
        running:
          type: integer
          example: 0
        passed:
          type: integer
          example: 110
        failed:
          type: integer
          description: Conclusion `failure` or `timedOut`.
          example: 2
        cancelled:
          type: integer
          example: 0
        skipped:
          type: integer
          example: 97
        abandoned:
          type: integer
          example: 0
      required:
        - total
        - queued
        - running
        - passed
        - failed
        - cancelled
        - skipped
        - abandoned
      description: >-
        The latest attempt of every job, counted. The fields other than `total`
        sum to `total`.
    Mergeability:
      type: string
      enum:
        - mergeable
        - notMergeable
        - inProgress
        - unspecified
      description: >-
        The provider's view of whether the pull request can merge. `unspecified`
        means the provider has not reported one.
      example: mergeable
    MergeabilityDetails:
      type: object
      properties:
        provider:
          type: string
          enum:
            - github
          example: github
        reasons:
          type: array
          items:
            $ref: '#/components/schemas/MergeabilityReason'
          maxItems: 100
          description: The reasons the provider is blocking the merge.
          example:
            - code: reviewRequired
              message: needs 1 more approving review
              have: 0
              need: 1
      required:
        - provider
        - reasons
      description: >-
        Present only when Trunk recorded structured reasons for a `notMergeable`
        verdict — absent otherwise (a repo Trunk has not enriched, or an entry
        past the not-ready window). Absence never means the pull request is
        mergeable; fall back to `mergeability`.
    MergeabilityReason:
      type: object
      properties:
        code:
          $ref: '#/components/schemas/MergeabilityReasonCode'
        message:
          type: string
          description: >-
            Human-readable explanation, for display. Machines should branch on
            `code`, not this string.
          example: needs 1 more approving review
        have:
          type: integer
          minimum: 0
          description: '`reviewRequired` only: approving reviews currently present.'
          example: 0
        need:
          type: integer
          minimum: 0
          description: '`reviewRequired` only: approving reviews required.'
          example: 1
        check:
          type: string
          description: '`awaitingCheck` / `failingCheck` only: the required check''s name.'
          example: build
        ontoPrNumber:
          type: integer
          minimum: 0
          description: >-
            `stackNeedsRebase` only: the number of the pull request this branch
            must be rebased onto.
          example: 3
      required:
        - code
        - message
      description: One structured reason behind a `notMergeable` verdict.
    MergeabilityReasonCode:
      type: string
      enum:
        - conflict
        - behind
        - draft
        - closed
        - pending
        - awaitingCheck
        - failingCheck
        - reviewRequired
        - changesRequested
        - stackNeedsRebase
        - other
      description: >-
        Why the pull request is not mergeable. `behind`, `pending`, and
        `awaitingCheck` resolve without author action (Trunk updates the branch;
        GitHub is still computing; a required check is still running); the rest
        need the author to act. `stackNeedsRebase` means a PR in the middle of
        this GitHub stack was pushed to without rebasing the ones above it.
        `other` is a block Trunk could not attribute to a specific rule.
      example: reviewRequired
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        An API key, sent as `Authorization: Bearer <key>`. An organization admin
        creates one in the Trunk app under **Settings → Developer → API Keys**
        and chooses the merge-queue permissions it holds; a key with none can
        read merge queues but change nothing. Those permissions scope merge
        queue only: every key can use the Flaky Tests and Dynamic CI endpoints,
        including their writes, whatever permissions it holds.
    trunkToken:
      type: apiKey
      in: header
      name: x-trunk-token
      description: >-
        A short-lived first-party token, sent in the `x-trunk-token` header. The
        `trunk` CLI sends one after `trunk auth login`, and the `trunk-io/login`
        action obtains one for a GitHub Actions run.


        **A token from a GitHub Actions run can only upload impacted targets**
        (`PUT /v2/impacted-targets`), for the repository the run belongs to;
        every other endpoint refuses it.

````