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

# Bind an agent

> Registers an agent key for the holder authenticated by the partner access
token. Call this once per agent. `publicKey` is optional; omit it for
API-key-only agents.

`agentApiKey` is returned **once**. Store it on your backend.




## OpenAPI

````yaml api-reference/agent-openapi.json POST /v2/auth/agent/keys/partner
openapi: 3.0.3
info:
  title: AIR Agent APIs
  version: 1.1.0
  description: >
    Partner-facing agent APIs for binding a holder's agent, minting a
    short-lived

    agent JWT, listing the holder's credentials, verifying them offchain, and

    minting a merchant checkout JWT.


    **Hosts:** AIR API (bind, keys, session, checkout) and Credential API (list,

    verify). The partner must have agent keys enabled. The AIR Kit partner
    access

    token is a **user-bound** holder session.


    **Typical flow**


    1. Bind once (`POST /v2/auth/agent/keys/partner`). Save `agentApiKey` — it
    is
       returned only on bind and rotate.
    2. Create a session per operation (`POST /v2/auth/agent/session`). The agent
       JWT lasts **15 minutes** and has no refresh token.
    3. List (`GET /v2/credentials`) and/or verify
       (`POST /v2/credentials/verify-by-agent`) with `Authorization: Bearer`.
    4. Optional: mint a checkout JWT (`POST /v2/auth/agent/checkout-session`)
    when
       the bound key includes `commerce.checkout`.

    Partner bind cannot include `wallet.sign`. `openid` is added automatically
    on

    bind. Partner scopes: `credentials.read`, `credentials.verify`,

    `commerce.checkout`. Mutating key routes (bind, rotate, revoke) require

    `x-partner-jwt`. Listing keys and updating a nickname use the AIR Kit
    session

    only.
  contact:
    name: Moca Network
    url: https://moca.network
servers:
  - url: '{AIR_API}'
    description: AIR API (bind, keys, session, checkout)
    variables:
      AIR_API:
        description: Sandbox or Production
        default: https://air.api.sandbox.air3.com
        enum:
          - https://air.api.sandbox.air3.com
          - https://air.api.air3.com
security: []
tags:
  - name: Agent keys
    description: Bind and manage partner-bound agent keys (AIR API).
  - name: Agent session
    description: Mint a short-lived agent JWT (AIR API).
  - name: Agent checkout
    description: Mint a merchant checkout JWT (AIR API).
  - name: Credentials
    description: List and verify the holder's credentials (Credential API).
paths:
  /v2/auth/agent/keys/partner:
    servers:
      - url: '{AIR_API}'
        description: AIR API
        variables:
          AIR_API:
            description: Sandbox or Production
            default: https://air.api.sandbox.air3.com
            enum:
              - https://air.api.sandbox.air3.com
              - https://air.api.air3.com
    parameters:
      - $ref: '#/components/parameters/XPartnerId'
    post:
      tags:
        - Agent keys
      summary: Bind an agent
      description: >
        Registers an agent key for the holder authenticated by the partner
        access

        token. Call this once per agent. `publicKey` is optional; omit it for

        API-key-only agents.


        `agentApiKey` is returned **once**. Store it on your backend.
      operationId: bindPartnerAgentKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BindAgentKeyRequest'
            example:
              scope: credentials.read credentials.verify
              nickname: Shopping agent
      responses:
        '201':
          description: Agent bound. `agentApiKey` is returned only this once.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentKeyCreated'
              example:
                id: 3f1a9c8e-2b7d-4f60-a1c5-e9b8d7f6a4c2
                publicKey: null
                createdAt: '2026-08-19T12:00:00.000Z'
                scope: openid credentials.read credentials.verify
                nickname: Shopping agent
                partnerId: 11111111-2222-4333-8444-555555555555
                agentApiKey: air_ag_<secret>
        '400':
          $ref: '#/components/responses/AirBadRequest'
        '401':
          $ref: '#/components/responses/AirUnauthorized'
        '403':
          $ref: '#/components/responses/AirForbidden'
        '409':
          $ref: '#/components/responses/AirConflict'
      security:
        - PartnerSession: []
          PartnerLoginJwt: []
