bithuman-ai Authentication API

Verify API credentials with `POST /v1/validate`.

Operations 3

POST /v1/validate Validate API secret #
POST /v1/runtime-tokens/mint Mint a scoped runtime token for one agent #
POST /v1/runtime-tokens/request Request a runtime token, or start a cloud avatar #

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/bithuman-ai:bithuman-ai-authentication-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

bithuman-ai-authentication-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Bithuman Ai Authentication API
  version: '1.0'
  contact:
    name: bitHuman Support
    url: https://www.bithuman.ai/discord
  x-logo:
    url: https://docs.bithuman.ai/bithuman-mark.png
  description: 'Operations tagged Authentication across 2 of this provider''s published API definitions: openapi.yaml, bithuman-ai-openapi.yaml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.bithuman.ai
  description: Production
security:
- apiSecret: []
tags:
- name: Authentication
  description: Verify API credentials with `POST /v1/validate`.
paths:
  /v1/validate:
    post:
      operationId: validateApiSecret
      x-codeSamples:
      - lang: shell
        label: cURL
        source: "curl -X POST https://api.bithuman.ai/v1/validate \\\n  -H \"api-secret: $BITHUMAN_API_SECRET\"\n# → {\"valid\": true}\n"
      summary: Validate API secret
      description: 'Verify that your API secret is valid and your account is active.


        Always returns HTTP 200. Inspect the `valid` field in the body

        to determine outcome — invalid or missing credentials yield

        `{"valid": false}` rather than a 401. The secret goes in the

        `api-secret` header; a secret sent as `Authorization: Bearer` is

        not read and also yields `{"valid": false}`.'
      tags:
      - Authentication
      responses:
        '200':
          description: Validation complete (check the `valid` field)
          content:
            application/json:
              schema:
                type: object
                properties:
                  valid:
                    type: boolean
                    example: true
    servers:
    - url: https://api.bithuman.ai
      description: Production
  /v1/runtime-tokens/mint:
    post:
      operationId: mintScopedRuntimeToken
      x-codeSamples:
      - lang: shell
        label: cURL
        source: "curl -X POST https://api.bithuman.ai/v1/runtime-tokens/mint \\\n  -H \"api-secret: $BITHUMAN_API_SECRET\" \\\n  -H \"content-type: application/json\" \\\n  -d '{\"agent_code\": \"A80HVD8577\"}'\n# → {\"scoped_token\": \"...\", \"user_id\": \"...\", \"agent_code\": \"A80HVD8577\", \"expires_at\": 1757280000}\n"
      summary: Mint a scoped runtime token for one agent
      description: 'Exchange your API secret, **server-side**, for a 1-hour token bound to a

        single `agent_code` — so a browser, a phone app or any other client you

        do not fully control never holds your master secret.


        This is the credential the on-device paths accept. It works as

        `Authorization: Bearer ` on

        the model download route, including

        the `?member=` fetch the browser and Android runtimes use.


        The scope is real: presenting the token for a **different** agent code

        answers `404`, exactly like a code you do not own. It expires in one

        hour and is not refreshable — mint another.


        **LiveKit plugin.** With `"scope": "livekit-cloud"` this mints the token

        to pass to `livekit-plugins-bithuman` as `api_secret` instead of your API

        secret. The plugin writes that value into LiveKit room attributes, where

        every participant can read it. This token can only start this agent''s

        cloud avatar session. It is also bound to `room_name` and `livekit_url`

        when you send them, and it bills your account. For another agent, room

        or LiveKit server it answers `403`. It cannot download the model or call

        any other endpoint. See LiveKit integration.


        Call this from your server. Never ship the api-secret this endpoint

        consumes to a client.'
      tags:
      - Authentication
      security:
      - apiSecret: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - agent_code
              properties:
                agent_code:
                  type: string
                  example: A80HVD8577
                  description: The one agent this token may act for.
                scope:
                  type: string
                  enum:
                  - runtime-heartbeat
                  - livekit-cloud
                  default: runtime-heartbeat
                  description: '`livekit-cloud` mints the launch-only token for the LiveKit plugin''s cloud mode. Omit it for the runtime token described above.'
                room_name:
                  type: string
                  description: '`livekit-cloud` only. Binds the token to this LiveKit room.'
                livekit_url:
                  type: string
                  example: wss://your-project.livekit.cloud
                  description: '`livekit-cloud` only. Binds the token to this LiveKit server. It must be the URL the plugin connects to.'
      responses:
        '200':
          description: A scoped token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  scoped_token:
                    type: string
                  user_id:
                    type: string
                  agent_code:
                    type: string
                    example: A80HVD8577
                  expires_at:
                    type: integer
                    description: Unix seconds; one hour from minting.
        '400':
          description: '`agent_code` is required, or `scope` is not one of the two values.'
        '401':
          description: Missing or invalid api-secret.
    servers:
    - url: https://api.bithuman.ai
      description: Production
  /v1/runtime-tokens/request:
    post:
      operationId: requestRuntimeToken
      x-codeSamples:
      - lang: shell
        label: cURL
        source: "curl -X POST https://api.bithuman.ai/v1/runtime-tokens/request \\\n  -H \"api-secret: $BITHUMAN_API_SECRET\" \\\n  -H \"content-type: application/json\" \\\n  -d '{\"agent_code\": \"A80HVD8577\"}'\n# → data.token is a short-lived runtime JWT the SDK uses to run a session\n"
      - lang: shell
        label: cURL (start a cloud avatar)
        source: "curl -X POST https://api.bithuman.ai/v1/runtime-tokens/request \\\n  -H \"api-secret: $BITHUMAN_API_SECRET\" \\\n  -H \"content-type: application/json\" \\\n  -d '{\"mode\": \"gpu\", \"model\": \"essence-2\", \"agent_id\": \"<your agent code>\",\n       \"livekit_url\": \"wss://your-project.livekit.cloud\",\n       \"livekit_token\": \"<avatar join token>\", \"room_name\": \"your-room\"}'\n# → {\"avatar_session_started\": true, \"model\": \"essence-2\", ...}\n"
      summary: Request a runtime token, or start a cloud avatar
      description: 'Exchange your API secret for a short-lived runtime token that authorizes one avatar session. The SDKs call this for you; call it directly when building a custom runtime. Free to call; the session it authorizes is billed per `GET /v1/pricing`.


        **With `mode`, the same endpoint starts a cloud avatar** in your LiveKit room instead: send `mode`, `agent_id` (or `image` for an Expression 1 photo), `livekit_url`, `livekit_token` and `room_name`. The avatar joins as `bithuman-avatar-agent` and lip-syncs the audio you stream to it. The token, audio and latency rules are on Cloud avatar without the plugin.


        **`fingerprint` must be at least 32 characters** when you send it. A shorter one is rejected `400 VALIDATION_ERROR` — a common surprise when a custom runtime passes a short device id. It is optional: leave it out rather than send a short one.'
      tags:
      - Authentication
      security:
      - apiSecret: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              oneOf:
              - title: Runtime token
                type: object
                properties:
                  agent_code:
                    type: string
                    description: Agent code the session runs (attribution + transcript).
                    example: A80HVD8577
                  billing_type:
                    type: string
                    description: Selects the model and pricing schedule for the session.
                    example: agent-voice-chat
                  room_name:
                    type: string
                    description: LiveKit room name to associate the session with its transcript.
                  user_id:
                    type: string
                    description: Optional. Attribute billing to a specific end-user (owner override).
                  fingerprint:
                    type: string
                    minLength: 32
                    description: Optional runtime-instance fingerprint (analytics only). When present it must be **at least 32 characters** — a shorter value is rejected `400 VALIDATION_ERROR` ("String should have at least 32 characters"), so omit the field rather than send a short device id.
                    example: <device-fingerprint>
              - title: Start a cloud avatar
                type: object
                required:
                - mode
                properties:
                  mode:
                    type: string
                    description: '`gpu`. Sending `mode` is what makes this call start an avatar. The older value `cpu` also works and requires `agent_id`.'
                    example: gpu
                  model:
                    type: string
                    description: 'The model to render: essence-1, essence-2, expression-1 or expression-2. Recommended. Left out, the server picks from `mode` and the agent''s models; the response''s `model` says which one launched.'
                    example: essence-2
                  agent_id:
                    type: string
                    description: The agent code. Required unless `image` is sent.
                  image:
                    type: string
                    description: 'Expression 1 only, with no `agent_id`: a portrait as a public http(s) URL (fetched with a plain GET, must answer 200 without authentication), raw base64, or a `data:image/...;base64,` URI. JPEG or PNG, one face, head and shoulders.'
                  livekit_url:
                    type: string
                    description: Your LiveKit server URL.
                    example: wss://your-project.livekit.cloud
                  livekit_token:
                    type: string
                    description: 'The avatar''s LiveKit join token: identity `bithuman-avatar-agent`, kind `agent`, attribute `lk.publish_on_behalf` set to your audio sender''s identity.'
                  room_name:
                    type: string
                    description: The LiveKit room the avatar joins.
                    example: your-room
                  version:
                    type: string
                    description: '`v1` or `v2`, with a bare family name only (`essence` + `v2` = essence-2).'
      responses:
        '200':
          description: 'A runtime token (`data.token` is a short-lived JWT for one session), or, when the body has `mode`, the cloud avatar is starting: a flat object with `avatar_session_started: true` and `model`, the model the session launched as, plus echoes of `mode`, `agent_id` and `image` and your `user_id`. Until 2026-10-19, a Free account''s runtime token and cloud avatar start also carry `plan_notice` and the `X-Bithuman-Plan-Notice` header; show it as sent. From 2026-10-19, a Free account''s cloud avatar start is refused with `403 PLAN_REQUIRED` before anything is launched or billed.'
          headers:
            X-Bithuman-Plan-Notice:
              schema:
                type: string
              description: 'The same text as `plan_notice`: "Free-plan API and SDK access ends on 2026-10-19. Upgrade at https://www.bithuman.ai/pricing to keep it.", or, for a Free account keeping access on top-up credits bought before 2026-09-27, the wording that says so.'
          content:
            application/json:
              schema:
                oneOf:
                - title: Runtime token
                  type: object
                  properties:
                    data:
                      type: object
                      properties:
                        token:
                          type: string
                        transaction_id:
                          type: string
                    status:
                      type: string
                      example: success
                    status_code:
                      type: integer
                      example: 200
                - title: Cloud avatar started
                  type: object
                  properties:
                    avatar_session_started:
                      type: boolean
                      example: true
                    model:
                      type: string
                      example: essence-2
                    mode:
                      type: string
                      example: gpu
                    agent_id:
                      type: string
                      nullable: true
                    image:
                      type: string
                      nullable: true
                    user_id:
                      type: string
                    plan_notice:
                      type: string
                      description: Free accounts, until 2026-10-19.
                    session_id:
                      type: string
                      example: cs_4f1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e
                      description: 'End or read the session by this id: /v1/runtime-sessions/{session_id}.'
              examples:
                runtimeToken:
                  summary: Runtime token
                  value:
                    data:
                      transaction_id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                      token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
                    status: success
                    status_code: 200
                cloudAvatar:
                  summary: Cloud avatar started
                  value:
                    avatar_session_started: true
                    model: essence-2
                    mode: gpu
                    agent_id: <your agent code>
                    image: null
                    user_id: <your user id>
        '400':
          description: '`VALIDATION_ERROR` — a field failed validation. The most common cause is a `fingerprint` shorter than 32 characters; the message names the field and the rule. For a cloud avatar, also: `image` without `agent_id` on a model other than Expression 1, or an Essence 1 session without `livekit_url`, `livekit_token` and `room_name`; nothing is launched or billed.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: VALIDATION_ERROR
                  message: 'Validation failed: fingerprint: String should have at least 32 characters'
                  httpStatus: 400
                status: error
                status_code: 400
        '402':
          description: '`INSUFFICIENT_BALANCE` — not enough credits to start. Top up at the error''s `topup_url`.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: INSUFFICIENT_BALANCE
                  message: Insufficient balance to complete this action. Please add funds to continue.
                  httpStatus: 402
                  topup_url: https://www.bithuman.ai/billing#credits
                status: error
                status_code: 402
        '403':
          description: '`PLAN_REQUIRED` — from 2026-10-19, a Free account''s API secret, or (cloud avatar) a model not in your plan. `CONCURRENCY_LIMIT_REACHED` — a new cloud session would pass your plan''s concurrent sessions; live sessions are never cut off. Both carry `upgrade_url`. `RUNTIME_SUSPENDED` — the key was revoked, or runtime access is suspended (no link; a plan change does not clear it). `ACCOUNT_SUSPENDED` — the balance is too far below zero.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                plan_required:
                  summary: A Free account from 2026-10-19
                  value:
                    error:
                      code: PLAN_REQUIRED
                      message: API and SDK access starts at the Creator plan. Upgrade at https://www.bithuman.ai/pricing to keep using your API secret.
                      httpStatus: 403
                      upgrade_url: https://www.bithuman.ai/pricing
                    status: error
                    status_code: 403
                concurrency_limit_reached:
                  summary: The plan's concurrent cloud sessions
                  value:
                    error:
                      code: CONCURRENCY_LIMIT_REACHED
                      message: Your Creator plan allows 3 cloud avatar sessions at once, and 3 are running (3/3). End a session, or upgrade your plan at https://www.bithuman.ai/pricing.
                      details:
                        tier: Creator
                        cap: 3
                        active: 3
                        upgrade_url: https://www.bithuman.ai/pricing
                      upgrade_url: https://www.bithuman.ai/pricing
                      httpStatus: 403
                    status: error
                    status_code: 403
        '404':
          description: 'Cloud avatar: no agent with this `agent_id` that you can start.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'Cloud avatar: `VALIDATION_ERROR`, the agent cannot be served as the requested model, or its own model is not ready yet. Nothing is launched or billed.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'Cloud avatar: no capacity right now, or a temporary failure. Retry after the `Retry-After` header.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    servers:
    - url: https://api.bithuman.ai
      description: Production
