WebSocket V3 Quick Start Guide
Beta: V3 · Current: V2 — V3 is a closed beta. Contact your Signapse account contact for access. Message shapes, defaults, and limits may change; read limits and config_applied from session.ready at runtime rather than hard-coding. Use V2 for new production integrations until V3 reaches GA.
Get a signed MP4 URL back from V3 in a few messages: open a session, send one text message, receive a result, close cleanly.
Prerequisites
- A WebSocket client (Node.js
ws, Pythonwebsockets, or any WebSocket-capable environment). - Beta access from Signapse — contact your account contact to be enabled on the endpoint.
- The beta endpoint:
wss://ai.api.production.signapsesolutions.com/ws/.
Hello World
Select a language in the code panel to see the complete example. Each one:
- Opens the socket to the beta endpoint
- Sends
session.startwithversion: "3.0",mode: "translate", and adigital_signer - On
session.ready, sends onetextmessage with a client-generatedid - Prints the MP4 URL from the
resultframe - Sends
session.end, receivessession.summary, and closes
Understanding the flow
session.start— must be the first message.versionmust be"3.0",modepicks the output shape (translatefor MP4 per message,streamfor HLS), andconfig.digital_signeris required.session.ready— echoes aconfig_appliedblock (defaults resolved) and alimitsobject. Readlimitsat runtime — they may be tuned per account.text— carriesid(unique within the session) and UTF-8data.idis echoed asrefon every downstream frame.text.ack— the message entered the pipeline. Rendering is still in flight.result— a signed MP4 URL, valid for 5 minutes. Includesduration_secondsand apipeline_msbreakdown.session.end/session.summary— clean close.session.summary.usage.total_video_duration_secis the billable duration for the session.
Pipelining and backpressure
Up to max_inflight (default 3) text messages can be in flight concurrently. Beyond that, the server returns backpressure with retry_after_seconds: 2. result messages may arrive out of order relative to submission — always correlate by ref.
Recovering a lost result
If the socket drops between text.ack and result, reconnect (starting a new session) and send {"type": "result.fetch", "id": "<original-text-id>"}. If the result is still cached (5-minute TTL) it is returned as a normal result frame; otherwise you get result_expired.
Common issues
| Problem | Solution |
|---|---|
session_not_started | session.start must be the first message on the socket. |
duplicate_id | Each text id must be unique within the session — use UUIDs or a monotonic counter. |
text_too_long | data exceeds limits.max_text_length (bytes, not characters). UTF-8 non-ASCII characters cost more. |
backpressure | Wait for outstanding results before sending more text messages. |
rate_limited | Honour retry_after_seconds. |
| Socket upgrade returns 400/401 | Your account is not enabled for the beta yet — contact Signapse. |
V3 vs V2
V3 adds:
- Explicit session lifecycle (
session.start/session.end) - Per-message correlation via
id→ref - Concurrent messages (up to
max_inflight) - Structured, typed error codes with
severityandretryable result.fetchrecovery within a 5-minute TTL- Runtime
limitsand timing diagnostics (pipeline_ms)
When to stay on V2:
- You need general availability today — V3 is in closed beta.
- You have a working V2 integration and don’t need per-message MP4 delivery or the recovery/telemetry additions.
// Install: npm install ws
const WebSocket = require('ws');
const ws = new WebSocket('wss://ai.api.production.signapsesolutions.com/ws/');
ws.on('open', () => {
ws.send(JSON.stringify({
type: 'session.start',
version: '3.0',
mode: 'translate',
config: { digital_signer: 'MAX', language: 'ASL', resolution: '720p' }
}));
});
ws.on('message', (data) => {
const msg = JSON.parse(data);
switch (msg.type) {
case 'session.ready':
console.log('Session ready:', msg.session_id, 'limits:', msg.limits);
ws.send(JSON.stringify({
type: 'text',
id: 'msg-1',
data: 'Welcome to Terminal 5.'
}));
break;
case 'text.ack':
console.log('Acked:', msg.ref);
break;
case 'result':
console.log('MP4 ready:', msg.url, 'expires:', msg.url_expires_at);
ws.send(JSON.stringify({ type: 'session.end' }));
break;
case 'error':
console.error('Error:', msg.code, msg.message, 'retryable:', msg.retryable);
break;
case 'session.summary':
console.log('Summary:', msg.usage);
break;
}
});
ws.on('close', () => console.log('Closed'));{
"type": "session.ready",
"session_id": "sess-8a2b1e3f",
"config_applied": {
"output_format": "MP4",
"digital_signer": "MAX",
"language": "ASL",
"resolution": "720p"
},
"limits": {
"max_text_length": 5000,
"max_messages_per_minute": 60,
"max_inflight": 3
}
}