Back to top

GET Protocol

Welcome to the GET Protocol API-documentation.

Versioning

This is v1.0

This is the stable version.

Specifying Versions:

Version is specified by in url the format is: api/v/. All url used below use the version of this document.

Versions are in the format X.X

If a version is invalid or unsupported it will return a 404.

Currently Supported version

Getting Started

Logging in as a customer

First, Login by requesting an access code for +31612345678

curl ''https://gus.api.sandbox.guts.events/api/v1/auth-ticketeer/guts/+31612345678 -X POST --data 'locale=en'

//Response
{"authid":"<auth_id>","tries_left":3,"used":false}

The user will now receive a SMS containing the access code. The code is a 4 digit number, e.g. 1234.

curl 'https://gus.api.sandbox.guts.events/api/v1/auth-verify/' -X POST '--data-raw '{"pincode":"8452","app":"web","verification_code":<authid>}'

//Response
{"status":"succse", "refresh_token":"<refresh_token>","jwt_token":"<jwt_token>"}

The system has two kind of users: Customers and Dashboard users. Both users use JWT for authentication but they have different ways of obtaining them.

Customers are identified by their mobile phone that they use to obtain a JWT token. Dashboard users use their username/password to authenticate.

Both types of users use the same endpoints. The system is aware of the type of user and might differentiate the retrieved results depending on the user type. In general, Dashboard users will see more information.

When logging in the api returns a refresh token and a jwt token. The jwt token is used for authentication. It needs to be added to the header of all endpoints that require authentication.

Authorization: JWT <token>

The jwt token is valid for 15 minutes. When it expires the refresh token can be used to retrieve a new jwt token. Post to the refresh endpoint and it will return a new jwt token AND refresh token. Use the jwt token to authenticate and store the new refresh token to retrieve the next jwt token. When unused, refresh tokens are valid for six months. To keep your app logged you’ll need to store the refresh token.

Check the authentication section for more details.

Pagination

All listing endpoints use pagination. It follows this format:

{
  "count": 1,
  "next": url,
  "previous": url,
  "results": ....
}

Error handling

The API will raise HTTP error codes when it receives malformed or incorrect input. There are cases where the API request was valid and well formed but some logic restriction prevents the call API call from completing successfully. Example: Trying to put a ticket in your cart when no tickets are available. In these cases the call will return a 200 but will provide a status in the payload.

{
  "status": "error|success",
  "error": "error_code_string"
}

Use Case: Getting Shop Access

Our ticketing platform has to deal with a high service load associated with ticket sales. Therefore the system makes use of a gatekeeper. This gatekeeper can throttle access to the ticketing service to prevent it from getting bogged down under high load.

For users to buy tickets at the ticketing service, they first need to retrieve coupons at the gatekeeper. The ticketservice will refuse to start a payment with the user without a coupon. If the load is low, the gatekeeper will immediately give users a coupon; if the load gets high, the gatekeeper will start a waitingline and hand out coupons accordingly.

Getting events information

To get started you need the gate_slug. It is suggested that the slug is part of the url your are using to let you users buy tickets. Using the gate_slug, you retrieve some information about the event and its shop

curl 'https://gate.api.sandbox.guts.events/api/v1.0/gates/<gate_slug>'

//Response
    {
        "id":423,
        "slug":"jy0iox",
        "human_slug":"",
        "title":"title",
        "subtitle":"subtitle",
        "image":"url",
        "shops":[320],
        "shop_slugs":["bnbgpz"],
        "start":"2019-05-14T08:00:00Z",
        "auto_queue_started":"0001-01-01T00:00:00Z",
        "type":"open",
        "state":"running",
        "message":"",
        "entries_per_minute":0,
        "time_to_start":-17818393
    }

And for shops information.

curl 'https://gate.api.sandbox.guts.events/api/v1.0/gates/<gate_slug>/shops'

//Response
        {
            [
                "id":320,
                "slug":"bnbgpz",
                "event_slug":"xdzf0q",
                "title":"",
                "subtitle":"",
                "location":"",
                "local_timezone":"Europe/Amsterdam",
                "city":"",
                "when":"2019-12-17T19:00:00Z",
                "time_till_soldout":"2019-11-15T11:37:24.761296Z",
                "state":"no_available",
                "publish_state":"published"
            ]
        }

Note that a gate can contain multiple shops

The most important part is the shop_slug and event_slug: you’ll need these to access the correct resources later when using the ticketing service. But first the user needs to retrieve a coupon.

Getting a Coupon

First get a handle to join the waitingline.

curl 'https://gate.api.sandbox.guts.events/api/v1.0/gates/<gate_slug>' -X POST

//Response

        {
            "status":"success",
            "handle":"6aa8efbf737905bbe65a015b89c2982a"
        }

The gatekeeper has now added the user to the queue. Based on load the gate will advance users within the queue. To check the users status.

curl 'https://gate.api.sandbox.guts.events/api/v1.0/line/<handle>

//Response

        {
            "handle":"6aa8efbf737905bbe65a015b89c2982a",
            "gate":"jy0iox",
            "number":"",
            "email":"",
            "entered":"2019-12-06T13:33:14.435384374Z",
            "position":1,
            "last_advanced":0,
            "minutes_till_turn":0.3333333333333333,
            "state":"waiting"|"turn",
            "message":""
        }

You’re supposed to poll this endpoint until the state has changed from waiting to turn. When the state is turn your can retrieve the coupon.

curl 'https://gate.api.sandbox.guts.events/api/v1.0/line/<handle>/select' -X POST

//Response

        {
            "status":"success",
            "coupon":"Omc0MjM6MDo2YWE4ZWZiZjczNzkwNWJiZTY1YTAxNWI4OWMyOTgyYTo4MDkzOWRmZGZlNDg2ZGQyNDU3Zjk4OTQ5YmQzNzFkMw=="
        }

Redeeming the Coupon

The coupon should be added to the request header when you call the shop endpoints. The user needs to be logged in for the coupon to be processed.

curl 'https://api.sandbox.guts.tickets/api/v1/shops/<shop_slug>/' -H 'coupon: coupon_hash' -H 'Authorization: JWT jwt_token

If the coupon is correctly processed, the response header will contain the header coupon:processed.

The following endpoints will process coupons:

  • https://api.sandbox.guts.tickets/api/v1/shops/<shop_slug>/

  • https://api.sandbox.guts.tickets/api/v1/events/<event_slug>/

  • https://api.sandbox.guts.tickets/api/v1/carts/<shop_slug>/<uuid>/checkout/

In a normal flow, the coupon will be processed during the cart checkout because it’s the first time the user will be authenticated. The shop and event endpoint process coupons to provide a good workflow for already logged in users.

A coupon can only be used once. After it has been processed it will be ignored.

Use Case: Buying a ticket flow

Before you can buy a tickets make sure you first complete the gatekeeper flow to obtain the shop_slug and a coupon. Make sure you add the coupon to your request header as described.

Getting the shop details

curl 'https://api.sandbox.guts.tickets/api/v1.0/shops/<shop_slug>/'

