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

# Claim a work item

> Records a lease for the named host and returns an item key for it. The body must carry `runnerProtocol`, at or above the gateway's minimum, or the claim is refused with `runner_upgrade_required` (426) and no lease is recorded. A runner key that is not yet bound to a host key binds to the one in `hostKey` when the claim is signed by it; see the signature headers. A live lease held by another key is refused: `claim_not_held` (403) when it carries the same `host` name, `work_item_claimed` (409) otherwise. A claim by the key holding the lease extends it, keeping the same lease id, whatever `host` it sends. The answer names the `repositories` the build checks out, each with the branch it works on and the primary first, and the primary's `branch`. A claim the build cannot own is refused and recorded as a lease already released as failed, which uses up the build request or amend trigger behind it: `pull_request_from_fork`, `pull_request_on_default_branch`, `pull_request_ambiguous` and `pull_request_repository_not_connected` and `repository_not_reachable` (422), and `branch_claimed_elsewhere` (409). Each names the repository it is about in `repository`. A runner below protocol 16 that claims an item in a factory with more than one connected repository is refused with `runner_protocol_too_old` (426), no lease is recorded, so the request stays available to a newer runner. On a gateway that holds GitHub App keys the answer also carries `commitAuthor`, the App's bot account, and `coAuthor` when the member who asked for the build signed in with GitHub; the runner authors the build's commits as the first and credits the second.



## OpenAPI

````yaml /openapi.yaml post /v1/work-items/{workItemId}/claim
openapi: 3.0.3
info:
  contact:
    email: hello@outerlayer.ai
    url: https://www.outerlayer.ai
  description: >-
    The OuterLayer Gateway API lets you ingest coding-agent sessions and record
    evidence of work programmatically.


    Most teams reach it through the `outerlayer` CLI, which calls it for them.

    Call it directly to build your own integration or to automate what the
    dashboard does.


    Versioning: every endpoint is prefixed with `/v1/`. Breaking changes ship
    under a new version prefix (`/v2/`, etc.) with a 90-day-minimum deprecation
    window; anything additive lands on the current prefix.


    Vocabulary: the dashboard calls this API's `app` a **factory** — the unit
    that owns a set of repositories, the agent sessions worked on them, and the
    evidence they produce. They are the same entity. The API keeps `app` in its
    paths, headers, and field names because those are a published contract; only
    the product surface was renamed.
  title: OuterLayer Gateway API
  version: '1.0'
servers:
  - description: Production (OuterLayer Cloud)
    url: https://api.outerlayer.ai
  - description: Local dev server (self-hosted gateway)
    url: http://localhost:9418
security:
  - AppId: []
    BearerAuth: []
tags:
  - description: >-
      What a CLI login token can read about its owner without naming a factory,
      such as the factories they can use.
    name: Account
  - description: >-
      Coding-agent session ingest (outerlayer sync) and content-addressed
      session images.
    name: Agents
  - description: >-
      Evidence artifacts (screenshots, recordings, reports, logs) emitted as
      proof of a change and anchored to pull requests.
    name: Artifacts
  - description: >-
      Pass/fail outcomes of checks run in your own CI or compute, anchored to
      pull requests with the run URL as proof.
    name: Emitted Results
  - description: >-
      The acceptance criteria of a work item, recorded as one list. The Criteria
      tab, its count and the item status read that list.
    name: Criteria
  - description: >-
      What any agent found wrong about a change under review or about a rule it
      ran on, recorded on a work item.
    name: Findings
  - description: >-
      Find, file and edit the issue a spec lives in, through OuterLayer, with no
      tracker credential on the caller's side.
    name: Specs
  - description: >-
      Add or remove a source's statement that it is working on an issue or pull
      request, and read what is currently live.
    name: Work Items
  - description: >-
      What the factory's GitHub App installation lets builds do on each
      connected repository, and whether each default branch requires a pull
      request.
    name: Repositories
  - description: >-
      A runner host's heartbeat — its CLI version, slots and last request for
      work — and the factory's list of hosts with a derived status.
    name: Hosts
  - description: Query server feature availability.
    name: Capabilities
  - description: Per-model LLM pricing data. Public, unauthenticated.
    name: Pricing
  - description: >-
      Create, list, and revoke factory API keys. Plaintext returned exactly once
      at creation.
    name: API Keys
  - description: >-
      Factory CRUD — a factory is owned by an organization and is the unit every
      other resource hangs off. Lets a headless agent provision one without the
      dashboard.
    name: Apps
  - description: >-
      Agent-coding session list and full transcript reads, with actor-privacy
      controls for machine keys.
    name: Sessions
  - description: >-
      Per-model token spend and fleet-wide agent behavior tiles, including
      two-window comparisons.
    name: Metrics
  - description: Synced-commit history of the app's `.outerlayer/` context tree.
    name: Context
  - description: >-
      Session→PR attribution: which agent sessions produced which pull requests,
      and what each attributed PR cost.
    name: PRs
  - description: Service health checks.
    name: Health
  - description: >-
      Org member and role administration, authenticated with an org-scoped
      management API key (`olk_…`) minted in the dashboard's settings.
    name: Org Management
  - description: OAuth 2.1 discovery metadata for MCP connector clients.
    name: OAuth
