Intro§

Yesplan provides customers and third-party developers an API to access its event planning data. This is the documentation for the Yesplan v1 API. Read the contents of this page carefully, including the Restrictions and Responsibilities described at the bottom, to understand how to be a good API citizen and to understand general restrictions and concerns. The API is based on HTTP and follows certain, but not all, REST principles. This document assumes you are familiar with the HTTP protocol as documented in RFC 2616, it does not assume familiarity with REST.

Example§

It’s helpful to dive in straight away with a few examples. Suppose we want to get all events that are planned on a particular day, say January 1st 2013. Here’s the raw HTTP request that we can send to the server to get them:

GET /api/events/date:01-01-2013?api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA HTTP/1.1
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
Host: theater.yesplan.be
Accept: */*

The above request was performed with the curl command line utility as follows:

$ curl 'https://theater.yesplan.be/api/events/date:01-01-2013?api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA'

Throughout this manual we mostly use curl to show how requests can be performed. For very simple requests like the above, you can also simply type the URL into a web browser. But note that not all requests can be performed through a browser. A browser will also not show all of the details of the server’s response. Another user-friendly alternative that we provide to help you experiment with the API is a web application based on Swagger UI. The screenshot below shows how it can be used to perform the above request.

The server responds to our request with the HTTP response shown below. You can use curl‘s --include option to show the full response, or the --verbose option to show the complete request and response interaction. Swagger UI will not show you the full request, but does show all of the details of the response.

HTTP/1.1 200
Server: nginx/1.0.6
Date: Fri, 31 May 2013 14:42:30 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-length: 4087
X-RateLimit-Level: 199

{
    "pagination": {},
    "data": [{
        "id": "2677668865-1351067918",
        "url": "https://theater.yesplan.be/api/event/2677668865-1351067918",
        "name": "Nieuw",
        "starttime": "2013-01-01T07:00:00+01:00",
        "endtime": "2013-01-02T07:00:00+01:00",
        "locations": [{
            "_type": "location",
            "name": "Concertzaal",
            "id": "803222785-1347529798",
            "url": "https://theater.yesplan.be/api/location/803222785-1347529798"
        }],
        ✃

Note that the body in the above response has been shortened as well as reformatted for readability. The Content-length header doesn’t match the length of the body as shown, but is simply the length of the original body returned by the server.

Let’s take a closer look at the request and response. Our request specifies the HTTP method GET and the URL that begins with https://theater.yesplan.be/api/. Two important bits in the URL are the part /events/date:01-01-2013 and the part api_key. The first part specifies that we want to get all of the events that match the Yesplan query date:01-01-2013. The Yesplan query language is explained in more detail in the chapter “Query Language.” For this example, it’s sufficient to know that the query date:01-01-2013 matches all the events that are planned on January 1st 2013. The second important part of the URL tells the server who we are. The API key is similar to a username and password and gives a certain access level on the server. This is explained in more detail in the section “Security.” For this example, you only need to know that an API key must be passed in with every request. Otherwise the server will not give access to any data.

The body of the response gives us the events data we’re interested in. As indicated in the response header, the content type for the body is application/json; referring to the JSON format as documented in RFC4627. The Yesplan HTTP API always uses JSON, no other format is supported. The JSON object in the response body has two attributes, “pagination” and “data”. We’ll skip over the “pagination” one for this example. The “data” attribute has as its value an array of JSON objects, each of these represents an event that matches our query date:01-01-2013. They have attributes such as “name” (which holds the name of the event), “starttime” (which holds the date and time at which the event starts, as a string in the ISO 8601 standard format) and “locations” (which holds the locations in which the event is planned). So we can see here there’s an event planned to start on January 1st at 7:00 (in the GMT+1 time zone), named “Nieuw” and planned in the location “Concertzaal”.

The JSON object included in the “locations” attribute has a “url” attribute. The URL attribute tells us where to get a complete representation of the data about the location “Concertzaal”. Within the context of the JSON object that represents the event “Nieuw”, only some of the attributes are included, chiefly the “name” attribute and the “url” attribute. This strikes a balance between, on one hand, giving you some information about the piece of data that is linked to without the need to perform another HTTP request, while on the other hand, not overloading the responses with a lot of detail that you may not be interested in. To get the full JSON object we perform another request specifying the GET method and the URL from the attribute, completed with an API key. The full request is:

GET /api/location/803222785-1347529798?api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA HTTP/1.1
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
Host: theater.yesplan.be
Accept: */*