//Response
    {
        "id": 1,
        "slug": "pkdcbk",
        ...
        "ticket_kinds":[
            {
                ...
                "id": <id_1>,
                ...
            },
            {
                ...
                "id": <id_2>,
                ...
            }

Create a cart

Next we need to create a cart. You’ll need to create a uuid4 for the cart yourself the format is

example: 98bebab2-3969-4ec4-b16c-dcabfc4e9c5f

Next we retrieve the cart.

curl 'https://api.sandbox.guts.tickets/api/v1.0/carts/<shop_slug>/<uuid>

//Response
{
    "uuid":"<uuid>",
    "ticket_kinds": []
}

Fill the cart

As you can see the cart is now empty. We can fill the cart with tickets by sending a PUT request with this data payload structure. The kind key is the ID of the ticket kind that the user selects. These IDs are available in the event detail response under the key ticket_kinds. Make sure you always send the whole ticket/rank state.

{
    "ticket_kinds": [
        { "id": <kind_1>, "amount": 2 },
        { "id": <kind_2>, "amount": 1 }
    ]
}
curl 'https://api.sandbox.guts.tickets/api/v1.0/carts/<shop_slug>/<uuid>' -X PUT -H 'Content-Type: application/json; charset=utf-8' --data '{"ticket_kinds": [{"id": 1, "amount":0},{"id": 2, "amount":1}]}'

Payment

To start a payment we first have to checkout the cart. At this point the user has to be logged in. So make sure to authenticate the user using the correct Authorization header (see example).

curl 'https://api.sandbox.guts.tickets/api/v1.0/carts/<shop_slug>/<uuid>/checkout/' -X PUT -H 'Authorization: JWT <jwt_token>'

//Response
{"order": <id>, "state": ""}

Using the returned order we can start a payment on the order.

curl 'https://api.sandbox.guts.tickets/api/v1.0/orders/<order_id>/start_payment/' -X POST -H 'Authorization: JWT <jwt_token> -H 'Content-Type: application/json; charset=utf-8' --data '{"psp_arguments", {"return_page": <your_url>}}'

//Response
{"status": "redirect": <url>}

The return_url should be the url of your landing page that handles the order completion.

After this list your new tickets.

curl 'https://api.sandbox.guts.tickets/api/v1.0/tickets/' -H 'Authorization: JWT <jwt_token>'

Use Case: Retrieving QR code

To scan a users ticket you’ll will need retrieve the QR code. QR code are not per ticket but per event. The scanner knows which tickets belong to which user. So each user has only one QR code for all tickets of the same event.

Getting the code

curl 'https://api.sandbox.guts.tickets/api/v1.0/events/<event_slug>/code'

//Response
    {
        "code": <qrcode>,

The code should be rendered unchanged as a standard qrcode. The code itself is valid for 15 seconds. So a new one should be retrieved every 15 seconds

Use Case: External Authentication

The GET Protocol only allows user to login with a mobile phone using an sms. If you want create a different login flow (email and password for example) you’ll have to create your own login flow. After the user has logged into your system your can request authentication as a ticketeer token on behalf of a user. You can then pass along this token to your user.

  • This will create a separate user in our system that can only be accessed by your ticketeer

  • This requires an api key specific to your ticketeer.

User hash

You’ll be identifying your user by a hash. This can be anything, it’s up to you. We suggest to build the hash based on how you identify your users. This is has two benefits:

  • You don’t have to keep track of some sort of id. You can build the hash on the fly based on the user’s credentials

  • It allows you to keep all personal information outside of the GET Protocol

Login external user

An example using python3 to generate a hash

>>> import hashlib
>>> h = hashlib.sha256()
>>> h.update(b"username@mail.com")
>>> h.hexdigest()
'5ef7609155bc0a9f37d1a149e6d7dcf63d2bb841ecdad3667e7149e5dfff9df1'
curl -X POST --data '{"user_hash":"5ef7609155bc0a9f37d1a149e6d7dcf63d2bb841ecdad3667e7149e5dfff9df1","app":"mobile"}' https://gus.api.sandbox.guts.events/api/v1/external-auth/ --header "x-api-key:welcome"
Response
{
    "status":"success",
    "token":"jwt_token",
    "refresh_token":"refresh_token"
}

Use Case: External Ticketeer

Integrate an external system that handles the sales and seating with GUTS. A user can see his tickets in the GUTS ticket wallet app and scan his ticket with GUTS scanner.

Authentication

A dashboard user account is required to continue the procedure. Contact GUTS to learn more and have your account generated. Check here how to login and here how to use the tokens.

Get organization ID

You need to know your organization id if you want to create an event. Check here on how to retrieve it. Normally you are going to be part of one organization, so the list will contain only one item, which will be used to create the event. We are going to use the key id of that item for the next steps and refer to it as organization_id.

Create event

Check here how to create an event. You probably want to use hide: true and organization: <organization_id> from the previous step. We refer to the returned id as event_id.

(Optional) Upload cover photo for event

In order to set the cover photo for an event you need to:

  1. Request upload url from GET Protocol, check here how to do that, setting field cover.

  2. After that you need to upload the image to the amazon s3 bucket using the key returned by request upload url.

// We use javascript here for convenience, transforming the following code to another language is trivial.
// We assume that data is the response data from request_upload
// We use axios here, this can be replaced with any library

const s3Object = new FormData();

Object.keys(data.fields).forEach((k) => {
    s3Object.append(k, data.fields[k]);
});
s3Object.append('Content-Type', image.type);
s3Object.append('file', image);
axios.post(data.url, s3Object).then(() => {
    const url = data.url + data.fields.key
    // Your image is on the url, you can use it in cover key in event url
})
  1. Use the resulting key as cover in event edit api.

Create shop

Check here how to create a shop. We refer to the id of the object returned as shop_id

Create privilege type

Check here how to create a PrivilegeType. In the case of external ticketeer the recommended payload is:

{
    "name":"My Ticket",
    "total":"0",
    "blocks":0,
    "upsell":false,
    "event": "<event_id>" // from previous step
}'

We refer to the id of the object returned as privilegetype_id

Create ticket kind

Check here how to create a ticket-kind. In the case of external ticketeer the recommended payload is:

{
   "shops": ["<shop_id>"], // From previous step
   "name": "My ticket kind",
   "privilege_types": ["privilegetype_id"] // from previous step
   "description": "My description", //OPTIONAL
   "price_buildup": [{"tag": "ticket", "vat": 0, "price": "34.00", "is_base": true}], // Adding the correct value will make reporting better
   "for_sale": false, // don't sell through GUTS
   "guest": true
}

We refer to the id of the object returned as ticketkind_id

Publish Event

Check here

Register Ticket

You need to have already obtained the user’s mobile phone in your system. Note: normalizing mobile phone is not required. +31611111111 and 0611111111 are both valid. After a successful ticket sale in your system, register ticket in GET Protocol.

Check here how to make the request. You need to use ticketkind_id from previous step as ticket_kind. You need to use “pool”: “new” to create new tickets instead of using the ones that are for sale. If you followed the steps above, the ticketkind does not have any available tickets for sale. You need to use “paid_to”: “eo” meaning that the ticket was already paid to the Event organizer without going through GET Protocol backend. You need to use “free”: false" meaning that it is not a gift.

The response contains an array of tickets, and each of them contains an array of privileges (in this case all of them are of length one). We are going to refer to the ids of this single item of the privileges array as privilege_id. We are going to refer to the ids of the tickets list as ticket_id

Register Seating for a ticket

Check here how to edit privileges. You need to use privilege_id from above and use info to add your seating details. This field will show up in the GUTS apps.

Invalidate tickets (Optional)

In case of editing/changing tickets in your system and you want to keep GET Protocol in sync, you can invalidate tickets. You need to use ticket_id from previous step.

Authentication Endpoints

Authentication and Users

IMPORTANT Authentication for customers is on different domain then the rest of the application When a user must be logged in to a specific ticketeer. Only resources belonging to that ticketeer can be accessed else a 404 is returned.

Customer request verification_code

Customer request verification_code
POST/api/v1/auth-ticketeer/{ticketeer}/{recipient}

Example URI

POST /api/v1/auth-ticketeer/ticketeer/recipient
URI Parameters
HideShow
ticketeer
string (required) 

name of the ticketeer logging into

recipient
string (required) 

phoneumber of recipient include contrycode

Request
HideShow
Headers
Content-Type: application/json
Body
{
  "locale": "en"
}
Schema
{
    "type": "object",
    "properties": {
        "locale": {
            "type": "string"
            "description": "determines language used in SMS"
        }
    },
    "required": ["locale"]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "verification_code": "7b5601a3-4a25-4955-8568-4f703a219aa1",
    "tries_left":3,
}

Customer login

Customer login
POST/api/v1/auth-verify

Example URI

POST /api/v1/auth-verify
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "pincode": "2834",
  "verification_code": "7b5601a3-4a25-4955-8568-4f703a219aa1",
  "app": "web"
}
Schema
{
    "type": "object",
    "properties": {
        "pincode": {
            "type": "string"
            "description": "pin sent to users phone"
        },
        "verification_code": {
            "type": "string"
            "description": "id of verification_code"
        }
        "app": {
            "type": "string"
            "description": "id of client used. This allow to be logged in to multiple devices",
            "pattern":"queue|mobile|wallet|shop|ios|android|web|default"
        }
    },
    "required": ["pin", "verification_code", "app"]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
        "status" : "error"
        "error": "invalid_pin"|"used_verification_code"
        "tries_left":2,
    }
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
        "status" : "success"
        "tries_left":2,
        "token": "jwt token"
        "refresh_token": "refresh token"
    }

Refresh Token

Refresh Token
POST/api/v1/refresh

Use this endpoint to retrieve a new jwt token and refresh token.

Example URI

POST /api/v1/refresh
Request
HideShow
Headers
Content-Type: application/json
Body
{
    "refresh_token": "refresh token",
}
Schema
{
    "type": "object",
    "properties": {
        "refresh_token": {
            "type": "string"
            "description": "refresh token"
        }
    },
    "required": ["refresh_token",]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
        "status" : "error"
        "error": "refresh_token_expired"|"refresh_token_not_found"
    }
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
        "status" : "succes"
        "token": "jwt token"
        "refresh_token": "new refresh token"
    }

