Partner API base path is /api/v1 on https://api.dcast.pro. This site documents the live surface; use the Quickstart QA curls to validate keys and routes.

Embed a live stream (player and chat) on your website

You want viewers to watch your live broadcast inside your own web page, with the chat next to the player. The job is a handful of API calls, and you never write the player markup yourself: the API returns it ready to paste.

The short version: create the stream with POST /streams, allow your domain with PATCH /me/embed-allowlist, read the player and chat code from GET /streams/:id/embed and paste it as returned, point your encoder at the ingest address from the first answer, and call POST /streams/:id/start once hasSignal is true. Run the calls on your server with a pk_ key; the key never goes into browser code.

Steps in order

  1. Create the stream: POST /streams with a title and a visibility. Keep the id; the answer also carries streamKey and the ingest addresses your encoder sends to.
  2. Allow your website: PATCH /me/embed-allowlist with the domains that may show the player. The call replaces the whole list, so read the current one from GET /me (embedAllowlist) first and send it back with your domain added. An empty list means every website may show the stream.
  3. Get the embed code: GET /streams/:id/embed returns responsive and iframe for the player and chat.iframe for the live chat.
  4. Send the picture from your encoder (OBS or a hardware encoder) to the ingest address, then read GET /streams/:id/status until hasSignal is true.
  5. Go live: POST /streams/:id/start. Viewers can watch from this moment.
  6. End the show: POST /streams/:id/end. The same embed code works for the next broadcast of the stream.

The calls

CallAuthWhat you get
POST /streamskeyA stream card: id, streamKey, ingest, watchUrl, playback.
GET /mekeyembedAllowlist, the current list of allowed websites, with plan and planLimits.
PATCH /me/embed-allowlistkeyThe new list as embedAllowlist. The list belongs to the account and narrows every embed of it.
GET /streams/:id/embedkeyresponsive, iframe, url, width, height, aspectRatio and chat.iframe, chat.url.
GET /streams/:id/statuskeystatus (LIVE or OFFLINE), isLive, hasSignal, viewersCount, startedAt, endedAt, durationSeconds.
GET /streams/:id/status/streamkeyThe same fields as server-sent events: ready first, then status each time a value changes. Use it for a live dashboard.
POST /streams/:id/startkeyPuts the stream on air for viewers.
POST /streams/:id/endkeyEnds the broadcast. The stream card stays and can go live again.
GET /streams/:id/recording/qualitieskeyAfter a broadcast: the recording kept on the stream card, as qualities with quality, height, sizeBytes, ready and a downloadUrl for each.

Example with curl

# 1. Create the stream  → data.id, data.streamKey, data.ingest, data.watchUrl
curl -s -X POST "https://api.dcast.pro/api/v1/streams" -H "Authorization: Bearer pk_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" -d '{"title":"STREAM_TITLE","visibility":"PUBLIC"}'

# 2. Read the current allowlist (data.embedAllowlist), then send it back with your domain added
curl -s -H "Authorization: Bearer pk_YOUR_KEY_HERE" "https://api.dcast.pro/api/v1/me"
curl -s -X PATCH "https://api.dcast.pro/api/v1/me/embed-allowlist" -H "Authorization: Bearer pk_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" -d '{"domains":["example.com","*.example.com"]}'

# 3. The player and chat code  → data.responsive, data.iframe, data.chat.iframe
curl -s -H "Authorization: Bearer pk_YOUR_KEY_HERE" "https://api.dcast.pro/api/v1/streams/STREAM_ID/embed"

# 4. Wait for the encoder  → data.hasSignal
curl -s -H "Authorization: Bearer pk_YOUR_KEY_HERE" "https://api.dcast.pro/api/v1/streams/STREAM_ID/status"

# 5. Go live, and end the show
curl -s -X POST -H "Authorization: Bearer pk_YOUR_KEY_HERE" "https://api.dcast.pro/api/v1/streams/STREAM_ID/start"
curl -s -X POST -H "Authorization: Bearer pk_YOUR_KEY_HERE" "https://api.dcast.pro/api/v1/streams/STREAM_ID/end"

