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.
crypto.randomBytes(32)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).
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.
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.
// 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.
Connect WebRTC
Set up a WebRTC peer connection and exchange SDP (Session Description Protocol) with the server.
// 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
https://api.openai.com/v1/realtime/sessionshttps://api.itannix.com/v1/realtime/sessionsSame 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.