Skip to Content
SignStream APIWebSocketsV3 Quick Start (beta)

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, Python websockets, 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:

  1. Opens the socket to the beta endpoint
  2. Sends session.start with version: "3.0", mode: "translate", and a digital_signer
  3. On session.ready, sends one text message with a client-generated id
  4. Prints the MP4 URL from the result frame
  5. Sends session.end, receives session.summary, and closes

Understanding the flow

  • session.start — must be the first message. version must be "3.0", mode picks the output shape (translate for MP4 per message, stream for HLS), and config.digital_signer is required.
  • session.ready — echoes a config_applied block (defaults resolved) and a limits object. Read limits at runtime — they may be tuned per account.
  • text — carries id (unique within the session) and UTF-8 data. id is echoed as ref on every downstream frame.
  • text.ack — the message entered the pipeline. Rendering is still in flight.
  • result — a signed MP4 URL, valid for 5 minutes. Includes duration_seconds and a pipeline_ms breakdown.
  • session.end / session.summary — clean close. session.summary.usage.total_video_duration_sec is 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

ProblemSolution
session_not_startedsession.start must be the first message on the socket.
duplicate_idEach text id must be unique within the session — use UUIDs or a monotonic counter.
text_too_longdata exceeds limits.max_text_length (bytes, not characters). UTF-8 non-ASCII characters cost more.
backpressureWait for outstanding results before sending more text messages.
rate_limitedHonour retry_after_seconds.
Socket upgrade returns 400/401Your 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 idref
  • Concurrent messages (up to max_inflight)
  • Structured, typed error codes with severity and retryable
  • result.fetch recovery within a 5-minute TTL
  • Runtime limits and 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.

Request
// 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'));
Response
{
  "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
  }
}
Last updated on
Question? Give us feedback
support@signapse.ai