External authentication

External authentication
POST/api/v1/external-auth

Example URI

POST /api/v1/external-auth
Request
HideShow
Headers
Content-Type: application/json
x-api-key: ticketeer-token
Body
{
    "user_hash": "hash",
    "app", "mobile"
}
Schema
{
    "type": "object",
    "properties": {
        "user_hash": {
            "type": "string"
            "description": "hash to identify user"
            "pattern":"^[a-zA-z0-9\-\/_\+=]+$"
        },
        "app": {
            "type": "string"
            "description": "id of client used. This allow to be logged in to multiple devices",
            "pattern":"queue|mobile|wallet|shop|ios|android|web|default"
        }
    },
    "required": ["user_hash", "app"]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
        "status" : "succes"
        "token": "jwt token"
        "refresh_token": "new refresh token"
    }

Event organizer Login

Event organizer Login
POST/api/v1.0/api-token-auth/

Event organizers login to GET Protocol using their credentials instead of a mobile phone. Contact GET Protocol to get your credentials.

Example URI

POST /api/v1.0/api-token-auth/
Request
HideShow
  • =

    {
          "username": "MY USERNAME",
          "password": "MY PASSWORD"
      }
Headers
Content-Type: application/json
Schema
{
    "type": "object",
    "properties": {
        "username": {
            "type": "string"
            "description": "Username provided"
        },
        "password": {
            "type": "string"
            "description": "Your password"
        }
    },
    "required": ["username", "password"]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 62721,
  "username": "+3161345678",
  "first_name": "",
  "last_name": "",
  "email": "",
  "verified": false,
  "date_joined": "2019-02-06T12:26:15.357093+01:00",
  "profile_complete": false,
  "gender": null,
  "birthdate": null,
  "zipcode": "",
  "house_number": "",
  "locale": "nl",
  "opt_in": null,
  "avatar": null,
  "can_share_tickets": true,
  "refresh_token": "refresh_token",
  "jwt_token": "jwt_token"
}

JWT Token Refresh

JWT Token Refresh
POST/api/v1.0/api-token-refresh/

Eventually the jwt token will expire. A new one can be retrieved using the refresh token. If a new refresh token is generated the old one will become invalid.(logging in on a different device)

Example URI

POST /api/v1.0/api-token-refresh/
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "client_id": "web",
  "refresh_token": "refresh_token"
}
Schema
{
    "type": "object",
    "properties": {
        "client_id": {
            "type": "string",
            "description": "can be anything, allows to be signed in 
                            multiple devices"
        },
        "refresh_token": {
            "type": "string",
            "description": "determines language used in SMS"
        }
    },
    "required": ["client_id", "refresh_token"]
}
Response  201
HideShow
Headers
Content-Type: application/json
Body
{
  "token": "jwt_token",
  "refresh_token": "refresh_token"
}

Self

Self
GET/api/v1.0/users/self

Return the user that makes the request. The user is located from the information in the JWT token in the header.

Example URI

GET /api/v1.0/users/self
Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "id":1,
    "username":"+3161234568",
    "first_name":"",
    "last_name":"",
    "email":"email@gmail.com",
    "verified":false,
    "is_active":true,
    "date_joined":"2018-04-03T11:15:55+02:00",
    "profile_complete":true,
    "gender":"o",
    "birthdate":"1989-01-02T01:00:00+01:00",
    "zipcode":"",
    "house_number":"",
    "locale":"en",
    "opt_in":"true",
}

Update details

Update details
PUT/api/v1.0/users/{id}

Example URI

PUT /api/v1.0/users/1
URI Parameters
HideShow
id
number (required) Example: 1

id of users

Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Body
{
    "id":1,
    "username":"+3161234568",
    "first_name":"",
    "last_name":"",
    "email":"email@gmail.com",
    "verified":false,
    "is_active":true,
    "date_joined":"2018-04-03T11:15:55+02:00",
    "profile_complete":true,
    "gender":"o",
    "birthdate":"1989-01-02T01:00:00+01:00",
    "zipcode":"",
    "house_number":"",
    "locale":"en",
    "opt_in":"true",
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "id":1,
    "username":"+3161234568",
    "first_name":"",
    "last_name":"",
    "email":"email@gmail.com",
    "verified":false,
    "is_active":true,
    "date_joined":"2018-04-03T11:15:55+02:00",
    "profile_complete":true,
    "gender":"o",
    "birthdate":"1989-01-02T01:00:00+01:00",
    "zipcode":"",
    "house_number":"",
    "locale":"en",
    "opt_in":"true",
}

