Speak Restreaming via API
A Speak room stores restream profiles, which say where the meeting stream goes and with which key. A profile belongs to the room rather than to a single call, so a YouTube or Twitch destination set once works in every meeting held in that room. The room interface calls this object a destination; the API calls it a restream profile and uses the restreams and restream_id fields.
Through the API you define profiles when you create a room and change them with a separate request. The host no longer pastes a URL and a key before going live: they open the restream panel and flip a toggle. Before you begin, read the general API guidelines.
Who this article is for
- Webinar platform developers — you create rooms that must already contain streaming destinations
- LMS and CRM backend developers — the broadcast schedule and platform URLs live in your system
- Integrators — you need to fill in stream keys without involving the host
When to set restream profiles in code
- Rooms are created in batches. Your system creates a room per webinar, and each one needs YouTube and Twitch ready to go.
- The host must not see the keys. You keep platform keys on your side, and the host only flips a toggle in the room.
- A platform reissued a key. You change
stream_keywith one request instead of opening every room in the interface. - Destinations depend on the schedule. One course streams to YouTube, another to Twitch, and your backend decides which.
How restream profiles work
- You create a room and pass a
restreamsarray with a name, URL, and stream key. - Kinescope detects the platform from the URL domain and returns it in the
servicefield. - Profiles come back in the
restreamsfield of the room object and stay there until the room is deleted. - A host or co-host turns on the profile they need in the restream panel, with no URL or key to type.
- While a profile is not streaming, you can change it with
PATCH.
What you need
- A workspace API token in the
Authorization: Bearer YOUR_API_TOKENheader. - The room owner’s ID for the
owner_idfield. The user must belong to the same workspace, otherwise the request fails. - A URL and a stream key from the external platform. Restreaming in Speak explains where each platform keeps them.
Create a room with restream profiles
POST https://
The API has no “add a profile to a room” method. Profiles are defined only when the room is created.
curl -X POST 'https://api.kinescope.io/v1/speak/rooms' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"owner_id": "5b8a54a1-1f4f-4a5f-9a3a-2a4b0e2f1c77",
"name": "Webinar: case studies",
"type": "permanent_meeting",
"restreams": [
{
"name": "YouTube Live",
"url": "rtmp://a.rtmp.youtube.com/live2",
"stream_key": "xxxx-xxxx-xxxx-xxxx-xxxx"
},
{
"name": "Twitch",
"url": "rtmp://live.twitch.tv/app",
"stream_key": "live_xxxxxxxxxx"
}
]
}'
Profile fields:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Profile name, 1 to 128 characters |
url | string | Yes | The platform’s RTMP URL, without the stream key |
stream_key | string | Yes | The platform’s stream key, 1 to 512 characters |
Send url and stream_key separately: do not join them into one string. Kinescope trims spaces and trailing slashes in url itself.
Profiles are created together with the room in a single transaction. If even one profile fails validation, the room is not created, so fix the request body and send the whole thing again. A room holds up to 15 profiles.
A successful request returns 200 OK with the room object:
{
"data": {
"id": "9f1d3c02-77a0-4f5e-8b26-1e0a5d3c8b41",
"name": "Webinar: case studies",
"type": "permanent_meeting",
"code": "jqi-qhua-glk",
"link": "https://speak.kinescope.io/jqi-qhua-glk",
"status": "pending",
"restreams": [
{
"id": "3c7f1b84-5d20-4e91-a0c6-8f2b1d4e7a93",
"room_id": "9f1d3c02-77a0-4f5e-8b26-1e0a5d3c8b41",
"name": "YouTube Live",
"url": "rtmp://a.rtmp.youtube.com/live2",
"stream_key": "xxxx-xxxx-xxxx-xxxx-xxxx",
"service": "youtube",
"created_at": "2026-10-12T13:20:00.000000Z",
"updated_at": null
}
],
"created_at": "2026-10-12T13:20:00.000000Z"
}
}
Save the profile id: you need it to change the URL or the key.
Which platforms Kinescope recognizes
Kinescope computes service from the url domain, so you never send it. When the URL changes, the value is recalculated.
| Value | Domain |
|---|---|
youtube | youtube.com |
twitch | twitch.tv |
telegram | t.me |
kinescope | kinescope.io |
custom | any other domain |
Subdomains count too: rtmp:// resolves to youtube.
Read the saved profiles
There is no separate endpoint that lists profiles. They arrive in the restreams field of the room object, sorted by creation date:
curl 'https://api.kinescope.io/v1/speak/rooms/9f1d3c02-77a0-4f5e-8b26-1e0a5d3c8b41' \
-H 'Authorization: Bearer YOUR_API_TOKEN'
Every room in the GET /v1/speak/rooms response carries the same field, so you can export the profiles of all rooms with one paginated request.
Change the URL, key, or name
PATCH https://
Send only the fields you need to change:
curl -X PATCH 'https://api.kinescope.io/v1/speak/rooms/9f1d3c02-77a0-4f5e-8b26-1e0a5d3c8b41/restreams/3c7f1b84-5d20-4e91-a0c6-8f2b1d4e7a93' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"stream_key": "yyyy-yyyy-yyyy-yyyy-yyyy"
}'
| Value to send | Result |
|---|---|
| Omit a field | Its value does not change |
"name": "New name" | Changes the profile label in the destination list |
"url": "rtmp://..." | Changes the platform URL, and service is recalculated from the new domain |
"stream_key": "..." | Changes the stream key |
Length limits match those at creation: name is 1 to 128 characters, stream_key is 1 to 512.
The response contains the updated profile, not the whole room. The change applies the next time the restream starts.
409 with code 409298. Stop the restream in the room first, then repeat the request.Delete profiles together with the room
DELETE https://
The API has no method for deleting a single profile. Profiles live exactly as long as the room does:
curl -X DELETE 'https://api.kinescope.io/v1/speak/rooms/9f1d3c02-77a0-4f5e-8b26-1e0a5d3c8b41' \
-H 'Authorization: Bearer YOUR_API_TOKEN'
The request ends the room, disconnects participants, shuts down active restreams, and deletes all of the room’s profiles. Repeating DELETE on the same room also returns success, so it is safe inside a retry loop.
To remove a single destination and keep the room, a host or co-host clicks Delete next to the destination in the restream panel. The same panel is where profiles are added to a room that already exists.
Limits
| Item | Value |
|---|---|
| Profiles per room | up to 15 |
| Restreams running at once in a call | up to 5 |
name length | 1 to 128 characters |
stream_key length | 1 to 512 characters |
| Starting and stopping a restream via API | not available |
| Adding and deleting a single profile via API | not available |
stream_key in plain text. A stream key lets anyone broadcast to your platform account, so call these endpoints only from your backend. Do not expose an API token in a browser or mobile application, and do not show raw API responses to end users.Handle common errors
| HTTP | Code | When it happens |
|---|---|---|
400 | 400289 | The room creation request contains more than 15 profiles |
400 | 400400 | name, url, or stream_key fails validation |
404 | 404404 | The room or the profile was not found in your workspace |
409 | 409298 | The profile is streaming and cannot be changed |
The error body format and the invalid_params fields are described in the general API guidelines.
404404 is easy to hit with a valid restream_id and the wrong room_id: a profile is looked up strictly inside the room you name and inside your workspace.
What’s next?
After you set up restream profiles:
- Restreaming in Speak — how the host starts destinations from the room and what a dropped stream looks like
- Speak login link with the administrator role — a JWT in the link so the host can start restreams right away
- Speak API reference — rooms, participants, and calls with parameters and examples
- General API Guidelines — authorization, response format, and rate limits
Questions? Write to the support chat in the Kinescope interface.