AgoraPI User Guide

This page explains the different possibilities offered by AgoraPI, with simple examples.

  1. Generalities: resources, authentication
  2. Basic usage: creating a poll, voting, getting the results
  3. Ranked votes: sending a ranked vote, understanding the result
  4. User management: creating users, voting on their behalf

Generalities Top

Resources

AgoraPI is a RESTful API, i.e., endpoints are mapped to resources, and HTTP methods are used to interact with them:

Resources include: polls, choices (propositions of a poll), votes, result entries, and charts. Most of them are identified using a unique ID (consisting of an arbitrary sequence of alphanumeric characters), automatically generated for you. This ID is returned every time a new resource is created, and it can be used to refer to this specific resource later on.

Data transfer

When performing a GET request, parameters may be added on the query string, in particular when searching for resources (for example, poll_id=P123456789). For POST, PUT and PATCH requests, some data is expected in the body of the request, and should be transfered in JSON format.

Every API request leads to a response by the server. If the request failed, the response status may be one of

In case of success, the response status is in general 200, and the response body contains the JSON serialization of the returned data (resources retrieved, or actual data added or updated). For example, when requesting the list of choices from poll P123456789, the API may return the following data:

[
    {
        "id": "C111111111",
        "poll_id": "P123456789",
        "num": 1,
        "label": "first choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C222222222",
        "poll_id": "P123456789",
        "num": 2,
        "label": "second choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C333333333",
        "poll_id": "P123456789",
        "num": 3,
        "label": "third choice",
        "description": null,
        "image_url": null
    }
    ]

Note that there are 2 exceptions to that:

Authentication

To preserve your data privacy, all API requests must be identified using an API token sent as the query parameter api_token. This token (obtained in your account) authentifies the incoming request as coming from you, and will give access to all of your data (read and write). As a consequence, you must keep your tokens secret! (However, in case a token has leaked and is compromised, it is always possible to replace it by a new one, on the token management page.)

On the API side, all requests are encrypted with SSL/TLS since our servers only respond to HTTPS requests.

A missing or invalid API token may give you the following status codes:

An API token has a “scope” it can interact with. Another token has a different scope, so you can use different tokens for different applications (a poll created with a token will not exist for the other ones). If necessary, or if in doubt that a token has leaked, you may replace it with another one on your account. This new token will have the same rights that the initial one, and this initial one stops working immediately.

Examples

The remaining sections of this guide contain example of requests. They can easily be performed on your side in a terminal using the given cURL samples (get it from your usual package manager, or from the official website). This samples are formatted as follows:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/info?api_token=$API_TOKEN"

Option -i activates the display of the response headers (so that the status code, and the potential links to next results pages, are displayed), -H initializes some headers and -X sets the HTTP method to use. These samples assume that the API_TOKEN shell variable is defined and contains your own token. In order to do that, simply execute

API_TOKEN=<replace this with your token>

The cURL command above is a good way to start using the API, and to test that your token works. If it does, you should get some information associated with it, otherwise the response status code and body will tell you what is wrong.

Basic usage Top

Creating a poll

To create a poll, simply POST a new poll resource, by sending the JSON-encoded poll in the request body (option -d of cURL). For convenience, the endpoint /polls/with-choices allows to create a poll with a set of initial choices:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/polls/with-choices?api_token=$API_TOKEN" \
     -d '{"title": "My poll title", "choices": [{"label": "first choice"}, {"label": "second choice"}]}'

This command should return (along with a 200 status) a JSON-encoded content similar to this one:

{
    "id": "P123456789",
    "creation_date": "2017-06-01T12:00:00.000000+02:00",
    "user_id": "U000000001",
    "title": "My poll title",
    "description": null,
    "poll_status": "OPEN",
    "options": {
        "anonymous": false
    },
    "choices": [
    {
        "id": "C111111111",
        "poll_id": "P123456789",
        "num": 1,
        "label": "first choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C222222222",
        "poll_id": "P123456789",
        "num": 2,
        "label": "second choice",
        "description": null,
        "image_url": null
    }
    ]
}