Gatekeeper Endpoints

Gatekeeper

IMPORTANT the gate keeper is on different domain then the rest of the application

To buy tickets you need the slug of the gate to a specific shop. Note multiple gates can point to the same shop and a gate can point to multiple shops.

Gate Detail
GET/api/v1.0/gates/{gate_slug}

Example URI

GET /api/v1.0/gates/123a9s
URI Parameters
HideShow
gate_slug
string (required) Example: 123a9s

slug of gate

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 423,
  "slug": "jy0iox",
  "human_slug": "",
  "title": "title",
  "subtitle": "subtitle",
  "image": "url",
  "shops": [
    320
  ],
  "shop_slugs": [
    "bnbgpz"
  ],
  "start": "2019-05-14T08:00:00Z",
  "auto_queue_started": "0001-01-01T00:00:00Z",
  "type": "open",
  "state": "running",
  "message": "",
  "entries_per_minute": 0,
  "time_to_start": -17818393
}

Gate Shops
GET/api/v1.0/gates/{gate_slug}/shops

Example URI

GET /api/v1.0/gates/123a9s/shops
URI Parameters
HideShow
gate_slug
string (required) Example: 123a9s

slug of gate

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    [
        "id":320,
        "slug":"bnbgpz",
        "event_slug":"xdzf0q",
        "title":"",
        "subtitle":"",
        "location":"",
        "local_timezone":"Europe/Amsterdam",
        "city":"",
        "when":"2019-12-17T19:00:00Z",
        "time_till_soldout":"2019-11-15T11:37:24.761296Z",
        "state":"no_available",
        "publish_state":"published"
    ]
}

Enter Gate
POST/api/v1.0/gates/{gate_slug}

Example URI

POST /api/v1.0/gates/123a9s
URI Parameters
HideShow
gate_slug
string (required) Example: 123a9s

slug of gate

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "status": "success",
  "handle": "6aa8efbf737905bbe65a015b89c2982a"
}

Check Line
GET/api/v1.0/line/{handle}

Example URI

GET /api/v1.0/line/123a9s
URI Parameters
HideShow
handle
string (required) Example: 123a9s

handle identifying a specific customer. Handed out by gatekeeper.

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "handle":"6aa8efbf737905bbe65a015b89c2982a",
    "gate":"jy0iox",
    "number":"",
    "email":"",
    "entered":"2019-12-06T13:33:14.435384374Z",
    "position":1,
    "last_advanced":0,
    "minutes_till_turn":0.3333333333333333,
    "state":"waiting"|"turn",
    "message":""
}

Retrieve Coupon
POST/api/v1.0/line/{handle}/select

Example URI

POST /api/v1.0/line/123a9s/select
URI Parameters
HideShow
handle
string (required) Example: 123a9s

handle identifying a specific customer. Handed out by gatekeeper.

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "status": "success",
  "coupon": "Omc0MjM6MDo2YWE4ZWZiZjczNzkwNWJiZTY1YTAxNWI4OWMyOTgyYTo4MDkzOWRmZGZlNDg2ZGQyNDU3Zjk4OTQ5YmQzNzFkMw=="
}

Ticketing Endpoints

Organizations

List
GET/api/v1.0/organizations/

Example URI

GET /api/v1.0/organizations/
Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 1,
      "name": "My Org",
      "permissions": [],
      "floorplans": []
    }
  ]
}

Details
GET/api/v1.0/organizations/{id}

Example URI

GET /api/v1.0/organizations/123
URI Parameters
HideShow
id
string (required) Example: 123

id of an organization

Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 123,
  "name": "My Org",
  "permissions": [],
  "floorplans": []
}

Events

A listing of all events.

List
GET/api/v1.0/events/{?filter,own}

Example URI

GET /api/v1.0/events/?filter=upcoming&own=True
URI Parameters
HideShow
filter
string (optional) Example: upcoming

only show upcoming events

own
boolean (optional) Example: True

only show events the user has tickets for. (this flag requires being logged in) (second response)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "count": 1,
    "next": null,
    "previous":null,
    "results": [
        {
            "id": 359,
            "title": "delete",
            "subtitle": null,
            "when": "2019-05-01T00:21:00Z",
            "ends": "2029-12-31T23:00:00Z",
            "local_timezone": "Europe/Amsterdam",
            "location": "location",
            "sublocation": "",
            "address": "address",
            "city": "Amsterdam",
            "country": "NL",
            "cover": null,
            "slug": "vf76jy",
            "currency": {
                "code": "EUR",
                "name": "Euro",
                "decimals": 2
        }
    ]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "count":1,
    "next":null,
    "previous":null,
    "results":[
        {
            "id":11,
            "title":"title",
            "subtitle":"subtitle",
            "when":"2017-04-07T15:30:00Z",
            "ends":"2017-04-09T01:00:00Z",
            "local_timezone":"Europe/Amsterdam",
            "location":"location",
            "sublocation":"",
            "address":"",
            "city":"Amsterdam",
            "country":"NL",
            "slug":"e671jc",
            "cover":"https://cover.jpg",
            "seated":false,
            "user_purchased_tickets": 0,
            "user_purchased_upsells": 0,
            "default_gate":"e671jc",
        }
    ]
}

Create
POST/api/v1.0/events/

Example URI

POST /api/v1.0/events/
Request
HideShow
Headers
Content-Type: application/json
Body
{
    organization: 12,
    doors_open: ISO8601,
    when: ISO8601,
    ends: ISO8601,
    title: string,
    hide: true,

    subtitle: string,
    description: html_string,
    location: string,
    city: string,
    cover: 'url'

}
Schema
{
    "type": "object",
    "properties": {
        "organization": {
            "type": "integer"
            "description": "id of organization"
        },
        "doors_open": {
            "type": "ISO8601"
            "description": "start time of scanning"
        },
        "when": {
            "type": "ISO8601"
            "description": "start time of event"
        },
        "ends": {
            "type": "ISO8601"
            "description": "end time of event"
        },
        "title": {
            "type": "string",
            "description": "Title of event"
        },
        "hide": {
            "type": boolean,
            "description": "should the event be hidden from the GUTS website?"
        },
        "cover": {
            "type": "url",
            "description: "cover image of event"
        },[POST /api/v1.0/events/]
        "subtitle": {
            "type": "string",
            "description": "Subtitle of event"
        },
        "description": {
            "type": "html|string"
            "description": "Extra information for the event"
        },
        "location": {
            "type": "string",
            "description": "Description of the event location"
        },
        "city": {
            "type": "string",
            "description": "city of the event"
        }
    },
    "required": ["organization", "doors_open", "when", "ends", "title", "hide"]
}
Response  201
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 11,
  "seating_image": null,
  "cover": "https://cover.jpg",
  "currency": {
    "code": "EUR",
    "name": "Euro",
    "decimals": 2
  },
  "seating_finalized": false,
  "seated": false,
  "ticketgroup": null,
  "user_purchased_tickets": 0,
  "user_purchased_upsells": 0,
  "default_gate": "oel46n",
  "slug": "oel46n",
  "human_slug": "human-slug",
  "when": "2017-10-01T12:00:00Z",
  "ends": "2017-10-01T21:59:00Z",
  "local_timezone": "Europe/Amsterdam",
  "doors_open": "2017-10-01T12:00:00Z",
  "title": "Pitch on the beach",
  "subtitle": "1 October 2017",
  "description": "<p>Description</p>",
  "has_interactive_seating_image": false,
  "location": "Safari Lodge",
  "sublocation": "",
  "city": "",
  "address": "",
  "country": "",
  "latitude": "0.0000000",
  "longitude": "0.0000000",
  "publish_state": "published",
  "organization": 6
}

