Embedding
Mint short-lived tokens on your backend and embed an avatar in any website.
Embed an avatar
Drop an agent onto any page as an iframe — no SDK install required:
<iframe src="https://www.bithuman.ai/embed/A23WJF0199" allow="microphone *; camera *; autoplay *" style="width:100%;height:100vh;border:0"></iframe>
A23WJF0199 is the wise-pup sample avatar (Expression 2). Replace it with your agent code — find it in the
Library or the Deploy & Share dialog.
Warning Keep
microphone *(andcamera *for camera chat) inallow, with the*. The embed redirects to another origin, so a bareallow="microphone"leaves the microphone silently blocked. A restrictivePermissions-Policyon your page blocks it too.
Production: mint a token
POST /v1/embed-tokens/request requestEmbedToken
For per-visitor session tracking and rate limiting, mint a short-lived embed token on your backend (never expose your API secret in frontend code) and append it to the iframe URL.
POST /v1/embed-tokens/request
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | yes | Your agent’s code. This endpoint reads agent_id only: agent_code returns 400. |
fingerprint | string | yes | Stable per-visitor string (any format). Used for per-visitor rate limiting and — if you run your own LLM — sent to your endpoint as the OpenAI user field so you can tell whose call it is (details). Supply one value per end user and reuse it across their visits. |
model | string | no | essence-1, essence-2, expression-1 or expression-2; defaults to the agent’s model. A model the agent does not have returns 409 MODEL_; one outside your plan, 403 PLAN_. |
Every entry of supported_models in the mint response (and in GET /v1/agent/status/{id}) is a model name you can send back as model unchanged.
Call it from your server, so the API secret never reaches the browser; data.token goes on the iframe URL.
The token is a 1-hour, HS256-signed JWT. Mint one per visitor session.
supported_models lists the canonical model families the agent can be
launched as right now (useful for building your own model picker). The
response always includes the model baked into the token (the agent’s own
model when you omit it).
Use the token in the iframe
Pass it as a query string:
curl
curl -X POST https://api.bithuman.ai/v1/embed-tokens/request \
-H "api-secret: $BITHUMAN_API_SECRET" -H "Content-Type: application/json" \
-d '{"agent_id": "A23WJF0199", "fingerprint": "3f9a2c1b8e7d4a6f0b21c4d5e6f70812"}'
Python
import os, requests
resp = requests.post(
"https://api.bithuman.ai/v1/embed-tokens/request",
headers={"api-secret": os.environ["BITHUMAN_API_SECRET"]},
json={
"agent_id": "A23WJF0199",
"fingerprint": "3f9a2c1b8e7d4a6f0b21c4d5e6f70812",
},
)
print(resp.json())
Node
const resp = await fetch("https://api.bithuman.ai/v1/embed-tokens/request", {
method: "POST",
headers: {
"api-secret": process.env.BITHUMAN_API_SECRET,
"Content-Type": "application/json",
},
body: JSON.stringify({
agent_id: "A23WJF0199",
fingerprint: "3f9a2c1b8e7d4a6f0b21c4d5e6f70812",
}),
});
console.log(await resp.json());
Response
{
"status": "success",
"status_code": 200,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"sid": "f3c9...",
"model": "expression-2",
"supported_models": ["expression-2"]
}
}<iframe src="https://www.bithuman.ai/embed/YOUR_AGENT_CODE?token=THE_TOKEN" allow="microphone *; camera *; autoplay *" style="width:100%;height:100vh;border:0"></iframe>Session events
Every conversation on an embed of your agent can POST room.join and chat.push
events, including the text of every message, to a URL on your account. See
session events.
Notes
- The embed token is more constrained than a runtime token — it’s purpose-built for cross-origin iframe authentication.
- WebRTC requires a secure context: serve the embedding page over HTTPS or
the browser will block microphone access (except on
localhost). - The
fingerprintshould be generated once per device and persisted, so per-visitor rate limits track the same visitor across sessions. - An embedded session bills to the agent’s owner at the rates on pricing.
See the interactive API reference for the full request and response schema.