Embed agents
Put a live Buda agent in front of your users — hosted iframe URLs or native embed tokens, without ever shipping your API key.
Give your users a real agent without exposing your secret. Your backend mints a short-lived embed credential scoped to one session and one external user; the frontend talks to Buda with that credential only. Your sk_ API key never leaves your server.
There are two flavors:
- iframe URL (
/embed-urls) — a ready-made, Buda-hosted chat UI you drop into an<iframe>. - Native token (
/embed-sessions) — a short-lived token your own UI (mobile app, mini program, extension) uses to call the embed JSON endpoints.
Both are created server-side with your API key. Both expire.
iframe vs native token
iframe URL (/embed-urls) | Native token (/embed-sessions) | |
|---|---|---|
| You get | A full embedUrl to use as iframe src | A token + the embed API URLs |
| UI | Buda-hosted chat page | You build the chat UI |
| Best for | Websites, portals, admin panels | Mobile apps, mini programs, extensions |
| Frontend calls | None (the hosted page handles it) | /api/v1/embed/chat-sessions/{sessionId} |
Never iframe /api/v1/embed/... directly — those are JSON APIs, not pages. Only the returned embedUrl is meant to be an iframe src.
Generate an embed URL (iframe)
Mint the URL from your backend
curl -X POST https://buda.im/api/v1/spaces/YOUR_SPACE_ID/agents/YOUR_AGENT_ID/embed-urls \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"externalUserId": "customer-123",
"displayName": "Kelly",
"ttlSeconds": 3600,
"mode": "chat"
}'The response includes embedUrl, sessionId, and expiresAt:
{
"embedUrl": "https://buda.im/embed/api-claw/SESSION_ID#token=SHORT_LIVED_TOKEN",
"sessionId": "SESSION_ID",
"expiresAt": "2026-05-26T12:00:00.000Z"
}Use it as the iframe src
<iframe
src="https://buda.im/embed/api-claw/SESSION_ID#token=SHORT_LIVED_TOKEN"
title="Buda Agent"
allow="microphone"
style="width: 400px; height: 600px; border: 0;"
></iframe>The token rides in the URL hash fragment, so it is not sent to the server with the initial page request — the hosted page reads it in the browser and uses it only for embed JSON calls.
Generate a native token
For UIs you fully control, mint a session and ship only the token:
curl -X POST https://buda.im/api/v1/spaces/YOUR_SPACE_ID/agents/YOUR_AGENT_ID/embed-sessions \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"externalUserId": "wechat-openid-oABC123",
"displayName": "Kelly",
"ttlSeconds": 3600,
"mode": "chat"
}'Return only token, sessionId, and the embed API URLs to the client. The client then sends messages and polls replies with the token:
# Send a message
curl -X POST https://buda.im/api/v1/embed/chat-sessions/SESSION_ID/messages \
-H "Authorization: Bearer EMBED_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "message": "How do I reset my device?", "mode": "chat" }'
# Poll for the agent reply
curl https://buda.im/api/v1/embed/chat-sessions/SESSION_ID \
-H "Authorization: Bearer EMBED_TOKEN"Token lifetime and external users
externalUserId(required) — your own ID for the end user (a customer ID, device ID, or WeChatopenid). Buda labels the session with it; end users never need a Buda account.ttlSeconds— how long the token is valid. Minimum 60, maximum 86400 (24 hours), default 3600 (1 hour).sessionId— pass an existing one to continue a conversation; omit it to start a new session.mode— the prompt mode (chat,agent,thinking, orbuild-app).
When a token expires, mint a fresh one from your backend.
Security
- Keep your
sk_key server-side. Only short-lived embed credentials should reach a browser or device. - Scope per user. One embed credential maps to one
externalUserIdand one session — it can't reach your other Spaces or agents. - Let it expire. Use the shortest practical
ttlSecondsand refresh on demand rather than issuing long-lived tokens. - Tokens are bound to their session. A token presented for a different
sessionIdis rejected with403.