Note that the resulting IDs (of the poll and of the choices) are returned, so you can store them for future use.

You may add extra choices at any time, using the /choices (one choice) or /choices/for-poll/P123456789 (multiple choices) endpoints:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/choices?api_token=$API_TOKEN" \
     -d '{"poll_id": "P123456789", "label": "third choice"}'
{
    "id": "C333333333",
    "poll_id": "P123456789",
    "num": 3,
    "label": "third choice",
    "description": null,
    "image_url": null
}

Again, note the new ID, and the numbering of the choice (num is 3, since it is the third choice added to the poll).

Voting

Before voting, one may want to list the different propositions. In order to do that, just make a GET call to the /choices endpoint with the poll_id parameter, to look for choices:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/choices?api_token=$API_TOKEN&poll_id=P123456789"
[
    {
        "id": "C111111111",
        "poll_id": "P123456789",
        "num": 1,
        "label": "first choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C222222222",
        "poll_id": "P123456789",
        "num": 2,
        "label": "second choice",
        "description": null,
        "image_url": null
    },
    {
        "id": "C333333333",
        "poll_id": "P123456789",
        "num": 3,
        "label": "third choice",
        "description": null,
        "image_url": null
    }
    ]

Be aware that this request may produce a 206 response status, in case there are many choices, so you should always check the response status code to make sure you got all choices.

Voting for the best proposition is as simple as sending the poll_id and choice_id to the /votes endpoint:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/votes?api_token=$API_TOKEN" \
     -d '{"poll_id": "P123456789", "choice_id": "C111111111"}'
{
    "vote_date": "2017-06-01T12:10:00.000000+02:00",
    "user_id": "U000000002",
    "poll_id": "P123456789",
    "choice_id": "C111111111",
    "rank": 1
}

Voting for several preferred propositions at once is possible, by sending to the /votes/for-poll/P123456789 endpoint the list of desired choices:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/votes/for-poll/P123456789?api_token=$API_TOKEN" \
     -d '[{"choice_id": "C111111111"}, {"choice_id": "C333333333"}]'
[
    {
        "vote_date": "2017-06-01T12:20:00.000000+02:00",
        "user_id": "U000000003",
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00.000000+02:00",
        "user_id": "U000000003",
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    }
    ]

Obtaining results

Before asking for results, obtaining the list of existing votes may be interesting:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/votes?api_token=$API_TOKEN&poll_id=P123456789"
[
    {
        "vote_date": "2017-06-01T12:10:00+02:00",
        "user_id": "U000000002",
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00+02:00",
        "user_id": "U000000003",
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00+02:00",
        "user_id": "U000000003",
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    }
    ]

Once more, be careful about 206 response status code, indicating a partial response.

Results can be obtained on the /polls/P123456789/results/{result-type} endpoints. The most usual result is the majority vote count:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/polls/P123456789/results/majority?api_token=$API_TOKEN"
[
    {
        "choice": {
            "id": "C111111111",
            "poll_id": "P123456789",
            "num": 1,
            "label": "first choice",
            "description": null,
            "image_url": null
        },
        "rank": 1,
        "score": 2
    },
    {
        "choice": {
            "id": "C333333333",
            "poll_id": "P123456789",
            "num": 3,
            "label": "third choice",
            "description": null,
            "image_url": null
        },
        "rank": 2,
        "score": 1
    },
    {
        "choice": {
            "id": "C222222222",
            "poll_id": "P123456789",
            "num": 2,
            "label": "second choice",
            "description": null,
            "image_url": null
        },
        "rank": 3,
        "score": 0
    }
    ]

As you may notice, a result is a (potentially paginated) list of result entries, each of them consisting of a choice associated with a rank and a score. Entries are sorted by increasing rank and decreasing score (best choices first). For the majority, the score indicates the number of times the choice was voted for, here twice for choice 1 and once for choice 3 (see the list of votes above).