This request can be performed with curl as follows:

$ curl 'https://theater.yesplan.be/api/location/803222785-1347529798?api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA'

The server’s response is:

HTTP/1.1 200
Server: nginx/1.0.6
Date: Wed, 05 Jun 2013 13:56:40 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-length: 1291
X-RateLimit-Level: 199

{
    "_type": "location",
    "url": "https://theater.yesplan.be/api/location/803222785-1347529798",
    "id": "803222785-1347529798",
    "name": "Concertzaal",
    "description": "",
    "costmodels": [{
        "name": "daily",
        "cost": "50.00 /Day",
        "price": "100.00 /Day",
        ✃

The response gives us the complete JSON object with all of the data on the location “Concertzaal”. Besides the “name”, “url”, “id” and “_type” attributes which we already got in the previous response, there’s also a “description” attribute and a “costmodels” attribute; as well as a few other attributes that’ve been left out here for the sake of brevity.

API Organization§

The Yesplan HTTP API provides access to Yesplan event planning data through the HTTP protocol. The general operating principle of HTTP is that a server offers a collection of HTTP resources which are identified by a URL and on which HTTP methods can be applied. Note there’s some potential confusion here as the term “resource” is also used in Yesplan in a different meaning, we rely on context to disambiguate whether “resource” refers to a resource in het Yesplan sense - a piano, Scotty the technician, the Concert Hall or some other resource that is used to organize an event - or a resource in the HTTP sense.

The HTTP resources provided by the Yesplan API can be divided into 6 groups. For the first two of these, examples are given in the previous section.

The first group are the resources that represent a single entity in Yesplan. All these resources are identified by a URL with a path of the form /{singular}/{id} where singular is a singular word, such as “event” or “contact”, and id is an internal identifier. Two examples given in the “Examples” section are the resource identified by the URL https://theater.yesplan.be/api/location/803222785-1347529798 and the resource identified by the URL https://theater.yesplan.be/api/event/2677668865-1351067918. For the first, the singular word is “location” and the id is “803222785-1347529798”, for the second the singular word is “event”. These resources always support the GET method and may also support PUT.

The second group are the resources that represent a collection of Yesplan entities that match a query. All these resources are identified by a URL with a path of the form /{plural}/{query} where plural is a plural word, such as “events”, “contacts” or “locations” and query is a query in Yesplan query language. The example from the previous section is the resource identified by the URL https://theater.yesplan.be/api/events/date:01-01-2013, the plural word being “events” and the query being “date:01-01-2013”. These resources always only support the GET method.

The third group are the resources that represent a collection of all Yesplan entities of a certain kind. These are similar to the resources in the second group, assuming a fixed query *:*. Their URL path is of the form /{plural} where plural is a plural word. Two examples are the resource identified by the URL https://theater.yesplan.be/api/events, where the plural is events, and the resource identified by the URL https://theater.yesplan.be/api/locations, where the plural is locations. These resources always only support the GET method.

The fourth group are the resources that represent additional properties of a single entity in Yesplan. The URL for these has a path of the form /{singular}/{id}/{name}, where name is the name of the property. An example URL is https://theater.yesplan.be/api/event/803222785-1347529798/customdata. These resources always support the GET method and may also support PUT.

The fifth group are the resources that represent the additional properties of a collection of Yesplan entities that match a query. The URL for these has a path of the form /{plural}/{query}/{name}. An example URL is https://theater.yesplan.be/api/events/date:01-01-2013/customdata. These resources always only support the GET method.

The sixth group are the resources that are variations on the above five. The URL for these resources have a URL similar to the resource on which they are a variation, but with extra query parameters. These are documented in more detail in the section “Variation Resources.”

Attributes Type Reference Documentation§

For more detailed information about the various attributes that the JSON objects in API responses may have, you can consult the type reference documentation. For a given Yesplan server, the type reference documentation is available at the URL with path /api/doc/. As shown in the screenshot, it lists the URL forms for the HTTP resources that represent a single Yesplan entity, and those that represent a subordinate of a single entity. The pages linked to give more details about the JSON objects you can expect in response to GET requests for those resources.

Custom Data Reference§

The image above shows the type reference documentation for custom data elements. There is a correspondence between the values of the “type” attribute and the “value” attribute that is not shown in the type reference documentation. This correspondence is documented in more detail below: for each type of custom data field, a screenshot is shown of what it look like in Yesplan, along with how that field is represented in the API.

Input Field§

API Example:

{
    "keyword": "group_group_inputfield",
    "name": "Input Field",
    "type": "String",
    "value": "Lorem ipsum dolor sit amet"
}

Numeric Input Field§

API Example:

{
    "keyword": "group_group_numericfield",
    "name": "Numeric Field",
    "type": "Number",
    "value": 42
}

Text Field§

>

API Example:

{
    "keyword": "group_group_textfield",
    "name": "Text Field",
    "type": "Text",
    "value": "Lorem ipsum dolor sit amet,✃"
}

Yes/No Field§

API Example:

{
    "keyword": "group_group_ynfield",
    "name": "Y/N Field",
    "type": "Y/N",
    "value": "Yes"
}

API Example:

{
    "keyword": "group_group_dropdownfield",
    "name": "Dropdown Field",
    "options": [ "Apple", "Banana", "Cherry" ],
    "type": "Dropdown",
    "value": "Banana"
}

Checkboxes§

API Example:

{
    "keyword": "group_group_checkboxfield",
    "name":"Checkbox Field",
    "options": [ "Amber", "Bronze", "Copper" ],
    "type": "Checkbox",
    "value": [ "Amber", "Copper" ]
}

Date Input Field§

API Example:

{
    "keyword": "group_group_datefield",
    "name": "Date Field",
    "type": "Date",
    "value": "2013-12-01"
}

Time Input Field§

API Example:

{
    "keyword": "group_group_timefield",
    "name": "Time Field",
    "type": "Time",
    "value": "14:08"
}

Date and Time Input Field§

API Example:

{
    "keyword": "group_group_dateandtimefield",
    "name": "Date and Time Field",
    "type": "DateAndTime",
    "value": "2013-12-01T14:08"
}

Contact Field§

API Example:

{
    "keyword": "group_group_contactfield",
    "name": "Contact Field",
    "type": "Contact",
    "value": {
        "_type": "contactbooking",
        "id": "50-1384775202",
        "url": "http://theater.yesplan.be/api/contactbooking/50-1384775202",
        "contact": {
            "_type": "person",
            "id": "21-1384775202",
            "name": "John Doe",
            "url": "http://theater.yesplan.be/api/contact/21-1384775202"
        }
    }
}

Resource Field§

API Example:

{
    "keyword": "group_group_resourcefield",
    "name": "Resource Field",
    "type": "Resource",
    "value": [
        {
            "_type": "resourcebooking",
            "id": "51-1384775867",
            "url": "http://localhost:8080/api/resourcebooking/51-1384775867",
            "resource": {
                "_type": "resource",
                "id": "24-1384775867",
                "resourcetype": "material",
                "name": "Beer",
                "group": "Miscellaneous",
                "roles": [],
                "url": "http://localhost:8080/api/resource/24-1384775867"
            }
        }
    ]
}

Attachment Field§

API Example:

{
    "keyword": "group_group_attachmentfield",
    "name": "Attachment Field",
    "type": "Attachment",
    "value": {
        "comment": "Yesplan website",
        "dataurl": "http://www.yesplan.be/",
        "date": "2013-11-18",
        "username": "Administrator"
    }
}

Comment Field§

API Example:

{
    "keyword": "group_group_commentfield",
    "name": "Comment Field",
    "options": [ "Comments" ],
    "type": "Label",
    "value": null
}

Event Labels§

API Example:

{
    "keyword": "group_group_eventlabelsfield",
    "name": "Event Labels Field",
    "type": "Labels",
    "value": [ "Label 1", "Label 2" ]
}

Integration Data§

API Example:

{
    "keyword": "group_group_integrationdatafield",
    "name": "Integration Data Field",
    "type": "Integration info",
    "value": "ABC"
}

Remote Data§

API Example:

{
    "keyword": "group_group_remotedatafield",
    "name": "Remote Data Field",
    "type": "Remote info",
    "value": null
}

Publication Trigger§

API Example:

{
    "keyword": "group_group_publicationtriggerfield",
    "name": "Publication Trigger Field",
    "type": "String",
    "value": "ACTIVE"
}

Computed Field§

API Example:

{
    "keyword": "group_group_computedfield",
    "name": "Computed Field",
    "type": "Derived",
    "value": "G"
}

Variation Resources§

The Yesplan API offers a number of HTTP resources that can be thought of as variations on some of the other resources. These are mostly related to custom data and pricing data. They have URLs of the following forms:

Where:

Entity with Custom Data Variations§

A response to a GET request on a URL with a customdata_keywords query parameter will include JSON objects that are the same as the one in the response to a GET request on the same URL without the query parameter, except that extra attributes “customdata” will be included. The customdata_keywords parameter’s value should be a comma-separated list of custom data keywords. The “customdata” attribute will then include the values of the custom data fields with those keywords. For example, with the following request we get the information on a particular event together with its values for the custom data fields with the keywords “xls_prognose” and “xls_opkomst”:

GET /api/event/2677668865-1351067918?customdata_keywords=xls_prognose,xls_opkomst&api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA HTTP/1.1
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
Host: theater.yesplan.be
Accept: */*

The server’s response for this example is:

HTTP/1.1 200
Server: nginx/1.0.6
Date: Fri, 07 Jun 2013 12:45:52 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-length: 1484
X-RateLimit-Level: 199

{
    "id": "2677668865-1351067918",
    "url": "https://theater.yesplan.be/api/event/2677668865-1351067918",
    "name": "Nieuw",
    "starttime": "2013-01-01T07:00:00+01:00",
    "endtime": "2013-01-02T07:00:00+01:00",
    "locations": [{
        "_type": "location",
        "name": "Concertzaal",
        "id": "803222785-1347529798",
        "url": "https://theater.yesplan.be/api/location/803222785-1347529798"
    }],
    "customdata": [{
        "name": "Prognose opkomst",
        "keyword": "xls_prognose",
        "type": "Number",
        "value": 500
    },
    {
        "name": "Werkelijke opkomst",
        "keyword": "xls_opkomst",
        "type": "Number",
        "value": 533
    }],
    ✃

Note the value for the “customdata” attribute, which is an array of JSON objects, one for each of the specified custom data keywords “xls_prognose” and “xls_opkomst”.

Custom Data Limited to Specific Keywords§

The API allows retrieving only specific custom data fields, using URLs that include a “keywords” query parameter. The parameter’s value should be a comma-separated list of custom data keywords. For example, the following request gets the custom data field values for the fields with keywords “xls_prognose” and “xls_opkomst” of the event with identifier “2677668865-1351067918”:

GET /api/event/2677668865-1351067918/customdata?keywords=xls_prognose,xls_opkomst&api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA HTTP/1.1
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
Host: theater.yesplan.be
Accept: */*

The server’s response to the above request includes the values of the custom data fields as a JSON array for the key “items”:

HTTP/1.1 200
Server: nginx/1.0.6
Date: Fri, 07 Jun 2013 12:53:32 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-length: 311
X-RateLimit-Level: 199

{
    "event": {
        "_type": "event",
        "name": "Nieuw",
        "id": "2677668865-1351067918",
        "url": "https://theater.yesplan.be/api/event/2677668865-1351067918"
    },
    "items": [{
        "name": "Prognose opkomst",
        "keyword": "xls_prognose",
        "type": "Number",
        "value": 500
    },
    {
        "name": "Werkelijke opkomst",
        "keyword": "xls_opkomst",
        "type": "Number",
        "value": 533
    }]
}

Custom Data Limited to Values Only§

The API will normally give out an entity’s custom data field values along with the name and type of the field. It’s also possible to retrieve only the values of the custom data fields for a specific entity. For example, the following request gets the custom data field values for the event with identifier “2677668865-1351067918”:

GET /api/event/2677668865-1351067918/customdata?valuesonly&api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA HTTP/1.1
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
Host: theater.yesplan.be
Accept: */*

In this case, the server’s response to the above request includes the custom data field values as a JSON object for the key “items”, the keys in the object are the keywords of the custom data fields, the values are the value of the custom data field for the event:

HTTP/1.1 200
Server: nginx/1.0.6
Date: Fri, 07 Jun 2013 12:56:05 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-length: 2251
X-RateLimit-Level: 199

{
    "event": {
        "_type": "event",
        "name": "Nieuw",
        "id": "2677668865-1351067918",
        "url": "https://theater.yesplan.be/api/event/2677668865-1351067918"
    },
    "items": {
        "xls_opkomst": 533,
        "xls_prognose": 500,
        "info_extralabels": [],
        "info_verantwoordelijke": null,
    ✃

Pricing Data in Summary Form§

The API allows limiting the costing and pricing data that is retrieved to resource groups, without retrieving the details of each resource booking. The HTTP resources with URLs of the form /api/event/{id}/costings have variations with a ‘summarized’ query parameter, so with a URL of the form /api/event/{id}/costings?summarized. The same applies to /api/events/{query}/costings, /api/group/{id}/costings and /api/groups/{query}/costings.

Making Modifications§

Some of the HTTP resources in the API can be modified through application of the HTTP method PUT. These are the resources with URL paths of the forms:

Modifying Attributes§

API clients can attach some extra attributes to events, contacts and contact links. The extra attributes are ignored by Yesplan, they are specific to the API client. The extra attributes are always included in the entity’s JSON representation as a JSON object for the key “attributes”. They can be modified through a PUT request. Which attributes can be set is determined by the client associated with the API key that is used to authenticate the request. The following is an example request where the extra attribute “ticketmaticid” is set to value “123” on the event with identifier “2677668865-1351067918”:

PUT /api/event/2677668865-1351067918?api_key=6F5A671121FB7123ECD3B3E3E8DBE7EE HTTP/1.1
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5
Host: theater.yesplan.be
Accept: */*
Content-type: application/json
Content-Length: 36

{"attributes":{"ticketmaticid":123}}

The above request can be performed using curl as follows:

$ curl --request PUT
       --header 'Content-type: application/json'
       --data-ascii '{"attributes":{"ticketmaticid":123}}'
       'https://theater.yesplan.be/api/event/2677668865-1351067918?api_key=6F5A671121FB7123ECD3B3E3E8DBE7EE'

The server’s response for the above request indicates success with status code 204. The response does not include a body:

HTTP/1.1 204
Server: nginx/1.0.6
Date: Thu, 14 Nov 2013 08:52:38 GMT
Connection: keep-alive
Content-length: 0

Responses to GET requests on the same URL will subsequently include the extra attribute, as in this example:

HTTP/1.1 200
Server: nginx/1.0.6
Date: Thu, 14 Nov 2013 09:14:34 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-length: 1316
X-RateLimit-Level: 199

{
    "id": "2677668865-1351067918",
    "url": "https://theater.yesplan.be/api/event/2677668865-1351067918",
    "name": "Nieuw",
    "starttime": "2013-01-01T07:00:00+01:00",
    "endtime": "2013-01-02T07:00:00+01:00",
    "attributes": {
        "ticketmaticid": 123
    },
    ✃
}

Modifying Custom Data§

API clients can modify the custom data of events, contacts, resource bookings and so on. The fields to modify can be passed to the server as a JSON array of objects, where each object has the keys “keyword” and “value”. The value for the key “keyword” should be the keyword of the custom data field to modify, and the value of the key “value” should be the new value of the custom data field. For example, the following request will modify the fields with keywords “comments” and “invoice_date” of the event with identifier “2677668865-1351067918”:

PUT /api/event/2677668865-1351067918/customdata?api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA HTTP/1.1
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8y zlib/1.2.5
Host: theater.yesplan.be
Accept: */*
Content-type: application/json
Content-Length: 115

[
    {
        "keyword": "comments",
        "value": "Some comments on\nthis event"
    },
    {
        "keyword": "invoice_date",
        "value": "2013-12-01"
    }
]

The above request can be performed using curl as follows (in the above, the request body has been reformatted for readability):

$ curl --request PUT
       --header 'Content-type: application/json'
       --data-ascii '[{"keyword": "comments","value": "Some comments on\nthis event"},{"keyword": "invoice_date","value": "2013-12-01"}]'
       'https://theater.yesplan.be/api/event/2677668865-1351067918/customdata?api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA'

The server’s response for the above request indicates success with status code 204, and will not have a body.

The JSON object to pass for the key “value” depends on the type of the custom data field. The types are included in the responses to GET requests on the custom data HTTP resource. The following table documents what values can be used. Fields with a type that is not listed in this table cannot be modified through the API, these are the types: Contact, Resource, Labels, Derived, Label and Remote info.

Field kind Type in API Value
Input field String A JSON string, without any newline characters.
Text field Text A JSON string, newlines are allowed using the LF character (ASCII value: 10, JSON escape code: “\n”).
Numeric input field Number A JSON number.
Y/N field Y/N The JSON string "Yes" or the string "No".
Dropdown Dropdown The JSON string of the selected option.
Checkboxes Checkbox A JSON array with the strings of the options to select.
Date input Date A JSON string with the data in ISO 8601 format, for example "2013-12-01".
Time input Time A JSON string with the time in ISO 8601 format, for example "14:08".
Date and time input DateAndTime A JSON string with the data and/or time in ISO 8601 format, for example "2013-12-01", "14:08" or "2013-12-01T14:08".
Attachment field Attachment A JSON object with keys “dataurl” and, optionally, “comment”. Note: can only be used to attach links, attaching files is not possible through the API.

Pagination§

Several resources in the API use pagination, in particular the resources that are based on a Yesplan query. The results of the query are spread over several resources that each cover a part or “page” of the results. Each page is represented as a JSON object with two attributes: “data” and “pagination”. The value of the “data” attribute contains the actual data, while “pagination” contains a link to the next page of the results if there is one. To get all of the results, an API client can retrieve the first page and follow its “next” link to retrieve the second page, which can in turn have a “next” link to a third page and so on. For example, to retrieve all events, the first page is retrieved with a request as follows:

GET /api/events?api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA HTTP/1.1
Host: theater.yesplan.be
Accept: */*

The response to this request has a JSON object as body where the “data” is an array of events. These are not all events however, as the object also has an attribute “pagination” which indicates there’s a second page. The “next” attribute has as value the URL of the second page. Pages are not available indefinitely, instead they can only be retrieved until a certain time, as indicated by the “expires” attribute.

HTTP/1.1 200
Server: nginx/1.0.6
Date: Mon, 17 Feb 2014 14:16:15 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-length: 110972
X-RateLimit-Level: 199

{
    "pagination": {
        "next": "https://theater.yesplan.be/api/events?page=2&book=1018634753",
        "expires": "2014-02-17T15:26:14+01:00"
    },
    "data": [{
        "id": "58287617-1368693346",
        "url": "https://theater.yesplan.be/api/event/58287617-1368693346",
        "name": "New Event",
        …
    },
    {
        "id": "68268033-1369725038",
        "url": "https://theater.yesplan.be/api/event/68268033-1369725038",
        ✃

To retrieve the second page, a GET request can be done using the url from the “next” attribute, as follows:

GET /api/events?page=2&book=1018634753&api_key=5DCFB3CD88D5195D96FAC1DDCB1236CA HTTP/1.1
User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
Host: theater.yesplan.be
Accept: */*

In this example, the response again includes a “next” attribute, for the third page:

HTTP/1.1 200
Server: nginx/1.0.6
Date: Mon, 17 Feb 2014 14:17:38 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-length: 116138
X-RateLimit-Level: 199

{
    "pagination": {
        "next": "https://theater.yesplan.be/api/events?page=3&book=1018634753",
        "expires":"2014-02-17T15:26:14+01:00"
    },
    "data": [{
        "id":"727241985-1339168163",
        "url":"https://theater.yesplan.be/api/event/727241985-1339168163",
        ✃

To get all results, the third page needs to be retrieved and so on, until the last page where the “pagination” attribute does not include a “next” attribute, which indicates that the last page has been reached.

Error Responses§

When processing a response from the API, you should make sure your code always first checks that the response’s status code is 200. Most other status codes indicate some kind of error. A definition of the various status codes can be found in section 10 of RFC2616. The body of the response may or may not include further details on the error; and may or may not be parseable as JSON. We are working to make the API’s behavior in this respect more consistent. You should pay particular attention to handling responses with status code 429, as explained in more detail in the section “Rate Limitations.”

It’s helpful to consider the implication of how the HTTP protocol is specified to error responses. If you want to access all events planned on January 1st, 2013 but accidentally do a GET request on a URL with path /api/eventis/date:01-01-2013 or one with path /api/events/dade:01-01-2013, as far as the HTTP protocol is concerned, both errors are the same: there is no resource that is identified by the URL, therefore the appropriate response is a response with status code 404 (“Not Found”). As far as Yesplan is concerned, the two errors are somewhat different: in the first case, Yesplan does not know about any “eventis” entities, in the second case, the keyword “dade” is not a supported keyword in the Yesplan query language. We are working to improve the API so that the bodies of responses with status code 404 give you a more detailed error description to aid in debugging, but at the moment, this is not the case yet for all responses with this status code.

Security and Authentication§

The Yesplan HTTP API relies on secure HTTP (HTTPS) to encrypt communication between client and server. All requests should be performed over HTTPS.

All requests also require authentication through an API key. The API key provides a way for users to let a client program act on their behalf without handing out the username and password that they use to log in to Yesplan web application. By using different API keys for different programs, the user can deny access to one client by deleting the associated API key, without affecting the other clients and without the need to change passwords. API keys can be added or deleted through the Yesplan “Preferences” and ”Global Settings” panes.

All requests need to include an API key as the value of an api_key URL query parameter. If no key is provided, or the key is not valid, the server’s response will have status code 401. See the request/response interaction below for an example.

GET /api/events/date:01-01-2013 HTTP/1.1
User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5
Host: theater.yesplan.be
Accept: */*
HTTP/1.1 401
Server: nginx/1.0.6
Date: Wed, 05 Jun 2013 15:03:39 GMT
Connection: keep-alive
Content-length: 0

If the user associated with the API key does not have permission to access certain data, the server’s response will have status code 403.

Rate Limitations§

We impose limits on the rate of API requests that can be performed. If you’re an API client developer, you should make sure the client can handle responses with status code 429 “Too Many Requests.” The client should wait the number of seconds specified in the “Retry-After” header before making the same request again. There is no guarantee that the second attempt will not also be responded to with the same status code. For further details on the semantics of this status code in HTTP, see section 4 in RFC 6585. If the client is an interactive GUI program, you should take into account that the number of seconds can be relatively high. We recommend using caches to ensure the client provides a smooth user experience.

Different requests have different impacts on the rate limits. We are still experimenting with the details and so these are subject to change, but generally speaking: the rate limits are tied to the amount of work the Yesplan server has to perform to respond to the requests. That is, less requests that are more work can be done before the server will respond with the 429 status code. Handling GET requests on URLs for collections of items, such as /events and /contacts/name:doe is more work for the server than handling GET requests on URLs for individual items, such as any of the URLs of the form /event/{id} or the form /resourcebooking/{id}. The implication for you as a client developer is that you should make sure that the client does not unnecessarily perform GET requests on URLs such as /events and that Yesplan queries used in requests are written to be as efficient as possible.

At this moment, you can expect to be able to make 200 requests per minute if you only use URLs that include an {id} parameter. Requests for URLs that include a {query} parameter are more restricted and their impact on the rate limit is proportional to the amount of time it takes to evaluate the given query. Moreover, the impact of both type of requests is cumulative. The rate limit is therefore implemented as an amount of tokens you can consume. Each request consumes a number of tokens and new tokens become available after a give time period. Whenever your tokens are depleted, Yesplan API lets you know how long to wait before new tokens become available using a 429 response.

Change Policy§

The attributes and resources available in the Yesplan API, as well as its policies, may change over time. Yesplan will use API versioning to prevent non-backward compatible modifications from immediately breaking existing API integrations. When a new version of the API is released, an end-of-life date for the previous version of the API will be announced, allowing as much time as possible for all existing API integrations to verify and adapt to the new API. Yesplan will use commercially reasonable efforts to notify you of any upcoming modifications to the API or its policies through release notes and this documentation. Yesplan also tracks deprecation of attributes of the API in its documentation.

Restrictions and Responsibilities§

Your use and access to the API is expressly conditioned on your compliance with the policies, restrictions and other provisions related to the API set forth below. If Yesplan believes that you have or attempted to violate any term, condition or the spirit of these policies or agreements, your right to access and use the API may be temporarily or permanently revoked.

You must respect and comply with the technical and policy-implemented limitations of the API and the restrictions Yesplan designs or informs you of in accessing or using the API or designing and implementing Yesplan API integrations. Without limiting the foregoing, you may not violate any explicit rate limitations on calling or otherwise utilizing the API.

You may not (i) interfere with, modify or disable any features, functionality or security controls of Yesplan or the API; (ii) defeat, avoid, bypass, remove, deactivate or otherwise circumvent any protection mechanisms for the API; or (iii) reverse engineer, decompile, disassemble or derive source code, underlying ideas, algorithms, structure or organizational form from Yesplan or the API.

You may not, under any circumstances, through an API integration or otherwise, repackage or resell the Yesplan service or API. You are not permitted to use or access the API in any manner that does or could potentially undermine the security of Yesplan, the API or any data or information stored or transmitted using the API.