Quickstart Guide

Get started with the ItanniX Realtime API in 5 minutes. If you're already using OpenAI Realtime API, you'll find this familiar.

Prerequisites

  • An ItanniX account (sign up at app.itannix.com)
  • A Client ID from the dashboard (create a client in your workspace)
  • An assistant configured in your workspace

Understanding Client ID & Secret

ItanniX uses a TOFU (Trust On First Use) authentication model designed for devices and applications. This approach keeps your API keys secure on our servers while allowing devices to authenticate without pre-registration.

1 Generate Secret
On your device, generate a random 32+ character secret
crypto.randomBytes(32)
2 First Request TOFU
Send ID + Secret. Server stores the hash and enrolls device.
X-Client-Id: abc-123
X-Client-Secret: ••••••••
3 Authenticated
Future requests verified instantly. Hash matches, access granted.
Same ID + Secret → Verified ✓

Client ID

What: A unique identifier for your device or app instance.
Where: Created in the ItanniX dashboard, or generate a UUID yourself.
Stored: Can be public - it identifies, but doesn't authenticate.

Client Secret

What: A password that proves device ownership.
Where: Generate on-device (32+ random characters).
Stored: Keep secret! Store securely on the device only.

Important: Once a secret is enrolled for a Client ID, subsequent requests must use the same secret. If you lose the secret, you can reset it in the dashboard under the client settings.

For web apps, generate and store the secret in localStorage. For mobile/embedded devices, use secure storage (Keychain, SecureStorage, NVS with encryption).

1

Get Your Client ID

Log into your dashboard and create a client. Each device or application instance should have its own Client ID. Copy the Client ID - you'll use it in all API requests.

Note: Use UUID format for Client IDs (e.g., d4f8e2a1-3b7c-4e9f-a5d6-1c2b3e4f5a6b). UUIDs are unique without coordination.

2

Create a Session

Create a WebRTC session by calling the sessions endpoint with your Client ID and Secret. This returns session info and ICE servers for WebRTC connection.

Create Session
// Generate a secret once and store it securely on your device
const CLIENT_ID = 'YOUR_CLIENT_ID';
const CLIENT_SECRET = 'YOUR_GENERATED_SECRET'; // 32+ char random string

const response = await fetch('https://api.itannix.com/v1/realtime/sessions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Client-Id': CLIENT_ID,
    'X-Client-Secret': CLIENT_SECRET
  },
  body: JSON.stringify({
    modalities: ['text', 'audio']
  })
});

if (!response.ok) {
  throw new Error(`Session creation failed: ${response.status}`);
}

const session = await response.json();
console.log('Session ID:', session.id);
console.log('ICE Servers:', session.iceServers);

TOFU Enrollment: The first time you connect with a secret, your device is enrolled. Store the secret securely - subsequent connections must use the same secret.

3

Connect WebRTC

Set up a WebRTC peer connection and exchange SDP (Session Description Protocol) with the server.

WebRTC Connection
// Create peer connection with ICE servers from session
const pc = new RTCPeerConnection({
  iceServers: session.iceServers || [
    { urls: 'stun:stun.cloudflare.com:3478' }
  ]
});

// Create data channel for JSON messages
const dataChannel = pc.createDataChannel('messages', { ordered: true });

dataChannel.onopen = () => {
  console.log('Data channel opened');
};

dataChannel.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log('Received:', message);
  // Handle messages: transcripts, function calls, etc.
};

// Get user media (microphone)
const stream = await navigator.mediaDevices.getUserMedia({
  audio: {
    sampleRate: 48000,
    channelCount: 1,
    echoCancellation: true,
    noiseSuppression: true
  }
});

// Add audio track to peer connection
stream.getAudioTracks().forEach(track => {
  pc.addTrack(track, stream);
});

// Create and send offer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

// Wait for ICE gathering to complete
await new Promise((resolve) => {
  if (pc.iceGatheringState === 'complete') {
    resolve();
  } else {
    pc.onicegatheringstatechange = () => {
      if (pc.iceGatheringState === 'complete') {
        resolve();
      }
    };
  }
});

// Send SDP offer to server
const sdpResponse = await fetch('https://api.itannix.com/v1/realtime', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/sdp',
    'X-Client-Id': CLIENT_ID,
    'X-Client-Secret': CLIENT_SECRET
  },
  body: pc.localDescription.sdp
});

if (!sdpResponse.ok) {
  throw new Error(`SDP exchange failed: ${sdpResponse.status}`);
}

// Set remote description from server's answer
const answerSdp = await sdpResponse.text();
await pc.setRemoteDescription({
  type: 'answer',
  sdp: answerSdp
});

// Handle remote audio stream
pc.ontrack = (event) => {
  const remoteStream = event.streams[0];
  const audio = new Audio();
  audio.srcObject = remoteStream;
  audio.autoplay = true;
  audio.play();
};

console.log('WebRTC connected!');

Migrating from OpenAI Realtime API?

If you're already using OpenAI's Realtime API, switching to ItanniX is straightforward. Here are the key differences:

1. Change the Base URL

From: https://api.openai.com/v1/realtime/sessions
To: https://api.itannix.com/v1/realtime/sessions

Same path structure - just change the domain!

2. Add Client ID Header

Add the X-Client-Id header to all requests:

headers: {
  'X-Client-Id': 'YOUR_CLIENT_ID',  // Add this header
  'Content-Type': 'application/json'
}

3. Remove Manual Configuration

You no longer need to specify model, voice, instructions, or tools in your requests. These are automatically configured from your assistant settings in the dashboard.

Before (OpenAI):

body: JSON.stringify({
  model: 'gpt-4o-mini-realtime-preview',
  voice: 'shimmer',
  instructions: 'You are a helpful assistant...',
  tools: [...]
})

After (ItanniX):

body: JSON.stringify({
  modalities: ['text', 'audio']
  // Config is auto-injected from your assistant!
})

4. That's It!

The response format, WebRTC protocol, and message structure are identical to OpenAI's Realtime API. Your existing client code should work with minimal changes.

Next Steps