AgoraPI allows for a more visual view of the results, and offers to generate result charts for you. Get a chart URL with a call to /polls/P123456789/results/majority/charts/{chart-type}, where {chart-type} can be:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/polls/P123456789/results/majority/charts/vbar?api_token=$API_TOKEN"
{
    "id": "gr34tCh4rt",
    "poll_id": "P123456789",
    "chart_type": "vbar",
    "result_type": "majority",
    "title": "My poll title",
    "url": "http://chart.open-agora.com/gr34tCh4rt"
}

Now, following the URL received in the response you can download the charts!

Example of vbar chart

Vertical bar chart representation of the result

Example of pie chart

Pie chart representation of the result

Note that to update a chart after someone has voted, you need to make another GET call to /polls/P123456789/results/majority/charts/{chart-type} (or, equivalently, a PUT to /charts/{chart-id}/update, where chart_id is the identifier received when creating the chart, in our example gr34tCh4rt). Updating a chart does not change its URL, but makes it point to an updated representation of the latest results.

Finally, when the poll is complete, you may close it to prevent further votes to be sent. Closing a poll consists of updating its status to CLOSED:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X PATCH "https://api.open-agora.com/polls/P123456789?api_token=$API_TOKEN" \
     -d '{"poll_status": "CLOSED"}'
{
    "id": "P123456789",
    "creation_date": "2017-06-01T12:00:00.000000+02:00",
    "user_id": "U000000001",
    "title": "My poll title",
    "description": null,
    "poll_status": "CLOSED",
    "options": {
        "anonymous": false
    }
}

Note that a poll may be re-opened at any time by setting its status back to OPEN, and so on.

You should be now ready for polling with AgoraPI! The following sections will guide you through more advanced features of the API.

Ranked votes Top

Sorting choices

An interesting feature of AgoraPI is the possibility to send ranked votes, by sorting choices. In practice, that means that a user can indicate a preference level for each choice. This is achieved by associating a rank to each vote: ranks start at 1 (default if omitted) for preferred propositions, and increase as preference decreases:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/votes/for-poll/P123456789?api_token=$API_TOKEN" \
     -d '[{"choice_id": "C222222222", "rank": 1}, {"choice_id": "C333333333", "rank": 2}]'
[
    {
        "vote_date": "2017-06-01T12:30:00+02:00",
        "user_id": "U000000004",
        "poll_id": "P123456789",
        "choice_id": "C222222222",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:30:00+02:00",
        "user_id": "U000000004",
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 2
    }
    ]

This vote indicates that the user prefers choice 2, then choice 3 comes next, and all remaining choices are ranked last.

Results

The main interest of such voting is that it is richer and more expressive than usual voting, and can be used to obtain more consensual results, taking into account all ranks expressed by each voter. In particular, results can be computed using the Condorcet method (see this post for a more detailed explanation of the algorithm). Here, result entries are sorted as usual, but the score indicates how much consensual the choice is (on a 0 to 100 scale):

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/polls/P123456789/results/condorcet?api_token=$API_TOKEN"
[
    {
        "choice": {
            "id": "C111111111",
            "poll_id": "P123456789",
            "num": 1,
            "label": "first choice",
            "description": null,
            "image_url": null
        },
        "rank": 1,
        "score": 67
    },
    {
        "choice": {
            "id": "C333333333",
            "poll_id": "P123456789",
            "num": 3,
            "label": "third choice",
            "description": null,
            "image_url": null
        },
        "rank": 1,
        "score": 67
    },
    {
        "choice": {
            "id": "C222222222",
            "poll_id": "P123456789",
            "num": 2,
            "label": "second choice",
            "description": null,
            "image_url": null
        },
        "rank": 3,
        "score": 0
    }
    ]

