Quick start

$ curl http://api.choir.io/KEY \
    -d label="hello" \
    -d sound="g/3" \
    -d text="Hello Choir!"
import requests
payload = dict(
    text="Hello Choir!"
r = requests.post('
require 'net/http'
require 'uri'
url = URI.parse('http://api.choir.io/KEY')
payload = {
    :sound =>"g/3",
    :label =>"hello",
    :text  =>"Hello Choir!"
Net::HTTP.post_form(url, payload)
// Use 'request' library: npm install request
var request = require('request');
    { form: { 
        label:  'hello',
        sound: 'g/3',
        text: 'Hello Choir!'} },
    function (error, response, body) {
        if (!error && response.statusCode == 200) {
$url = 'http://api.choir.io/KEY';
$data = array(
    'label' => 'hello', 
    'sound' => 'g/3',
    'text'  => 'Hello Choir!');

$options = array(
    'http' => array(
        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
        'method'  => 'POST',
        'content' => http_build_query($data),
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
using (var wb = new WebClient()) 
    var data = new NameValueCollection(); 
    data["sound"] = "g/3";
    data["label"] = "hello";
    data["text"]  = "Hello Choir!";

    var response = wb.UploadValues(
        "POST", data);
String charset = "UTF-8";
String query = String.format("label=%s&sound=%s&text=%s", 
     URLEncoder.encode("hello", charset), 
     URLEncoder.encode("g/3", charset), 
     URLEncoder.encode("Hello Choir!", charset));

URLConnection connection = new URL(
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
    "application/x-www-form-urlencoded;charset=" + charset);

OutputStream output = connection.getOutputStream();
try {
} finally {
;; add [clj-http “0.7.7”]
(use '[clj-http.client :only [post]])            
    (let [payload {
            "sound" "g/3"
            "label" "hello"
            "text" "Hello Choir!"}]
         (post "http://api.choir.io/KEY" 
            {:form-params payload}))

You can send data to Choir in a couple of lines of code in most languages. Each of the examples above will play an important sound with good connotations and an associated message. In the examples above, replace KEY with the API key shown in your management interface.

API Reference

Request parameters

The parameters either be a normal URL-encoded form, or a JSON object with the needed attributes. The post parameters are as follows:

A sound specification
(required) See Specifying sounds for the format.
A sound label
(optional) A short text string that groups related events together.
Player message
(optional) HTML snippet that will be displayed in the player.
Number of milliseconds over which to sprinkle the sound output.
(optional) This is useful to smooth out sounds. For instance, if you have a polling monitor, a bunch of events may arrive simultaneously every N seconds, producing an unpleasant effect in the sound stream. You can smooth things out by specifying a sprinkle parameter, which randomly delays sounds to spread them out over the specified number of milliseconds.

HTTP Status Codes

Everything worked as expected.
Bad Request
Often missing a required parameter.
Not Found
The requested key doesn't exist.
500, 502
Server errors
Something went wrong on our end.

API Keys

If you use the API, you will most likely integrate Choir at multiple points in your infrastructure. To make managing this easier, we let you create as many API keys as you like. Creating and destroying API keys is quick, easy and free - just add another Choir API endpoint on the integraiton page. Use keys liberally to manage your data feed security.

You can check whether a key exists by doing an HTTP GET of the same post URL. A 200 response indicates that the key exists, a 404 shows that it doesn't.

Specifying Sounds

Choir groups sounds together into packs. Here, for example, is the submarine soundpack, which is the default in Choir's current incarnation:

Notice that the sounds are organized along two axes. Sound is uniquely good at conveying emotion, and the first axis indicates whether the sound is good, neutral or bad. The second axis is an importance level, ranging from 0 for small background noises, to 3 for sounds that really make you sit up and notice.

Flexible Sound Specification

You specify the emotion and importance, and Choir chooses the sound. So, a positive sound with high importance (an example might be a crowd cheering, or exuberant whale-song), would be specified like this: g/3; A small, neutral, back-ground sound for a pageload or other high-frequency, low-importance event would be specified like this: n/0

Choir intelligently assigns sounds based on the label, so that sounds with the same label have the same sound, and sounds with different labels have different sounds (as far as permitted by the number of sounds in the pack). If the sound pack has no sounds in the specified quadrant (often the case for good/bad sounds at the lowest importance level, where it's hard to characterise emotion), we pick a sound from the neutral quadrant at the same level of importance instead.

There are a number of benefits to specifying sounds flexibly.

Direct Sound Specification

You can also directly specify a sound to be played, regardless of the user's current sound pack choice. This makes sense when the sound you've chosen has special semantic or other significance. An example might be a cash-register ka-ching when you make a new sale. Using the shell example below to illustrate, we can specifically request the joyful orca song from the submarine soundpack.

$ curl http://api.choir.io/KEY \
    -d label="hello" \
    -d sound="submarine/orca" \
    -d text ="Hello Choir!"