Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
2314 lines (1787 sloc) 44.4 KB

SoundCTL API v1 Documentation

Introduction

What is SoundCTL?

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.

Core concepts

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.

Processing

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


Quickstart

Here's a quick step by step guide to create your first stream using SoundCTL API.

Requirements

A SoundCTL instance, a terminal, cURL , FFmpeg, an mp3 music file.

Step 1 - Create an Input

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"
}

Step 2 - Start sending audio data

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"

Step 3 - Create an Output

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"
}

Step 4 - Create a Link

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"

Step 5 - Listen

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.



Demos & Prototypes

Here's a collection of simple demonstrations and prototypes built using SoundCTL's Audio API.

Web Audio Input

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.



HTTP API

Overview

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.



Authentication

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:

API Key

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

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

Roles

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).


Errors

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"
}


/inputs

POST /inputs

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"
}

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 500 Internal Server Error


DELETE /inputs

Request

DELETE /inputs/:id HTTP/1.1
Accept: application/json

Response

{
  "success": true
}

Errors

401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

Example

curl -v -X DELETE "https://callsign.soundctl.io/inputs/B0Lq8XrO6uYJbWK2"

GET /inputs/:id

Request

GET /inputs/:id HTTP/1.1
Accept: application/json

Response

HTTP 1.1 200 OK
Content-Type: application/json

Errors

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"
}

GET /inputs

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.

Errors

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"
}]

GET /inputs/:id/volume

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}
]

Errors

401 Unauthorized, 404 Not Found, 500 Internal Server Error


PATCH /inputs/:id/volume

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
}]

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error


GET /inputs/:id/eq

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
  }]
}]

Errors

401 Unauthorized, 404 Not Found, 500 Internal Server Error


PATCH /inputs/:id/eq

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
  }
}]

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error


GET /inputs/:id/filters

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
  }
}]

Errors

401 Unauthorized, 404 Not Found, 500 Internal Server Error


PATCH /inputs/:id/filters

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
}]

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error


GET /inputs/:id/meter

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

/links

POST /links

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"
}

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 500 Internal Server Error


DELETE /links/:id

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
}

Errors

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"

GET /links/:id

Request

GET /links/:id HTTP/1.1
Accept: application/json

Response

HTTP 1.1 200 OK
Content-Type: application/json

Errors

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"
}

GET /links

Request

GET /links HTTP/1.1
Accept: application/json

Response

HTTP 1.1 200 OK
Content-Type: application/json

Errors

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"
}]


/outputs

POST /outputs

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"
}

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 500 Internal Server Error


DELETE /outputs

Request

DELETE /outputs/:id HTTP/1.1
Accept: application/json

Response

HTTP 1.1 200 OK
Content-Type: application/json
{
  "success": true
}

Errors

401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error

Example

curl -v -X DELETE https://callsign.soundctl.io/outputs/NzZsGQDWxKh2X8Hc

GET /outputs/:id

Request

GET /outputs/:id HTTP/1.1
Accept: application/json

Response

HTTP 1.1 200 OK
Content-Type: application/json

Errors

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"
}

GET /outputs

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.

Errors

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"
}]

GET /outputs/:id/volume

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}
]

Errors

401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error


PATCH /outputs/:id/volume

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
}]

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error


GET /outputs/:id/eq

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
  }]
}]

Errors

401 Unauthorized, 404 Not Found, 500 Internal Server Error


PATCH /outputs/:id/eq

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
  }
}]

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error


GET /outputs/:id/filters

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
  }
}]

Errors

401 Unauthorized, 404 Not Found, 500 Internal Server Error


PATCH /outputs/:id/filters

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
}]

Errors

400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 500 Internal Server Error


GET /outputs/:id/meter

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
}]

Errors

401 Unauthorized, 404 Not Found, 500 Internal Server Error



WebSocket API

Overview

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.



Authentication

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.

API Key

var exampleSocket = new WebSocket("wss://callsign.soundctl.io/?key=yQsz3uvr9WdTUIdKTzcXbNo9fJoudvpqw8sT6mqOjkMYmPejg9EjpeV5Lut3UWm");

JSON Web Token

var exampleSocket = new WebSocket("wss://callsign.soundctl.io/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE0NjAxNzkwOTAsImV4cCI6MTQ5MTcxNTA5MCwicm9sZXMiOlsiY29uc3VtZXIiXX0.df-ZabXBsu9KJVpGYiVudHi56BM0oKyBkJtqTDqzF6o");


Messages

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

Message Object

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.

Examples

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

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.

Examples

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
  }]
}


Errors

In case of an error a Message will be sent to the client with an errors field containing a list of Error Objects.

Error Object

Name Type Description
code Integer Equivalent to the HTTP response status code.
info String A human-readable message providing more details about the error.

Examples

{
  "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"
  }]
}


Objects Reference

Volume

Properties

Name Type Valid values Description
level Number -120.00 <= N <= 120.00 Volume level in decibels.

Example

{
  "level": -4.50
}

Eq

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
  }]
}

Eq Band

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.

Filters

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
  }
}

Lowpass

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
}

Highpass

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
}

Meter

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
}]