components:
  parameters:
    XPartnerId:
      name: x-partner-id
      in: header
      required: true
      description: Your Partner ID (UUID) from the Developer Dashboard.
      schema:
        type: string
        format: uuid
  schemas:
    BindAgentKeyRequest:
      type: object
      required:
        - scope
      additionalProperties: false
      properties:
        scope:
          type: string
          description: >
            Space-delimited scopes. `openid` is added automatically. Allowed:

            `credentials.read`, `credentials.verify`, `commerce.checkout`.
            Partner

            bind cannot include `wallet.sign`.
          example: credentials.read credentials.verify
        nickname:
          type: string
          description: |
            Display name (letters, numbers, spaces, hyphens, colons; maximum 32
            characters). Defaults to `Agent YYYY-MM-dd HH:mm:ss` (UTC).
          maxLength: 32
          example: Shopping agent
        publicKey:
          type: string
          description: >
            secp256r1 (P-256) public key, PEM or base64 DER. Required only when
            the

            agent will create sessions with `signedMessage`.
          example: |
            -----BEGIN PUBLIC KEY-----
            MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE…
            -----END PUBLIC KEY-----
    AgentKeyCreated:
      allOf:
        - $ref: '#/components/schemas/AgentKey'
        - type: object
          required:
            - agentApiKey
          properties:
            agentApiKey:
              type: string
              description: Opaque secret with the prefix `air_ag_`. Returned only once.
              example: air_ag_<secret>
    AgentKey:
      type: object
      required:
        - id
        - createdAt
        - scope
      properties:
        id:
          type: string
          format: uuid
        publicKey:
          type: string
          nullable: true
          description: >-
            Masked PEM when a public key was bound; `null` for API-key-only
            agents.
        createdAt:
          type: string
          format: date-time
        scope:
          type: string
          description: Space-delimited scopes granted to the key, including `openid`.
          example: openid credentials.read credentials.verify
        nickname:
          type: string
          nullable: true
        partnerId:
          type: string
          format: uuid
          nullable: true
    AirError:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine-readable AIR API error code.
          enum:
            - INVALID_PARAMETER
            - UNAUTHORIZED
            - INVALID_TOKEN
            - AGENT_KEYS_DISABLED
            - AGENT_SCOPE_DENIED
            - AGENT_SCOPED_SESSION_DISABLED
            - CONFLICT_REQUEST
            - NOT_FOUND
            - INTERNAL_SERVER_ERROR
        message:
          type: string
  responses:
    AirBadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AirError'
          example:
            code: INVALID_PARAMETER
            message: scope is required
    AirUnauthorized:
      description: Missing or invalid partner session, partner JWT, or agent identity
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AirError'
          example:
            code: INVALID_TOKEN
            message: Unknown agent API key
    AirForbidden:
      description: >-
        Agent keys disabled for the partner, scope not a subset of the bound
        key, or `wallet.sign` on a partner route
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AirError'
          example:
            code: AGENT_KEYS_DISABLED
            message: Agent keys are not enabled for this partner
    AirConflict:
      description: Maximum agent keys per user reached
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/AirError'
          example:
            code: CONFLICT_REQUEST
            message: Maximum agent keys per user reached
  securitySchemes:
    PartnerSession:
      type: apiKey
      in: header
      name: x-partner-access-token
      description: >
        The holder's AIR Kit partner access token, from
        `airService.getAccessToken()`.

        Send it with `x-partner-id`.
    PartnerLoginJwt:
      type: apiKey
      in: header
      name: x-partner-jwt
      description: >
        JWT signed with your partner login key (the same key used for the AIR
        Kit

        login `partnerJwt`). Its `partnerId` must match `x-partner-id` and the

        AIR Kit session. Omit `email` unless it is this holder's. Body
        `partnerJwt`

        is accepted as a fallback.

````

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