components:
  schemas:
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              example: UNAUTHORIZED
            message:
              type: string
              example: Invalid API secret
            httpStatus:
              type: integer
              example: 401
            upgrade_url:
              type: string
              description: 'On `PLAN_REQUIRED`, `AGENT_LIMIT_REACHED` and `CONCURRENCY_LIMIT_REACHED` (403): where to choose a plan. Send the user there instead of retrying. See [Plan and credit refusals](https://docs.bithuman.ai/api/errors#plan-and-credit-refusals).'
              example: https://www.bithuman.ai/pricing
            topup_url:
              type: string
              description: 'On `INSUFFICIENT_BALANCE` (402): where to top up credits.'
              example: https://www.bithuman.ai/billing#credits
            details:
              type: object
              description: Code-specific fields. `CONCURRENCY_LIMIT_REACHED` sends `tier`, `cap`, `active` and `upgrade_url`.
              additionalProperties: true
        status:
          type: string
          example: error
        status_code:
          type: integer
          example: 401
  securitySchemes:
    apiSecret:
      type: apiKey
      name: api-secret
      in: header
      description: 'Your bitHuman API secret. Get one at

        [www.bithuman.ai/developer/api-keys](https://www.bithuman.ai/developer/api-keys).

        '
    bearerApiSecret:
      type: http
      scheme: bearer
      description: 'The same API secret, sent as `Authorization: Bearer <api-secret>`. Self-

        hosted runtimes send it this way; the classic `api-secret` header works

        on the same routes.

        '
x-refined-from:
- openapi.yaml
- bithuman-ai-openapi.yaml
x-tagGroups:
- name: Get started
  tags:
  - overview
  - quickstart
  - auth-guide
  - models
  - pricing
- name: Core concepts
  tags:
  - avatars-imx
  - audio-streaming
  - agent-lifecycle
- name: SDKs
  tags:
  - sdk-python
  - sdk-swift
  - cli
- name: Guides
  tags:
  - local-mode
  - building-avatars
- name: Deployment
  tags:
  - deploy-livekit
  - deploy-self-hosted
  - deploy-embed
- name: API reference
  tags:
  - Authentication
  - Agent Generation
  - Agent Management
  - Agent Context
  - Files
  - Dynamics
  - Embedding
  - Video
  - Billing
  - Account
  - Self-hosting
  - API secrets
  - Providers
  - Runtime sessions
  - Knowledge
  - Realtime
  - Status
  - Webhooks
- name: Resources
  tags:
  - community
  - changelog
  - support