{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/bithuman-ai/json-schema/bithuman-ai-agent-schema.json",
  "title": "Agent",
  "description": "An agent's full record, as returned by `GET /v1/agent/{code}` and `GET /v1/agent/status/{agent_id}`. Every field below is present on every response; fields that do not apply to the agent are `null` rather than absent. `GET /v1/agents` returns a shorter summary — see `AgentListItem`.",
  "x-generated": "2026-10-29",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/bithuman-ai-openapi.yaml#/components/schemas/Agent",
  "type": "object",
  "properties": {
    "code": {
      "type": "string",
      "description": "The agent's short code — the primary identifier used across the platform and the embed/viewer URLs."
    },
    "agent_id": {
      "type": "string",
      "description": "The same value as `code`, under the name the creation response uses."
    },
    "name": {
      "type": [
        "string",
        "null"
      ],
      "description": "The agent's display name. **Generated** from the prompt and portrait during the `persona` step — it cannot be supplied at creation or changed afterwards, and it is `null` until that step completes."
    },
    "description": {
      "type": [
        "string",
        "null"
      ],
      "description": "Generated one-paragraph description of the agent. `null` until the `persona` step completes."
    },
    "language": {
      "type": [
        "string",
        "null"
      ],
      "description": "Detected/assigned language tag, e.g. `en`."
    },
    "gender": {
      "type": [
        "string",
        "null"
      ]
    },
    "model": {
      "type": [
        "string",
        "null"
      ],
      "description": "The model family the agent was created with."
    },
    "supported_models": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Canonical model families this agent can be launched as right now — `essence-1` when its `.imx` exists, and `essence-2` / `expression-2` once their trained per-identity model has been generated. Tier slugs inherit their family and are not listed."
    },
    "model_status": {
      "type": "object",
      "description": "Readiness per model family, keyed by family name. A family is listed here before it is launchable, with the reason it is not — so a caller can tell \"still training\" from \"never requested\". `supported_models` is the `ready` subset of these keys.",
      "additionalProperties": {
        "$ref": "#/$defs/ModelStatusEntry"
      }
    },
    "subject": {
      "type": [
        "string",
        "null"
      ],
      "description": "The subject class the creation classifier recorded for the input, when one was run."
    },
    "system_prompt": {
      "type": [
        "string",
        "null"
      ]
    },
    "image_url": {
      "type": [
        "string",
        "null"
      ],
      "description": "Avatar face image URL."
    },
    "image_path": {
      "type": [
        "string",
        "null"
      ],
      "description": "The stored location of the portrait. Same value as `image_url` for agents whose portrait is public."
    },
    "video_url": {
      "type": [
        "string",
        "null"
      ],
      "description": "The agent's identity video URL — generated internally at creation (10 seconds, authored to loop without a seam). Read-only output; video is never a creation input."
    },
    "video_path": {
      "type": [
        "string",
        "null"
      ],
      "description": "The stored location of the identity video. Same value as `video_url` for agents whose video is public."
    },
    "model_url": {
      "type": [
        "string",
        "null"
      ],
      "description": "Where the model artifact lives. For `essence-1` this is a fetchable URL; for the second-generation families it is an opaque stored handle, **not** a link you can download. Use [the download endpoint](#operation/downloadAgentModel) to get the file itself."
    },
    "model_path": {
      "type": [
        "string",
        "null"
      ],
      "description": "The same stored handle as `model_url`, under its storage-side name."
    },
    "model_hash": {
      "type": [
        "string",
        "null"
      ],
      "description": "Content digest of the model artifact, when one has been recorded."
    },
    "voice_id": {
      "type": [
        "string",
        "null"
      ],
      "description": "Voice identifier."
    },
    "voice_path": {
      "type": [
        "string",
        "null"
      ],
      "description": "The same value as `voice_id`, under its storage-side name."
    },
    "status": {
      "type": "string",
      "description": "Current agent state — `processing`, `generating`, `completed`, `success` (all intermediate), `ready` (terminal success) or `failed` (terminal error). `deleted` for a deleted agent. Stop on `ready` or `failed`; a `final` field is coming."
    },
    "final": {
      "type": "boolean",
      "description": "Coming: not sent yet. When it is, `true` only when `status` is `ready` or `failed` (stop polling) and `false` for every other value, including `success`. Until then, stop on `ready` or `failed`."
    },
    "event_type": {
      "type": [
        "string",
        "null"
      ],
      "description": "Most recent pipeline event, e.g. `persona_created`, `voice_created`, `video_created`, `lip_created`."
    },
    "progress": {
      "type": [
        "number",
        "null"
      ],
      "format": "float",
      "minimum": 0,
      "maximum": 1,
      "description": "Generation progress as a fraction from 0.0 to 1.0."
    },
    "progress_msg": {
      "type": [
        "string",
        "null"
      ],
      "description": "Human-readable progress description."
    },
    "current_step": {
      "type": [
        "string",
        "null"
      ],
      "description": "Current generation step. Known values: `payment`, `persona`, `voice_image`, `video`, `awaiting_face_marking`, `lip_sync`, `done`."
    },
    "error_message": {
      "type": [
        "string",
        "null"
      ],
      "description": "Error details when `status` is `failed`; `null` otherwise."
    },
    "error_type": {
      "type": [
        "string",
        "null"
      ],
      "description": "Which stage the failure came from; `null` when the agent has not failed."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    },
    "dynamics": {
      "type": [
        "object",
        "null"
      ],
      "description": "Gesture configuration and available gestures. `{}` when none are configured."
    }
  },
  "$defs": {
    "ModelStatusEntry": {
      "type": "object",
      "description": "Per-family readiness for one of the agent's models.",
      "properties": {
        "state": {
          "type": "string",
          "description": "`ready` when the agent can be launched as this family, `pending` while it is still being prepared."
        },
        "reason": {
          "type": [
            "string",
            "null"
          ],
          "description": "Why the family is not ready yet; `null` once it is."
        },
        "updated_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "When this family last changed state. `null` for a family that was available from the agent's creation and never transitioned."
        },
        "planes": {
          "type": "object",
          "description": "Readiness for each place the agent runs, present only on the `essence-2` entry of an Essence 2 agent on the current engine. Absent (never `null`) for every other agent and model. `cloud` is the agent's state in the bitHuman cloud; `device` is the state of the copy for your own devices (the Swift, Android and Python SDKs, the CLI and the browser's `render=local`).",
          "properties": {
            "cloud": {
              "type": "string",
              "enum": [
                "pending",
                "ready",
                "failed"
              ],
              "description": "The agent's state in the bitHuman cloud; the same value as `state`."
            },
            "device": {
              "type": "string",
              "enum": [
                "absent",
                "preparing",
                "ready",
                "failed"
              ],
              "description": "`absent` not built yet; `preparing` requested or building; `ready` built and downloadable; `failed` the build stopped."
            }
          }
        }
      }
    }
  }
}