paths:
  /v1/work-items/{workItemId}/claim:
    post:
      tags:
        - Work Items
      summary: Claim a work item
      description: >-
        Records a lease for the named host and returns an item key for it. The
        body must carry `runnerProtocol`, at or above the gateway's minimum, or
        the claim is refused with `runner_upgrade_required` (426) and no lease
        is recorded. A runner key that is not yet bound to a host key binds to
        the one in `hostKey` when the claim is signed by it; see the signature
        headers. A live lease held by another key is refused: `claim_not_held`
        (403) when it carries the same `host` name, `work_item_claimed` (409)
        otherwise. A claim by the key holding the lease extends it, keeping the
        same lease id, whatever `host` it sends. The answer names the
        `repositories` the build checks out, each with the branch it works on
        and the primary first, and the primary's `branch`. A claim the build
        cannot own is refused and recorded as a lease already released as
        failed, which uses up the build request or amend trigger behind it:
        `pull_request_from_fork`, `pull_request_on_default_branch`,
        `pull_request_ambiguous` and `pull_request_repository_not_connected` and
        `repository_not_reachable` (422), and `branch_claimed_elsewhere` (409).
        Each names the repository it is about in `repository`. A runner below
        protocol 16 that claims an item in a factory with more than one
        connected repository is refused with `runner_protocol_too_old` (426), no
        lease is recorded, so the request stays available to a newer runner. On
        a gateway that holds GitHub App keys the answer also carries
        `commitAuthor`, the App's bot account, and `coAuthor` when the member
        who asked for the build signed in with GitHub; the runner authors the
        build's commits as the first and credits the second.
      operationId: claim-work-item
      parameters:
        - in: path
          name: workItemId
          required: true
          schema:
            type: string
        - description: >-
            HTTP Message Signature (RFC 9421) made with the runner key's host
            key: `runner=:<base64>:`.
          in: header
          name: Signature
          required: false
          schema:
            description: >-
              HTTP Message Signature (RFC 9421) made with the runner key's host
              key: `runner=:<base64>:`.
            type: string
        - description: >-
            The signature's covered components and parameters:
            `runner=("@method" "@path" "@query" "content-digest");created=<unix
            seconds>;nonce="<random>";keyid="<host key
            fingerprint>";alg="ed25519"`.
          in: header
          name: Signature-Input
          required: false
          schema:
            description: >-
              The signature's covered components and parameters:
              `runner=("@method" "@path" "@query"
              "content-digest");created=<unix
              seconds>;nonce="<random>";keyid="<host key
              fingerprint>";alg="ed25519"`.
            type: string
        - description: >-
            RFC 9530 digest of the request body, always sent, including for a
            request with none: `sha-256=:<base64>:`.
          in: header
          name: Content-Digest
          required: false
          schema:
            description: >-
              RFC 9530 digest of the request body, always sent, including for a
              request with none: `sha-256=:<base64>:`.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              properties:
                host:
                  maxLength: 255
                  minLength: 1
                  type: string
                hostKey:
                  pattern: ^[A-Za-z0-9_-]{43}$
                  type: string
                kind:
                  enum:
                    - implement
                    - amend
                  type: string
                runnerProtocol:
                  type: integer
                seconds:
                  exclusiveMinimum: true
                  maximum: 2147483647
                  minimum: 0
                  type: integer
              required:
                - host
                - kind
              type: object
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  data:
                    properties:
                      branch:
                        description: >-
                          The branch the build works on in the primary
                          repository: the head branch of the item's one open
                          pull request there, or `outerlayer/<factory>/<item
                          number>` when it has none. `null` only for a lease
                          recorded before claims named a branch.
                        nullable: true
                        type: string
                      coAuthor:
                        description: >-
                          The member who asked for the build, for the
                          `Co-authored-by` line the runner adds to each commit.
                          The address is
                          `<github-user-id>+<login>@users.noreply.github.com`,
                          from the GitHub account the member signed in with.
                          Absent when the build has no requester who is a member
                          of the org, when the requester signed in without
                          GitHub, and when `commitAuthor` is absent.
                        properties:
                          email:
                            type: string
                          name:
                            type: string
                        required:
                          - name
                          - email
                        type: object
                      commitAuthor:
                        description: >-
                          The identity every commit the build makes is authored
                          and committed under: the GitHub App's bot account,
                          named `<slug>[bot]`, with the address
                          `<bot-user-id>+<slug>[bot]@users.noreply.github.com`.
                          Absent on a gateway that holds no GitHub App keys.
                        properties:
                          email:
                            type: string
                          name:
                            type: string
                        required:
                          - name
                          - email
                        type: object
                      createdAt:
                        type: string
                      expiresAt:
                        type: string
                      host:
                        type: string
                      id:
                        type: string
                      itemKey:
                        description: >-
                          A signed key, prefixed `olitem_`, that acts only on
                          this work item and only while this lease is live. The
                          runner gives it to the build as its API key. A claim
                          by the lease's own holder returns the same key.
                        type: string
                      kind:
                        enum:
                          - implement
                          - amend
                        type: string
                      repositories:
                        description: >-
                          Every repository the build checks out, the primary
                          first and the others in name order. A factory with one
                          connected repository names one. Each repository has
                          the head branch of the item's one open pull request
                          there, or `outerlayer/<factory>/<item number>` when it
                          has none. Empty when the item names no repository and
                          the factory has connected none.
                        items:
                          properties:
                            branch:
                              description: >-
                                The branch the build works on in this
                                repository.
                              type: string
                            primary:
                              description: >-
                                `true` for the one repository the item itself
                                lives in or, failing that, the first the claim
                                chose.
                              type: boolean
                            repository:
                              description: The repository, as lower-case `owner/repo`.
                              type: string
                          required:
                            - repository
                            - branch
                            - primary
                          type: object
                        type: array
                      unreachable:
                        description: >-
                          Repositories the factory links that this claim leaves
                          out because the GitHub App installation that reaches
                          them is suspended on GitHub. The item's own repository
                          is never listed here: a suspended installation there
                          refuses the claim with `repository_not_reachable`.
                          Always present, as an empty list when nothing was left
                          out.
                        items:
                          properties:
                            reason:
                              description: Why the claim leaves the repository out.
                              enum:
                                - installation_suspended
                              type: string
                            repository:
                              description: The repository, as lower-case `owner/repo`.
                              type: string
                          required:
                            - repository
                            - reason
                          type: object
                        type: array
                    required:
                      - id
                      - host
                      - kind
                      - createdAt
                      - expiresAt
                      - branch
                      - repositories
                      - itemKey
                    type: object
                required:
                  - data
                type: object
          description: >-
            A lease is recorded for this host (new, or the caller's own
            extended).
        '400':
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                    type: object
                required:
                  - error
                type: object
          description: Invalid request parameters (validation failed).
        '401':
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                    type: object
                required:
                  - error
                type: object
          description: >-
            Missing or invalid API key, or a runner key's signature was refused:
            `runner_key_signature_required` (the request carries no signature),
            `runner_key_signature_invalid` (it does not verify against the host
            key the key is bound to, or the body does not match its digest),
            `runner_key_signature_stale` (`created` is more than five minutes
            from the gateway's clock) or `runner_key_signature_replayed` (the
            nonce was accepted in the last five minutes).
        '403':
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                    type: object
                required:
                  - error
                type: object
          description: >-
            A live lease is held by a different runner key that sent the same
            `host` name (`claim_not_held`).
        '404':
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                    type: object
                required:
                  - error
                type: object
          description: No such work item.
        '409':
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                    type: object
                required:
                  - error
                type: object
          description: >-
            A live lease is held by a different worker, the item is withdrawn,
            an implement claim names an item with no unused build request or
            with an open pull request, an amend claim names an item with no
            thread waiting on an agent since the last attempt, or another item's
            live lease already names a branch this claim would name in the same
            repository (`branch_claimed_elsewhere`, recorded as a failed lease,
            with the repository in `repository`).
        '422':
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                    type: object
                required:
                  - error
                type: object
          description: >-
            The build cannot own this claim, and the refusal is recorded as a
            failed lease: an open pull request comes from a fork
            (`pull_request_from_fork`), has the default branch as its head
            (`pull_request_on_default_branch`), the item has two open pull
            requests in one repository (`pull_request_ambiguous`), or one is in
            a repository the factory has not connected
            (`pull_request_repository_not_connected`), or the item's own
            repository sits behind a GitHub App installation that is suspended
            (`repository_not_reachable`). The body names the repository in
            `repository`. The runner does not retry it.
        '426':
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        enum:
                          - runner_upgrade_required
                          - runner_protocol_too_old
                        type: string
                      docs:
                        type: string
                      message:
                        type: string
                      minimum:
                        type: integer
                    required:
                      - code
                      - message
                      - minimum
                      - docs
                    type: object
                required:
                  - error
                type: object
          description: >-
            The request's `runnerProtocol` is missing or below the gateway's
            minimum (`runner_upgrade_required`, no lease is recorded), or the
            factory has more than one connected repository and the protocol is
            below 16 (`runner_protocol_too_old`, no lease is recorded). The body
            names the minimum and links the runner docs' upgrade section.
        '503':
          content:
            application/json:
              schema:
                properties:
                  error:
                    properties:
                      code:
                        type: string
                      message:
                        type: string
                    required:
                      - code
                      - message
                    type: object
                required:
                  - error
                type: object
          description: >-
            The gateway cannot sign an item key (`item_key_unavailable`), so no
            lease is recorded, GitHub was rate limiting or failing while the
            gateway read the item's pull request (`github_unavailable`, no lease
            is recorded, safe to retry), GitHub did not give the App's bot
            account (`github_unavailable`, no lease is recorded), or the store
            did not answer.
components:
  securitySchemes:
    AppId:
      description: Factory id the request is scoped to.
      in: header
      name: X-Outerlayer-App-Id
      type: apiKey
    BearerAuth:
      description: API key (sk_outerlayer_*)
      scheme: bearer
      type: http

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.