API reference
Errors
Every failure inside the core is thrown as a DialogueError with a stable code. What the hooks expose, though, is the lighter error EVENT payload — mind the difference.
Two shapes: the class vs. the event
The core throws a DialogueError (the full class). The event bus and hooks surface the lighter error event payload — just { code, message, recoverable }. useInterview().error is that payload, not the class, so it has no status or raw.
ts
import { isDialogueError, type DialogueError, type ErrorCode } from '@dialogueai/react';
// 1. The class — what the core throws (and what isDialogueError() narrows to).
// DialogueError extends Error with:
// code: ErrorCode // stable, switch on this
// recoverable: boolean // can retry() help?
// status?: number // HTTP status, if any
// raw?: unknown // original payload
// 2. The event payload — what hooks/onError/the bus give you (no status/raw):
type DialogueErrorEvent = { code: ErrorCode; message: string; recoverable: boolean };Use
isDialogueError(e) only on values you catch from a thrown core call (e.g. a rejected submit()). For lifecycle errors, read useInterview().error / onError and switch on .code.Handling errors
tsx
const { phase, error, retry } = useInterview(studyId);
if (phase === 'errored' && error) {
return (
<div>
<p>{error.message}</p>
{error.recoverable && <button onClick={retry}>Try again</button>}
</div>
);
}Only recoverable codes (the ✓ column below) respond to
retry(). Everything else needs a remount or a fixed config/embed.Remediation playbooks
The blockers integrators hit most often, and what actually fixes each:
| Code | Fix |
|---|---|
permission.policy-blocked | You are inside an iframe without media permissions. Add allow="camera; microphone; display-capture" to the iframe, and serve over HTTPS. Not recoverable from inside the SDK — the host embed must change. |
webrtc.blocked-by-network | A corporate firewall or VPN is blocking UDP/TURN. Ask the participant to switch networks; there is no client-side retry that fixes a blocked network. |
host.csp-blocks-livekit | Add the LiveKit signaling/media origins to the host page's Content-Security-Policy (connect-src + media-src). A same-origin proxy does not help here — WebRTC needs the real origins. |
config.already-open-elsewhere | Another interview instance is mounted. Tear it down (unmount the provider / Dialogue("destroy")) before opening a new one. Recoverable via retry() once the other instance is gone. |
config.screen-share-unavailable | The study requires screen share but the browser/context cannot provide it (no getDisplayMedia, or a blocking permissions policy). There is no fallback — the participant needs a supported browser. |
auth.origin-not-allowed | The page origin is not on the key allow-list. Add it in the Dialogue dashboard. This is a config fix, not a retry. |
Error codes
auth
| Code | Meaning | Recoverable |
|---|---|---|
auth.invalid-publishable-key | The publishable key was rejected. | — |
auth.bootstrap-failed | Bootstrap token exchange failed. | ✓ |
auth.bootstrap-token-expired | The bootstrap token had already expired. | — |
auth.invalid-bootstrap-token | The bootstrap token was malformed or rejected. | — |
auth.origin-not-allowed | The current origin is not allow-listed for this key. | — |
auth.token-refresh-failed | A session-token refresh failed. | — |
study
| Code | Meaning | Recoverable |
|---|---|---|
study.not-found | No study matches the studyId. | — |
study.paused | The study is paused. | — |
study.quota-exceeded | The study has hit its participant quota. | — |
study.not-active | The study is not currently accepting participants. | — |
study.already-completed | This participant already completed the study. | — |
permission / device
| Code | Meaning | Recoverable |
|---|---|---|
permission.camera-denied | Camera permission was denied. | ✓ |
permission.microphone-denied | Microphone permission was denied. | ✓ |
permission.screen-share-denied | Screen-share permission was denied. | ✓ |
permission.camera-not-readable | The camera is in use or unreadable. | ✓ |
permission.microphone-not-readable | The microphone is in use or unreadable. | ✓ |
permission.camera-overconstrained | No camera satisfies the constraints. | ✓ |
permission.policy-blocked | A permissions policy blocked media (e.g. iframe allow=). | — |
device.no-camera-found | No camera device is available. | ✓ |
device.no-microphone-found | No microphone device is available. | ✓ |
webrtc / host
| Code | Meaning | Recoverable |
|---|---|---|
webrtc.connection-failed | The WebRTC connection could not be established. | ✓ |
webrtc.blocked-by-network | Network/firewall blocked the media connection. | — |
webrtc.disconnected-unrecoverable | The connection dropped unrecoverably. | — |
host.csp-blocks-livekit | The host page's CSP blocks the LiveKit endpoint. | — |
config / internal
| Code | Meaning | Recoverable |
|---|---|---|
config.publishable-key-and-init-mismatch | init() called twice with a different config. | — |
config.already-open-elsewhere | An interview is already open elsewhere. | ✓ |
config.screen-share-unavailable | Screen share is required but unavailable. | — |
interview.studyId-locked | The studyId cannot change after creation. | — |
internal.unknown | An unexpected error. | — |
internal.contract-mismatch | A response did not match the expected contract. | — |