bubblio-dev Agent Keys API

Managed agent keys — minted by the platform's server for its signed-in users.

Operations 4

POST /v1/agent-keys Mint a managed agent key #
GET /v1/agent-keys List this account's managed keys #
DELETE /v1/agent-keys/{keyId} Revoke a managed key #
POST /v1/agent-keys/connect-grant Forward a just-minted key into a waiting connect grant (#38) #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/bubblio-dev:bubblio-dev-agent-keys-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

bubblio-dev-agent-keys-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Bubblio Dev Agent Keys API
  version: 1.0.0
  contact:
    email: bubblio@andresio.com
  description: 'Operations tagged agent-keys across 2 of this provider''s published API definitions: openapi.yaml, bubblio-dev-openapi.yaml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.bubblio.dev
  description: Hosted production platform — the canonical host.
- url: https://andresomar95--bubblio-api-serve.modal.run
  description: The same deployment under its infrastructure name (the SDK's default BUBBLIO_API_URL).
tags:
- name: agent-keys
  description: Managed agent keys — minted by the platform's server for its signed-in users.
paths:
  /v1/agent-keys:
    post:
      tags:
      - agent-keys
      summary: Mint a managed agent key
      description: 'Called by the PLATFORM''S SERVER (the SDK''s `mintAgentKey` / `createAgentKeyRoute`).

        `ctx` is the platform-signed user-context JWT — Bubblio checks WELL-FORMEDNESS ONLY

        (three dot-separated base64url segments) and can neither verify nor forge it (it

        stores only a hash of the API key the signing secret derives from). Custody rules:

        the raw `bak_` key is returned ONCE and stored SHA-256; the ctx is encrypted at

        rest immediately and never logged.


        `max_active_per_user` (#49) is the opt-in per-user active-key quota, enforced

        INSIDE the mint: a pre-check refuses the common at-cap case before any write, and

        the post-insert count is the race-proof enforcement — concurrent mints can fail

        CLOSED (a spurious 409 a retry resolves) but can never overshoot the cap, PROVIDED

        every concurrent mint for that user carries the cap (the SDK''s

        `createAgentKeyRoute` stamps it on every mint, grant path included). An UNCAPPED

        rival mint commits outside the enforcement and is never rolled back, so mixing

        capped and uncapped mints for one user can exceed the number the capped ones asked

        for.'
      operationId: mintAgentKey
      security:
      - apiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - ctx
              properties:
                ctx:
                  type: string
                  maxLength: 4096
                  pattern: ^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$
                  description: The platform-signed user-context JWT (shape-checked only).
                label:
                  type: string
                  maxLength: 60
                externalUserId:
                  type: string
                  maxLength: 128
                userHint:
                  type: string
                  maxLength: 80
                  description: Display-only, e.g. a masked email.
                max_active_per_user:
                  type: integer
                  minimum: 1
                  maximum: 1000
                  description: Requires externalUserId — the cap counts one user's active keys.
      responses:
        '201':
          description: The raw key — returned exactly once, never retrievable again.
          content:
            application/json:
              schema:
                type: object
                required:
                - key
                - id
                properties:
                  key:
                    type: string
                    description: bak_…
                  id:
                    type: string
                    format: uuid
        '400':
          $ref: '#/components/responses/CalmBadRequest'
        '409':
          description: '`code: key_cap_reached` — the user is at the requested cap (revoke a key or

            raise the cap); or `code: migration_pending` while the keys table lags.

            '
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalmError'
        '429':
          description: The per-customer mint ceiling (default 30/hour).
          headers:
            Retry-After:
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalmError'
    get:
      tags:
      - agent-keys
      summary: List this account's managed keys
      description: Display metadata ONLY — never hashes, never ctx, never the key.
      operationId: listAgentKeys
      security:
      - apiKey: []
      parameters:
      - name: externalUserId
        in: query
        schema:
          type: string
        description: Filter to one of the platform's users.
      responses:
        '200':
          description: 'The keys (or `migrationPending: true` with an empty list while the table lags).'
          content:
            application/json:
              schema:
                type: object
                required:
                - keys
                properties:
                  keys:
                    type: array
                    items:
                      $ref: '#/components/schemas/AgentKeyInfo'
                  migrationPending:
                    type: boolean
    servers:
    - url: https://api.bubblio.dev
      description: Hosted production platform — the canonical host.
    - url: https://andresomar95--bubblio-api-serve.modal.run
      description: The same deployment under its infrastructure name (the SDK's default BUBBLIO_API_URL).
  /v1/agent-keys/{keyId}:
    delete:
      tags:
      - agent-keys
      summary: Revoke a managed key
      description: 'Idempotent and customer-scoped; the row is kept (the quote path needs `revoked_at`

        to refuse honestly), and the FIRST revoke''s timestamp survives repeats. In-flight

        quotes made with the key refuse to confirm from this moment.'
      operationId: revokeAgentKey
      security:
      - apiKey: []
      parameters:
      - name: keyId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Revoked (idempotently).
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  revoked:
                    type: string
        '404':
          description: Not this customer's key (uniform with malformed ids).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalmError'
    servers:
    - url: https://api.bubblio.dev
      description: Hosted production platform — the canonical host.
    - url: https://andresomar95--bubblio-api-serve.modal.run
      description: The same deployment under its infrastructure name (the SDK's default BUBBLIO_API_URL).
  /v1/agent-keys/connect-grant:
    post:
      tags:
      - agent-keys
      summary: Forward a just-minted key into a waiting connect grant (#38)
      description: 'The phone-connect flow''s server half: the platform''s key route calls this INSTEAD

        of returning a fresh key to the browser. The raw key must hash to the named row

        (proof the caller holds the very key it is connecting); the write stamps the

        waiting quote and its approval, then flips the grant LAST, winner-only. The key

        rests encrypted for its ONE delivery through the agent''s poll. Idempotent for a

        retried POST of the SAME key; a different key against a granted grant is a 409

        (`code: conflict`) — one grant, one key, forever.'
      operationId: postConnectGrant
      security:
      - apiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - grantId
              - key
              - id
              properties:
                grantId:
                  type: string
                  pattern: ^g_[a-f0-9]{32}$
                key:
                  type: string
                  description: The raw bak_ key the mint just returned.
                id:
                  type: string
                  format: uuid
                  description: The minted key's row id.
      responses:
        '200':
          description: 'Connected (with `already: true` on an idempotent repeat).'
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  already:
                    type: boolean
        '400':
          $ref: '#/components/responses/CalmBadRequest'
        '404':
          description: 'Uniform miss: unknown, foreign, or malformed grant.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalmError'
        '409':
          description: 'Window closed (`code: expired`/`window_closed`), a different key already connected (`code: conflict`), or migration lag.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CalmError'
    servers:
    - url: https://api.bubblio.dev
      description: Hosted production platform — the canonical host.
    - url: https://andresomar95--bubblio-api-serve.modal.run
      description: The same deployment under its infrastructure name (the SDK's default BUBBLIO_API_URL).
components:
  schemas:
    AgentKeyInfo:
      type: object
      description: One managed key as the list reports it — never the key, a hash, or the ctx.
      properties:
        id:
          type: string
          format: uuid
        label:
          type:
          - string
          - 'null'
        externalUserId:
          type:
          - string
          - 'null'
        userHint:
          type:
          - string
          - 'null'
        createdAt:
          type: string
          format: date-time
        lastUsedAt:
          type:
          - string
          - 'null'
          format: date-time
        revokedAt:
          type:
          - string
          - 'null'
          format: date-time
    CalmError:
      type: object
      required:
      - error
      properties:
        error:
          type: string
        code:
          type: string
          description: Machine-readable refusal code, present where documented — branch on this, never on message text.
  responses:
    CalmBadRequest:
      description: One calm sentence naming the malformed field.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CalmError'
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: The platform's Bubblio API key (`bbl_…`). Server-side only.
    consentToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: The human's passkey-session token from `POST /approvals/session`.
x-refined-from:
- openapi.yaml
- bubblio-dev-openapi.yaml