Skip to content

Browser Sessions

POST /v1/browser-sessions

Called by the SDK for browser embeds when you pass experienceId. Auth is the page Origin against your allowlist — not an API key in the browser.

Request

POST https://api.liforma.ai/v1/browser-sessions
Origin: https://your-app.com
Idempotency-Key: optional-unique-key
Content-Type: application/json

{
"experienceId": "exp_t0i7acmq",
"locale": "en-GB",
"secondaryLocale": "fr-FR",
"mode": "conversation",
"speechInputMode": "auto",
"speechOnly": false
}

Response 201

SessionLaunchResponse: session plus opaque launch. Header: Cache-Control: no-store, private. Dual sessions also echo session.secondaryLocale when resolved.

Parameters

FieldRequiredDescription
experienceIdYesExperience to launch
localeNo

Primary / user language (BCP 47). SDK defaults to navigator.language when omitted.

secondaryLocaleNo*

Dual: paired / learning language (BCP 47). Required when the creator left the paired axis as Match; ignored when Fixed. Non-dual: when conversation is Match, immerses the session in this language (wins over browser/locale); ignored when Fixed.

learningLocaleNo

Alias of secondaryLocale — prefer for language-learning apps (tutors and roleplay). Must not disagree with secondaryLocale when both are set.

modeNoconversation or presenter
speechInputModeNoauto, manual, or off
runtimeContextNo

Session JSON for {{templates}} and later managed turns. Data only: it does not change tools, permissions, or capabilities. Rejected when it exceeds the size limits (32 KiB serialized).

speechOnlyNoWhen true, voice-only session without avatar/location assets

  • Language-learning apps can pass the same learningLocale (or secondaryLocale) for tutors and roleplay. Dual tutors use it as the learning axis (clip / v2a pipeline); non-dual roleplay immerses conversation and voice in that language when Studio left Match open (plain / v2b). Creator Fixed still wins.

Player chrome (startButton, closeButton, returnUrl, fit) is configured via SDK attach / component props — not on this request.

Checks

  • Origin header required
  • Browser embeds must be enabled for the project
  • Origin must be on the project allowlist
  • Experience must have a published revision
  • Quota and rate limits apply

CORS

api.liforma.ai returns CORS headers for the requesting Origin, including Idempotency-Key on preflight. CORS is not authorization — Origin allowlisting happens on the POST. The SDK calls this endpoint directly from the browser.

Optional Idempotency-Key (max 256 characters; longer values → 400 IDEMPOTENCY_KEY_INVALID): same key + same body replays the prior launch; same key + different body → 409 IDEMPOTENCY_CONFLICT; same key still pending → 409 IDEMPOTENCY_IN_PROGRESS with Retry-After: 1. Branch on error.code, not HTTP 409 alone.

Machine-readable contract: /openapi/sessions.json.

Example

curl -X POST https://api.liforma.ai/v1/browser-sessions \
  -H "Origin: https://your-app.com" \
  -H "Content-Type: application/json" \
  -d '{"experienceId": "exp_t0i7acmq"}'