No API call to join
Your backend does not call a Gravix API when a user joins a room. It signs the access token itself with our token library, and Gravix checks the signature when the user connects. So a join never waits on an extra service, and your App Certificate never leaves your server.
Token libraries
gravix-rtc-token on npm runs on Node 18+, Deno, Bun and edge runtimes, with no runtime dependencies and TypeScript types. gravix-token-go is the Go version (Go 1.21+) with the same options.
npm install gravix-rtc-token// server.ts (your backend, Node 18+). This file never ships inside an app.
import express from 'express';
import { createToken } from 'gravix-rtc-token';
const APP_ID = process.env.GRAVIX_APP_ID!; // from your dashboard
const APP_CERTIFICATE = process.env.GRAVIX_APP_CERTIFICATE!; // server only, never in an app
const REGION_URL = process.env.GRAVIX_URL!; // wss://YOUR-REGION-URL
const app = express();
app.use(express.json());
// requireUser is your own login check: the identity comes from YOUR session,
// never from the request body.
app.post('/rtc/token', requireUser, async (req, res) => {
const room = req.body?.room;
if (typeof room !== 'string' || !/^[\w.-]{1,64}$/.test(room)) {
return res.status(400).json({ error: 'invalid room' });
}
const token = await createToken(APP_ID, APP_CERTIFICATE, {
room, // the library adds your App ID prefix
identity: req.user.id,
name: req.user.name,
canPublish: true, // false = listen only; decide it here, not in the app
ttlSeconds: 60 * 60, // short-lived: 1 hour
});
res.json({ token, url: REGION_URL });
});
app.listen(3000);// token.go (your backend, Go 1.21+). gravixtoken is the gravix-token-go package.
func tokenHandler(w http.ResponseWriter, r *http.Request) {
user, ok := currentUser(r) // your own login check
if !ok {
http.Error(w, "sign in first", http.StatusUnauthorized)
return
}
var body struct {
Room string `json:"room"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil || body.Room == "" {
http.Error(w, "invalid room", http.StatusBadRequest)
return
}
// The App Certificate stays in the server's environment.
jwt, err := gravixtoken.New(os.Getenv("GRAVIX_APP_ID"), os.Getenv("GRAVIX_APP_CERTIFICATE")).
Room(body.Room).
Identity(user.ID).
Name(user.Name).
CanPublish(true). // false = listen only
TTL(time.Hour). // short-lived
ToJWT()
if err != nil {
http.Error(w, "could not sign", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{
"token": jwt,
"url": os.Getenv("GRAVIX_URL"), // wss://YOUR-REGION-URL
})
}Token options
Names are the Node option and the Go builder method.
| Node | Go | What it does |
|---|---|---|
room | Room | Required. The room name in your app. The library adds your App ID prefix. |
identity | Identity | Required. Your user ID, taken from your own session. |
name | Name | Display name shown to other participants. |
metadata | Metadata | Free-form string attached to the participant. |
attributes | Attributes | Key-value pairs attached to the participant. |
ttlSeconds | TTL | How long the token is valid. Default 6 hours, at most 24 hours. |
canPublish | CanPublish | May send audio and video. Default true; false = listener. |
canSubscribe | CanSubscribe | May receive others' audio and video. Default true. |
canPublishData | CanPublishData | May send data messages. Default true. |
canUpdateOwnMetadata | CanUpdateOwnMetadata | May change their own name, metadata and attributes. Default true; the SDKs use it to share the camera facing. |
canPublishSources | CanPublishSources | Limit publishing to some sources, for example the microphone only. |
hidden | Hidden | Joins without being shown to other participants. |
roomAdmin | RoomAdmin | Room moderator rights. |
roomName(appId, room) adds the App ID prefix to a room name and displayName(appId, room) strips it for display (RoomName and DisplayName in Go).
Managing rooms
A server API for managing rooms and participants from your backend is not published yet. If you need one for your app, tell us what you want to do and we will work it out with you.
