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

# Exchange agent credentials + platform_id for a short-lived JWT

> The Agent SDK calls this on first request to a platform and again on
401 from that platform (token expiry / revocation). Returns a 15-minute
RS256 JWT whose `aud` claim binds it to `platform_id` so the platform
middleware can reject mis-aimed tokens locally.

Empty `scopes` defaults to the agent's full permitted scope set for the
platform.




## OpenAPI

````yaml /openapi.yaml post /api/v1/auth/token
openapi: 3.0.3
info:
  title: MudraID Public Contracts (v1)
  version: 1.0.0
  description: |
    This document defines the **stable public contracts** between MudraID and
    the Python Agent SDK + FastAPI Platform Middleware. Per-service
    administrative and internal endpoints are intentionally omitted here —
    they are documented by each FastAPI service's auto-generated
    `/openapi.json` at runtime and may evolve more freely.

    What lives in *this* file (and may not change without a v1 deprecation
    window):

      - `POST /api/v1/auth/token` — agent → JWT exchange
      - `POST /api/v1/auth/agents/me/platforms` — SDK bootstrap
      - `GET /.well-known/jwks.json` — JWKS for platform middleware
      - `GET /api/v1/platforms/{platform_id}/scopes.yaml` — scope file for middleware
      - JWT claim shape
      - mudraid_scopes.yaml schema
servers:
  - url: https://api.mudraid.ai
    description: Production
security: []
tags:
  - name: agent-sdk
    description: |
      Endpoints called by the Python Agent SDK. These contracts are stable
      v1 — any breaking change requires a deprecation cycle.
  - name: platform-middleware
    description: |
      Endpoints called by the FastAPI Platform Middleware. Stable v1.
paths:
  /api/v1/auth/token:
    post:
      tags:
        - agent-sdk
      summary: Exchange agent credentials + platform_id for a short-lived JWT
      description: |
        The Agent SDK calls this on first request to a platform and again on
        401 from that platform (token expiry / revocation). Returns a 15-minute
        RS256 JWT whose `aud` claim binds it to `platform_id` so the platform
        middleware can reject mis-aimed tokens locally.

        Empty `scopes` defaults to the agent's full permitted scope set for the
        platform.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenRequest'
      responses:
        '200':
          description: JWT issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '401':
          description: >-
            Invalid credentials (unknown api_key_id OR wrong secret — same
            shape, no enumeration)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: >-
            Not permitted (agent inactive, platform access missing, no/invalid
            scopes)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate-limited (per api_key_id)
          headers:
            Retry-After:
              schema:
                type: integer
components:
  schemas:
    TokenRequest:
      type: object
      required:
        - api_key_id
        - secret
        - platform_id
      properties:
        api_key_id:
          type: string
          example: muid_kid_a3f8e9c1d2b4f5e6a7b8c9d0e1f2a3b4
          description: Public agent identifier (41 chars, `muid_kid_` + 32 hex).
        secret:
          type: string
          example: muid_sk_xY9kL2pQ4rT6vN8mZ1cX3bV5nL7kJ9hG
          description: Agent secret, set at registration / rotation. Never logged.
        platform_id:
          type: string
          format: uuid
          description: Target platform's UUID.
        scopes:
          type: array
          items:
            type: string
            example: payments:charge
          default: []
          description: |
            Requested scope subset. Empty array expands to the agent's full
            permitted set for this platform. All requested scopes must
            be a subset of what the agent is permitted on this platform.
        profile:
          type: string
          enum:
            - mudraid-native-jwt
          default: mudraid-native-jwt
          description: |
            Token profile to mint (Phase 1a). Only `mudraid-native-jwt` exists
            today; unknown values are rejected with 422. The issued JWT carries
            the chosen profile as the private claim `mudraid_token_profile`. The
            `oauth-at-jwt` profile is added in Phase 1b.
    TokenResponse:
      type: object
      required:
        - access_token
        - token_type
        - expires_in
      properties:
        access_token:
          type: string
          description: RS256 JWT. See JwtClaims for the payload shape.
        token_type:
          type: string
          enum:
            - Bearer
        expires_in:
          type: integer
          default: 900
          description: Lifetime in seconds (15 minutes).
    Error:
      type: object
      required:
        - detail
      properties:
        detail:
          type: string
          description: Human-readable error message.
        error_code:
          type: string
          description: |
            Machine-readable code (where surfaced). The token endpoint uses
            generic "invalid credentials" for both unknown-id and wrong-secret
            cases to resist enumeration.

````