Developers

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 getA full embedUrl to use as iframe srcA token + the embed API URLs
UIBuda-hosted chat pageYou build the chat UI
Best forWebsites, portals, admin panelsMobile apps, mini programs, extensions
Frontend callsNone (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 WeChat openid). 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, or build-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 externalUserId and one session — it can't reach your other Spaces or agents.
  • Let it expire. Use the shortest practical ttlSeconds and refresh on demand rather than issuing long-lived tokens.
  • Tokens are bound to their session. A token presented for a different sessionId is rejected with 403.

On this page