API conventions

Media type

For our media type we use hal+json. A short overview of conventions:

  • Links are located in a _links element. A link can be either one link, or a list of links. There will always be a self link. The self link will point to the same URL that you used to access the current representation (including the query parameters).
  • Embedded resources can be found in an _embedded element.
  • Properties of a resource are represented like regular json.
  • Every resource will have a profile link relation for documentation purposes.
  • We use CURIES (Compact URIs) to namespace custom link relations. As such, every resource will have a curies link relation. For example:
{
    "_links": {
        "curies": [{ "name": "shop", "href": "https://shopping-api-docs.paylogic.com/documentation/{rel}.html", "templated": true, "type": "text/html" }],
        "self": { "href": "https://shopping-api.paylogic.com/orders/87a2195h3gd162fb35c5a3dbd7bapo1l" },
        "profile": { "href": "https://shopping-api-docs.paylogic.com/documentation/orders.html", "type": "text/html" },
        "payment": { "href": "https://payments.paylogic.com?redirect=https://psp.paylogic.com/consumer/123", "type": "text/html" },
        "shop:etickets": { "href": "https://download.paylogic.com/eticket/sdfsdf235r245wsdgfw5235", "type": "text/html" },
        "shop:ordercancellation": { "href": "https://shopping-api.paylogic.com/ordercancellation", "type": "text/html" }
    },
}

In this case the shop:etickets and shop:ordercancellation references can be used to discover the documentation for these relationships by filling their values, etickets and ordercancellation, into the CURIE link. This will result in https://shopping-api-docs.paylogic.com/documentation/etickets.html and https://shopping-api-docs.paylogic.com/documentation/orderscancellation.html respectively.

URLs

We don’t see the need to burden you when building a client with constructing URLs (or even inspecting them), so we use absolute URLs wherever possible. This means that there will be no need to do anything with URLs themselves; you can simply follow the link relations.

Contextual documentation

Documentation of the resources themselves is accessible by following the profile link relation on the resource. These profiles describe the data of the resource, the method it accepts, which query parameters are permitted, and so on.

In addition, on the root resource a link with the relation help can be found. This link points to the root of the documentation for the API.

Roles and Permissions

Depending on how your access credentials are configured you either have access to or are disallowed access to certain properties or resources through roles. The role your application has depends on your use case and implementation details. The role is determined by us and can be based on the type of contract you have to use the API.

In the rest of the documentation we’ll indicate differences for the roles in a note like this:

Note

I am a note.

The system has the following roles available:

Role name Resources you have access to Notes
default event, product  
spa-sales event, product, bill, create order Consumer IP will always use the remote address.
sales event, product, bill, order (including create order)  
merchant event, product (including availability), bill order (including create order)  

Searching in collections via query parameters

When searching in collections, all specified query parameters (from the documentation or from the templated link in the representation) can be searched on for exact matches. In addition, it is often also possible to do more complicated queries.

The syntax for this is best explained by example:

Query parameter Description
/orders?total=20 All orders with as total exactly 20.
/orders?total__gte=20 All orders with as total greater than or equal to 20.
/orders?created__lt=2014-05-01 All orders created before the 1st of May 2014.
/orders?consumer.firstname__startswith=tom All orders for any consumer with a first name starting with “tom”.

The following options are only available for amounts, numbers, and date and time fields.

Condition Description
__lt Lower than, or before
__gt Greater than, or after
__lte Less than or equal
__gte Greater than or equal

The following options are only available for strings:

Condition Description
__startswith The string starts with the provided string.

Internationalization

Any values that are internationalized in our system (such as the name of an event) will return all languages and translations in a dictionary.

{
    "seat_name": {
        "en": "Seat",
        "nl": "Stoel",
        "de": "Sitzplatz",
        "fr": "Siège",
        "es": "Asiento",
        "pt": "Assento",
        "tr": "Sandalye",
        "pl": "Miejsce",
        "ru": "сиденья"
    }
}

At the time of writing, we support English, Dutch, German, French, Spanish, Portuguese, Turkish, Polish and Russian. All of these will be included.

Dates and time

The format of our dates and times follows ISO 8601, specifically in the format “YYYY-MM-DDThh:mm:ssZ” for datetimes, and “YYYY-MM-DD” for dates. All times are communicated in UTC (as shown by a trailing Z).

{
    "sale_start": "2014-01-28T20:25:00Z",
    "sale_end": "2014-06-09T17:25:00Z",
    "date_of_birth": "1986-12-30"
}

Country and state codes

To communicate country codes we use the country codes as specified in ISO 3166-1, specifically the two-letter country codes from ISO 3166-1 alpha-2. For states and other subdivisions, we use the codes as specified in ISO 3166-2.

{
    "country_of_residence": "NL",
    "shipment_country": "DE",
    "state": "US-AL"
}

Empty values for properties

If for a regular string field no value is known in our system, we will return an empty string (so merely “”). For multilingual fields, all languages will be included but those with no value will also have the empty string. A list field with no items will be displayed in the response as an empty list.

For objects and integer fields, we will display the value null. This was chosen over just removing the key, to be more explicit and to always specify all fields, so no confusion can arise over fields having to be there or not.

{
    "title": {
        "en": "",
        "nl": "",
        "de": "",
        "fr": "",
        "es": "",
        "pt": "",
        "tr": "",
        "ru": ""
    },
    "image_url": "",
    "minimum_age": null,
    "price": null,
    "genres": [
        // ...
    ]
}

HTTP verbs

We support GET, POST, PUT and DELETE (when each method is supported and makes sense, of course). We don’t use PATCH.

OPTIONS can be used to show the accepted methods and link you to an HTML page with further documentation.

# Request
OPTIONS /bill HTTP/1.1
Host: https://shopping-api.paylogic.com

# Response
HTTP/1.1 200 OK
Allow: OPTIONS, GET, POST
Link: <https://shopping-api-docs.paylogic.com/documentation/bill.html>; type=text/html; rel=help

Error handling

Errors usually simply return the corresponding HTTP status codes. If more information is required, we will provide more details in the response body. As mediatype for the error response body we use hal+json. The value of logref will be a UID.

Note

Please note that if you check only the properties of the response, for example the _links property you will not see the actual error message but only the help link.

{
    "logref": "<UID>",
    "message": "A payment method is needed for the creation of an order. Please retrieve a bill for the selected products to see which payment methods are available.",
    "type": "BAD_REQUEST",
    "_links": {
        "help": {
            "href": "http://shopping-api-docs.paylogic.com/documentation/orders.html",
            "type": "text/html"
        }
    },
    "details": null
}

Deprecation Policy

If we make changes to the API the existing field will have a deprecation warning attached, with a reference to the new field that should be used. It is up to the calling application to check for any deprecation warnings and use the new field instead. After a certain period, usually two weeks, the old field will be removed and applications using it will no longer work.