Gryt

API Reference

WebSocket events, REST endpoints, and data structures

Complete API documentation for the Gryt signaling server.

Web Client API

Audio Processing Hooks

useMicrophone

Manages microphone input and audio processing.

const { 
  microphoneBuffer, 
  isRecording, 
  analyser, 
  gainNode 
} = useMicrophone(shouldAccess: boolean);

Parameters:

  • shouldAccess (boolean): Whether to request microphone access

Returns:

  • microphoneBuffer (AudioBuffer): Raw microphone audio buffer
  • isRecording (boolean): Whether microphone is currently recording
  • analyser (AnalyserNode): Audio analyser for visualization
  • gainNode (GainNode): Volume control node

useSFU

Manages SFU connection and WebRTC handling.

const { 
  connect, 
  disconnect, 
  isConnected, 
  isConnecting,
  streamSources,
  connectionState 
} = useSFU();

Returns:

  • connect() (function): Connect to SFU server
  • disconnect() (function): Disconnect from SFU server
  • isConnected (boolean): Connection status
  • isConnecting (boolean): Connection in progress
  • streamSources (Map): Active audio streams
  • connectionState (string): Current connection state

useSockets

Manages WebSocket connections to signaling servers.

const { 
  sockets, 
  clients, 
  serverDetailsList,
  currentConnection 
} = useSockets();

Returns:

  • sockets (Map): Active WebSocket connections
  • clients (Map): Connected clients per server
  • serverDetailsList (Array): Available servers
  • currentConnection (string): Current server ID

Server API

WebSocket Events

Client → Server

EventPayloadDescription
join{ channelID: string }Join a voice channel
leave{}Leave current voice channel
updateNicknamestringUpdate user nickname
updateMutebooleanUpdate mute state
offerRTCSessionDescriptionWebRTC offer for SFU
answerRTCSessionDescriptionWebRTC answer from SFU
ice-candidateRTCIceCandidateICE candidate for connection

Server → Client

EventPayloadDescription
infoServerInfoServer information and channels
usersUserListCurrent users in channels
user-joinedUserInfoUser joined notification
user-leftUserInfoUser left notification
user-updatedUserInfoUser state changed
offerRTCSessionDescriptionWebRTC offer from SFU
answerRTCSessionDescriptionWebRTC answer to SFU
ice-candidateRTCIceCandidateICE candidate from SFU

REST Endpoints

Messages

GET /api/messages/:conversationId

Get messages for a conversation.

Query Parameters:

  • limit (number, optional): Number of messages to return (default: 50)
  • before (string, optional): ISO timestamp to get messages before

Response:

{
  "items": [
    {
      "id": "msg_123",
      "senderId": "user_456",
      "text": "Hello world",
      "attachments": ["file_789"],
      "created_at": "2024-01-15T10:30:00Z"
    }
  ]
}

POST /api/messages/:conversationId

Create a new message.

Request Body:

{
  "senderId": "user_456",
  "text": "Hello world",
  "attachments": ["file_789"]
}

Response:

{
  "id": "msg_123",
  "senderId": "user_456",
  "text": "Hello world",
  "attachments": ["file_789"],
  "created_at": "2024-01-15T10:30:00Z"
}

Uploads

POST /api/uploads

Upload a file.

Request: multipart/form-data

  • file: The file to upload

Response:

{
  "fileId": "file_789",
  "key": "uploads/file_789.jpg",
  "thumbnailKey": "thumbnails/file_789_320.jpg"
}

Custom Emojis

GET /api/emojis

List all custom server emojis. No authentication required.

Response:

[
  { "name": "pepehappy", "file_id": "abc-123" },
  { "name": "catjam", "file_id": "def-456" }
]

GET /api/emojis/img/:name

Serve a custom emoji image by name (128x128 PNG). Long-lived cache headers.

POST /api/emojis

Upload a custom emoji. Requires admin or owner role.

Request: multipart/form-data

  • file: Image file (any format; resized to 128x128 PNG server-side)
  • name: Emoji shortcode name (2-32 lowercase alphanumeric/underscore chars)

Response:

{ "name": "pepehappy", "file_id": "abc-123" }

DELETE /api/emojis/:name

Delete a custom emoji. Requires admin or owner role.

Response:

{ "ok": true }

Data Structures

ServerInfo

interface ServerInfo {
  name: string;
  members: string;
  channels: Channel[];
}

Channel

interface Channel {
  id: string;
  name: string;
  type: 'voice' | 'text';
}

UserInfo

interface UserInfo {
  id: string;
  nickname: string;
  isMuted: boolean;
  hasJoinedChannel: boolean;
  isConnectedToVoice: boolean;
  streamID?: string;
}

SFU API

WebSocket Events

Client → SFU

EventPayloadDescription
joinJoinMessageJoin a room with user information
leaveLeaveMessageLeave current room
offerRTCSessionDescriptionWebRTC offer from client
answerRTCSessionDescriptionWebRTC answer from client
ice-candidateRTCIceCandidateICE candidate from client

SFU → Client

EventPayloadDescription
joinedJoinedMessageConfirmation of room join
user-joinedUserJoinedMessageAnother user joined the room
user-leftUserLeftMessageUser left the room
offerRTCSessionDescriptionWebRTC offer from SFU
answerRTCSessionDescriptionWebRTC answer from SFU
ice-candidateRTCIceCandidateICE candidate from SFU

Message Types

JoinMessage

