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:
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
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:
-
Request upload url from GET Protocol, check here how to do that, setting field cover.
-
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
})
- 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_codePOST/api/v1/auth-ticketeer/{ticketeer}/{recipient}
Example URI
- ticketeer
string
(required)name of the ticketeer logging into
- recipient
string
(required)phoneumber of recipient include contrycode
Headers
Content-Type: application/json
Body
{
"locale": "en"
}
Schema
{
"type": "object",
"properties": {
"locale": {
"type": "string"
"description": "determines language used in SMS"
}
},
"required": ["locale"]
}
200
Headers
Content-Type: application/json
Body
{
"verification_code": "7b5601a3-4a25-4955-8568-4f703a219aa1",
"tries_left":3,
}
Customer login ¶
Customer loginPOST/api/v1/auth-verify
Example URI
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"]
}
200
Headers
Content-Type: application/json
Body
{
"status" : "error"
"error": "invalid_pin"|"used_verification_code"
"tries_left":2,
}
200
Headers
Content-Type: application/json
Body
{
"status" : "success"
"tries_left":2,
"token": "jwt token"
"refresh_token": "refresh token"
}
Refresh Token ¶
Refresh TokenPOST/api/v1/refresh
Use this endpoint to retrieve a new jwt token and refresh token.
Example URI
Headers
Content-Type: application/json
Body
{
"refresh_token": "refresh token",
}
Schema
{
"type": "object",
"properties": {
"refresh_token": {
"type": "string"
"description": "refresh token"
}
},
"required": ["refresh_token",]
}
200
Headers
Content-Type: application/json
Body
{
"status" : "error"
"error": "refresh_token_expired"|"refresh_token_not_found"
}
200
Headers
Content-Type: application/json
Body
{
"status" : "succes"
"token": "jwt token"
"refresh_token": "new refresh token"
}
External authentication ¶
External authenticationPOST/api/v1/external-auth
Example URI
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"]
}
200
Headers
Content-Type: application/json
Body
{
"status" : "succes"
"token": "jwt token"
"refresh_token": "new refresh token"
}
Event organizer Login ¶
Event organizer LoginPOST/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
-
=
{ "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"]
}
200
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 RefreshPOST/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
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"]
}
201
Headers
Content-Type: application/json
Body
{
"token": "jwt_token",
"refresh_token": "refresh_token"
}
Self ¶
SelfGET/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
Headers
Content-Type: application/json
Authorization: JWT <token>
200
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 detailsPUT/api/v1.0/users/{id}
Example URI
- id
number
(required) Example: 1id of users
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",
}
200
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 DetailGET/api/v1.0/gates/{gate_slug}
Example URI
- gate_slug
string
(required) Example: 123a9sslug of gate
200
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 ShopsGET/api/v1.0/gates/{gate_slug}/shops
Example URI
- gate_slug
string
(required) Example: 123a9sslug of gate
200
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 GatePOST/api/v1.0/gates/{gate_slug}
Example URI
- gate_slug
string
(required) Example: 123a9sslug of gate
200
Headers
Content-Type: application/json
Body
{
"status": "success",
"handle": "6aa8efbf737905bbe65a015b89c2982a"
}
Check LineGET/api/v1.0/line/{handle}
Example URI
- handle
string
(required) Example: 123a9shandle identifying a specific customer. Handed out by gatekeeper.
200
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 CouponPOST/api/v1.0/line/{handle}/select
Example URI
- handle
string
(required) Example: 123a9shandle identifying a specific customer. Handed out by gatekeeper.
200
Headers
Content-Type: application/json
Body
{
"status": "success",
"coupon": "Omc0MjM6MDo2YWE4ZWZiZjczNzkwNWJiZTY1YTAxNWI4OWMyOTgyYTo4MDkzOWRmZGZlNDg2ZGQyNDU3Zjk4OTQ5YmQzNzFkMw=="
}
Ticketing Endpoints ¶
Organizations ¶
ListGET/api/v1.0/organizations/
Example URI
Headers
Content-Type: application/json
Authorization: JWT <token>
200
Headers
Content-Type: application/json
Body
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "My Org",
"permissions": [],
"floorplans": []
}
]
}
DetailsGET/api/v1.0/organizations/{id}
Example URI
- id
string
(required) Example: 123id of an organization
Headers
Content-Type: application/json
Authorization: JWT <token>
200
Headers
Content-Type: application/json
Body
{
"id": 123,
"name": "My Org",
"permissions": [],
"floorplans": []
}
Events ¶
A listing of all events.
ListGET/api/v1.0/events/{?filter,own}
Example URI
- filter
string
(optional) Example: upcomingonly show upcoming events
- own
boolean
(optional) Example: Trueonly show events the user has tickets for. (this flag requires being logged in) (second response)
200
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
}
]
}
200
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",
}
]
}
CreatePOST/api/v1.0/events/
Example URI
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"]
}
201
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
}
DetailGET/api/v1.0/events/{slug}
Example URI
- slug
string
(required) Example: 9a6936593705b0998868slug of an event
200
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
}
EditPATCH/api/v1.0/events/
Example URI
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'
}
200
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 codeGET/api/v1.0/events/{slug}/code
Example URI
- slug
string
(required) Example: 9a6936593705b0998868slug of an event
200
Headers
Content-Type: application/json
Body
{
"code": "GPT:12341234"
}
Request upload urlPOST/api/v1.0/events/request_upload
Example URI
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"]
}
200
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":"..."}
}
}
PublishPOST/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
Headers
Content-Type: application/json
Body
No body is required
200
Headers
Content-Type: application/json
Body
{
'success': true
}
Shops ¶
A listing of all events.
ListGET/api/v1.0/shops/{?event_id,event_slug}
Example URI
- event_id
number
(optional) Example: 1only show shops from event with this id
- event_slug
string
(optional) Example: 9a6936593705b0998868only show shops from event with this slug
200
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
}
]
}
CreatePOST/api/v1.0/shops/
Example URI
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"]
}
201
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
}
DetailGET/api/v.1.1/shops/{id}
Example URI
- id
number
(required) Example: 1id of a shop
200
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
}
EditPUT/api/v.1.1/shops/{id}
Example URI
- id
number
(required) Example: 1id of a shop
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"]
}
200
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
}
EditPATCH/api/v.1.1/shops/{id}
Example URI
- id
number
(required) Example: 1id of a shop
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": []
}
200
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
}
DeleteDELETE/api/v1.0/shops/{id}
Example URI
- id
number
(required) Example: 1id of a shop
204
TicketKinds ¶
TicketKind listGET/api/v1.0/ticket-kinds/{?event_id}
Example URI
- event_id
number
(optional) Example: 102,filter tickets per event
200
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
}
]
}
DetailGET/api/v1.0/ticket_kinds/{id}/
Example URI
- id
number
(required) Example: 734id of ticket
200
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 simplePOST/api/v1.0/tickets/create/
Example URI
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"]
}
201
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.
ListGET/api/v1.0/tickets/{?event_id}
Show all tickets belonging to a user
Example URI
- event_id
number
(optional) Example: 102,filter tickets per event
Headers
Content-Type: application/json
Authorization: JWT <token>
200
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"
}
]
}
DetailGET/api/v1.0/tickets/{id}/
Show all tickets belonging to a user
Example URI
- id
number
(required) Example: 123620id of ticket
Headers
Content-Type: application/json
Authorization: JWT <token>
200
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 ticketPOST/api/v1.0/tickets/create_gift_ticket
Example URI
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"
}
}
}
}
201
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
}]
}
DeleteDELETE/api/v1.0/tickets/{id}
Example URI
- id
number
(required) Example: 1id of ticket
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.
-
…
ListGET/api/v1.0/privileges-types/
Example URI
200
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",
}]
}
CreatePOST/api/v1.0/privileges-types/
Example URI
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"
}
}
}
200
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.
ListGET/api/v1.0/privileges/
Example URI
200
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
}
]
}
EditPATCH/api/v1.0/privileges/{id}
Example URI
- id
number
(required) Example: 1id of privilege
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"
}
}
}
200
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 ¶
ListGET/api/v1.0/orders/
A list of all the orders belonging to the user.
Example URI
Headers
Content-Type: application/json
Authorization: JWT <token>
200
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
}
]
}
DetailGET/api/v1.0/orders/{id}
Example URI
- id
number
(required) Example: 1id of order
Headers
Content-Type: application/json
Authorization: JWT <token>
200
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 paymentPOST/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
- id
number
(required) Example: 1id of order
Headers
Content-Type: application/json
Authorization: JWT <token>
Body
{
psp_arguments: {"return_page": "your.app"}
}
200
Headers
Content-Type: application/json
Body
{
"status": "redirect",
"redirect": "psp_url"
}
200
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 cartGET/api/v1.0/carts/{slug}/{uuid}
Example URI
- uuid
string
(required) Example: uuid1 - uuid of cart.
- slug
string
(required) Example: slug of the shop the cart belongs
200
Headers
Content-Type: application/json
Body
{
"uuid": "uuid",
"ticket_kinds": []
}
Add ticketsPUT/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
- uuid
string
(required) Example: uuid1 - uuid of cart.
Headers
Content-Type: application/json
Body
{
"ticket_kinds": [
{
"id": 2,
"amount": 0
},
{
"id": 1,
"amount": 2
}
]
}
200
Headers
Content-Type: application/json
Body
{
"uuid": "uuid",
"ticket_kinds": [
{
"id": 2,
"amount": 0
},
{
"id": 1,
"amount": 2
}
]
}
CheckoutPUT/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
- uuid
string
(required) Example: uuid1 - uuid of cart
Headers
Content-Type: application/json
Authorization: JWT <token>
200
Headers
Content-Type: application/json
Body
{
"order": 1,
"state": "success"
}