Search documentation

Search pages and headings

API Reference

POST /v1/sessions

Bootstrap a chat stream and receive the credentials, first continuation token, and initial backlog.

Opens a chat stream. Call this once per video, then drive /v1/poll with what it returns.

POST /v1/sessions
Content-Type: application/json

Request

Field Type Required Default Description
videoId string yes A full YouTube URL or a bare 11-character video id
includeInitial boolean no true Include the backlog already on the page in messages

videoId is permissive about its input — see Client Usage for every URL form that resolves.

{
  "videoId": "https://www.youtube.com/watch?v=zvwJ29RFVww",
  "includeInitial": true
}

Response

Field Type Description
videoId string The resolved 11-character id
chatType "liveChatRenderer" | "liveChatReplayRenderer" Whether this is a live chat or a replay chat
client string The innertube client that worked, e.g. WEB
host string The host that client talks to, e.g. https://www.youtube.com
endpoint "get_live_chat" | "get_live_chat_replay" The innertube endpoint that worked
apiKey string Innertube API key scraped from sw.js
webVersion string Innertube client version scraped from sw.js
token string The first continuation token
timeoutMs number How long YouTube suggests waiting before the first poll
messages Message[] The initial backlog, or [] when includeInitial is false
{
  "videoId": "zvwJ29RFVww",
  "chatType": "liveChatRenderer",
  "client": "WEB",
  "host": "https://www.youtube.com",
  "endpoint": "get_live_chat",
  "apiKey": "AIzaSy...",
  "webVersion": "2.20240726.00.00",
  "token": "0ofMyAN...",
  "timeoutMs": 1000,
  "messages": []
}

Carrying the session forward

Five of these fields are the input to every subsequent poll:

const poll = {
  token: session.token,
  client: session.client,
  endpoint: session.endpoint,
  apiKey: session.apiKey,
  webVersion: session.webVersion,
}

token is replaced by each poll response; the other four stay fixed for the life of the stream.

Live versus replay

You do not choose between them — the server detects which one the video has. chatType tells you what it found, and endpoint tells you which innertube endpoint is being used to read it. The two do not always pair the way you would expect: the server picks whichever endpoint actually returns a parseable response, so a replay chat may still be read through get_live_chat.

Errors

Status Code Cause
400 INVALID_REQUEST Body failed schema validation
400 INVALID_VIDEO_ID videoId is not a URL or id this server can parse
404 NO_LIVE_CHAT No chat renderer with a continuation token was found
502 SW_JS_FAILED Could not read the API key / client version from sw.js
502 NO_WORKING_CLIENT No client + endpoint combination was accepted
502 UPSTREAM_ERROR YouTube returned an error while bootstrapping

Full descriptions in Errors.