type JoinMessage struct {
    RoomID   string `json:"roomId"`
    UserID   string `json:"userId"`
    UserInfo struct {
        Nickname string `json:"nickname"`
        IsMuted  bool   `json:"isMuted"`
    } `json:"userInfo"`
}

JoinedMessage

type JoinedMessage struct {
    RoomID    string   `json:"roomId"`
    UserID    string   `json:"userId"`
    Peers     []string `json:"peers"`
    Success   bool     `json:"success"`
    Message   string   `json:"message,omitempty"`
}

Debug Endpoints

EndpointMethodDescription
/healthGETHealth check
/debug/roomsGETActive rooms
/debug/peersGETPeer connections
/debug/tracksGETMedia tracks
/metricsGETPrometheus metrics

Auth Service API

Authentication Endpoints

User Registration

POST /api/register

Register a new user account.

Request Body:

{
  "email": "[email protected]",
  "password": "securepassword",
  "nickname": "UserNickname"
}

Response:

{
  "success": true,
  "message": "Registration successful. Please check your email for verification.",
  "userId": "user_123456789"
}

User Login

POST /api/login

Authenticate user and get access token.

Request Body:

{
  "email": "[email protected]",
  "password": "securepassword"
}

Response:

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "refresh_token_here",
  "user": {
    "id": "user_123456789",
    "email": "[email protected]",
    "nickname": "UserNickname",
    "verified": true
  }
}

Token Validation

GET /api/validate

Validate an authentication token.

Headers:

  • Authorization: Bearer <token>

Response:

{
  "valid": true,
  "user": {
    "id": "user_123456789",
    "email": "[email protected]",
    "nickname": "UserNickname",
    "verified": true
  }
}

Refresh Token

POST /api/refresh

Get a new access token using refresh token.

Request Body:

{
  "refreshToken": "refresh_token_here"
}

Response:

{
  "success": true,
  "token": "new_jwt_token_here",
  "refreshToken": "new_refresh_token_here"
}

User Management Endpoints

Get User Profile

GET /api/user/profile

Get current user's profile information.

Headers:

  • Authorization: Bearer <token>

Response:

{
  "id": "user_123456789",
  "email": "[email protected]",
  "nickname": "UserNickname",
  "avatar": "https://example.com/avatar.jpg",
  "verified": true,
  "created_at": "2024-01-15T10:30:00Z"
}

Update User Profile

PUT /api/user/profile

Update user profile information.

Headers:

  • Authorization: Bearer <token>

Request Body:

{
  "nickname": "NewNickname",
  "avatar": "https://example.com/new-avatar.jpg"
}

Response:

{
  "success": true,
  "user": {
    "id": "user_123456789",
    "email": "[email protected]",
    "nickname": "NewNickname",
    "avatar": "https://example.com/new-avatar.jpg",
    "verified": true
  }
}

Change Password

PUT /api/user/password

Change user password.

Headers:

  • Authorization: Bearer <token>

Request Body:

{
  "currentPassword": "oldpassword",
  "newPassword": "newpassword"
}

Response:

{
  "success": true,
  "message": "Password changed successfully"
}

Error Codes

Server Error Codes

CodeDescriptionSolution
AUTH_001Invalid credentialsCheck email/password
AUTH_002Token expiredUse refresh token
AUTH_003Rate limit exceededWait and retry
AUTH_004Account not verifiedCheck email for verification
AUTH_005Account suspendedContact support

WebSocket Error Codes

CodeDescriptionSolution
WS_001Connection failedCheck server status
WS_002Authentication requiredProvide valid token
WS_003Room not foundCheck room ID
WS_004User already in roomLeave current room first
WS_005Room fullWait for space

SFU Error Codes

CodeDescriptionSolution
SFU_001WebRTC connection failedCheck STUN servers and SFU UDP media port range
SFU_002Track not foundCheck track ID
SFU_003Room not foundCheck room ID
SFU_004Peer connection failedCheck network connectivity

SDK Examples

JavaScript SDK

import { GrytClient } from '@gryt/client-sdk';

const client = new GrytClient({
  serverUrl: 'wss://server.example.com',
  authToken: 'your-auth-token'
});

// Connect to server
await client.connect();

// Join a voice channel
await client.joinChannel('general');

// Update mute state
await client.setMuted(true);

// Leave channel
await client.leaveChannel();

Go SDK

package main

import (
    "github.com/gryt/sfu-go"
    "log"
)

func main() {
    client := sfu.NewClient("ws://localhost:5005")
    
    // Connect to SFU
    err := client.Connect()
    if err != nil {
        log.Fatal(err)
    }
    
    // Join room
    err = client.JoinRoom("test-room", "user-123")
    if err != nil {
        log.Fatal(err)
    }
    
    // Handle incoming tracks
    client.OnTrack(func(track *webrtc.TrackRemote) {
        log.Printf("Received track: %s", track.ID())
    })
}

Rate Limits

Authentication Service

  • Login attempts: 5 per 15 minutes per IP
  • Registration: 3 per hour per IP
  • API calls: 1000 per hour per user
  • Password reset: 3 per hour per email

Signaling Server

  • WebSocket messages: 100 per minute per connection
  • Room joins: 10 per minute per user
  • File uploads: 10 per hour per user

SFU Server

  • WebRTC connections: 50 per minute per IP
  • Track additions: 100 per minute per connection
  • ICE candidates: 200 per minute per connection

On this page