FAQ (19)·续

</details>

Chat

<details>

<summary>

I cannot send a chat message

</summary>

There could be multiple reasons for this.

First, try a sample meeting on the <a href="https://examples.realtime.cloudflare.com/">demo app ↗︎</a>. If you cannot send a message in the demo app, contact support. If you can send a message in the demo app, the issue is on the integration side.

To troubleshoot integration issues, first check if the user has joined the meeting successfully. If the user has <a href="https://developers.cloudflare.com/realtime/realtimekit/humans/core/meeting-object-explained/">joined</a> the meeting successfully, check if the user's <a href="https://developers.cloudflare.com/realtime/realtimekit/concepts/preset/">preset</a> has permissions to send messages. If you are using a custom UI, check if the core <a href="https://developers.cloudflare.com/realtime/realtimekit/humans/core/chat/">Chat APIs</a> are working to eliminate the Core SDK from the usual suspects.

If this does not solve the issue, check if your framework is blocking the UI. Frameworks like Material UI can block input focus using focus traps in Drawer component. There is usually a prop to disable the focus trap. Material UI has a <code>disableEnforceFocus</code> prop for this purpose.

If you are still unable to send a message, please contact support.

</details>

Notifications

<details>

<summary>

Why are SDK notifications not visible when my meeting tab is in the background or minimized? How can I see them without returning to the tab?

</summary>

Browsers do not show in-page content outside a backgrounded tab or minimized window. RealtimeKit UI Kit notifications are in-page elements, so they follow this browser behavior. Picture in Picture is a separate browser feature that can show participant video in a floating window, but it does not show notifications.<br>

A host may need to know when someone enters the waiting room, a participant joins, or recording starts while they are viewing another tab. To display system notifications outside the meeting tab, choose an approach:

  • Notifications API in the page: Use the browser <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification/Notification">Notification() constructor ↗︎</a> after requesting <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission_static">notification permission ↗︎</a>. This can notify users while the page is open. <a href="https://caniuse.com/mdn-api_notification_notification">Browser support ↗︎</a> varies, and the constructor does not work in most mobile browsers.
  • Service worker notifications: Use a service worker with <a href="https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification">showNotification() ↗︎</a>. This works in more browsers, including many mobile browsers. The meeting page must pass SDK events to the worker. A service worker alone cannot continue receiving SDK events after the tab closes.
  • Web Push: Use a service worker, the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Push_API">Push API ↗︎</a>, and a push subscription. Keep the <a href="https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe">VAPID private key on your server ↗︎</a>. Your backend can send push messages even when the meeting tab is closed.

Choose notification triggers based on where the event is available. While the meeting page is open, the SDK exposes <a href="https://developers.cloudflare.com/realtime/realtimekit/humans/core/remote-participants/events/">participant join, leave, audio, and video events</a>, <a href="https://developers.cloudflare.com/realtime/realtimekit/humans/core/local-participant/#events">local audio and video events</a>, and <a href="https://developers.cloudflare.com/realtime/realtimekit/humans/core/chat/#receiving-chat-messages">chat updates</a>. For backend-triggered notifications, subscribe to <a href="https://developers.cloudflare.com/realtime/realtimekit/webhooks/#supported-events">RealtimeKit webhooks</a>, then send relevant events to your clients. Webhooks cover a smaller set of events, including participant joins and recording status changes. They do not provide individual chat messages or waiting-room arrivals.

</details>

Recording

<details>

<summary>

Watermark images appear broken in recordings

</summary>

