AgentStream: WSS errors and handling
Short guide for AgentStream applets — Stream (unidirectional) and Voicebot (bidirectional) — when you host a wss:// endpoint. Exotel opens the WebSocket to your server; JSON events and post-call outcomes follow the main AgentStream docs.
Two places errors show up
Layer | What it is | Where |
|---|---|---|
WebSocket close code | Standard (RFC 6455) when the socket ends | Logs from your WebSocket server (the side that accepts Exotel’s connection), proxies, load balancers |
Streaming outcome | Success/failure + optional detail text | Passthru and other callbacks — often nested as Stream (same idea may appear on Status Callback depending on your setup) |
They are not the same signal. Correlate with CallSid and time.
Common WebSocket close codes
Code | Meaning |
|---|---|
1000 | Normal close |
1001 | Endpoint going away (restart, navigate, etc.) |
1002–1003 | Protocol / data type problem |
1006 | Abnormal — often no proper close frame (network drop, TLS, timeout, LB idle timeout, crash). Very common; check path and timeouts first. |
1007–1009 | Payload / policy / size |
1011 | Server error while handling the connection |
1012–1013 | Restart / try again (depends on stack) |
1005 and 1015 are reserved or synthetic in many APIs — you may still see them in logs.
Other products may use IANA-registered application codes (e.g. 3xxx) or private use 4000–4999 on your infra — not the same as text in Stream.Error.
If the socket drops often: validate wss://, cert, firewall / IP allowlist, proxy idle timeouts, and server cold start. For Support: CallSid, UTC time, close code + reason, server log snippet (redact secrets).
Stream.Error in callbacks
When streaming fails, Stream.Error may contain a short diagnostic string. Treat it as opaque — copy the full value for Exotel Support; you don’t need to parse it.
Interpret together with Stream.Status, DisconnectedBy, Disposition. If Status and Error seem inconsistent, trust the error detail and escalate with both.
Typical focus areas
Situation | Check |
|---|---|
Won’t connect | URL, DNS, TLS, firewall, allowlist |
Times out during setup | Cold start, CPU, proxy timeouts |
Dies on first events after connect | Upgrade path, auth, edge limits |
Mid-call | Load, backpressure, your app latency |
Voicebot-only | Bidirectional behaviour per AgentStream docs |
Passthru: Stream fields (when Voicebot or Stream ran before Passthru)
Present when the event store has them — field names:
StreamSID, StreamUrl, Status, Duration, RecordingUrl, Error, Disposition, DisconnectedBy, DetailedStatus
Leg1RingingDuration may sit next to Stream, not inside it. After Connect, you may also get Legs, DialCallStatus, DialWhomNumber, etc. Some parameters are tenant-specific — if something is missing, check your account docs or Support.
Encoding (query vs JSON) follows your Voice / App integration doc.
Quick checklist
- Make Passthru handlers idempotent (retries, dedupe on CallSid).
- Log CallSid, StreamSID, close code, full Stream.Error.
- Return 200 quickly; don’t log credentials in URLs.
See AgentStream Applets and the Unidirectional / Bidirectional pages on Exotel Docs for event shapes.