Detail
GET/api/v1.0/events/{slug}

Example URI

GET /api/v1.0/events/9a6936593705b0998868
URI Parameters
HideShow
slug
string (required) Example: 9a6936593705b0998868

slug of an event

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 11,
  "seating_image": null,
  "cover": "https://cover.jpg",
  "currency": {
    "code": "EUR",
    "name": "Euro",
    "decimals": 2
  },
  "seating_finalized": false,
  "seated": false,
  "ticketgroup": null,
  "user_purchased_tickets": 0,
  "user_purchased_upsells": 0,
  "default_gate": "oel46n",
  "slug": "oel46n",
  "human_slug": "human-slug",
  "when": "2017-10-01T12:00:00Z",
  "ends": "2017-10-01T21:59:00Z",
  "local_timezone": "Europe/Amsterdam",
  "doors_open": "2017-10-01T12:00:00Z",
  "title": "Pitch on the beach",
  "subtitle": "1 October 2017",
  "description": "<p>Description</p>",
  "has_interactive_seating_image": false,
  "location": "Safari Lodge",
  "sublocation": "",
  "city": "",
  "address": "",
  "country": "",
  "latitude": "0.0000000",
  "longitude": "0.0000000",
  "publish_state": "published",
  "organization": 6
}

Edit
PATCH/api/v1.0/events/

Example URI

PATCH /api/v1.0/events/
Request
HideShow
Headers
Content-Type: application/json
Body
{
    organization: 12,
    doors_open: ISO8601,
    when: ISO8601,
    ends: ISO8601,
    title: string,
    hide: true,

    subtitle: string,
    description: html_string,
    location: string,
    city: string,
    cover: 'url'

}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 11,
  "seating_image": null,
  "cover": "https://cover.jpg",
  "currency": {
    "code": "EUR",
    "name": "Euro",
    "decimals": 2
  },
  "seating_finalized": false,
  "seated": false,
  "ticketgroup": null,
  "user_purchased_tickets": 0,
  "user_purchased_upsells": 0,
  "default_gate": "oel46n",
  "slug": "oel46n",
  "human_slug": "human-slug",
  "when": "2017-10-01T12:00:00Z",
  "ends": "2017-10-01T21:59:00Z",
  "local_timezone": "Europe/Amsterdam",
  "doors_open": "2017-10-01T12:00:00Z",
  "title": "Pitch on the beach",
  "subtitle": "1 October 2017",
  "description": "<p>Description</p>",
  "has_interactive_seating_image": false,
  "location": "Safari Lodge",
  "sublocation": "",
  "city": "",
  "address": "",
  "country": "",
  "latitude": "0.0000000",
  "longitude": "0.0000000",
  "publish_state": "published",
  "organization": 6
}

Get Qr code
GET/api/v1.0/events/{slug}/code

Example URI

GET /api/v1.0/events/9a6936593705b0998868/code
URI Parameters
HideShow
slug
string (required) Example: 9a6936593705b0998868

slug of an event

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "code": "GPT:12341234"
}

Request upload url
POST/api/v1.0/events/request_upload

Example URI

POST /api/v1.0/events/request_upload
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "field": "cover",
  "filename": "filename.png"
}
Schema
{
    "type": "object",
    "properties": {
        "field": {
            "type": "oneOf: [cover, seating_image]"
            "description": "the field that you are about to edit"
        },
        "filename": {
            "type": "string"
            "description": "name of the file"
        }
    },
    "required": ["filename", "field"]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "url":"https://otas3staging.s3.amazonaws.com/",
    "fields":{
        "acl":"...",
        "cache-control":"...",
        "key":"...",
        "x-amz-algorithm":"...",
        "x-amz-credential":"...",
        "x-amz-date":"...",
        "policy":"...",
        "x-amz-signature":"..."}
    }
}

Publish
POST/api/v1.0/events/publish

Publishing an event:

  • Changes event state from draft to published.

  • Invalidates all the existing tickets

  • Shows event in ticket listings (if hide = true)

Example URI

POST /api/v1.0/events/publish
Request
HideShow
Headers
Content-Type: application/json
Body
No body is required
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
        'success': true
    }

Shops

A listing of all events.

List
GET/api/v1.0/shops/{?event_id,event_slug}

Example URI

GET /api/v1.0/shops/?event_id=1&event_slug=9a6936593705b0998868
URI Parameters
HideShow
event_id
number (optional) Example: 1

only show shops from event with this id

event_slug
string (optional) Example: 9a6936593705b0998868

only show shops from event with this slug

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "count":1,
    "next":null,
    "previous":null,
    "results":[
        {
            "id": 1,
            "slug": "pkdcbk",
            "name": "Default",
            "event_slug": "af3rdx,
            "ticket_kinds": [],
            "user_ticket_limit": 22,
            "max_tickets": 22,
            "user_purchased_tickets": 0,
            "state": "past",
            "sale_start": "2020-01-02T01:00:00+01:00",
            "sale_end": "2020-01-02T01:00:00+01:00",
            "ticket_layout": {},
            "human_slug": "welcome-to-the-village",
            "has_interactive_seating_image": false,
            "time_till_soldout": null
        }
    ]
}

Create
POST/api/v1.0/shops/

Example URI

POST /api/v1.0/shops/
Request
HideShow
Headers
Content-Type: application/json
Body
{
        name: string,
        event: int,
        sale_starts: ISO8601,
        sale_ends: ISO8601,
        max_tickets: int,
    }
Schema
{
    "type": "object",
    "properties": {
        "name": {
            "type": "shop 2"
            "description": "name of shop"
        },
        "event": {
            "type": "integer"
            "description": "id of event"
        },
        "name": {
            "type": "string",
            "description": "name of the shop",
        },
        "sale_start": {
            "type": "ISO8601"
            "description": "start time of sale on that shop"
        },
        "sale_ends": {
            "type": "ISO8601"
            "description": "end time of sale on that shop"
        },
        "max_tickets": {
            "type": "int"
            "description": "max tickets per order in that shop"
        }
    },
    "required": ["event", "name"]
}
Response  201
HideShow
Headers
Content-Type: application/json
Body
{
    "id": 1,
    "slug": "pkdcbk",
    "name": "Default",
    "event_slug": "af3rdx,
    "ticket_kinds": [],
    "user_ticket_limit": 22,
    "max_tickets": 22,
    "user_purchased_tickets": 0,
    "state": "past",
    "sale_start": "2020-01-02T01:00:00+01:00",
    "sale_end": "2020-01-02T01:00:00+01:00",
    "ticket_layout": {},
    "human_slug": "welcome-to-the-village",
    "has_interactive_seating_image": false,
    "time_till_soldout": null
}

