Every Livqeno app installs two packages: a server SDK on your backend, which holds the API key and mints tokens, and a client SDK in your app, which uses a token to join a call, a chat, or a live stream.
Quick start
- Install the server SDK in your backend project.
- Install the client SDK in your app project.
- Set
LIVQENO_API_KEYandLIVQENO_API_URLwhere your backend runs.
In your backend project:
pnpm add @livqeno/servernpm install @livqeno/serveryarn add @livqeno/serverbun add @livqeno/serverIn your app project:
pnpm add @livqeno/rtcnpm install @livqeno/rtcyarn add @livqeno/rtcbun add @livqeno/rtcThat is the whole install for a web video call. The rest of this page covers the other platforms, the system requirements, and how to check your setup. Already installed? Go straight to the Quickstart.
System requirements
Before you begin, make sure your environment meets these minimums:
| Package | Requirement |
|---|---|
@livqeno/server | Node.js 20 or later |
livqeno | Python 3.10 or later (tested on 3.10 to 3.13) |
@livqeno/react | React 18 or 19 |
@livqeno/react-native | React Native 0.73 or later, react-native-webrtc 124 or later |
livqeno_rtc, livqeno_chat, livqeno_live | Flutter 3.27 or later (Dart 3.6), Android minSdkVersion 23, iOS 13 |
Livqeno is hosted, so there are no servers, media relays, or databases to
install. Your backend only needs outbound HTTPS to https://api.livqeno.com.
Supported browsers
The browser packages (@livqeno/rtc, @livqeno/chat, @livqeno/live,
@livqeno/react) need three browser features: RTCPeerConnection,
navigator.mediaDevices.getUserMedia, and WebSocket. Chat needs only
WebSocket.
| Browser | Feature check | Tested end to end with real media |
|---|---|---|
| Chrome / Edge (Chromium) | Passes | Yes |
| Firefox | Passes | No |
| Safari (macOS and iOS) | Passes | No |
Check support at runtime with isBrowserSupported() before you show a call
screen. Learn more in Browser support.
Install with the CLI
The quickest way to set up a JavaScript project is the Livqeno CLI. It links
the folder to your project, detects your package manager from the lockfile
(pnpm-lock.yaml, yarn.lock, bun.lock, or package-lock.json), and
installs @livqeno/rtc with it.
npm install -g @livqeno/cli
livqeno config set apiUrl https://api.livqeno.com # once: the CLI defaults to localhost
livqeno login # opens your browser
livqeno init # link this folder to a project
livqeno sdk install # install @livqeno/rtclivqeno init asks you to pick a project and writes a swalvo.json file in the
current folder, so everyone who runs livqeno there uses the same project.
Commit it: it holds only the project id, never a secret.
To see the install command without running it:
livqeno sdk install --dry-runManual installation
Install the server SDK
Run this in your backend project. Pick your server's language. Not on TypeScript, Python, Go, Java or PHP? Call the REST API directly from any language.
pnpm add @livqeno/servernpm install @livqeno/serveryarn add @livqeno/serverbun add @livqeno/server@livqeno/server ships ESM and CommonJS builds and its own TypeScript
types, so both import and require work with no extra setup.
pip install livqeno # you import it as `livqeno`The package depends only on httpx, and ships type hints. It has a
synchronous Livqeno client and an AsyncLivqeno client for asyncio frameworks
such as FastAPI.
go get github.com/atulsinghhhh/swalvo-sdks/sdks/go/livqenoNeeds Go 1.22 or later and uses only the standard library. Every method
takes a context.Context. Details: Go SDK.
The Java SDK isn't on Maven Central yet. Run mvn install in sdks/java,
then add the dependency:
<dependency>
<groupId>com.livqeno</groupId>
<artifactId>livqeno-server</artifactId>
<version>0.1.0</version>
</dependency>Needs Java 17 or later. Its only runtime dependency is jackson-databind.
Details: Java SDK.
composer require livqeno/livqeno-phpNeeds PHP 8.1 or later with ext-curl and ext-json. Until the package is
on Packagist, install it from a checkout with a Composer path repository.
Details: PHP SDK.
Install the client SDK
Run this in your app project. Pick the platform your users are on.
pnpm add @livqeno/rtcnpm install @livqeno/rtcyarn add @livqeno/rtcbun add @livqeno/rtcThat's enough for calls. For other products, install the matching package:
| You want | Install | Import |
|---|---|---|
| Calls only | @livqeno/rtc | createRTCClient |
| Chat only | @livqeno/chat | createChatClient |
| Calls and chat (or live streaming) | @livqeno/live | createLivqeno |
@livqeno/rtc and @livqeno/chat don't depend on each other, so a
calls-only app never ships chat code.
pnpm add @livqeno/rtc @livqeno/reactnpm install @livqeno/rtc @livqeno/reactyarn add @livqeno/rtc @livqeno/reactbun add @livqeno/rtc @livqeno/react@livqeno/react adds components and hooks, like <LivqenoRoom> and
useCamera(), on top of @livqeno/rtc. Need chat too? Add
@livqeno/chat.
pnpm add @livqeno/react-native @livqeno/rtc react-native-webrtc react-native-incall-managernpm install @livqeno/react-native @livqeno/rtc react-native-webrtc react-native-incall-manageryarn add @livqeno/react-native @livqeno/rtc react-native-webrtc react-native-incall-managerbun add @livqeno/react-native @livqeno/rtc react-native-webrtc react-native-incall-managerThen install the iOS pods:
cd ios && pod installreact-native-webrtcis required. Install it, but you never import it.react-native-incall-manageris optional. It routes call audio to the speaker or earpiece.- Camera and microphone permissions go in your native project files. See React Native and Permissions.
dependencies:
livqeno_rtc: ^0.2.2 # video calls
livqeno_chat: ^0.1.1 # chat
livqeno_live: ^0.2.0 # live streamingOr run flutter pub add livqeno_rtc. Install only the packages you use:
livqeno_live builds on the other two.
Phones need camera and microphone permissions declared up front. See Flutter.
Set up environment variables
Your backend needs two values. Store them in your environment or secrets manager, never in source control:
LIVQENO_API_KEY=rvk_dev_... # from the dashboard or `livqeno keys create`
LIVQENO_API_URL=https://api.livqeno.com| Variable | What it's for |
|---|---|
LIVQENO_API_KEY | Proves a request comes from your backend. One key per environment. |
LIVQENO_API_URL | Where the SDK sends requests. |
The server SDKs don't read environment variables on their own. Pass both values in yourself when you create the client, once at startup:
import { Livqeno } from '@livqeno/server';
export const livqeno = new Livqeno({
apiKey: process.env.LIVQENO_API_KEY!,
baseUrl: process.env.LIVQENO_API_URL!,
});import os
from livqeno import Livqeno
livqeno = Livqeno(
api_key=os.environ["LIVQENO_API_KEY"],
base_url=os.environ["LIVQENO_API_URL"],
)client := livqeno.New(
os.Getenv("LIVQENO_API_KEY"),
livqeno.WithBaseURL(os.Getenv("LIVQENO_API_URL")),
)import com.livqeno.server.Livqeno;
Livqeno livqeno = Livqeno.builder()
.apiKey(System.getenv("LIVQENO_API_KEY"))
.baseUrl(System.getenv("LIVQENO_API_URL"))
.build();$client = new \Livqeno\Client(
apiKey: getenv('LIVQENO_API_KEY'),
baseUrl: getenv('LIVQENO_API_URL'),
);Set up TypeScript
Every JavaScript package ships its own type declarations. There is nothing
extra to install, and no @types/* package to add.
Most types you need come from the package you call. For example, the grant your backend returns and the room your app joins are both typed:
import { createRTCClient } from '@livqeno/rtc';
const grant = await fetch('/join-room', { method: 'POST' }).then((r) => r.json());
const client = createRTCClient(grant);
const room = await client.join(grant.roomName); // typed RoomErrors are typed too: every SDK throws an error with message, code and
requestId, never a raw DOMException or HTTP body. On the server, narrow
with isLivqenoError:
import { isLivqenoError } from '@livqeno/server';
try {
await livqeno.rooms.list();
} catch (error) {
if (isLivqenoError(error)) console.error(error.code, error.requestId);
throw error;
}Use with Next.js
A Next.js app holds both halves, so it installs both packages:
pnpm add @livqeno/server @livqeno/rtc @livqeno/reactnpm install @livqeno/server @livqeno/rtc @livqeno/reactyarn add @livqeno/server @livqeno/rtc @livqeno/reactbun add @livqeno/server @livqeno/rtc @livqeno/reactKeep each package on its side of the boundary:
app/
├── api/
│ └── join-room/
│ └── route.ts ← @livqeno/server and your API key (server only)
└── call/
├── page.tsx ← Server Component, renders the client component
└── call-client.tsx ← 'use client' — @livqeno/rtc / @livqeno/react
lib/
└── livqeno.ts ← the one shared Livqeno instance- A Route Handler is server code, so it's the right place for
@livqeno/serverandLIVQENO_API_KEY. @livqeno/rtc,@livqeno/chat, and every@livqeno/reacthook run only in the browser. Use them in a file marked'use client', and never callcreateRTCClient()during server rendering.
The full walkthrough is in Next.js. See also React.
Check your setup
With the CLI
From a folder linked with livqeno init, run:
livqeno devIt checks that the folder is linked to a project, the API is reachable, the
media servers are up, and @livqeno/rtc is in your package.json:
Livqeno project:
my-video-app
Project ID:
16281d1e-5b0c-4f3e-9a51-7d2c8e4b9a10
API:
✓ Connected
RTC:
✓ Available
SDK:
✓ @livqeno/rtc installed
Environment:
development
Ready for development.From your backend
Make one authenticated call with your key. If it returns, the key, the URL and the network path are all correct:
import { Livqeno } from '@livqeno/server';
const livqeno = new Livqeno({
apiKey: process.env.LIVQENO_API_KEY!,
baseUrl: process.env.LIVQENO_API_URL!,
});
const rooms = await livqeno.rooms.list();
console.log(`Connected. ${rooms.length} room(s) in this environment.`);import os
from livqeno import Livqeno
livqeno = Livqeno(
api_key=os.environ["LIVQENO_API_KEY"],
base_url=os.environ["LIVQENO_API_URL"],
)
rooms = livqeno.rooms.list()
print(f"Connected. {len(rooms)} room(s) in this environment.")client := livqeno.New(os.Getenv("LIVQENO_API_KEY"), livqeno.WithBaseURL(os.Getenv("LIVQENO_API_URL")))
rooms, err := client.Rooms.List(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Printf("Connected. %d room(s) in this environment.\n", len(rooms))Livqeno livqeno = Livqeno.builder()
.apiKey(System.getenv("LIVQENO_API_KEY"))
.baseUrl(System.getenv("LIVQENO_API_URL"))
.build();
List<Room> rooms = livqeno.rooms().list();
System.out.println("Connected. " + rooms.size() + " room(s) in this environment.");$client = new \Livqeno\Client(apiKey: getenv('LIVQENO_API_KEY'), baseUrl: getenv('LIVQENO_API_URL'));
$rooms = $client->rooms->list();
echo 'Connected. ' . count($rooms) . " room(s) in this environment.\n";curl "$LIVQENO_API_URL/v1/rooms" \
-H "Authorization: Bearer $LIVQENO_API_KEY"A RAVEN_AUTH_ERROR (401) means the key is wrong or revoked. A connection error
usually means LIVQENO_API_URL is unset and the SDK is calling localhost.
Which package do I need?
| Package | Runs on | Uses | Reference |
|---|---|---|---|
@livqeno/server | Your TypeScript backend | API key | TypeScript |
livqeno | Your Python backend | API key | Python |
github.com/atulsinghhhh/swalvo-sdks/sdks/go/livqeno | Your Go backend | API key | Go |
com.livqeno:livqeno-server | Your Java / JVM backend | API key | Java |
livqeno/livqeno-php | Your PHP backend | API key | PHP |
@livqeno/rtc | Browser | RTC token | Next.js |
@livqeno/chat | Browser | Chat token | Next.js |
@livqeno/live | Browser | Both tokens, one object | Livqeno Client |
@livqeno/react | Browser (React) | Hooks for RTC and chat | React |
@livqeno/react-native | iOS, Android | RTC and chat | React Native |
livqeno_rtc, livqeno_chat, livqeno_live | iOS, Android (Flutter) | RTC, chat, streaming | Flutter |
@livqeno/cli | Your terminal | Your dashboard login | CLI |
Upgrade your SDKs
Every SDK is before version 1.0, so a minor release can change an API. Read the Changelog before you upgrade, and upgrade the server and client packages together.
pnpm add @livqeno/server@latest @livqeno/rtc@latestnpm install @livqeno/server@latest @livqeno/rtc@latestyarn add @livqeno/server@latest @livqeno/rtc@latestbun add @livqeno/server@latest @livqeno/rtc@latestpip install --upgrade livqenogo get -u github.com/atulsinghhhh/swalvo-sdks/sdks/go/livqenocomposer update livqeno/livqeno-phpflutter pub upgrade livqeno_rtc livqeno_chat livqeno_liveA caret on a 0.x version (^0.2.2) never crosses a minor version. To move to
a new minor, change the constraint in pubspec.yaml.