- Introduction
- HTTP API
- WebSocket API
- Objects Reference
SoundCTL is a simple API for real-time audio processing, mixing and routing. Our goal is to provide developers with a simple and programmatic interface to our powerful audio engine.
Inputs
Inputs are used to get audio data into your SoundCTL instance. There are two types of Input:
- data : input consisting of audio data sent by the client to your instance.
Examples: music file, microphone.
- url : input consisting of the URL of a remote resource to be loaded into your instance.
Examples: YouTube URL, Soundcloud track URL, Icecast/Shoutcast stream etc.
Links
A Link is a connection between an input and an output. It's the way to route audio from an input to an output, just like an aux cable.
Outputs
An Output is a live stream transmitted by your instance at which your clients can connect and listen to. An Output is an entity that receives data from an Input through a Link, encodes it and makes it available to all your clients.
Both Inputs and Outputs have several controls and properties that allow you to have the highest degree of control over your sound.
Controls:
- Volume
- Equalizer
- Filters (highpass/lowpass)
Read-Only Properties:
- Volume level peaks and averages
Here's a quick step by step guide to create your first stream using SoundCTL API.
A SoundCTL instance, a terminal, cURL , FFmpeg, an mp3 music file.
First of all let's create an input by issuing the following command:
curl -H 'Authorization: api YOUR_API_KEY' -H 'Content-Type: application/json' -X POST -d '{"type": "data", "format": "mp3"}' "https://YOUR_INSTANCE_ID.soundctl.io/inputs"
Note: Make sure you replace YOUR_API_KEY and YOUR_INSTANCE_ID with the appropriate values. You can find both in your dashboard.
If everything went smoothly you'll get a nice JSON response similar to this:
{
"type": "data",
"id": "REn35K4Ogh04LZ6k",
"createAt": "2016-05-06T07:41:26.512Z",
"status": "idle",
"format": "mp3",
"streamUrl": "https://YOUR_INSTANCE_ID.soundctl.io/rx/REn35K4Ogh04LZ6k.mp3"
}
Now we are going to use a very useful tool called FFmpeg to stream a mp3 encoded audio file to our instance.
To do so we need to use the streamUrl from the previous response and start sending data to it:
ffmpeg -re -i track.mp3 -c:a copy -f mp3 "https://YOUR_INSTANCE_ID.soundctl.io/rx/REn35K4Ogh04LZ6k.mp3?key=YOUR_API_KEY"
curl -H 'Authorization: api YOUR_API_KEY' -H 'Content-Type: application/json' -X POST -d '{"type": "transmission", "format": "mp3"}' "https://YOUR_INSTANCE_ID.soundctl.io/outputs"
Again if everything went right you'll get a JSON response containing the output's info:
{
"type": "transmission",
"id": "GN0aqrW7mUBdZbzY",
"createAt": "2016-05-06T07:55:24.750Z",
"status": "active",
"format": "mp3",
"bitRate": 128,
"sampleRate": 48000,
"channels": 2,
"streamUrl": "https://YOUR_INSTANCE_ID.soundctl.io/tx/GN0aqrW7mUBdZbzY.mp3"
}
Here we are going to connect the Input and the Output we just created.
To do so we create a Link:
curl -H 'Authorization: api YOUR_API_KEY' -H 'Content-Type: application/json' -X POST -d '{"src": "REn35K4Ogh04LZ6k", "dst": "GN0aqrW7mUBdZbzY"}' "https://YOUR_INSTANCE_ID.soundctl.io/links"
Now it's time to verify that everything worked correctly by listening to the transmission:
ffplay "https://YOUR_INSTANCE_ID.soundctl.io/tx/GN0aqrW7mUBdZbzY.mp3"
Note: You can use any player of your choice to play the output transmission.
Here's a collection of simple demonstrations and prototypes built using SoundCTL's Audio API.
This demo lets you create a transmission directly from your browser.
It works by capturing your microphone's input through the WebAudio API. It then automatically encodes and sends it to your SoundCTL instance, ready to mixed and broadcasted.
SoundCTL HTTP API is REST friendly. It has predictable resource-oriented URLs. It supports Authentication through built-in HTTP features and cross-origin resource sharing allowing you to interact securely with our API from any client-side app. Requests and reponses are all in JSON format for easy and human-readable data representation.
SoundCTL enforces a secure connection (SSL/TLS) on all API calls. Any attempt to make a request over a non encrypted connection will fail. Any API request without authentication will also fail with HTTP status code 401.
SoundCTL provides two methods of authentication:
Each time you create a new SoundCTL.io instance we will randomly generate for you an API key that you can use to access the API routes. You can authenticate using your API Key either by HTTP Authorization header (recommended) or by URL query param:
curl -v -H "Authorization: api yQsz3uvr9WdTUIdKTzcXbNo9fJoudvpqw8sT6mqOjkMYmPejg9EjpeV5Lut3UWm" "https://callsign.soundctl.io/inputs"
curl -v "https://callsign.soundctl.io/inputs?key=yQsz3uvr9WdTUIdKTzcXbNo9fJoudvpqw8sT6mqOjkMYmPejg9EjpeV5Lut3UWm"
Security Note 1 By authenticating using this method (API Key) you'll have both read and write permissions on all the provided API routes. Be careful and keep you key secured :)
Security Note 2 In the unfortunate case your API key is compromised you can generate a new one from your dashboard.
JSON Web Tokens or JWT are an open standard to securely transmit information between clients and the API. They are also a mean to authenticate to the API.
You can generate tokens for any of your clients by using your API Key as the secret.
Security Note
Using your API key to sign the tokens means that in case you need to regenerate it, all existing tokens will be permanently invalidated.
We currently support only SHA-256 as the HMAC hashing algorithm.
Example JWT Token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NjAxNzkwOTAsImV4cCI6MTQ5MTcxNTA5MCwicm9sZXMiOlsiY29uc3VtZXIiXX0.df-ZabXBsu9KJVpGYiVudHi56BM0oKyBkJtqTDqzF6o
It decodes into:
Header:
{
"typ": "JWT",
"alg": "HS256"
}
Payload:
{
"iat": 1460179090,
"exp": 1491715090,
"roles": ["consumer"]
}
Like API keys, tokens can be used to authenticate a connection either by HTTP Authorization Header (recommended) or URL Query Param:
curl -v -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NjAxNzkwOTAsImV4cCI6MTQ5MTcxNTA5MCwicm9sZXMiOlsiY29uc3VtZXIiXX0.df-ZabXBsu9KJVpGYiVudHi56BM0oKyBkJtqTDqzF6o" https://callsign.soundctl.io/inputs
curl -v https://callsign.soundctl.io/inputs?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NjAxNzkwOTAsImV4cCI6MTQ5MTcxNTA5MCwicm9sZXMiOlsiY29uc3VtZXIiXX0.df-ZabXBsu9KJVpGYiVudHi56BM0oKyBkJtqTDqzF6o
By using JSON Web Tokens it is possible to grant different levels of access to the API. The following roles are defined:
Role | Description |
---|---|
admin | The admin role has read and write permissions on all API routes. It is the same level of access as when using the API Key as authentication method. |
producer | The producer role has read permissions on all routes and write permissions on patchable routes (can only use GET and PATCH methods). |
consumer | The consumer role has read-only permissions (can only use GET method). |
In case of an error a valid HTTP Status code will be returned in the response header along with an informative JSON object in the body:
Name | Type | Description |
---|---|---|
statusCode | Integer | HTTP Response status code. |
error | String | HTTP status message. |
message | String | A message providing more details about the error. |
Example:
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Wrong API key"
}
Creates an Input.
Request
POST /inputs HTTP/1.1
Content-Type: application/json
Accept: application/json
JSON properties required to create an Input :
Name | Type | Valid values | Description |
---|---|---|---|
type | enum | data url |
The type of the input to be created. |
data Input
JSON properties required to create an Input of type data :
Name | Type | Valid values | Description |
---|---|---|---|
format | enum | opus flac aac mp3 |
The format of the audio stream to be sent. |
Example
{
"type": "data",
"format": "mp3"
}
url Input
JSON properties required to create an Input of type url :
Name | Type | Valid values | Description |
---|---|---|---|
url | String | 1 <= N <= 255 characters | URL of the remote resource to be used as input. |
Example
{
"type": "url",
"sourceUrl": "https://www.youtube.com/watch?v=ZkAT5krv_6c"
}
Response
HTTP 1.1 201 Created
Content-Type: application/json
Location: /inputs/:id
Payload Properties
JSON properties in the response body:
Name | Type | Description |
---|---|---|
id | String | The unique identifier of the resource. |
type | String | The input type. |
createAt | String | Time at which the input was created. (ISO 8601). |
status | enum | The input status. |
data Input
Additional JSON properties in the response body if the Input type is data :
Name | Type | Description |
---|---|---|
format | String | The format of the audio stream to be sent. |
streamUrl | String | The URL to be used for sending the audio data. |
Example
{
"id": "Lq1K8EZWwUYZ3kO5",
"type": "data",
"format": "mp3",
"streamUrl": "https://callsign.soundctl.io/rx/Lq1K8EZWwUYZ3kO5.mp3",
"createdAt": "2016-03-04T20:50:47.242Z",
"status": "idle"
}
To start feeding live audio data to an Input of type data you need to make an HTTP POST request and send the data using chunked encoding :
POST /rx/Lq1K8EZWwUYZ3kO5.mp3 HTTP/1.1
Transfer-Encoding: chunked
Host: callsign.soundctl.io
Example
ffmpeg -re -i example_track.mp3 -acodec copy -f mp3 "https://callsign.soundctl.io/rx/Lq1K8EZWwUYZ3kO5.mp3?key=yQsz3uvr9WdTUIdKTzcXbNo9fJoudvpqw8sT6mqOjkMYmPejg9EjpeV5Lut3UWm"
url Input
Additional JSON properties in the response body if the Input type is url :
Name | Type | Description |
---|---|---|
sourceUrl | String | URL of the remote resource used as input. |
Example
{
"id": "B0Lq8XrO6uYJbWK2",
"type": "url",
"sourceUrl": "https://www.youtube.com/watch?v=ZkAT5krv_6c",
"createdAt": "2016-03-04T20:50:47.242Z",
"status": "idle"
}
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 500 Internal Server Error
Request
DELETE /inputs/:id HTTP/1.1
Accept: application/json
Response
{
"success": true
}
401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Example
curl -v -X DELETE "https://callsign.soundctl.io/inputs/B0Lq8XrO6uYJbWK2"
Request
GET /inputs/:id HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Example
curl -v "https://callsign.soundctl.io/inputs/Lq1K8EZWwUYZ3kO5"
Response
{
"id": "Lq1K8EZWwUYZ3kO5",
"type": "data",
"format": "mp3",
"streamUrl": "https://callsign.soundctl.io/rx/Lq1K8EZWwUYZ3kO5.mp3",
"createdAt": "2016-03-04T20:50:47.242Z",
"status": "active"
}
Request
GET /inputs HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
Properties
Type | Description |
---|---|
Array of Input Objects | An array of all the existing inputs. |
401 Unauthorized
, 500 Internal Server Error
Example
curl -v "https://callsign.soundctl.io/inputs"
Response
[{
"id": "Lq1K8EZWwUYZ3kO5",
"type": "data",
"format": "mp3",
"streamUrl": "https://callsign.soundctl.io/rx/Lq1K8EZWwUYZ3kO5.mp3",
"createdAt": "2016-03-04T20:50:47.242Z",
"status": "active"
}, {
"id": "B0Lq8XrO6uYJbWK2",
"type": "url",
"sourceUrl": "https://www.youtube.com/watch?v=ZkAT5krv_6c",
"createdAt": "2016-03-04T20:50:47.242Z",
"status": "active"
}]
Retrieves the Volume of the specified Input.
Request
GET /inputs/:id/volume HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
In case of success the response body will be an array of Volume objects. The length of the array will be equal to the number of audio channels of the Input.
[
{"level": 6.00},
{"level": -5.00}
]
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Updates the Volume of the specified input.
Request
PATCH /inputs/:id/volume HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
Request body needs to be a valid JSON Patch as defined by RFC 6902.
Example
[{
"op": "replace",
"path": "/0/level",
"value": 4.00
}, {
"op": "replace",
"path": "/1/level",
"value": -4.00
}]
Response
HTTP 1.1 200 OK
Content-Type: application/json-patch+json
[{
"op": "replace",
"path": "/0/level",
"value": 4.00
}, {
"op": "replace",
"path": "/1/level",
"value": -4.00
}]
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Retrieves the Eq of the specified Input.
Request
GET /inputs/:id/eq HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
In case of success the response body will be an array of Eq objects. The length of the array will be equal to the number of audio channels of the Input.
[{
"bands": [{
"gain": 2,
"bw": 1.5,
"freq": 60
}, {
"gain": 2,
"bw": 1.5,
"freq": 120
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}]
}, {
"bands": [{
"gain": 2,
"bw": 1.5,
"freq": 60
}, {
"gain": 2,
"bw": 1.5,
"freq": 120
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}]
}]
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Updates the Eq of the specified Input.
Request
PATCH /inputs/:id/eq HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
Request body needs to be a valid JSON Patch as defined by RFC 6902.
[{
"op": "replace",
"path": "/0/bands/0",
"value": {
"gain": 1.00,
"bw": 2.00,
"freq": 45.00
}
}]
Response
HTTP 1.1 200 OK
Content-Type: application/json-patch+json
[{
"op": "replace",
"path": "/0/bands/0",
"value": {
"gain": 1.00,
"bw": 2.00,
"freq": 45.00
}
}]
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Retrieves the Filters of the specified Input.
Request
GET /inputs/:id/filters HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json-patch+json
In case of success the response body will be an array of Filters objects. The length of the array will be equal to the number of audio channels of the Input.
[{
"lowpass": {
"bw": 0.66,
"freq": 20000.0
},
"highpass": {
"bw": 0.66,
"freq": 20.0
}
}, {
"lowpass": {
"bw": 0.66,
"freq": 20000.0
},
"highpass": {
"bw": 0.66,
"freq": 20.0
}
}]
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Updates the Filters of the specified Input.
Request
PATCH /inputs/:id/filters HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
Request body needs to be a valid JSON Patch as defined by RFC 6902.
[{
"op": "replace",
"path": "/0/highpass/freq",
"value": 450
}, {
"op": "replace",
"path": "/1/highpass/freq",
"value": 450
}]
Response
HTTP 1.1 200 OK
[{
"op": "replace",
"path": "/0/highpass/freq",
"value": 450
}, {
"op": "replace",
"path": "/1/highpass/freq",
"value": 450
}]
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Request
GET /inputs/:id/meter HTTP/1.1
Accept: application/json
HTTP 1.1 200 OK
Content-Type: application/json
In case of success the response body will be an array of Meter objects. The length of the array will be equal to the number of audio channels of the Input.
Example
[{
"peak": 73.0,
"avg": 16.0
}, {
"peak": 65.0,
"avg": 14.0
}]
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Creates a Link.
Request
POST /links HTTP/1.1
Content-Type: application/json
Accept: application/json
Properties
JSON properties required to create an Link :
Name | Type | Description |
---|---|---|
src | String | The id of the source resource. |
dst | String | The id of the destination resource. |
Example
{
"src": "Lq1K8EZWwUYZ3kO5",
"dst": "NzZsGQDWxKh2X8Hc"
}
Response
HTTP 1.1 201 Created
Content-Type: application/json
Location: /links/:id
Payload Properties
JSON properties in the response body:
Name | Type | Description |
---|---|---|
id | String | The id of the resource. |
src | String | The id of the source resource. |
dst | String | The id of the destination resource. |
createdAt | String | Time at which the link was created. (ISO 8601). |
Example
{
"id": "23thKlDCqF0rJPZy",
"src": "Lq1K8EZWwUYZ3kO5",
"dst": "NzZsGQDWxKh2X8Hc",
"createAt": "2016-03-04T20:50:47.242Z"
}
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 500 Internal Server Error
Destroys a Link
Request
DELETE /links/:id HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
{
"success": true
}
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Example
curl -v -X DELETE "https://callsign.soundctl.io/links/23thKlDCqF0rJPZy"
Request
GET /links/:id HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Example
curl -v "https://callsign.soundctl.io/links/23thKlDCqF0rJPZy"
{
"id": "23thKlDCqF0rJPZy",
"src": "Lq1K8EZWwUYZ3kO5",
"dst": "NzZsGQDWxKh2X8Hc",
"createAt": "2016-03-04T20:50:47.242Z"
}
Request
GET /links HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Example
curl -v "https://callsign.soundctl.io/links"
[{
"id": "23thKlDCqF0rJPZy",
"src": "Lq1K8EZWwUYZ3kO5",
"dst": "NzZsGQDWxKh2X8Hc",
"createAt": "2016-03-04T20:50:47.242Z"
}]
Creates an Output.
Request
POST /outputs HTTP/1.1
Content-Type: application/json
Accept: application/json
JSON properties required to create an Output :
Name | Type | Valid values | Description |
---|---|---|---|
type | enum | data url |
The type of the output to be created. |
format | enum | opus flac aac mp3 |
Audio stream format. |
bitRate | Number | Look at Supported formats | Audio stream bit rate in kbit/s. |
sampleRate | Number | Look at Supported formats | Audio stream sampling rate in hertz. |
Example
{
"type": "transmission",
"format": "opus",
"bitRate": 64,
"sampleRate": 48000
}
Response
HTTP 1.1 201 Created
Content-Type: application/json
Location: /outputs/:id
Payload Properties
JSON properties in the response body:
Name | Type | Description |
---|---|---|
id | String | The unique identifier of the resource. |
type | String | The output type. |
createAt | String | Time at which the output was created. (ISO 8601). |
streamUrl | String | The URL at which clients can connect to and play the stream. |
format | enum | Audio stream format. |
bitRate | Number | Audio stream bit rate in kbit/s. |
sampleRate | Number | Audio stream sampling rate in hertz. |
channels | Number | Number of audio channels. |
Example
{
"id": "NzZsGQDWxKh2X8Hc",
"type": "transmission",
"format": "mp3",
"streamUrl": "http://callsign.soundctl.io/tx/NzZsGQDWxKh2X8Hc.mp3",
"bitRate": 64000,
"sampleRate": 48000,
"channels": 2,
"createdAt": "2016-03-04T20:50:47.242Z"
}
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 500 Internal Server Error
Request
DELETE /outputs/:id HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
{
"success": true
}
401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Example
curl -v -X DELETE https://callsign.soundctl.io/outputs/NzZsGQDWxKh2X8Hc
Request
GET /outputs/:id HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Example
curl -v https://callsign.soundctl.io/outputs/NzZsGQDWxKh2X8Hc
{
"id": "NzZsGQDWxKh2X8Hc",
"type": "transmission",
"format": "mp3",
"streamUrl": "http://callsign.soundctl.io/tx/NzZsGQDWxKh2X8Hc.mp3",
"bitRate": 64000,
"sampleRate": 48000,
"channels": 2,
"createdAt": "2016-03-04T20:50:47.242Z"
}
Request
GET /outputs HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
Properties
Type | Description |
---|---|
Array of output Objects | An array of all the existing outputs. |
401 Unauthorized
, 403 Forbidden
, 404 Not Found
Example
curl -v https://callsign.soundctl.io/outputs
[{
"id": "NzZsGQDWxKh2X8Hc",
"type": "transmission",
"format": "mp3",
"streamUrl": "http://callsign.soundctl.io/tx/NzZsGQDWxKh2X8Hc.mp3",
"bitRate": 64000,
"sampleRate": 48000,
"channels": 2,
"createdAt": "2016-03-04T20:50:47.242Z"
}]
Retrieves the Volume of the specified Output.
Request
GET /outputs/:id/volume HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
In case of success the response body will be an array of Volume objects. The length of the array will be equal to the number of audio channels of the Output.
Example
[
{"level": 6.00},
{"level": -5.00}
]
401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Updates the Volume of the specified Output.
Request
PATCH /outputs/:id/volume HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
Request body needs to be a valid JSON Patch as defined by RFC 6902.
[{
"op": "replace",
"path": "/0/level",
"value": 4.00
}, {
"op": "replace",
"path": "/1/level",
"value": -4.00
}]
Response
HTTP 1.1 200 OK
Content-Type: application/json-patch+json
[{
"op": "replace",
"path": "/0/level",
"value": 4.00
}, {
"op": "replace",
"path": "/1/level",
"value": -4.00
}]
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Retrieves the Eq of the specified Output.
Request
GET /outputs/:id/eq HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
In case of success the response body will be an array of Eq objects. The length of the array will be equal to the number of audio channels of the Output.
[{
"bands": [{
"gain": 2,
"bw": 1.5,
"freq": 60
}, {
"gain": 2,
"bw": 1.5,
"freq": 120
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}]
}, {
"bands": [{
"gain": 2,
"bw": 1.5,
"freq": 60
}, {
"gain": 2,
"bw": 1.5,
"freq": 120
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}]
}]
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Updates the Eq of the specified Output.
Request
PATCH /outputs/:id/eq HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
Request body needs to be a valid JSON Patch as defined by RFC 6902.
[{
"op": "replace",
"path": "/0/bands/0",
"value": {
"gain": 1.00,
"bw": 2.00,
"freq": 45.00
}
}]
Response
HTTP 1.1 200 OK
Content-Type: application/json-patch+json
[{
"op": "replace",
"path": "/0/bands/0",
"value": {
"gain": 1.00,
"bw": 2.00,
"freq": 45.00
}
}]
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Retrieves the Filters of the specified Output.
Request
GET /outputs/:id/filters HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
In case of success the response body will be an array of Filters objects. The length of the array will be equal to the number of audio channels of the Output.
Example
[{
"lowpass": {
"bw": 0.66,
"freq": 20000.0
},
"highpass": {
"bw": 0.66,
"freq": 20.0
}
}, {
"lowpass": {
"bw": 0.66,
"freq": 20000.0
},
"highpass": {
"bw": 0.66,
"freq": 20.0
}
}]
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
Updates the Filters of the specified Output.
Request
PATCH /outputs/:id/eq HTTP/1.1
Accept: application/json
Content-Type: application/json-patch+json
In case of success the response body will be an array of Filters objects. The length of the array will be equal to the number of audio channels of the Output.
[{
"op": "replace",
"path": "/0/highpass/freq",
"value": 450
}, {
"op": "replace",
"path": "/1/highpass/freq",
"value": 450
}]
Response
HTTP 1.1 200 OK
Content-Type: application/json-patch+json
[{
"op": "replace",
"path": "/0/highpass/freq",
"value": 450
}, {
"op": "replace",
"path": "/1/highpass/freq",
"value": 450
}]
400 Bad Request
, 401 Unauthorized
, 403 Forbidden
, 404 Not Found
, 500 Internal Server Error
Retrieves the Meter of the specified Output.
Request
GET /outputs/:id/meter HTTP/1.1
Accept: application/json
Response
HTTP 1.1 200 OK
Content-Type: application/json
In case of success the response body will be an array of Meter objects. The length of the array will be equal to the number of audio channels of the Output.
[{
"peak": 73.0,
"avg": 16.0
}, {
"peak": 65.0,
"avg": 14.0
}]
401 Unauthorized
, 404 Not Found
, 500 Internal Server Error
SoundCTL WebSocket API allows you to send Messages and receive Events in real-time, granting you the highest degree of control over your instance.
With the exception of Events the two APIs (HTTP and WebSocket) are interchangeable.
SoundCTL WebSocket API has the huge advantage of having a persistent bidirectional connection between server and clients, thus being able to send and receive a vast amount of updates in a small period of time while also keeping all the connected clients synchronized through Events.
As for the HTTP API, authentication is done either by using an API key or a JSON Web Token.
For security reasons all WebSocket connections must be initiated using the secure wss://
protocol.
Please refer to the HTTP Authentication section for more info.
var exampleSocket = new WebSocket("wss://callsign.soundctl.io/?key=yQsz3uvr9WdTUIdKTzcXbNo9fJoudvpqw8sT6mqOjkMYmPejg9EjpeV5Lut3UWm");
var exampleSocket = new WebSocket("wss://callsign.soundctl.io/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NjAxNzkwOTAsImV4cCI6MTQ5MTcxNTA5MCwicm9sZXMiOlsiY29uc3VtZXIiXX0.df-ZabXBsu9KJVpGYiVudHi56BM0oKyBkJtqTDqzF6o");
A Message is a JSON Object consisting of:
- a method identifying the action to be taken
- a path identifying the target resource
- a data object containing the payload of the request in case of success
- a list of errors in case of failure
Name | Type | Required | Description |
---|---|---|---|
method | String | true | Equivalent to the HTTP API request header method. |
path | String | true | Equivalent to the HTTP API request header URL. |
payload | Object or Array of Objects | false | Equivalent to the HTTP API request body. Not present in case of error. |
error | Object | false | An Error Object. Present only in case of error. |
Creates a new Input of type data.
{
"method": "post",
"path": "/inputs",
"payload": {
"type": "data",
"format": "mp3"
}
}
Retrieves the Input.
{
"method": "get",
"path": "/inputs/Lq1K8EZWwUYZ3kO5"
}
Updates Volume levels of an Output.
{
"method": "patch",
"path": "/outputs/6502a3d",
"data": [{
"op": "replace",
"path": "/0/level",
"value": 4.00
}, {
"op": "replace",
"path": "/1/level",
"value": -4.00
}]
}
Error destroying an Output.
{
"method": "delete",
"path": "/outputs/38cb6e3",
"errors": [{
"code": 404,
"info": "resource not found"
}]
}
Events are one of the main features of the WebSocket API. Their main purpose is to update a client whenever a resource is created, updated or destroyed. Events triggered by the change of a resource are broadcasted to all the connected clients hence keeping them synchronized.
An Input has been created:
{
"method": "post",
"path": "/inputs",
"payload": {
"id": "Lq1K8EZWwUYZ3kO5",
"type": "data",
"format": "mp3",
"streamUrl": "https://callsign.soundctl.io/LskcHe.mp3",
"createdAt": "2016-03-04T20:50:47.242Z",
"status": "idle"
}
}
The Volume of an Input has been updated:
{
"method": "post",
"path": "/inputs/Lq1K8EZWwUYZ3kO5/volume",
"payload": [{
"op": "replace",
"path": "/0/level",
"value": 4
}, {
"op": "replace",
"path": "/1/level",
"value": -4
}]
}
An Input has been destroyed:
{
"method": "delete",
"path": "/inputs/Lq1K8EZWwUYZ3kO5"
}
Input Meter update:
{
"method": "post",
"path": "/inputs/Lq1K8EZWwUYZ3kO5/meter",
"payload": [{
"op": "replace",
"path": "/0/peak",
"value": 22.33
}, {
"op": "replace",
"path": "/1/peak",
"value": 16.11
}]
}
In case of an error a Message will be sent to the client with an errors field containing a list of Error Objects.
Name | Type | Description |
---|---|---|
code | Integer | Equivalent to the HTTP response status code. |
info | String | A human-readable message providing more details about the error. |
{
"method": "delete",
"path": "/outputs/38cb6e3",
"errors": [{
"code": 404,
"info": "resource not found"
}]
}
{
"method": "post",
"path": "/inputs",
"errors": [{
"code": 400,
"info": "the specified audio format is not supported"
}]
}
Properties
Name | Type | Valid values | Description |
---|---|---|---|
level | Number | -120.00 <= N <= 120.00 | Volume level in decibels. |
Example
{
"level": -4.50
}
Properties
Name | Type | Description |
---|---|---|
bands | Array(16) | Array of Eq Band Objects |
Example
{
"bands": [{
"gain": 2.00,
"bw": 1.50,
"freq": 60.00
}, {
"gain": 2.00,
"bw": 1.50,
"freq": 120.00
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}, {
"gain": 0,
"bw": 1,
"freq": 0
}]
}
Properties
Name | Type | Valid values | Description |
---|---|---|---|
gain | Number | -50.0 <= N <= 20.0 | Amplitude response (gain) in decibels. |
bw | Number | 0.5 <= N <= 4.0 | Bandwidth (passband) in octaves. |
freq | Number | 20.0 <= N <= 20000.0 | Center frequency in hertz. |
Example
{
"gain": 2.00,
"bw": 1.50,
"freq": 45.00
}
Info
An Eq Band object with freq set to 0 is considered inactive.
Properties
Name | Type | Description |
---|---|---|
lowpass | Object | Lowpass Filter Object |
highpass | Object | Highpass Filter Object |
Example
{
"lowpass": {
"bw": 1.00,
"freq": 16000.0
},
"highpass": {
"bw": 1.00,
"freq": 45.0
}
}
Name | Type | Valid values | Description |
---|---|---|---|
bw | Number | -50.0 <= N <= 20.0 | Bandwidth in octaves. |
freq | Number | 20.0 <= N <= 20000.0 | Cutoff frequency in hertz. |
Example
{
"bw": 1.00,
"freq": 16000.0
}
Name | Type | Valid values | Description |
---|---|---|---|
bw | Number | -50.0 <= N <= 20.0 | Bandwidth in octaves. |
freq | Number | 20.0 <= N <= 20000.0 | Cutoff frequency in hertz. |
Example
{
"bw": 1.00,
"freq": 45.0
}
Properties
Name | Type | Valid values | Description |
---|---|---|---|
peak | Number | -120.00 <= N <= 120.00 | Volume level peak in decibels. |
avg | Number | -120.00 <= N <= 120.00 | Volume level average in decibels. |
Example
[{
"peak": 73.0,
"avg": 16.0
}, {
"peak": 65.0,
"avg": 14.0
}]