Detail
GET/api/v.1.1/shops/{id}

Example URI

GET /api/v.1.1/shops/1
URI Parameters
HideShow
id
number (required) Example: 1

id of a shop

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "id": 1,
    "slug": "pkdcbk",
    "name": "Default",
    "event_slug": "af3rdx,
    "ticket_kinds": [],
    "user_ticket_limit": 22,
    "max_tickets": 22,
    "user_purchased_tickets": 0,
    "state": "past",
    "sale_start": "2020-01-02T01:00:00+01:00",
    "sale_end": "2020-01-02T01:00:00+01:00",
    "ticket_layout": {},
    "human_slug": "welcome-to-the-village",
    "has_interactive_seating_image": false,
    "time_till_soldout": null
}

Edit
PUT/api/v.1.1/shops/{id}

Example URI

PUT /api/v.1.1/shops/1
URI Parameters
HideShow
id
number (required) Example: 1

id of a shop

Request
HideShow
Headers
Content-Type: application/json
Body
{
        name: string,
        event: int,
        sale_starts: ISO8601,
        sale_ends: ISO8601,
        max_tickets: int,
    }
Schema
{
    "type": "object",
    "properties": {
        "name": {
            "type": "shop 2"
            "description": "name of shop"
        },
        "event": {
            "type": "integer"
            "description": "id of event"
        },
        "name": {
            "type": "string",
            "description": "name of the shop",
        },
        "sale_start": {
            "type": "ISO8601"
            "description": "start time of sale on that shop"
        },
        "sale_ends": {
            "type": "ISO8601"
            "description": "end time of sale on that shop"
        },
        "max_tickets": {
            "type": "int"
            "description": "max tickets per order in that shop"
        }
    },
    "required": ["event", "name"]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "id": 1,
    "slug": "pkdcbk",
    "name": "Default",
    "event_slug": "af3rdx,
    "ticket_kinds": [],
    "user_ticket_limit": 22,
    "max_tickets": 22,
    "user_purchased_tickets": 0,
    "state": "past",
    "sale_start": "2020-01-02T01:00:00+01:00",
    "sale_end": "2020-01-02T01:00:00+01:00",
    "ticket_layout": {},
    "human_slug": "welcome-to-the-village",
    "has_interactive_seating_image": false,
    "time_till_soldout": null
}

Edit
PATCH/api/v.1.1/shops/{id}

Example URI

PATCH /api/v.1.1/shops/1
URI Parameters
HideShow
id
number (required) Example: 1

id of a shop

Request
HideShow
Headers
Content-Type: application/json
Body
{
        name: string,
        event: int,
        sale_starts: ISO8601,
        sale_ends: ISO8601,
        max_tickets: int,
    }
Schema
{
    "type": "object",
    "properties": {
        "name": {
            "type": "shop 2"
            "description": "name of shop"
        },
        "event": {
            "type": "integer"
            "description": "id of event"
        },
        "name": {
            "type": "string",
            "description": "name of the shop",
        },
        "sale_start": {
            "type": "ISO8601"
            "description": "start time of sale on that shop"
        },
        "sale_ends": {
            "type": "ISO8601"
            "description": "end time of sale on that shop"
        },
        "max_tickets": {
            "type": "int"
            "description": "max tickets per order in that shop"
        }
    },
    "required": []
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "id": 1,
    "slug": "pkdcbk",
    "name": "Default",
    "event_slug": "af3rdx,
    "ticket_kinds": [],
    "user_ticket_limit": 22,
    "max_tickets": 22,
    "user_purchased_tickets": 0,
    "state": "past",
    "sale_start": "2020-01-02T01:00:00+01:00",
    "sale_end": "2020-01-02T01:00:00+01:00",
    "ticket_layout": {},
    "human_slug": "welcome-to-the-village",
    "has_interactive_seating_image": false,
    "time_till_soldout": null
}

Delete
DELETE/api/v1.0/shops/{id}

Example URI

DELETE /api/v1.0/shops/1
URI Parameters
HideShow
id
number (required) Example: 1

id of a shop

Response  204

TicketKinds

TicketKind list
GET/api/v1.0/ticket-kinds/{?event_id}

Example URI

GET /api/v1.0/ticket-kinds/?event_id=102,
URI Parameters
HideShow
event_id
number (optional) Example: 102,

filter tickets per event

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 734,
      "type_id": 525,
      "available_from": "2018-04-30T13:49:02+02:00",
      "available_to": "2019-04-19T23:59:00+02:00",
      "root": true,
      "combi": false,
      "price_buildup": [
        {
          "tag": "Base Ticket",
          "vat": "0.21",
          "price": "1.00"
        }
      ],
      "price": "1.00",
      "created": "2018-09-04T16:03:38.727535+02:00",
      "modified": "2019-02-04T12:45:32.263222+01:00",
      "name": "Paid entrance",
      "description": "",
      "for_sale": true,
      "max_amount": 100,
      "max_per_user": null,
      "local_available_from": null,
      "local_available_to": null,
      "guest": false
    }
  ]
}

Detail
GET/api/v1.0/ticket_kinds/{id}/

Example URI

GET /api/v1.0/ticket_kinds/734/
URI Parameters
HideShow
id
number (required) Example: 734

id of ticket

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 734,
  "type_id": 525,
  "available_from": "2018-04-30T13:49:02+02:00",
  "available_to": "2019-04-19T23:59:00+02:00",
  "root": true,
  "combi": false,
  "price_buildup": [
    {
      "tag": "Base Ticket",
      "vat": "0.21",
      "price": "1.00"
    }
  ],
  "price": "1.00",
  "created": "2018-09-04T16:03:38.727535+02:00",
  "modified": "2019-02-04T12:45:32.263222+01:00",
  "name": "Paid entrance",
  "description": "",
  "for_sale": true,
  "upsell": false,
  "max_amount": 100,
  "max_per_user": null,
  "local_available_from": null,
  "local_available_to": null,
  "guest": false
}

Create simple
POST/api/v1.0/tickets/create/

Example URI

