Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.apifycloud.io/llms.txt

Use this file to discover all available pages before exploring further.

Organised by symptom — search for what your users report, not what you think the cause is. Each entry links to the relevant guide for the full context.

The widget doesn’t appear on the page

Your CSP blocks the iframe. Add the widget origin to the relevant directives — see Embedding — Content Security Policy.
Some blocklists flag third-party embedded widgets. Ask the visitor to allowlist your domain, or test with blockers disabled to confirm.
The app id in the iframe URL must match the one in the console. A typo surfaces an error screen inside the iframe. The app id is visible in the console under the app’s settings.
WebRTC requires HTTPS. The page embedding the widget must also be served over HTTPS.
Some sites set X-Frame-Options or a frame-ancestors CSP directive that prevents iframes from embedding anything. If you see a browser console error about framing being refused, review those headers on your own site (not ours).

Widget loads but shows an error

The app needs a VoIP provider activated in the console for the widget to initialise. Without it, the session-token request fails and the widget drops into the error state. Check the app’s provider configuration.
The visitor’s browser couldn’t reach our runtime — typically a transient connectivity issue or a corporate proxy blocking the request. Retrying usually resolves it.
If the embed’s widget key doesn’t match what the runtime expects (for example, after a manual copy-paste error), the session token request is rejected and the widget enters the error state. Verify the widget key in the console matches what’s embedded.

Widget shows the “closed” state

The profile’s business hours evaluate to closed at the visitor’s access time. Confirm the schedule and timezone in the console. See Business hours.
The widget accepts an internal flag that boots it directly into the closed state (useful for testing the closure UI). Check the URL used on the failing page for any unexpected parameters.

Microphone permission fails

Browsers cache the denied state indefinitely. The widget surfaces a “permission blocked” message with the steps to re-enable it. Pages can’t programmatically re-prompt after a deny.
The microphone only works on https://. The widget surfaces a clear error message in this case.
If you embedded the iframe manually, the attribute is required — see Embedding.
If your page is nested in another iframe, the outer container must delegate microphone=(self "https://c2c.apifycloud.io"). See Embedding — Nested iframes.
On iOS, Settings → Safari → Microphone has a global setting. If the user has set it to “Deny”, page-level grants don’t override it.

Can’t tap the call button (disabled)

If you configured required fields in the pre-call form, the call button stays disabled until all of them have a value. Hover the button for the “complete the required fields” tooltip.
The widget surfaces a mic banner before the call button is usable. The visitor must grant permission first.
Briefly after page load, the widget fetches a session token. The call button is inactive during that window. If it stays inactive, see Widget loads but shows an error.

Call starts but doesn’t reach the agent

If the app has no SIP destination (directly or via a default profile), the answer webhook replies with a spoken “no destination” message instead of connecting the call. Add at least one SIP destination in the console.
Passing ?r=PROFILE_ID for a profile that doesn’t exist for this app silently falls back to the default. If the default is also missing, the call fails with a spoken error. Double-check the profile id.
The SIP endpoint you configured may be offline, behind a firewall, or incorrectly formatted. Test the URI from your contact centre’s side to confirm it can receive calls.

Call connects but no audio (one-way or no-way)

Happens when the call is initiated without a user gesture. Always trigger calls from a direct tap or click.
Ask the user to check system volume and the active output device (Bluetooth headset vs. speakers). The widget uses the OS default.
Some corporate networks block UDP, which degrades WebRTC audio. See Network requirements.

Calls cut off or drop unexpectedly

WebRTC sessions don’t survive IP changes. This is a protocol limitation.
Check the Network indicator state at the time of the drop. Sustained poor → call fails.
Obvious but common. Mobile devices locking the screen usually maintain the call; desktops sleeping don’t.

Calls sound bad (distortion, echo, jitter)

BT headsets can add latency and introduce artefacts. Wired earbuds are usually cleaner.
A surprising share of “bad call” reports trace back to cheap USB headsets with variable mic gain. See Audio quality — admin fixes.
See the Network indicator state. Consistent amber/red is a network quality issue, not a widget bug.
Agents not using a headset (speakers + mic open) get feedback. Require headsets for agents.

Survey doesn’t appear after the call

Each profile has a Satisfaction Survey toggle. If it’s off, the widget jumps from ended directly to closed and no survey renders.
The survey only renders if the Call Studio design includes survey blocks on the survey page. An empty page means the widget also skips to closed.
If the call ends in the error state (media failure, no destination, etc.), the widget doesn’t show a survey.

A block I added in Call Studio doesn’t appear in the widget

Call Studio has a separate page per call state (idle, calling, ended, survey, survey_submitted, closed). A block you added on the ended page is only rendered when the call has ended — not when you open the widget from idle.
Make sure the save action completed in Call Studio. Reload the editor to confirm the change persists.
If the widget design has a dedicated survey_submitted page, after the visitor submits the survey the widget switches to that page. Blocks on the regular survey page aren’t rendered there.

Webhooks don’t arrive

After 20 consecutive failures the integration is deactivated automatically. In the console, its status shows Paused — fix the underlying issue, then reactivate it. See Integrations — Circuit breaker.
Easy to miss. Open the integration editor and confirm the event name is selected.
Any 4xx response stops retries immediately. Fix the endpoint to accept the payload or correct the integration config.
64 KB cap. Widget events are well under this — if you’re hitting it, the URL context is likely being abused.

Events arrive with missing context

Keys must match ^[a-zA-Z0-9_\-.]{1,64}$. Names with spaces, non-ASCII characters, or special symbols are dropped silently. See Embedding — URL context.
Later keys are dropped once the total budget is hit. Keep values short.
Per-value cap — individual oversized values get truncated.
session, preview, configId, r, lang are reserved for the runtime and never exposed as context.

Custom code doesn’t fire

Move it to Body end in Call Studio, or wrap it in a DOMContentLoaded listener.
Check the iframe’s dev tools Network tab for blocked requests — ad blockers, privacy extensions, or the user’s corporate proxy can block third-party scripts.
The sandbox has an opaque origin. See Custom code — Limitations.
Handler errors are swallowed to protect other handlers. Check the sandbox iframe’s console directly.

Parent-frame events not received

When embedded in an iframe, the widget can send postMessage events to the parent page. If your parent isn’t receiving them:
The widget only emits to origins explicitly authorised for your app. Without an allowlist, it emits nothing — by design.
Firefox doesn’t expose the parent’s origin automatically. The parent page must send a c2c:handshake message after the iframe loads. See Embedding — Firefox handshake.

Preview mode differs from production

The widget’s preview mode (used inside Call Studio) is deliberately isolated from real call flows:
  • No audio session is established — the VoIP SDK doesn’t initialise, and tapping the call button does not place a real call.
  • Custom code is not executed — the sandbox iframe isn’t created in preview, so injected analytics / scripts won’t run.
  • Events aren’t forwarded to integrations — the preview never hits your webhook endpoints.
  • A state switcher is visible — an extra UI control lets designers navigate between widget states manually.
If your preview and production behave differently, it’s almost always one of these by design.

Getting support

If none of the above matches, open a support ticket with:
  • App ID
  • Browser and OS versions
  • Timestamp of the issue (include timezone)
  • Steps to reproduce

What’s next

Network requirements

What your network needs for reliable calls.

Security

Sandbox, encryption, and data boundaries.