Introduction
Intel® Collaboration Suite for WebRTC (Intel® CS for WebRTC) solution provides a set of REST (Representational State Transfer) API for conference management. Manager clients can be implemented by different programming languages through these APIs.
Definitions
Resource: the kind of data under manipulation
Verb: HTTP verb. The mapping to operations is as following:
- Create operations: POST - Read operations: GET - Update operations(entirely): PUT - Update operations(partially): PATCH - Delete operations: DELETE
URI: the Universal Resource Identifier, or name through which the resource can be manipulated.
Request Body: the request data that user need supply to call the API. Json format data is requried.
Response Body: the response data is returned through HTTP response in JSON text format.
Making a Call
With all the management API, perform the following steps to implement each call.
- Create a string for the http request that consist of the format [HTTP verb][url] + [headers] + [request body](optional)
- Use your preferred language's network library (or http library) to send the request to REST server.
- For authentication, REST API accept HTTP authentication on each request, see Authentication and Authorization for details.
- Read the response in your programming language, and parse the response JSON data.
- Use the data in your application.
The following common HTTP status code may be returned after you make a call:
- 200 - OK. Some calls return with a JSON format response while some calls return a plain text response indicates success. - 401 - Not authenticated or permitted. - 403 - Forbidden. - 404 - NOT found or no such resource.
Besides the common HTTP response code, there are also some internal status code for specific error conditions. Following is an example for response body used to represent internal error in JSON format.
{
"error":{
"code": 1001,
"message": "Resource not found"
}
}
Note: "code": 1001 is a status code for internal error. And all the error following the same format.
Here is a table describing the internal error code.
code | description |
---|---|
1001 | general not found |
1002 | service not found |
1003 | room not found |
1004 | stream not found |
1005 | participant not found |
1101 | authentication not found |
1102 | permission denied |
1201 | failed to call cluster |
1301 | request data error |
1401 | database error |
2001 | unexpected server error |
Authentication and Authorization
The management API can only be called after authorized. To get authorized, each request should be a HTTP request with "Authorization" filed in the header. So the server can determine whether it is a valid client. The value of "Authorization" is something like:
MAuth realm=http://webrtc.intel.com,
mauth_signature_method=HMAC_SHA256,
mauth_username=test,
mauth_role=role,
mauth_serviceid=53c74879209ee7f96e5cbc9c,
mauth_cnonce=87428,
mauth_timestamp=1406079112038,
mauth_signature=ZjA5NTJlMjE0ZTY4NzhmZWRjZDkxYjNmZjkyOTIxYzMyZjg3NDBjZA==
Mauth realm=http://webrtc.intel.com, mauth_signature_method=HMAC_SHA256
mauth_username
andmauth_role
are optional.mauth_serviceid
is the ID of the service.mauth_cnonce
is a random value between 0 and 99999.mauth_timestamp
is the timestamp of the request.mauth_signature
is a signature of this request. It uses HMAC_SHA256 to sign timestamp, cnonce, username(optional), role(optional) with service key. Then encrypted it with BASE64.
Python example of encryption algorithm (JavaScript version can be found in provided samples):
from hashlib import HMAC_SHA256
import hmac
import binascii
toSign = str(timestamp) + ',' + str(cnonce)
if (username != '' and role != ''):
toSign += ',' + username + ',' + role
signed = self.calculateSignature(toSign, key)
def calculateSignature(toSign, key):
hash = hmac.new(key, toSign, HMAC_SHA256)
signed = binascii.b2a_base64(hash.hexdigest())[:-1]
return signed
toSign is the signature.
Note: If authentication failed, a response with code 401 would be returned.
Management Resource
The management API uses REST model to accessing different resources. The resources in conference management can be grouped into seven kinds:
- Rooms
- Participants
- Streams
- Streaming-ins
- Streaming-outs
- Recordings
- Token
Rooms
Description:
A room is the conference where users can communicate by real-time video and audio. Rooms are served by services. These resources can only be accessed after authenticated to their owner services. Rooms can have different settings for various scenarios. Making call on room resources provides users the ability to customize rooms for different needs.
Data Model:
object(Room):
{
_id: string,
name: string,
participantLimit: number, // -1 means no limit
inputLimit: number,
roles: [ object(Role) ],
views: [ object(View) ],
mediaIn: object(MediaIn),
mediaOut: object(MediaOut),
transcoding: object(Transcoding),
notifying: object(Notifying),
sip: object(Sip)
}
object(Role): {
role: string,
publish: {
video: boolean,
audio: boolean
},
subscirbe: {
video: boolean,
audio: boolean
}
}
object(View): {
label: string,
audio: object(ViewAudio),
video: object(ViewVideo) | false
}
object(ViewAudio): {
format: { // object(AudioFormat)
codec: string, // "opus", "pcmu", "pcma", "aac", "ac3", "nellymoser"
sampleRate: number, // "opus/48000/2", "isac/16000/2", "isac/32000/2", "g722/16000/1"
channelNum: number // E.g "opus/48000/2", "opus" is codec, 48000 is sampleRate, 2 is channelNum
},
vad: boolean
}
object(ViewVideo):{
format: { // object(VideoFormat)
codec: string, // "h264", "vp8", "h265", "vp9"
profile: string // For "h264" output only, CB", "B", "M", "H"
},
parameters: {
resolution: object(Resolution),
framerate: number, // valid values in [6, 12, 15, 24, 30, 48, 60]
bitrate: number, // Kbps
keyFrameInterval: number, // valid values in [100, 30, 5, 2, 1]
},
maxInput: number, // positive integer
bgColor: {
r: 0 ~ 255,
g: 0 ~ 255,
b: 0 ~ 255
},
motionFactor: number, // float
keepActiveInputPrimary: boolean,
layout: {
fitPolicy: string, // "letterbox" or "crop".
templates: {
base: string, // valid values ["fluid", "lecture", "void"].
custom: [
{ region: [ object(Region) ] },
{ region: [ object(Region) ] }
]
}
}
}
object(Resolution): {
width: number,
height: number
}
object(Region): {
id: string,
shape: string,
area: {
left: number,
top: number,
width: number,
height: number
}
}
object(MeidaIn): {
audio: [ object(AudioFormat) ], // Refers to the AudioFormat above.
video: [ object(VideoFormat) ] // Refers to the VideoFormat above.
}
object(MediaOut): {
audio: [ object(AudioFormat) ], // Refers to the AudioFormat above.
video: {
format: [ object(VideoFormat) ], // Refers to the VideoFormat above.
parameters: {
resolution: [ string ], // Array of resolution.E.g. ["x3/4", "x2/3", ... "cif"]
framerate: [ number ], // Array of framerate.E.g. [5, 15, 24, 30, 48, 60]
bitrate: [ number ], // Array of bitrate.E.g. [500, 1000, ... ]
keyFrameInterval: [ number ] // Array of keyFrameInterval.E.g. [100, 30, 5, 2, 1]
}
}
}
object(Transcoding): {
audio: boolean,
video: {
format: boolean,
framerate: boolean,
bitrate: boolean,
keyFrameInterval: boolean
}
}
object(Notifying): {
participantActivities: boolean,
streamChange: boolean
}
object(Sip): {
sipServer: string,
username: string,
password: string
}
Resources:
- /v1/rooms/
- /v1/rooms/{roomId}
/v1/rooms
POST
Description:
This function can create a room.
parameters:
parameters | type | annotation |
---|---|---|
roomConfig |
request body | Configuration used to create room |
This is for roomConfig
:
object(RoomConfig):
{
name:name, // Required
options: object(Room) // Refers to room data model listed above. Optional
}
response body:
type | content |
---|---|
json | A room data model represents the room created |
GET
Description:
List the rooms in your service.
parameters:
parameters | type | annotation |
---|---|---|
null | null | null |
response body:
type | content |
---|---|
json | List of room data |
Here is an example of json data:
[room0, room1, ...]
Note: Elements in list are of room data model.
Pagination
Requests that return multiple rooms will not be paginated by default. To avoid too much data of one call, you can set a custom page size with the ?per_page
parameter. You can also specify further pages with the ?page
parameter.
GET 'https://sample.api/rooms?page=2&per_page=10'
Note that page numbering is 1-based and that omitting the ?page
parameter will return the first page.
/v1/rooms/{roomId}
GET
Description:
Get information on the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
undefined | request body | Request body is null |
response body:
type | content |
---|---|
json | The required room data model |
DELETE
Description:
Delete the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID to be deleted |
undefined | request body | Request body is null |
response body: response body is empty.
PUT
Description:
Update a room's configuration entirely.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
options or {} | request body | Room configuration |
Note: options
is same as object(Options)
in 5.1, /v1/rooms/POST.
response body:
type | content |
---|---|
json | The updated room data model |
Participants
Description:
ParticipantDetail model:
object(Permission):
{
publish: {
audio: true | false,
video: true | false
} | false,
subscribe: {
audio: true | false,
video: true | false
} | false
}
object(ParticipantDetail):
{
id: string(ParticipantId),
role: string(participantRole),
user: string(userId),
permission: object(Permission)
}
Resources:
- /v1/rooms/{roomId}/participants
- /v1/rooms/{roomId}/participants/{participantId}
/v1/rooms/{roomId}/participants
GET
Description:
List participants currently in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
undefined | request body | Request body is null |
response body:
type | content |
---|---|
json | All participants in the specified room |
/v1/rooms/{roomId}/participants/{participantId}
GET
Description:
Get a participant's information from the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{participantId} | URL | Participant ID |
undefined | request body | Request body is null |
response body:
type | content |
---|---|
json | The detail information of the specified participant |
PATCH
Description:
Update the permission of a participant in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{participantId} | URL | Participant ID |
items | request body | Permission item list to be updated |
Note: This is the definition of items.
items=[
object(PermissionUpdate)
]
object(PermissionUpdate):
{
op: "replace",
// There are 2 kinds of path and value. Choose one of them.
path: "/permission/[publish|subscribe]",
value: object(Value)
OR
path: "/permission/[publish|subscribe]/[video|audio]",
value: boolean
}
object(Value):
{
audio: boolean,
video: boolean
}
response body:
type | content |
---|---|
json | The updated permission information of the specified participant |
DELETE
Description:
Drop a participant from a room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{participantId} | URL | Participant ID |
undefined | request body | Request body is null |
response body: response body is empty.
Streams
Description:
Streams model:
object(StreamInfo):
{
id: string(StreamID),
type: "forward" | "mixed",
media: object(MediaInfo),
info: object(MixedInfo) | Object(ForwardInfo)
}
object(MediaInfo):
{
audio: object(AudioInfo) | false,
video: object(VideoInfo) | false
}
object(AudioInfo):
{
status: "active" | "inactive", // For forward stream
source: "mic" | "screen-cast" | "raw-file" | "encoded-file" | "streaming", // For forward stream
format: object(AudioFormat),
optional: {
format: [object(AudioFormat)]
}
}
object(AudioFormat):
{
codec: "pcmu" | "pcma" | "opus" | "g722" | "iSAC" | "iLBC" | "aac" | "ac3" | "nellymoser",
sampleRate: number, // Optional
channelNum: number // Optional
}
object(VideoInfo):
{
status: "active" | "inactive", // For forward stream
source: "camera" | screen-cast" | "raw-file" | "encoded-file" | "streaming", // For forward stream
format: object(VideoFormat),
parameters: {
resolution: object(Resolution), // Optional
framerate: number(FramerateFPS), // Optional
bitrate: number(Kbps), // Optional
keyFrameInterval: number(Seconds), // Optional
},
optional: {
format: [object(VideoFormat)]
parameters: {
resolution: [object(Resolution)],
framerate: [number(FramerateFPS)],
bitrate: [number(Kbps] | string("x" + Multiple),
keyFrameRate: [number(Seconds)]
}
}
}
}
object(VideoFormat):
{
codec: "h264" | "h265" | "vp8" | "vp9",
profile: "CB" | "B" | "M" | "H" // For "h264" codec only
}
object(VideoParameters):
{
resolution: object(Resolution), // Refers to section 5.1, object(Resolution).
framerate: number,
bitrate: number,
keyFrameInterval: number
}
object(ForwardInfo):
{
owner: string(ParticipantId),
type: "webrtc" | "streaming" | "sip",
inViews: [string(ViewLabel)],
attributes: object(ExternalDefinedObj)
}
object(MixedInfo):
{
label: string(ViewLabel),
layout: [{
stream: string(StreamId) | undefined,
region: object(Region)
}]
}
Resources:
- /v1/rooms/{roomId}/streams
- /v1/rooms/{roomId}/streams/{streamId}
/v1/rooms/{roomId}/streams
GET
Description:
List streams in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
undefined | request body | Request body is null |
response body:
type | content |
---|---|
json | All streams in the specified room |
/v1/rooms/{roomId}/streams/{streamId}
GET
Description:
Get a stream's information from the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{streamId} | URL | Stream ID |
undefined | request body | Request body is null |
response body:
type | content |
---|---|
json | A stream's information in the specified room |
PATCH
Description:
Update a stream's given attributes in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{streamId} | URL | Stream ID |
items | request body | An array with attributes to be updated |
Note: Here is a definition of items.
items=[
object(StreamInfoUpdate)
]
object(StreamInfoUpdate):
{
// There are 4 kinds of op, path, value. Choose one of them.
op: "add" | "remove",
path: "/info/inViews",
value: string
OR
op: "replace",
path: "/media/audio/status" | "/media/video/status",
value: "active" | "inactive"
OR
op: "replace",
path: "/info/layout/[0-9]+/stream", // "/info/layout/[0-9]+/stream" is a pattern to match the needed path.
value: string
OR
op: 'replace', // For mixed stream
path: '/info/layout',
value: [
object(StreamRegion):
{
stream: string | undefined, // stream can ONLY be absent at the very last consecutive positions.
region: object(Region)
}
]
}
response body:
type | content |
---|---|
json | A stream's updated information in the specified room |
DELETE
Description:
Delete the specified stream from the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{streamId} | URL | Stream ID |
undefined | request body | Request body is null |
response body: response body is empty.
Streaming-ins
Description:
Streaming-ins model is same as Stream model.
Resources:
- /v1/rooms/{roomId}/streaming-ins
- /v1/rooms/{roomId}/streaming-ins/{streamId}
/v1/rooms/{roomId}/streaming-ins
POST
Description:
Add an external RTSP/RTMP stream to the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
pub_req | request body | Json format data with connection and media |
Note:
Object(StreamingInRequest) {
url: string,
media: {
audio: "auto" | true | false,
video: "auto" | true | false
},
transport: {
protocol: "udp" | "tcp", // "tcp" by default.
bufferSize: number // The buffer size in bytes in case "udp" is specified, 8192 by default.
}
}
response body:
type | content |
---|---|
json | The detail information of the external RTSP/RTMP stream |
/v1/rooms/{roomId}/streaming-ins/{streamId}
DELETE
Description:
Stop the specified external streaming-in in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{streamId} | URL | Stream ID |
undefined | request body | Request body is null |
response body: response body is empty.
Streaming-outs
Description:
Streaming-outs model:
object(StreamingOut):
{
id: string(id),
media: object(OutMedia),
url: string(url)
}
object(OutMedia):
{
audio: object(StreamingOutAudio) | false,
video: object(StreamingOutVideo) | false
}
object(StreamingOutAudio):
{
from: string(StreamId),
format: object(AudioFormat) // Refers to object(AudioFormat) in 5.3, streams data model.
}
object(StreamingOutVideo):
{
from: string(StreamId),
format: object(VideoFormat), // Refers to object(VideoFormat) in 5.3, streams data model.
parameters: object(VideoParametersSpecification)
}
object(VideoParametersSpecification):
{
resolution: object(Resolution), // Refers to object(Resolution) in 5.3, streams data model.
framerate: number(WantedFrameRateFPS),
bitrate: number(WantedBitrateKbps) | string(WantedBitrateMultiple),
keyFrameInterval: number(WantedKeyFrameIntervalSecond)
}
Resources:
- /v1/rooms/{roomId}/streaming-outs
- /v1/rooms/{roomId}/streaming-outs/{streamOutId}
/v1/rooms/{roomId}/streaming-outs
GET
Description:
Get all the ongoing streaming-outs in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
undefined | request body | Request body is null |
response body:
type | content |
---|---|
json | All the ongoing streaming-outs in the specified room |
POST
Description:
Start a streaming-out to the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
options | request body | Json format with url and media |
Note:
options={
url: url,
media: object(MediaSubOptions)
}
object(MediaSubOptions):
{
audio: {
from: string, // target StreamID
format: { // not work for streaming-out, "aac" will be used
codec: string, // for recording, "opus", "pcmu" ... available codec in target stream
sampleRate: number, // optional, depends on codec
channelNum: number // optional, depends on codec
}
} || false,
video: {
from: string, // target StreamID
format: { // not work for streaming-out, "h264" will be used
codec: string, // for recording, "vp8", "h264" ... available codec in target stream
profile: string // optional, depends on codec ("h264")
},
parameters: { // following values should be in stream's default/optional list
resolution: { width: number, height: number }, // optional
framerate: number, // optional
bitrate: string || number, // optional
keyFrameInterval: number // optional
}
} || false
}
response body:
type | content |
---|---|
json | The started streaming-out |
/v1/rooms/{roomId}/streaming-outs/{streaming-outId}
PATCH
Description:
Update a streaming-out's given attributes in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{streaming-outId} | URL | Streaming-out ID |
items | request body | An array with attributes to be updated |
Note: Here is the definition of items.
items=[
object(SubscriptionControlInfo)
]
object(SubscriptionControlInfo):
{
// There are 6 kinds of op, path and value. Choose one of them.
op: "replace",
path: "/media/audio/from" | "/media/video/from",
value: string
OR
op: "replace",
path: "/media/video/parameters/resolution",
value: object(Resolution) // Refers to object(Resolution) in 5.3 streams, streams model.
OR
op: "replace",
path: "/media/video/parameters/framerate",
value: "6" | "12" | "15" | "24" | "30" | "48" | "60"
OR
op: "replace",
path: "/media/video/parameters/bitrate",
value: "x0.8" | "x0.6" | "x0.4" | "x0.2"
OR
op: "replace",
path: "/media/video/parameters/keyFrameInterval",
value: "1" | "2" | "5" | "30" | "100"
}
response body:
type | content |
---|---|
json | A updated streaming-out's attributes |
DELETE
Description:
Stop the specified streaming-out in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{streaming-outId} | URL | Streaming-out ID |
undefined | request body | Request body is null |
response body: response body is empty.
Recordings
Description:
Recordings data model:
object(Recordings):
{
id: string(id),
media: object(OutMedia), // Refers to object(OutMedia) in 5.5.
storage: {
host: string(host),
file: string(filename)
}
}
Note:
object(OutMedia) is same as streaming-outs data model in 5.5.
Resources:
- /v1/rooms/{roomId}/recordings
- /v1/rooms/{roomId}/recordings/{recordingId}
/v1/rooms/{roomId}/recordings
GET
Description:
Get all the ongoing recordings in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
undefined | request body | Request body is null |
response body:
type | content |
---|---|
json | All the ongoing recordings in the specified room |
POST
Description:
Start a recording in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
options | request body | Json format with container and media |
Note:
options={
container: string,
media: object(MediaSubOptions) // Refers to object(MediaSubOptions) in 5.5.
}
container={'mp4' | 'mkv' | 'auto' | 'ts'} // The container type of the recording file, 'auto' by default.
response body:
type | content |
---|---|
json | A recording in the specified room |
/v1/rooms/{roomId}/recordings/{recordingId}
PATCH
Description:
Update a recording's given attributes in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{recordingId} | URL | Recording ID |
items | request body | An array with attributes to be updated |
Note:
items=[
object(SubscriptionControlInfo) // Refers to object(SubscriptionControlInfo) in 5.5.
]
response body:
type | content |
---|---|
json | A updated recording's attributes in the specified room |
DELETE
Description:
Stop the specified recording in the specified room.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{recordingId} | URL | Recording ID |
undefined | request body | Request body is null |
response body: response body is empty.
Token
Description:
A token is the ticket for joining the room. The token contains information through which clients can connect to server application. Note that the different rooms may have different network information, so the room must be specified for token resource. The same token cannot be reused if it has been used once. Re-generate token if clients need to connect at the second time.
Data Model:
Token data in Json example:
object(Tokens):
{
room: roomID,
user: participant's user ID,
role: participant's role,
reprefence: object(Preference)
}
object(Preference):
{
isp: string,
region: string
}
Resources:
- /v1/rooms/{roomId}/tokens
/v1/rooms/{roomId}/tokens
POST
Description:
Create a new token when a new participant access a room needs to be added.
parameters:
parameters | type | annotation |
---|---|---|
{roomId} | URL | Room ID |
{preference_body} | request body | Json format with preference, user and role |
Note:
preference_body={
preference: object(Preference), // Preference of this token would be used to connect through, refers to Data Model.
user: string, // Participant's user ID
role: string // Participant's role
}
response body:
type | content |
---|---|
json | A token created for a new participant |
Service
Description:
The service represents the host of a set of rooms. Each service has its own identifier. The service ID and key are required to generate authentication header for HTTP requests. Note that there is one super service whose ID can be specified by toml file. The service resource can only be manipulated under super service authentication while other resouces require corresponding host service's authentication. (This API may change in later versions)
Data Model:
Service data in JSON example:
object(Service):
{
_id: string, // The ID of the service
name: string, // The name of the service
key: string, // The key of the service
encrypted: boolean // Encrypted or not
rooms: [ string ] // The list of room ID under this service
}
Resources:
- /services
- /services/{serviceId}
/services
GET
Description:
Get all the services.
parameters:
parameters | type | annotation |
---|---|---|
null | null | null |
response body:
type | content |
---|---|
json | List of service data |
Here is an example of json data:
[service0, service1, ...]
Note: Elements in list are of service data model.
POST
Description:
This function can create a service.
parameters | type | annotation |
---|---|---|
ServiceConfig | request body | Configuration used to create service |
This is for ServiceConfig:
object(ServiceConfig):
{
name: string, // Name of the service to create
key: string // Key of the service to create
}
response body:
type | content |
---|---|
json | A service data model represents the service created |
/services/{serviceId}
GET
Description:
Get information on the specified service.
parameters:
parameters | type | annotation |
---|---|---|
{serviceId} | URL | Room ID |
undefined | request body | Request body is null |
response body:
type | content |
---|---|
json | The required service data model |
DELETE
Description:
Delete the specified service.
parameters:
parameters | type | annotation |
---|---|---|
{serviceId} | URL | Room ID to be deleted |
undefined | request body | Request body is null |
response body: response body is empty.