POST /api/v1.0/tickets/create/
Request
HideShow
Headers
Content-Type: application/json
Body
{
    "upsell":false,
    "privilege_types":[100],
    "price_buildup":[{"price":<price>,"tag":"Base","vat":"0","is_base":true}],
    "name":"Ticket 1",
    "guest":true,
    "shops":[123]
}
Schema
{
    "type": "object",
    "properties": {
        "upsell": {
            "type": "boolean"
            "description": "upsell ticket, e.g. Parking, beer, ..."
        },
        "name": {
            "type": "string",
            "description": "name of the ticket"
        },
        "privilege_types": {
            "type": "array",
            "description"; "list of privilege_type_ids (integers) that are associated with the ticket kind."
        },
        "shops": {
            "type": "array",
            "description": "List of shop_ids that the ticket will be available at"
        },
        "guest": {
            "type": "boolean",
            "description": "Is it a ticketkind for guests?"
        },
        "price_buildup": {
            "type": "array",
            "description": "extended information of price, the total price is the sum of these parts",
            "item": {
                "type": "object",
                "properties": {
                    "is_base": {
                        "type": "boolean",
                        "description": "is this part the base price? Exactly one item has to be true"
                    },
                    "tag": {
                        "type": "string",
                        "description": "tag the price part, useful for reports"
                    },
                    "price": {
                        "type": "decimal string",
                        "description: "price of the part"
                    },
                    "vat": {
                        "type": "float [0-1]",
                        "description" "vat of the price part"
                    }
            },
        },
        "for_sale": {
            "type": "boolean",
            "description": "false disables selling this ticket kind"
        }
    },
    "required": ["for_sale", "price_buildup", "amount", "name", "privilege_ids", "shops"]
}
Response  201
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 734,
  "type_id": 525,
  "available_from": "2018-04-30T13:49:02+02:00",
  "available_to": "2019-04-19T23:59:00+02:00",
  "root": true,
  "combi": false,
  "price_buildup": [
    {
      "tag": "ticket",
      "vat": "0",
      "price": "34.00",
      "is_base": true
    }
  ],
  "price": "34.00",
  "created": "2018-09-04T16:03:38.727535+02:00",
  "modified": "2019-02-04T12:45:32.263222+01:00",
  "name": "Name",
  "description": "",
  "for_sale": true,
  "upsell": false,
  "max_amount": 100,
  "max_per_user": null,
  "local_available_from": null,
  "local_available_to": null,
  "guest": false
}

Tickets

All tickets have a Ticket kind. The ticket kinds are determined by the organiser when setting up an event. A ticket kind can represent a simple entrance ticket but there is much more. There are combi tickets, early bird, upsell and guest tickets.

When a customer buys a ticket he specifies the ticket kind. The api then creates a ticket with the correct ticket kind for the user.

List
GET/api/v1.0/tickets/{?event_id}

Show all tickets belonging to a user

Example URI

GET /api/v1.0/tickets/?event_id=102,
URI Parameters
HideShow
event_id
number (optional) Example: 102,

filter tickets per event

Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 123620,
      "state": "resold",
      "guest": false,
      "kind_name": "Paid entrance",
      "kind_description": "",
      "owner_id": 9500,
      "kind_id": 734,
      "price": 1,
      "event": 102,
      "seatings": [],
      "resellable": false,
      "type": "normal"
    },
    {
      "id": 330230,
      "state": "sold",
      "guest": false,
      "kind_name": "Paid entrance",
      "kind_description": "",
      "owner_id": 9500,
      "kind_id": 734,
      "price": 1,
      "event": 102,
      "seatings": [],
      "resellable": true,
      "type": "normal"
    }
  ]
}

Detail
GET/api/v1.0/tickets/{id}/

Show all tickets belonging to a user

Example URI

GET /api/v1.0/tickets/123620/
URI Parameters
HideShow
id
number (required) Example: 123620

id of ticket

Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 123620,
  "state": "resold",
  "guest": false,
  "kind_name": "Paid entrance",
  "kind_description": "",
  "owner_id": 9500,
  "kind_id": 734,
  "price": 1,
  "event": 102,
  "seatings": [],
  "resellable": false,
  "type": "normal"
}

Create gift ticket
POST/api/v1.0/tickets/create_gift_ticket

Example URI

POST /api/v1.0/tickets/create_gift_ticket
Request
HideShow
Headers
Content-Type: application/json
Body
[{
    'username': mobile,
    'ticket_kind': ticket_kind_id,
    'notify_customer': true will send an SMS to the customer,
    'amount': 2, // how many tickets?
    'pool': 'new', // Create new ticket, not use one of the precreated ones
    'paid_to': 'eo', // EO: Event organizer
    'free': false, // always false, true means that the ticket was a gift from the theater
    'payment_method': 'pin' | 'cash' | 'digital' | 'other'
}, {
    'username': mobile,
    'ticket_kind': ticket_kind_id,
    'notify_customer': false,
    'amount': 3,
    'pool': 'new,
    'paid_to': 'eo',
    'free': false,
    'payment_method': 'pin' | 'cash' | 'digital' | 'other'
}]
Schema
{
    "type": "array",
    "items": {
        "type": "object",
        "required": [
            "username",
            "ticket_kind",
        ],
        "properties": {
            "username": {"type": "string"},
            "ticket_kind": {"type": "integer"},
            "notify_customer": {"type": "boolean", "default": True,
                                "description": "send email or sms to user"},
            "amount": {"type": "integer", "default": 1, "minimum": 1,
                    "description": "this value is ignored when privileges are specified"},
            "pool": {
                "type": "string", "default": "available",
                "pattern": "available|new|locked",
                "description": "options are available, locked, new."
                "Determines which pool to user for the privileges"
            },
            "free": {"type": "boolean", "default": true},
            "privileges": {
                "type": "array",
                "items": {"type": "integer"},
                "description": "ids of privileges to be used. Will only work for non combi tickets. Will create a tickets for each privileges
            },
            "payment_method": {
                "type": ["string", "null"],
                "pattern": "pin|cash|digital|other",
                "description": "How was the payment done, if any"
            },
            "paid_to": {
                "type": ["string", "null"],
                "description": "To whom was the payment done"
            }
        }
    }
}
Response  201
HideShow
Headers
Content-Type: application/json
Body
{
    'status': 'success',
    'tickets': [{
        'id': 17, 
        'state': 'sold',
        'guest': false,
        'kind_name': 'entrance regular',
        'kind_description': '',
        'owner_id': 55,
        'kind_id': 28,
        'price': '0.00',
        'event': 82,
        'resellable': false,
        'type', 'normal',
        'privileges': [{
            'id': 410,
            'type_id': 29,
            'allocated_id': 17,
            'info': null,
            'seat': null,
            'created': '2019-04-25T11:01:53.583184+02:00',
            'modified': '2019-04-25T11:01:53.583209+02:00',
            'locked': false,
            'claimed': false
        }],
        'put_for_sale_by_id': null
    }]
}

Delete
DELETE/api/v1.0/tickets/{id}

Example URI

DELETE /api/v1.0/tickets/1
URI Parameters
HideShow
id
number (required) Example: 1

id of ticket

Response  204

PrivilegeTypes

In GET Protocol a PrivilegeType is the model that describes and categorizes the privileges. It is part of a TicketKind, which plays the same role for the ticket. One TicketKind can contain more than one PrivilegeTypes, meaning that the Ticket produced will contain more than one privilege. Privileges of an upsell PrivilegeType won’t count for user limits and will be reported differently in the dashboard (e.g. Parking PrivilegeType).

Examples:

  • TicketKind of PrivilegeType Rank1Entrance. A user obtaining a ticket of this TicketKind will receive a privilege of Rank1Entrance type.

  • TicketKind of SaturdayEntrance and SundayEntrance. A user obtaining a ticket of this TicketKind will receive a privilege of SaturdayEntrance type and a privilege of SundayEntrance type.

List
GET/api/v1.0/privileges-types/

Example URI

GET /api/v1.0/privileges-types/
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
    "previous": null,
    "next": null,
    "count": 2,
    "results": [{
        "id": 421, 
        "event_id": 100, 
        "name": "NAME",
        "description": "Description",
        "upsell": false,
        "created": "2019-04-25T11:39:50.325983+02:00", 
        "modified": "2019-04-25T11:39:50.712387+02:00", 
    }]
}

