> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sempera.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Web SDK

> Connecting a browser to a session with a realtime media web client; no Sempera SDK package is published yet; the OpenAPI document is the machine-readable contract.

There is no published Sempera SDK package yet: the TypeScript and Python clients in [TypeScript and Python SDKs](https://docs.sempera.org/sdks.md) are generated from the contract but are not on npm or PyPI. The OpenAPI document at `https://api.sempera.org/openapi.json` is the machine-readable contract, generated from the running route table.

## Connecting a browser to a Web voice session today

1. Your server calls `POST /v1/sessions` with your API key and receives `{"url", "token", "expires_at"}`, plus a `transport` field that names the realtime media protocol the `url` and `token` are for.
2. Your page connects with an open-source realtime-media web client for that protocol. This page does not name the client library or version Sempera has tried; write to [hello@sempera.org](mailto:hello@sempera.org) if you need them. The sketch below shows the shape any such client has. It is not a package to install:

```ts theme={null}
// `connect` stands for your realtime-media client's connect call. `session` is the JSON your server returned.
const room = await connect(session.url, session.token);
await room.enableMicrophone();
```

3. The agent joins the room and speaks; audio tracks arrive as remote participants. When the conversation ends, disconnect and read `GET /v1/sessions/{id}` for the transcript.

The token is scoped to one room and never lets the browser call the API. For `web_voice`, the join token expires after five minutes. `expires_at` is the token's actual expiry, not the maximum length of an already connected conversation. Keep your API key on your server and issue a session only after checking your own customer's identity and authorization.

Compatibility note: `POST /v1/sessions` web voice join tokens now use a five-minute window instead of the media default. Request a fresh session if the visitor has not joined by `expires_at`. App Talk and simulator tokens are unchanged. This join window is separate from a connected call's duration.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.