From 2e85335823effedd1a210e7bdf81ba11f62b1aef Mon Sep 17 00:00:00 2001 From: David Zhao Date: Thu, 9 Jul 2026 01:30:28 +0200 Subject: [PATCH 1/2] update readme to reflect LKAPI interfaces will merge after api release --- README.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/README.md b/README.md index e7fa81b1..cf68bce5 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,21 @@ async def main(): asyncio.run(main()) ``` +### Authentication + +Authenticate with an API key and secret (recommended for backend use), or with a +pre-signed token for client-side use, where the API secret must not be exposed. +Any omitted value falls back to `LIVEKIT_URL`, `LIVEKIT_API_KEY`, +`LIVEKIT_API_SECRET`, and `LIVEKIT_TOKEN`. + +```python +# API key & secret (backend) +lkapi = api.LiveKitAPI("https://my-project.livekit.cloud", api_key="...", api_secret="...") + +# pre-signed token (client-side); the token must already carry the grants for the calls +lkapi = api.LiveKitAPI.with_token(my_token, "https://my-project.livekit.cloud") +``` + ### Using other APIs Services can be accessed via the LiveKitAPI object. @@ -91,6 +106,38 @@ dispatch_svc = lkapi.agent_dispatch connector_svc = lkapi.connector ``` +### Error handling + +A failed server API call raises `api.ServerError`, which exposes the error +`code`, `message`, and any server-provided `metadata`. + +```python +try: + await lkapi.room.create_room(api.CreateRoomRequest(name="my-room")) +except api.ServerError as e: + print(e.code, e.message) +``` + +A failed SIP dial (e.g. the callee is busy or doesn't answer) raises +`api.SipCallError`, a `ServerError` subclass that also exposes the SIP response +status: + +```python +try: + await lkapi.sip.create_sip_participant(api.CreateSIPParticipantRequest( + sip_trunk_id="ST_...", + sip_call_to="+15105550100", + room_name="my-room", + wait_until_answered=True, + )) +except api.SipCallError as e: + print(e) # e.g. "SIP call failed: 486 Busy Here (resource_exhausted)" + if e.sip_status_code == 486: + ... # busy +except api.ServerError as e: + print(e.code, e.message) # any other API error +``` + ## Using Real-time SDK ```shell From 558eb0a9efb56ab2b6ad320902e1f551c8d57be2 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 10 Jul 2026 16:41:16 +0200 Subject: [PATCH 2/2] updates --- livekit-api/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/livekit-api/README.md b/livekit-api/README.md index 14b5e35f..18c5daba 100644 --- a/livekit-api/README.md +++ b/livekit-api/README.md @@ -4,3 +4,26 @@ Access LiveKit server APIs and generate access tokens. See https://docs.livekit.io/reference/server/server-apis for more information. +## Authentication + +Every request to the server APIs is authenticated. `LiveKitAPI` supports two modes: + +- **API key & secret** — recommended for backend use. The SDK signs a short-lived token per request from your key and secret. Keep your API secret on the server; never ship it to a client. +- **Access token** — for client-side use where the API secret must not be exposed. Pass a pre-signed [access token](https://docs.livekit.io/home/get-started/authentication/) that already carries the grants for the operations you'll perform; the SDK sends it verbatim. + +```python +from livekit import api + +# API key & secret: set LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET, +# then construct with no arguments... +lkapi = api.LiveKitAPI() + +# ...or pass any of them explicitly to override the corresponding env var: +lkapi = api.LiveKitAPI("https://my.livekit.host", api_key="api-key", api_secret="api-secret") + +# Pre-signed access token (client-side): with LIVEKIT_URL set, pass just the token: +lkapi = api.LiveKitAPI.with_token("a-pre-signed-token") +``` + +The url and credentials fall back to the `LIVEKIT_URL`, `LIVEKIT_API_KEY`, `LIVEKIT_API_SECRET`, and `LIVEKIT_TOKEN` environment variables. Values you pass explicitly take precedence; the environment variables are used only as a fallback for arguments you omit — an ambient `LIVEKIT_TOKEN`, for example, won't override an explicitly-provided API key and secret. +