PulseRTC
DEVELOPER INTEGRATION GUIDE // AUDIO & VIDEO CALLING

Add Audio & Video Calling to Your Website or App

Integrate 1-on-1 voice calls, HD video consultations, and service-app calling workflows with PulseRTC in 3 steps—with prepaid minute billing and ephemeral STUN/TURN relay built in.

STEP 1

Get App ID & Secret

Sign up in the Developer Portal to get 1,000 free calling minutes, an App ID, and a server-only App Secret.

STEP 2

Mint Token on Your Backend

When two users start a call on your website/app, your backend calls POST /v1/rtc/token to fetch a short-lived room JWT and ICE TURN servers.

STEP 3

Join Room from Client SDK

Pass the token into @pulsertc/sdk (Web, React Native, or Flutter) to stream low-latency 48kHz audio & HD video.

Backend Token Minting (Keep App Secret Private)
// 1. Run this on your website/app backend (keep App Secret private)
app.post('/api/calls/join-token', async (req, res) => {
  const response = await fetch('https://pulse.amiyogroup.com/v1/rtc/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-app-id': process.env.RTC_APP_ID,       // e.g. prtc_...
      'x-app-secret': process.env.RTC_APP_SECRET // secret stays on server
    },
    body: JSON.stringify({
      roomName: `order-${req.body.bookingId}`,
      identity: req.user.id,
      displayName: req.user.name,
      role: 'speaker'
    })
  });

  if (response.status === 403) {
    // Tenant minute balance exhausted or suspended
    return res.status(403).json(await response.json());
  }

  // Returns { wsUrl, token, iceServers, roomName, identity, expiresAt }
  return res.json(await response.json());
});
Frontend & Mobile App Calling SDK
import { PulseClient } from '@pulsertc/sdk';

// Point tokenEndpoint to YOUR backend route that returns { wsUrl, token, iceServers }
const client = new PulseClient({
  appId: 'prtc_your_app_id',
  tokenEndpoint: '/api/calls/join-token',
});

// Start a 1-on-1 or group HD Video + Audio Call in your website
const room = await client.joinRoom({
  roomName: 'consultation-room-42',
  identity: 'customer_104',
  displayName: 'Riya Patel',
  audio: true,
  video: true, // set false for Voice-Only calling
});

// Listen for remote participants & attach audio/video elements
client.on('trackSubscribed', ({ track, participant }) => {
  const el = track.attach();
  document.getElementById('remote-media-grid')?.appendChild(el);
});

// In-call controls
await client.setMicrophoneEnabled(false); // mute mic
await client.setCameraEnabled(false);     // toggle video
await client.leaveRoom();
Calling Control Plane Endpoints
POST/v1/rtc/token· Auth: x-app-id + x-app-secret (server-to-server)

Verifies active tenant & prepaid balance (> 0 mins), mints a scoped LiveKit SFU JWT, and returns ephemeral Coturn STUN/TURN credentials.

POST/v1/rtc/usage/report· Auth: Bearer Tenant JWT

Records metered participant-seconds, deducts tenant minute balance, and triggers call.completed / quota.low outbound webhooks.

GET/v1/rtc/records· Auth: Bearer Tenant JWT

Returns Call Detail Records (CDRs) per App ID, room, participant, and billed minutes.

GET / POST/v1/outbound-webhooks· Auth: Bearer Tenant JWT

Register HTTPS webhook receivers for call.completed and quota.low events signed with HMAC-SHA256.

POST/v1/webhooks/livekit | /razorpay | /stripe· Auth: Signed HMAC Header

Automated SFU participant_left minute metering and prepaid bundle top-up fulfillment.

Verifying Call & Quota Webhooks

Receive signed call.completed and quota.low notifications on your app server:

import crypto from 'node:crypto';

// Verify X-PulseRTC-Signature: t=17944...,v1=abcdef...
export function verifyWebhookSignature(rawBody, sigHeader, secret) {
  const parts = Object.fromEntries(sigHeader.split(',').map((kv) => kv.split('=')));
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)
    .digest('hex');
  return parts.v1 === expected;
}
Standard Error Codes
403 ZERO_BALANCE

Tenant minute balance reached 0.00. Top up a bundle to resume token minting.

403 ACCOUNT_SUSPENDED

Account suspended by platform admin. Token generation is blocked until reactivated.

401 INVALID_APP

Unknown or revoked App ID/Secret. Generate or check credentials in /portal.

429 RATE_LIMITED

Per-minute API rate limit exceeded. Respect X-RateLimit-Reset header before retrying.