When you pass a watermark image URL via the <a href="https://developers.cloudflare.com/api/resources/realtime_kit/subresources/recordings/methods/start_recordings/">Start Recording</a> API, the recorder loads that image inside a browser running in a Cloudflare container. If the image appears broken, check the following:

  • CORS headers: The image URL must return proper CORS headers (for example, <code>Access-Control-Allow-Origin: *</code>) in the HTTP response. Without these headers, the browser blocks the image from loading.
  • Direct image URL: The URL must point directly to the image file (for example, <code>https://example.com/logo.png</code>), not to an HTML page that embeds the image.
  • No redirects: The URL must not redirect to another location. The recorder fetches the URL as-is, so redirects may cause the image to fail to load.

</details>

Network access

<details>

<summary>

Which domains and ports must I allowlist when my network restricts outbound traffic?

</summary>

If your network restricts outbound traffic, refer to <a href="https://developers.cloudflare.com/realtime/realtimekit/platform/network-allowlist/">Network allowlist</a> for the domains and ports required for your RealtimeKit integration.

</details>

<details>

<summary>

How can I check if my network and devices are ready for a RealtimeKit meeting?

</summary>

Go to <a href="https://test.realtime.cloudflare.com/">test.realtime.cloudflare.com ↗︎</a> and run the pre-call test. The test checks your camera, microphone, and network, and verifies connectivity to Cloudflare Realtime endpoints, so you can confirm that the required services are not blocked by your network or firewall before joining a meeting. For required domains and ports, refer to <a href="https://developers.cloudflare.com/realtime/realtimekit/platform/network-allowlist/">Network allowlist</a>.

</details>

Demo App

<details>

<summary>

Can I use the Cloudflare hosted demo app or examples in my website as an iframe?

</summary>

We strongly recommend against embedding the Cloudflare hosted demo app or examples as an iframe in your website, even if you pass authentication tokens via URL parameters.

Instead, set up the default meeting UI in your own website by following the <a href="https://developers.cloudflare.com/realtime/realtimekit/humans/ui-kit/">UI Kit setup guide</a> or deploy the <a href="https://github.com/cloudflare/realtimekit-web-examples/">RealtimeKit web examples ↗︎</a> under your own domain. The effort required for either approach is minimal and provides significant benefits:

  • Control: You maintain full control over the user experience, structure, and interface.
  • Stability: Your implementation remains consistent and will not change overnight, protecting your product from sudden disruptions.
  • Reliability: You control when and how to upgrade, ensuring a stable experience for your users.

The demo app and example applications may be updated at any time without prior notice.

</details>

Billing

<details>

<summary>

How are Audio/Video Participant and Audio-Only Participant minutes charged?

</summary>

RealtimeKit bills active participant minutes. Billing starts when a participant joins a meeting session and stops when they leave it.

<br>

Key billing rules:

  • No-shows are not billed: Adding someone with the <a href="https://developers.cloudflare.com/api/resources/realtime_kit/subresources/meetings/methods/add_participant/">Add Participant API</a> does not incur charges. RealtimeKit does not charge for that participant if they never join the meeting.
  • Usage is billed by duration: RealtimeKit charges for the exact time, including seconds, that a participant spends in an active session. The participant is still billed when they do not produce or consume audio or video.
  • Multiple tabs are billed separately: If someone joins from multiple browser tabs with the same auth token, RealtimeKit bills each tab separately. The RealtimeKit dashboard displays the aggregated duration for that participant.

For more information about the difference between meetings and sessions, refer to <a href="https://developers.cloudflare.com/realtime/realtimekit/concepts/">RealtimeKit concepts</a>.

<br>

For example:

  • If two participants join at 7:00 p.m. and leave at 7:30 p.m., each participant uses 30 minutes. RealtimeKit charges 60 participant minutes.
  • If one participant joins at 4:00 p.m., another joins at 4:03 p.m., and both leave at 5:00 p.m., they use 60 and 57 minutes. RealtimeKit charges 117 participant minutes.
  • If one participant joins at 3:00 p.m. and leaves at 3:27 p.m., while another joins at 3:05 p.m. and leaves at 3:30 p.m., they use 27 and 25 minutes. RealtimeKit charges 52 participant minutes.
  • If five participants are expected but only two join, RealtimeKit charges participant minutes only for the two participants who joined.
  • If two participants are expected to join a pre-created meeting at 2:00 p.m. but neither joins, RealtimeKit does not charge any participant minutes.

<br>

Creating meetings and participant tokens does not incur charges.

</details>

<details>

<summary>

How is composite recording export charged?

</summary>

For composite recordings, a recorder joins the meeting as a hidden virtual participant and records its view. For more information, refer to the <a href="https://developers.cloudflare.com/realtime/realtimekit/recording-guide/">recording guides</a>.

After the final participant leaves, the recorder remains active for the meeting's <a href="https://developers.cloudflare.com/api/resources/realtime_kit/subresources/meetings/methods/create/#(resource)%20realtime_kit.meetings%20%3E%20(method)%20create%20%3E%20(params)%200%20%3E%20(param)%20session_keep_alive_time_in_secs%20%3E%20(schema)"><code>session_keep_alive_time_in_secs</code></a>. The default is 60 seconds, and the maximum is 600 seconds.

RealtimeKit does not charge participant minutes for the recorder. Instead, it charges export minutes for the recorded duration. Refer to <a href="https://developers.cloudflare.com/realtime/realtimekit/platform/pricing/">RealtimeKit pricing</a> for current rates.

<br>

When <a href="https://developers.cloudflare.com/api/resources/realtime_kit/subresources/meetings/methods/create/#(resource)%20realtime_kit.meetings%20%3E%20(method)%20create%20%3E%20(params)%200%20%3E%20(param)%20record_on_start%20%3E%20(schema)"><code>record_on_start</code></a> is <code>true</code>:

  • If two participants join at 7:00 p.m. and leave at 7:30 p.m., recording starts at 7:00 p.m. After both participants leave, the recorder remains active for the default 60-second session keep-alive period. Recording stops at 7:31 p.m., so RealtimeKit charges 31 export minutes.
  • If five participants are expected but only two join at 8:00 p.m. and leave at 8:20 p.m., recording runs until 8:21 p.m. with the default session keep-alive period. RealtimeKit charges 21 export minutes. The charge would remain 21 export minutes if all five participants joined and left at the same times because participant count does not affect recording export minutes.
  • If nobody joins a pre-created meeting, recording does not start. Creating a meeting with <code>record_on_start</code> set to <code>true</code> does not incur charges by itself.

<br>

When someone starts recording during an active session:

  • If recording starts at 4:20 p.m. and the final participant leaves at 5:00 p.m., it stops at 5:01 p.m. by default. RealtimeKit charges 41 export minutes.
  • If recording starts at 4:20 p.m. and someone calls <a href="https://developers.cloudflare.com/realtime/realtimekit/humans/core/end-a-session/"><code>kickAll()</code></a> at 5:00 p.m., recording stops immediately. RealtimeKit charges 40 export minutes.
  • If a meeting and recording start at 4:20 p.m., the meeting uses a two-minute keep-alive period, and all participants close their tabs at 5:00 p.m., recording stops at 5:02 p.m. RealtimeKit charges 42 export minutes.

<br>

This keep-alive period helps workflows that must preserve a single recording across brief disconnections. For example, an education technology (EdTech) application might record a timed take-home assignment in a one-participant meeting. If the participant loses their network connection and rejoins before the keep-alive period expires, the recorder continues the same recording. The recording contains an empty gap during the disconnection, but the application does not need to combine two separate recordings.

<br>

The export charges include the keep-alive period. To avoid this extra time, explicitly end the session by calling <a href="https://developers.cloudflare.com/realtime/realtimekit/humans/core/end-a-session/"><code>kickAll()</code></a> or the <a href="https://developers.cloudflare.com/api/resources/realtime_kit/subresources/active-session/methods/kick_all_participants/">Kick all participants API</a>.

</details>

Was this helpful?

YesNo

On this page

FAQ (19)·续 - 图1Docs

{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/realtime/realtimekit/faq/#page","headline":"FAQ","description":"Frequently asked questions about RealtimeKit meetings, recordings, and SDK usage.","url":"https://developers.cloudflare.com/realtime/realtimekit/faq/","inLanguage":"en","image":"https://developers.cloudflare.com/realtime/realtimekit/faq/og.png?v=786a2d2ed91c9b96","dateModified":"2026-10-26","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}


description: Build RealtimeKit meetings for people using the web and mobile SDKs, with the prebuilt UI Kit or the Core SDK. title: Build for humans image: https://developers.cloudflare.com/realtime/realtimekit/humans/og.png?v=cb0a46c7cb9b4df3


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/realtime/llms.txt
Use this file to discover all available pages before exploring further.