Condorcet result is best viewed using an horizontal bar chart (X-axis is a percentage):

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/polls/P123456789/results/condorcet/charts/hbar?api_token=$API_TOKEN"
{
    "id": "n1c4rCh4rt",
    "poll_id": "P123456789",
    "chart_type": "hbar",
    "result_type": "condorcet",
    "title": "My poll title",
    "url": "http://chart.open-agora.com/n1c4rCh4rt"
}

Example of hbar chart

Horizontal bar chart representation of the Condorcet result

User management Top

Users

Finally, if the application using AgoraPI is user-aware, it may use some other features to:

AgoraPI users can be created using the /users route:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/users?api_token=$API_TOKEN" \
     -d '{}'
{
    "id": "U100000000",
    "email": null,
    "name": null
}

In this example we sent no user data, but note that if needed, an email address and/or a name (arbitrary strings used to identify the user on the application side) can be given.

Voting

user_id’s can then be sent to the API when:

The latter possibility can be achieved either by sending a user_id into the vote resource sent to /votes, or by adding it to the endpoint URL /votes/for-poll/P123456789/for-user/{user-id}. This second URL allows more flexibility: several votes (for several choices) can be sent at once, and these votes can either replace (PUT method) or complement (POST method) any existing vote for this user.

Remark that even in the case of a POST request, since at most one vote per user per choice may exist, any previous vote from the given user for a given choice is removed and replaced by the new one. Here, we invert the vote user U000000004 sent earlier in section 3:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X POST "https://api.open-agora.com/votes/for-poll/P123456789/for-user/U000000004?api_token=$API_TOKEN" \
     -d '[{"choice_id": "C333333333", "rank": 1}, {"choice_id": "C222222222", "rank": 2}]'
[
    {
        "vote_date": "2017-06-01T12:40:00+02:00",
        "user_id": "U000000004",
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:40:00+02:00",
        "user_id": "U000000004",
        "poll_id": "P123456789",
        "choice_id": "C222222222",
        "rank": 2
    }
    ]

Note that in the absence of user_id in the request body or the URL, then a new user is created for the request. This new user ID is returned as part of the response, as seen in the examples of section 2.

Anonymous polls

Finally, the API offers the possibility to create anonymous polls. This can be achieved at creation time, by setting the anonymous option to true, or later on, by updating the poll:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X PATCH "https://api.open-agora.com/polls/P123456789?api_token=$API_TOKEN" \
     -d '{"options": {"anonymous": true}}'
{
    "id": "P123456789",
    "creation_date": "2017-06-01T12:00:00.000000+02:00",
    "user_id": "U000000001",
    "title": "My poll title",
    "description": null,
    "poll_status": "OPEN",
    "options": {
        "anonymous": true
    }
}

Note that to preserve confidentiality of existing votes, an anonymous poll cannot be reverted to a non-anonymous one!

Once a poll is anonymous, nothing changes, only it becomes impossible to associate votes to users again. Retrieved votes will come with an empty user_id:

curl -i -H "Accept: application/json" -H "Content-type: application/json" \
     -X GET "https://api.open-agora.com/votes?api_token=$API_TOKEN&poll_id=P123456789"
[
    {
        "vote_date": "2017-06-01T12:10:00+02:00",
        "user_id": null,
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00+02:00",
        "user_id": null,
        "poll_id": "P123456789",
        "choice_id": "C111111111",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:20:00+02:00",
        "user_id": null,
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:40:00+02:00",
        "user_id": null,
        "poll_id": "P123456789",
        "choice_id": "C333333333",
        "rank": 1
    },
    {
        "vote_date": "2017-06-01T12:40:00+02:00",
        "user_id": null,
        "poll_id": "P123456789",
        "choice_id": "C222222222",
        "rank": 2
    }
    ]

You are now ready to go!

Enjoy AgoraPI and feel free to contact us in case of trouble, or if you have any suggestion to make.

AgoraPI Reference

Executable reference

For further details on how to use AgoraPI, have a look at the exhaustive reference, in which all API calls can be tested.

The cURL commands generated by these live calls are shown, to facilitate command-line interaction.

Screenshot of Open Agora in Slack