Create
POST/api/v1.0/privileges-types/

Example URI

POST /api/v1.0/privileges-types/
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "event_id": 123,
  "name": "NAME",
  "upsell": false,
  "description": "",
  "total": 100,
  "blocks": 20
}
Schema
{
    "type": "object",
    "properties": {
        "event_id": {
            "type": "int",
            "description": "Id of the event that this privilegeType belongs"
        },
        "upsell": {
            "type": "boolean",
            "description": "Is this privilegeType an upsell?"
        },
        "name": {
            "type": "string",
            "description": "name, this will show up while scanning"
        },
        "description": {
            "type": "string",
            "description": "Only useful for dashboard users"
        },
        "total": {
            "type": "int",
            "description": "How many privileges can this PrivilegeType create in total?"
        }
        "blocks": {
            "type": "int",
            "description": "No of privileges from the total that are not available for sale"
        }
    }
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
        "id": 1234, 
        "event_id": 123, 
        "name": "NAME",
        "description": "",
        "upsell": false,
        "created": "2019-04-25T11:39:50.325983+02:00", 
        "modified": "2019-04-25T11:39:50.712387+02:00", 
    }

Privileges

In GET Protocol a privilege is the object that gives the user the privilege to perform certain actions. Examples:

  • User has the privilege to enter the theater A for show X and seat on Seat Y.

  • User has the privilege to park on a parking spot on theater X on day Y.

A Ticket is a collection of privileges. The privilege is the item that gets scanned (executed) when a user goes through the scanning process.

List
GET/api/v1.0/privileges/

Example URI

GET /api/v1.0/privileges/
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "previous": null,
  "next": null,
  "count": 2,
  "results": [
    {
      "id": 421,
      "type_id": 31,
      "allocated_id": 19,
      "note": "",
      "info": "NOTE",
      "seat": "INFO",
      "code": "code",
      "created": "2019-04-25T11:39:50.325983+02:00",
      "modified": "2019-04-25T11:39:50.712387+02:00",
      "locked": false,
      "claimed": true
    },
    {
      "id": 421,
      "type_id": 31,
      "allocated_id": 19,
      "note": "",
      "info": "NOTE",
      "seat": "INFO",
      "code": "code",
      "created": "2019-04-25T11:39:50.325983+02:00",
      "modified": "2019-04-25T11:39:50.712387+02:00",
      "locked": false,
      "claimed": true
    }
  ]
}

Edit
PATCH/api/v1.0/privileges/{id}

Example URI

PATCH /api/v1.0/privileges/1
URI Parameters
HideShow
id
number (required) Example: 1

id of privilege

Request
HideShow
Headers
Content-Type: application/json
Body
{
  "note": "NOTE",
  "info": "INFO"
}
Schema
{
  "type": "object",
  "properties": {
    "note": {
      "type": "string",
      "description": "internal text not visible to the customer"
    },
    "info": {
      "type": "string",
      "description": "Text visible to the customer"
    }
  }
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 421,
  "type_id": 31,
  "allocated_id": 19,
  "note": "",
  "info": "NOTE",
  "seat": "INFO",
  "code": "code",
  "created": "2019-04-25T11:39:50.325983+02:00",
  "modified": "2019-04-25T11:39:50.712387+02:00",
  "locked": false,
  "claimed": true
}

Orders

List
GET/api/v1.0/orders/

A list of all the orders belonging to the user.

Example URI

GET /api/v1.0/orders/
Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 1,
      "total": "10.00",
      "state": "pending",
      "last_payment_status": "pending",
      "details": {
        "event_id": 10,
        "privacy_policy_url": null,
        "items": [
          {
            "kind": 3007,
            "rank": "Test",
            "amount": 1,
            "price": 10,
            "sub": 10
          }
        ],
        "title": "title"
      },
      "owner": "4",
      "success_text": "",
      "paid_to": null
    }
  ]
}

Detail
GET/api/v1.0/orders/{id}

Example URI

GET /api/v1.0/orders/1
URI Parameters
HideShow
id
number (required) Example: 1

id of order

Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 1,
  "total": "10.00",
  "state": "pending",
  "last_payment_status": "pending",
  "details": {
    "event_id": 10,
    "privacy_policy_url": null,
    "items": [
      {
        "kind": 3007,
        "rank": "Test",
        "amount": 1,
        "price": 10,
        "sub": 10
      }
    ],
    "title": "title"
  },
  "owner": "4",
  "success_text": "",
  "paid_to": null
}

Start payment
POST/api/v1.0/orders/{id}/start_payment/

The psp_arguments are passed directly to your external payment provider. For development there is a dummy payment provider. The dummy requires one argument, return_page. This is the url you want the user return to after completing the dummy payments. The endpoint will return an url where the user can make its payment. If the order is not in a pending state it will return status: error.

Example URI

POST /api/v1.0/orders/1/start_payment/
URI Parameters
HideShow
id
number (required) Example: 1

id of order

Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Body
{
    psp_arguments: {"return_page": "your.app"}
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "status": "redirect",
  "redirect": "psp_url"
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "status": "error",
  "error": "invalid_order_state"
}

Carts

To buy tickets, they have to be put into a cart. Tickets that are in a cart are reserved and cannot be bought by somebody else. A cart can only hold tickets of a single shop. Also shops can have rules on the maximum amount of tickets each user can buy. These are also enforced.

uuid Cart.

The Frontend needs to create uid of the cart itself. If it doesn’t exist yet the api will create it on the fly. The format is standard uuid4

[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}

Get cart
GET/api/v1.0/carts/{slug}/{uuid}

Example URI

GET /api/v1.0/carts/slug of the shop the cart belongs/uuid
URI Parameters
HideShow
uuid
string (required) Example: uuid

1 - uuid of cart.

slug
string (required) Example: slug of the shop the cart belongs
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "uuid": "uuid",
  "ticket_kinds": []
}

Add tickets
PUT/api/v1.0/carts/{uuid}

When updating tickets make sure you send the whole tickets state. Not just the tickets you want to add.

Example URI

PUT /api/v1.0/carts/uuid
URI Parameters
HideShow
uuid
string (required) Example: uuid

1 - uuid of cart.

Request
HideShow
Headers
Content-Type: application/json
Body
{
  "ticket_kinds": [
    {
      "id": 2,
      "amount": 0
    },
    {
      "id": 1,
      "amount": 2
    }
  ]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "uuid": "uuid",
  "ticket_kinds": [
    {
      "id": 2,
      "amount": 0
    },
    {
      "id": 1,
      "amount": 2
    }
  ]
}

Checkout
PUT/api/v1.0/carts/{uuid}/checkout/

Checking out the cart will create an order to start a payment. The user needs to be logged in to perform this action. If the content of the cart is changed the order gets cancelled.

Example URI

PUT /api/v1.0/carts/uuid/checkout/
URI Parameters
HideShow
uuid
string (required) Example: uuid

1 - uuid of cart

Request
HideShow
Headers
Content-Type: application/json
Authorization: JWT <token>
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "order": 1,
  "state": "success"
}

Generated by aglio on 02 Jul 2020