# 6. After the show, the recording kept on the stream card  → data.qualities[].downloadUrl
curl -s -H "Authorization: Bearer pk_YOUR_KEY_HERE" "https://api.dcast.pro/api/v1/streams/STREAM_ID/recording/qualities"

After the show: the recording

With recording on (the default of POST /streams) each broadcast is kept as a recording on the stream card, not as a separate video. After POST /streams/:id/end, read GET /streams/:id/recording/qualities: it lists the qualities of the recording, each with a downloadUrl for the file. A stream that has never been on air answers 404 NOT_FOUND.

Putting the player on the page

  • Paste responsive exactly as returned: it fills the width of its container in the shape of the stream. Use iframe only when you need one fixed pixel size.
  • For a smaller player, put responsive into a narrower container (for example max-width: 480px). Do not set a height, a border or a corner radius on the iframe.
  • Every embedded player starts playing by itself, muted, once it has loaded, so keep one player per page.
  • The live chat opens in the light skin, like the player. On a dark page add ?theme=dark to the chat address (chat.url, or the src of the chat iframe, also inside withChat); ?theme=auto follows the visitor's system setting and ?theme=light is the default. The skin comes only from this address, never from the visitor's DCAST account.

Which code fits which site builder

The Embed window of a stream card gives each code in two forms: the iframe tags, or one element with data-dcast-player, data-dcast-chat or data-dcast-player-chat and the script https://dcast.tv/embed/dcast.js, which draws the same iframes. Choose by what your site builder keeps.

Site builderWhat works
Shopify, Elementor, WordPress, Webflow, Squarespace, Tilda, Framer, KajabiAny code: the iframe tags or the script.
Wix, GoDaddy, Blackboard Ultra, Google SitesOnly the Player with chat block, pasted as one element.
Canvas, Blackboard Original, SharePoint, Moodle, Drupal, JoomlaDepends on the site's settings. The script is usually removed, so start with the iframe tags.
Notion, Medium, Substack, Slack, DiscordNot possible yet: these services embed from a link (oEmbed), which DCAST does not offer.

The list of allowed websites is checked against every page that frames the player, not only the last one. A builder that wraps your page in its own frame is one of those pages, so there the separate player or chat can stay blank, and the Player with chat block as one element is the code to use.

Some builders run pasted code inside a restricted (sandboxed) frame that removes permissions such as fullscreen, sound or copying. DCAST cannot change that from its side.

A separate player and a separate chat are two independent elements. In the script form each code sits in its own element, so a page builder usually puts them one under the other; in the iframe form they stand side by side. If your site keeps them in one row without wrapping, the chat is squeezed to a sliver on a phone. To keep the player and the chat together on every screen, use the Player with chat block (data-dcast-player-chat or withChat).

Put only one player of a given card on a page. If two players carry the same id, the standalone chat takes the size of the first one in the page.

Who may watch

The visibility of the stream decides who may watch: PUBLIC, LINK_ONLY, ACCESS_KEY (a password), REGISTERED or PRIVATE. The embed allowlist decides on which websites the player may appear. Both are described in Streams.

Limits

Every plan can create a stream; the plan sets how many streams run at once, how many viewers watch and how long a session may last. A call that reaches one answers with a code such as PLAN_STREAM_LIMIT_REACHED (409). The numbers of the Free plan are on Free live streaming and video API, and every plan is on pricing.

A refused call answers with error.code and error.message. The codes are listed in Errors & limits.

For AI agents

Connect the DCAST MCP server at https://api.dcast.pro/mcp. Each tool is one API operation, and dcast_get_recipe returns the exact tool-call sequence for a job.

Recipe: embed-live-player-and-chat-on-a-website. The tools run in this order: create_stream, get_embed_domains, set_embed_domains, get_stream_embed_codes, then start_stream once get_stream_status shows hasSignal true, and end_stream when the show is over.

Ask the person before set_embed_domains, because it replaces the whole list. Take the player code from get_stream_embed_codes and paste player.responsive, and chat.iframe if chat is wanted, exactly as returned; never write an iframe by hand. Call reveal_stream_key only when the person asks for the encoder address and key, and never print the key into code.

Never ask the person to create, copy or paste an API key. If the website's own server must call DCAST, call ask_site_access: the person clicks one Allow link and the key goes straight into the site's environment. You never see it.