Introduction
The Ingresso API is designed to allow you to sell from Ingresso’s inventory of event tickets. Ingresso has connected to a large number of ticketing system APIs, allowing us to transact directly on the venue’s system. By integrating with the Ingresso API you are able to view and purchase live ticketing inventory from a number of different venues.
Example partners that have integrated with the Ingresso API are GetYourGuide and lastminute.com. We also build our own ticketing websites entirely on top of the API, for example From The Box Office.
The Ingresso API is a fully transactional API, loosely based on REST. You format GET or POST requests in JSON and you will receive either a JSON-formatted response or an HTTP error. The API is internally known as F13, which is why you see /f13 in the endpoints.
We describe objects in a consistent way across different resources (for example the output of events and performances includes a cost_range object and this is described in the same format). The idea behind this is that standard code can be used on the client side to read all parts of the output.
This API replaces the Ingresso XML API. The XML API relies on temporary tokens from each call being passed in to the next call; these has been removed in favour of permanent IDs. One benefit of this change is that a call near the end of the booking process, such as reserve, can be called without needing to remake the preceding calls (such as requesting availability), opening up additional potential solutions. The output is also more compact leading to faster response times in most cases.
Postman examples
We have a public library available for Postman that closely matches the examples included in this documentation.
Click below to import our collection of API examples.
or download directly here
F13 API Browser
We have also developed the F13 API Browser.
- Move through the Ingresso booking flow using your own API account
- Easy to use - it can be given to non-technical people to check that the API is returning expected data
- For each step the request and response data is output in a friendly format and as JSON
Basic booking flow
The Ingresso API was designed to support the more complex task of booking
tickets for live entertainment events, and some parameters use language
(e.g. seat
) reflective of that. However, the API includes
support for booking a wide range of different products,
including general-admission attractions products, merchandise and more.
For most products that have limited capacity availability, the following basic booking flow should be followed to ensure the most accurate availability is shown to your customer, but some additional parameters may be used to shortcut this flow for some types of products.
List events including from prices and a single image
curl https://api.ticketswitch.com/f13/events.v1 \
-u "demo:demopass" \
-d "req_cost_range" \
-d "req_media_triplet_one" \
--compressed \
-G
gzip must be used for all requests (with curl you can use the –compressed flag). Most http libraries support compression (though you may need to enable this somehow), but if not and you are receiving gzip errors you can pass “Accept-Encoding: gzip” in the headers then unzip the response. curl uses the -u flag to pass HTTP Basic Authentication credentials in the format user:password.
List performances for event ID 6IF
curl https://api.ticketswitch.com/f13/performances.v1 \
-u "demo:demopass" \
-d "event_id=6IF" \
-d "page_len=200" \
--compressed \
-G
Display availability for the 9th May performance
curl https://api.ticketswitch.com/f13/availability.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B0T" \
--compressed \
-G
Reserve 2 tickets in price band A in the Circle
curl https://api.ticketswitch.com/f13/reserve.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B0T" \
-d "ticket_type_code=CIRCLE" \
-d "price_band_code=A/pool" \
-d "no_of_seats=2" \
--compressed \
-G
Purchase the tickets
curl https://api.ticketswitch.com/f13/purchase.v1 \
-u "demo:demopass" \
-d "transaction_uuid=XXXXXXXX" \
--compressed \
-G
The Ingresso API supports multiple use cases and variations, but below is a typical workflow:
Retrieve a list of events.
Retrieve a list of performances for an event.
Retrieve availability for a performance, including seat numbers if the event is seated.
Optionally you can request discounts for the selected tickets, and purchase multiple items at once by adding them to a trolley.
reserve tickets for a set period of time.
purchase the reserved tickets.
Philosophy
- Returned data is as simple as possible for the task in-hand
- Transaction flow is as simple as possible for the task in hand
- Default missing parameters sensibly instead of returning an error
- Always try and complete a call in some way instead of erroring
Types of API integration
The Ingresso API supports a variety of different integration types.
Full integration: this is where our partner uses all functionality of the Ingresso API to retrieve listings of events and performances (often in advance to populate their own database) then to request availability and reserve and purchase tickets in real-time.
Feather: Ingresso offer a seat selection widget product called Feather that can be embedded on your website. It is used in conjunction with the Ingresso API to reduce the development needed to offer seat selection to your customers. You use the API to retrieve performances so you can present a calendar to customers. When a performance is selected, you use Feather to display availability for that performance, and to reserve the customer’s chosen seats. Feather will handle complexities like preventing single seats from being left, and suggesting alternate seats when the desired seats are no longer available. If the reserve is successful you will return a transaction reference that you can then purchase via the API. View the Feather documentation and demo.
Partial Integration: Ingresso also offer partners an individually branded “white label” ticketing website - for example Ticketmaster Theatre and From The Box Office are fully developed by Ingresso. It is possible to use the API in conjunction with a white label website as a partial integration. Some examples of partial integrations:
a) Maintain a listing of events on your own site, and use Ingresso’s white label website for booking the tickets. In this case the Ingresso API can be used to list events.
b) Ingresso have invested in a high-conversion booking app (where the customer selects their performance and seats). This page is often where most development time is spent. It is possible to link to our booking page and we will automatically redirect back to your checkout page once the customer has successfully reserved their seats. You can link to our full booking page or just use Feather to add seat selection to your site.
c) Use the Ingresso API to display events, performances and availability, then send your customer to our white label website for checkout. It is possible for Ingresso to then redirect the customer back to your confirmation page if the purchase is successful.
Payment Options
If you use the checkout page of Ingresso’s white label website, then Ingresso will take care of collecting payment from the customer. However if you wish to develop your own checkout page these are the options for taking payment:
You take payment: you purchase tickets from Ingresso on credit / on account and take payment from the customer yourself. You will be invoiced regularly by Ingresso. This option is typically only offered to partners with the capability to sell a high volume of tickets. There are two ways for you to take payment:
a) Using a payment provider of your choosing.
b) Using your own Stripe account. Stripe is a developer-friendly payment provider that is simple to integrate with. Our API provides integration support for Stripe. You just need to collect a Stripe token after your customer enters their payment details; Ingresso’s Stripe integration will then ensure the payment is captured and all edge cases are handled.
Ingresso takes payment: for the majority of partners Ingresso will take payment using Stripe, so you need to collect a Stripe token and pass that in when purchasing tickets.
These options are discussed in more detail in purchase.
How to get access to the API
All examples shown in this documentation are for the demo
user. This user has
access to test product only - you can make purchases with this user without any
impact on live tickets, or any need to contact us first.
The process for going on sale is:
Start your integration using the
demo
user. This is the user that all partners use during testingOnce you have made good progress contact us to agree a commission deal: commercial@ingresso.co.uk
When you have finished the integration we will check to ensure you support the required functionality
We will then give you a live account and you can go live
Authentication
Example request with authentication
curl https://api.ticketswitch.com/f13/events.v1 \
-u "demo:demopass" \
-d "s_keys=matthew" \
-d "s_coco=uk" \
--compressed \
-G
from pyticketswitch import Client
client = Client(user='demo', password='demopass')
curl uses the -u flag to pass basic auth credentials in the format user:password.
Connect as the
demosub
subuser with Dutch as the preferred language
curl https://api.ticketswitch.com/f13/events.v1/demo/demosub/nl \
-u "demo:demopass" \
-d "s_keys=matthew" \
-d "req_extra_info" \
--compressed \
-G
Authenticate when using the API by including your username and password in the request. Authentication to the API is performed via HTTP Basic Auth.
This is all you need, but there are two additional optional parameters that can be included:
Some of our partners require sub users for particular use cases such as running their own affiliate programme.
It is possible to pass in a preferred language code, overriding the language code/s in the HTTP header.
These parameters are included in the URL after the version number:
/f13/events.v1/USER/SUBUSER/LANG_CODE
Using a ‘-’ for the subuser or language code will cause it to be ignored, so to ignore the subuser:
/f13/events.v1/USER/-/LANG_CODE
Errors
Example
HTTP/1.1 400 Bad Request
{
"error_code": 8,
"error_desc": "Bad data supplied"
}
APIError(
msg='Bad data supplied',
code=8,
response=<Response [400]>
)
When an error happens the API will return a non 2XX
HTTP status code and a
message about the error in the response body. The message will include a
human readable description of the error and a code that can be used by
application to recognise the issue and handle it appropriately.
Some method calls can have partial failures. For example a reservation call might be successful for one order in the trolley but fail to reserve a second order, or a purchase call might be successful in that we successfully attempted a payment but the users card was declined, or the backend system fell over mid transaction. In these situations the API will return a 200 HTTP status code with details of the issues in the response body. You should consult the documentation for the specific end point for details on how to handle these situations.
Status codes
Details of the general HTTP status codes can be found below:
Status Code | Description |
---|---|
200 - OK |
The response can be interpreted as explained in the documentation. |
400 - Bad Request |
Your call was missing data required to satisfy the request. This response generally occurs due to missing parameters. |
401 - Unauthorised |
No authentication parameters were provided or the given parameters were invalid. |
403 - Forbidden |
You are trying to access something your account doesn’t have access to. |
404 - Not Found |
Then the endpoint you were trying to reach does not exist. |
405 - Method Not Allowed |
You have tried to use a POST request when the endpoint was expecting a GET request (or vice versa). |
410 - Gone |
The resource you were trying to access no longer exists. This is primarily used around transactions when temporary resources (such as callouts) have expired. |
460 - Invalid Parameters |
The parameters passed to the API were technically valid, but were rejected due to their content. Refer to the error description and error code for further details. |
5XX - Server Errors |
Something unexpectedly went wrong and the API was unable to do what you asked it to do. Refer to the error description and error code for further details. |
One specific case that is worth mentioning in detail is when the API returns a 502 HTTP status code. This indicates that your request required a connection to an upstream server (for example the supplier ticketing system, or a payment provider), but we were unable to establish the connection. Some of the supplier systems that our API connects to are fragile; we do what we can to mitigate this, but sometimes those upstream servers simply won’t be available to service your request. In these situations you could attempt to retry the request in case it was just momentary issue, failing that waiting a short time may help. Both scheduled and unscheduled major outages will be recorded on our status page.
Error codes
Error codes provide a computer readable classifier of an error. They will be useful in identifying errors and handling them appropriately.
Error Code | Description |
---|---|
2 |
Bad channel. |
3 |
User authentication failure. |
4 |
Failed to create connection to the backend system. |
5 |
Host is on a forbidden network. |
6 |
Failed to connect to database. |
7 |
Membership authentication failed. |
8 |
Bad data supplied. |
2000 |
Email address is invalid. This error will also provide a secondary error_key field that will provide a code for working out exactly what’s wrong with the email address (see below). |
3000 |
Unrecognised card type from number. |
3001 |
Card type not accepted. |
3002 |
Not a valid card number. |
3003 |
Invalid expiry date. |
3004 |
Invalid CV2. |
3005 |
Missing issue number. |
3006 |
Invalid issue number. |
3007 |
Missing start date. |
3008 |
Invalid start date. |
Email error keys
Email error keys break down the 2000
error code into more explicit issues.
Key | Description |
---|---|
addr_dot_before_at_must_be_quoted |
A ‘.’ before the ‘@’ sign should be quoted |
addr_cannot_end_in_dot |
Address cannot end in ‘.’ |
addr_cannot_have_dot_immediately_after_at |
Cannot have ‘.’ immediately after ‘@’ sign |
addr_cannot_have_dot_dot_after_at |
Cannot have ‘..’ after ‘@’ sign |
addr_cr_within_quotes |
Carriage return within quotes |
addr_cr_not_allowed_after_at |
Carriage returns not allowed after ‘@’ sign |
addr_may_not_be_blank |
Email addresses may not be blank |
addr_may_not_end_with_at |
Email addresses may not end with ‘@’ sign |
addr_may_not_start_with_at |
Email addresses may not start with ‘@’ sign |
addr_missing_at |
Missing ‘@’ sign |
addr_needs_at_least_one_dot |
Must have at least one ‘.’ after ‘@’ sign |
addr_spaces_before_at_must_be_quoted |
Spaces before ‘@’ sign must be quoted |
addr_spaces_not_allowed_after_at |
Spaces not allowed after ‘@’ sign |
addr_tabs_not_allowed_after_at |
Tabs not allowed after ‘@’ sign |
addr_unterminated_quote_before_at |
Unterminated quote before ‘@’ |
addr_non_ascii_in_quotes |
Non-ASCII character in quotes |
addr_dot_expected_after_quotes |
A ‘.’ is expected after quotes |
addr_non_ascii_before_at |
Non-ASCII character before ‘@’ sign |
addr_control_character_before_at |
Control character before ‘@’ sign |
addr_specials_before_at_must_be_quoted |
Special characters before ‘@’ sign must be quoted |
addr_non_ascii_after_at |
Non-ASCII character after ‘@’ sign |
addr_control_character_after_at |
Control character after ‘@’ sign |
addr_specials_after_at |
Special characters not allowed after ‘@’ sign |
addr_bad_email_domain |
This domain is not e-mailable |
Backend system errors
It’s important to note that the majority of errors that you are likely to see are caused by failures in the backend systems that we are attempting to connect to your behalf. Generally these issues will present themselves in the availability, reservation, and purchase calls. If you experience unexpected results from these calls but there is no indication of an explicit error having happened it’s worth checking our status page to see if there are any known issues ongoing with any of the backend systems:
https://status.ingresso.co.uk/
Variables controlling output
The output from a given resource may be augmented beyond the
basic result in one of two ways. Firstly there are extra functions
which may be available for a given resource, which are specific to
that resource. These are triggered using variables with the prefix add_
such as add_discount_codes
on the availability resource which
is used to control whether or not discount codes are also retrieved and
returned.
The second type of augmentation is specific to the returned objects themselves
and is thus applicable to the output of any resource which returns one of these
objects. The most obvious example is an event object, which can be described
with many extra pieces of information about it. These variables are all prefixed
with req_
as they are requests to the objects to output something extra or
different about themselves, for example req_cost_range
.
Note that the req_
and add_
variables all result in extra
processing to retrieve the requested data, which will slow down the resource,
sometimes substantially. They should therefore only be used where necessary.
Request ID logging
In order to more easily trace the effect of API calls through the TicketSwitch
system, every API response will include a tracking ID in the header
X-Request-Id
. This value is used internally to the Ingresso platform to
track requests to supplier systems and other internal services, and is recorded
against reservation and purchase records as well as call logs. If you need to
debug any request made to the API, please include this request ID when
contacting Ingresso. We recommend including this and other headers in your logs
if an error occurs.
API libraries / SDKs
Our API libraries implement a thin client over the API. Where the API will return JSON, the API wrappers return language-specific objects (at the moment we have only implemented a single language):
- python: Pyticketswitch
Examples will be included in this documentation, but if you require further detail you can refer to the appropriate documentation for the language wrapper.
Required Minimum Functionality
Before your application can go live, there are a number of minimum implementation requirements it must meet. The test data available can help make sure your implementation is working as expected and can handle various types of errors and edge cases. To validate the functionality of your application, Ingresso will use the following representative tests.
List performance dates or times
A given event may have multiple performances on different days and times, and the customer must be able to choose the one they want to attend. This can be done by listing them, or in a calendar interface, or in any other way that is appropriate for your application.
Representative Test: User selects The Unremarkable Incident of the Cat at Lunchtime
(event ID 7AB)
When the event is selected in the interface,
Then it should display the two available performances, 1 January {this year + 1}
and 1 January {this year + 2}, at 15:30:00 UTC.
Support undated events
Some venues such as theme parks sell undated tickets. These events
have need_performance
= false
and have an auto-generated
performance that your integration should auto-select. It should be
possible for customers to purchase tickets without having to choose or
see the auto-generated date in the API.
Representative Test: User selects Ingressoland - Any Time
(event ID 1D7B8)
It is possible to make it to checkout without needing to select a date (i.e.
the performance is auto-selected).
Support best available booking flow
At a minimum, the customer must be able to specify the number of tickets they want and for which ticket type and price band. The Ingresso backend will then reserve the best available tickets that meet the requirements.
Representative Test: User selects 3 tickets for event 6IF in the stalls band B
When the reservation is made
Then the application shows a reservation confirmation screen with 3 tickets
from that price band, and allows the user to proceed with the booking and
payment process
Display the full ticket price to the customer before purchase
The customer must be shown the full price they will pay before the purchase is confirmed and their payment taken.
Representative Test: User confirms reservation of 1 ticket for event 7AB in the stalls
band A (e.g. seat B4)
When the confirmation and payment screen is displayed
Then the full price should be displayed as £55.00, showing a £50.00 seat price
and a £5.00 surcharge. Any dispatch methods that incur an additional cost
should also be listed separately. A total price should be displayed in a
highlighted font showing the price the customer will pay (by adding the prices
together).
Display different send methods including eTickets
Various venues support different methods of sending tickets (including post, collect from box office, or printable eTickets). Some of these may carry an additional fee. Where available, different send methods should be offered to the customer, and your application should support eTickets (either provided by Ingresso or your own format with a barcode retrieved from the Ingresso API).
Representative Test: User confirms reservation of tickets for Toy Story –
The Opera (7AA)
When the customer selects the Toy Story(7AA) event
Then the available send methods of Printable eTicket and Post worldwide are
shown.
Representative Test: User selects Printable eTicket and checks out
When the customer has purchased the tickets
Then the ticket with the appropriate barcode will be sent to their email or
otherwise permanently saved within your application after purchase has been
confirmed
Display special seat conditions to customer before purchase
Some seats in venues may have restricted views of the stage, or other information associated with them. It’s important that the customers are made aware of any special seat conditions that will apply before they purchase. Messages can be classified as restricted view or not, but it is necessary in all cases to display these messages (sometimes we aren’t able to accurately classify a restricted view message). These messages must be displayed to the customer before they purchase, and also in the purchase confirmation that is sent to the customer.
Representative Test: User reserves any seats for a Thursday performance of
Swan Lake (event 6IE)
When the reservation is made
Then the application should show that these seats have restricted views before
taking payment.
For customers implementing seat selection functionality:
Representative Test: User selects seats C5 and C6 for event 7AB
When the seats are selected
Then the application should show that these seats have restricted views, and
show the seat text for C6 (“Haunted seat”).
Release tickets if customer does not proceed with the booking flow
A customer may change their mind about the number or type of tickets to be reserved for a performance. If your customer selects and reserves tickets, then goes back to select and reserve additional tickets or removes the reserved tickets from their basket, the initial tickets should be released.
Representative Test: User makes a reservation for any ticket then clicks
“back” and makes another selection, or removes items from their basket
When the customer selects a second reservation or empties their basket
Then your application should call the release
resource of the
Ingresso API. This must be done before any further call to reserve
.
Optionally it should also display a message to the customer indicating the
ticket reservation has been released.
Gracefully handle reservation failures and seat changes
Especially for popular shows, it is quite common that seats that are requested are purchased by other customers before they can be purchased by the user of your application. In this case, the Ingresso system will return a failure or, in some cases, continue the reservation but with different seats than you may expect.
Representative Test: User makes a reservation including seat H10 for event
7AA or 7AB
When the customer reserves seat H10 (by itself or with other seats),
Then the reservation will fail and your application should indicate that the
reservation for that ticket type and price band could not be completed, and
that their card has not been charged.
Representative Test: User reserves a number of seats including seat D7 for
event 7AA or 7AB
When the customer reserves a number of seats including D7 on 7AB,
Then the reservation process will proceed but the seat numbers will have been
changed and your application should notify the customer that the seats have
changed.
Gracefully handle purchase failures
The purchase process can fail for various reasons. The purchase call will usually return a reason for failure, if known, after which the reserve status will be set to “failed” and the tickets automatically released by the backend. The reserve must be made again and the seat numbers can change, so your application must notify the customer and show the confirmation again before attempting to repurchase.
Representative Test: User attempts to purchase any number of tickets for
event 6IE and enters fail part one
in address line two
When the customer enters fail part one
in the address line two and clicks to
purchase
Then the application should attempt the purchase through the Ingresso API. When
it returns the failure, a notification should be displayed to the customer and
a new reservation should be made, indicating the seats may have changed.
Handle purchase timeouts
Occassionally supplier systems can suffer performance problems or outages that result in purchase requests taking a long time. In this case Ingresso will not time out. If the purchase ends up succeeding after 2 minutes we will return purchase success to you, and you will be invoiced for the tickets as normal. If you have asked Ingresso to send confirmation emails on your behalf the customer will receive an email once the purchase succeeds.
Our recommendation:
- If a purchase is taking a long time then encourage your customer to wait as long as possibe, for example by telling them after 30 seconds “Sorry we are still awaiting confirmation from the ticket supplier, please wait a further 15 seconds”.
- If you time out on the front-end then you should have backend code to handle the case where the Ingresso purchase succeeds, or a process to reconcile the successful transactions we think you have made (for example using the transaction reporting endpoint) against the transactions you have confirmed to customers, and ask Ingresso (customerservices@ingresso.co.uk) to cancel any orders you haven’t confirmed. Note that it won’t be possible to cancel bookings for performances that have passed.
Recommended Functionality
In addition to basic best-available booking flow and error handling outlined above, Ingresso recommends supporting additional functionality that will benefit your customers and help improve your user experience. The following functionality can be validated with the representative tests:
Support seat selection booking flow
For many events the backend system supports seat selection. When making a reserve for a performance, requested seats can also be passed to the API and where possible the request will be accommodated. Your application should supply an interface to allow customers to request specific seats.
Representative Test: User selects any performance for event 7AB
When the customer clicks on a performance for event 7AB
Then the application shows which seats are available (either just listing them,
or using an interactive seating chart).
(Required) Seat selection respects leaving singles policy
If seat selection is supported, your interface must respect the
allows_leaving_single_seats
attribute set for each price band by a performance
availability call. If the seat selection chosen by your customer would leave a
single seat by itself in a block, and this is not allowed by the venue for the
price band the seats are in, your application must indicate to the customer that
this reservation will fail.
Representative Test: User opens event 7AA and selects seats B3 and B4
When the customer selects seats B3 and B4 (leaving B2 unselected)
Then the application should display a warning to the customer (preferably on
the seat selection screen, but definitely prior to making a reserve call to the
API).
(Required) Seat selection respects contiguous seat selection policy
Some events allow selection of discontiguous seats, and others don’t. If the event allows contiguous seat selection only, you should display a warning if the customer selects seats that are not next to each other.
Representative Test: User opens event 7AA and selects seats B3 and B5
When the customer clicks B5
Then the application should display a notification that the seat selection is
invalid.
Representative Test: User opens event 7AB and selects seats B3 and B5
When the customer clicks B5
Then the booking flow should proceed as usual, because this event allows
discontiguous seat selection.
Display special offers to customers
If a special offer is available for an event, it may help attract your customers. Where available, Ingresso recommends that special offers be highlighted and displayed.
Representative Test: User looks for special offers
When the customer interacts with your application (either in the main view or
for an event with a special offer, such as 7AB)
Then a prominent notice is seen displaying details of the available special
offers and the associated event (e.g. 7AB has 8% off CIRCLE-A seats, and no
fees for STALLS-B seats).
Allow customers to select discount codes
Some events have discounted ticket prices for children, students, etc. Your customers will appreciate being able to select these discount tickets where available.
Representative Test: User requests a ticket for The Nutcracker (6IF)
When the customer requests tickets for event 6IF in Stalls-A
Then they should be able to choose between a normal ADULT ticket, and
discounted CHILD, STUDENT and OAP tickets.
Display all event information to customers
Most events include additional media information. Displaying this information to your customers will help build interest and credibility.
Representative Test: User clicks on The Nutcracker (6IF)
When the customer selects the main event page or information page
Then the associated media (video, images, copy text, seating plan, etc.) will
be displayed or linked.
Testing
To help with implementation and to meet the minimum and recommended functionality requirements above, we have a number of test events that you can use to validate your application and make test purchases. Many of these events also have specific conditions that can be used to test edge cases in the reservation process - please see below for details.
For testing best available events, use “Matthew Bourne’s Nutcracker TEST” (event ID = 6IF) and “Matthew Bourne’s Swan Lake test” (6IE).
- Swan Lake (6IE) has default discounts only
- Swan Lake (6IE) reserves will fail for Tuesday performances
- Swan Lake (6IE) has restricted view seats on ticket 2 and 3 on Thursdays
- The Nutcracker (6IF) has a maximum of 3 mixed discounts
- The Nutcracker (6IF) has no availability on Saturday nights
- The Nutcracker (6IF) has no discounts in the stalls on the 1st of the month
- The Nutcracker (6IF) has no OPA or STUDENT discounts in price band B
- The Nutcracker (6IF) has “collect from the venue” and “post” dispatch methods available
- Ingressoland (1D7B8) is an undated event, meaning a dummy performance is displayed - this shouldn’t be displayed to the user and should be auto-selected
For testing events that allow selection of specific seats, use either “The Unremarkable Incident of the Cat at Lunchtime” (event ID = 7AB) or “Toy Story - The Opera” (7AA).
- Unremarkable Incident (7AB) allows discontiguous seat selection and leaving singles
- Unremarkable Incident (7AB) also has some discounts and special offers for some seat bands
- Toy Story (7AA) allows contiguous seat selection only and does not permit leaving singles
Additionally, both events have the following conditions in common:
- A reservation including seat H10 will always fail
- A reservation including seat D7 will return a different seat selection from the same block of seats (as if that seat had become unavailable)
- Seats A1, A2, A10 and C5 have restricted views
- Seat A6 has seat text attached to the seat
- Seat C6 has both seat text and a restricted view
There is a seating plan available for 7AB and 7AA, which will be helpful if you decide to implement seat selection on your front end. Please contact us and we can talk you through how to do this.
It may be useful to use our B2B website as a
working example during your development.
You can sign in using your own credentials or with affiliate ID: demo
and
password: demopass
We have a number of other events for different types of events such as attractions and hotels - you will see these if you list all events.
Some of these other test events have specific conditions that you can check:
- La Femme (6L9) has blanket discounts
- La Femme (6L9) has a special offer
- V&A memberships (6KF) only allow a single ticket to be selected and have a type
of
use_last_perf
- California Disney (9XY) is post only (can be used to generate ‘no sends’ if you select a performance date within the next few days)
- Flamingoland family passes (6KU) are not valid on Mondays
It can be useful to test different dispatch methods:
- The Unremarkable Incident (7AB) has “self-print voucher” (also known as an eTicket) with a barcode data attached
- Toy Story (7AA) has a “self-print voucher” option without the barcode
Live Testing
Sometimes partners wish to make test purchases of live events via our API. If you do that please ensure you:
- Always check with us before purchasing something - email operations@ingresso.co.uk
- Choose a date that is as far in advance as possible. If you book tickets for today there normally won’t be enough time to cancel them.
- After you put through a successful test purchase either cancel it via the API (if that is possible - often it isn’t) or notify customerservices@ingresso.co.uk so they can cancel it.
- Use “test” as either the customer first or last name - an internal Ingresso alert is sent for transactions for a “test” customer that haven’t yet been cancelled.
Versioning
The API version number forms part of the URL, for example https://api.ticketswitch.com/f13/events.v1 uses version 1. We will always endeavour to add functionality and make changes in a backward-compatible manner, but when that is not possible we will implement a new version. We will then introduce a deprecation schedule for the replaced version and notify all partners that have integrated.
API Support
We only provide support to partners that we have provided a test account to. If you have a test or live account and you encounter problems with the API:
Check the Ingresso status page. If there is an issue reported on the status page this indicates we are already aware.
If your issue does not fit the description of the current issue, or we have not reported an issue you should contact us under the SLAs and with the contact details we have previously agreed.
Events
An event describes a product within the Ingresso system such as a theatre show,
a theme park, or a sporting event. The event will also include information about
the venue and its geographic location. An event will normally have one or more
performances. An event without available performances will be
considered dead
and won’t be turn up in searches unless explicitly requested.
Each event has a unique event_id
that identifies the event to other parts of
the API.
There are two event-related resources:
Events list: list all events or search for events.
Events by ID: return detail for one or more events by their ID.
These resources are described below, followed by detail of the additional parameters that can be passed to each.
Events list
This resource lists events. It accepts a number of search parameters to filter the list returned. The list is paged to avoid large volumes of data being accidentally returned.
Definition
GET https://api.ticketswitch.com/f13/events.v1
Request
Example request
curl https://api.ticketswitch.com/f13/events.v1 \
-u "demo:demopass" \
-d "keywords=matthew" \
-d "country_code=uk" \
--compressed \
-G
from pyticketswitch import Client
client = Client(user='demo', password='demopass')
events, meta = client.list_events(keywords=['matthew'], country_code='uk')
These are the available search / filter parameters:
Parameter | Description |
---|---|
keywords |
Space separated list of search keywords, e.g. lion king new york or paris tours . |
date_range |
Date range in the form yyyymmdd:yyyymmdd (both are optional) to filter events to those with performances within the date range. |
airport_code |
Return events near an airport (specified using an IATA airport code) |
circle |
Return events within in a circular geographical area. Three colon-separated values are needed for latitude, longitude, and radius in kilometres. Example: 51.52961137:-0.10601562:10 . |
city_code |
Return events in a particular city. The list of city codes can be retrieved using the cities resource. |
country_code |
2-digit country code (using ISO 3166-1 alpha-2). |
add_dead_events |
Include dead events in the results. This could be useful if you dynamically retrieve the list of events from Ingresso and want to continue to display an event page after an event dies, for example to help with search engine optimisation. |
offers_only |
If set to true the response will only include events with a special offer. Note that we rely on cached data, so we cannot guarantee complete accuracy. |
These parameters are used to control the output if more than one event is returned:
Parameter | Description |
---|---|
page_length |
Length of a page, default 50. |
page_number |
Zero-indexed page number, default 0. Should be used in conjunction with the page_length parameter. |
sort_order |
Valid values are most_popular (based on sales across all partners over the last 48 hours), alphabetic , cost_ascending (lowest price first, based on the minimum total price [seatprice + surcharge] for the event), cost_descending (highest price first, based on the maximum total price for the event), critic_rating (average critic rating, highest to lowest), recent , last_sale . When there is a tie alphabetic ordering is used to break the tie. Note: there is a slight performance impact to using cost_ascending or cost_descending if you are not also using the req_cost_range parameter. |
These parameters can be passed in to request additional data for each event, and are described in more detail in the additional parameters section below:
Parameter | Description |
---|---|
req_avail_details |
Returns availability details - a cached list of unique ticket types and price bands available for this event across all performances. This parameter is not commonly used. |
req_avail_details_with_perfs |
This will add the list of available performance dates to each avail detail object. Only valid if used alongside req_avail_details. |
req_avail_detail_discounts |
Adds non standard discounts to availability details Only valid when used alongside req_avail_details |
req_cost_range |
Returns cost ranges - a from price and offer detail for each event. Most partners include this parameter. |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. This is the most commonly used offer cost range. |
req_cost_range_details |
Returns a list of unique ticket types and price bands and their cost ranges across all performances. This parameter is not commonly used. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only 1 consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
req_cost_range_discounts |
Adds alternate discounts to cost range data Only valid if used alongside req_cost_range |
req_extra_info |
Returns the descriptive info for the event, returned as individual sections (structured_info ) or as a single summary (event_info / event_info_html ). |
req_media_triplet_one |
Triplet one (jpg/png 520x390). See further detail on media. |
req_media_triplet_two |
Triplet two if available (jpg/png 520x390). |
req_media_triplet_three |
Triplet three if available (jpg/png 520x390). |
req_media_triplet_four |
Triplet four if available (jpg/png 520x390). |
req_media_triplet_five |
Triplet five if available (jpg/png 520x390). |
req_media_seating_plan |
Graphical seating plan of the venue if available (jpg/png varying size). |
req_media_square |
Small square image suitable for search or event avatar (jpg/png 140x140). |
req_media_landscape |
Small landscape banner suitable for search (jpg/png 220x115). |
req_media_marquee |
Large landscape banner suitable for a page heading, if available (jpg/png 700x300). |
req_media_supplier |
Logo of the supplier/producer, if available (jpg/png varying size). |
req_meta_components |
Returns a list of meta component events. This will only add data if the event is a “meta event” such as a touring show that is comprised of individual component events. |
req_reviews |
Returns event reviews if available. |
req_video_iframe |
Returns video iframe information if available. |
Response
{
"results": {
"event": [
{
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
{
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"custom_filter": [],
"event_desc": "Matthew Bourne's Swan Lake test",
"event_id": "6IE",
"event_path": "/6IE-matthew-bourne-s-swan-lake-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IF",
"6KU",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Swan-Lake-test",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 90,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
}
],
"paging_status": {
"page_length": 50,
"page_number": 0,
"pages_remaining": 0,
"results_remaining": 0,
"total_unpaged_results": 2
}
}
}
from pyticketswitch.event import Event
[
Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_add_on=False,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
is_auto_quantity_add_on=False,
upsell_list=[
'6IE',
'MH0'
],
critic_review_percent=100,
),
Event(
id='6IE',
status='live',
description="Matthew Bourne's Swan Lake test",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=90,
show_performance_time=True,
has_performances=True,
is_add_on=False,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
is_auto_quantity_add_on=False,
upsell_list=[
'6IF',
'6KU',
'MH0'
],
)
]
Attribute | Description |
---|---|
city_code |
Code of the city where the event is taking place. |
city_desc |
Name of the city where the event is taking place. |
classes |
A collection of categories (a.k.a. “classes”) that this event belongs to. The index is the class code, the value is the class description. |
country_code |
2-digit country code (using ISO 3166-1 alpha-2) |
country_desc |
Name of the country where the event is taking place. |
critic_review_percent |
The aggregate critic review score, e.g. 80 for 80%. |
custom_filter |
Array of custom filter codes. This can be ignored by partners. |
event_desc |
Name of the show or event e.g. The Lion King . |
event_id |
Unique identifier for the event. |
event_path |
If you also use a white label website this can be used to navigate to the event page, e.g. /2J5V-la-pedrera-skip-the-line/ . |
event_status |
Will be live for a normal event search. Other values are dead and pending but these will only be displayed when using the include_dead or include_non_live parameters. |
event_type |
Currently all events are of type simple_ticket . In future we may add hotel_room and misc_item . |
geo_data |
A block containing the following geo co-ordinates: |
geo_data.latitude |
Latitude of the event. |
geo_data.longitude |
Longitude of the event. |
has_no_perfs |
true if the event has no performances. All events must have performances to be sold, so an event without performances cannot be sold and will likely soon have its event_status set to dead . |
is_add_on |
false if this event is an add-on event. This means it can only be added to a trolley containing tickets for an event that lists this in its add_ons . |
is_auto_quantity_add_on |
false Indicates whether add on quantity will be modified based on the number of ticket orders, if true number of addons will be equal to total number of tickets for all parent events in the trolley. |
is_seated |
true for seated events. |
max_running_time |
Maximum length / duration in minutes (not always present). |
min_running_time |
Minimum length / duration in minutes (not always present). |
need_departure_date |
Flag indicating whether the event needs a departure date specified. This is false for most events. Most partners can ignore this. |
need_duration |
Flag indicating whether the event needs duration (specific to hotel_room events only). Most partners can ignore this. |
need_performance |
Flag indicating if an event supports performances. For events that require a date and time to be selected this will be true . Other events, for example some attraction tickets, are valid for any date; these events will return false however they will still return a list of dummy performances - you should not present these performances to the end user but you should programmatically choose any single performance when requesting availability. |
postcode |
Postcode of the event location. |
show_perf_time |
false if the performance time is not relevant, for example some events use a performance description rather than specific times. |
source_code |
Source supplier code e.g. nimax . |
source_desc |
Source supplier description e.g. Nimax . |
user_review_percent |
The aggregate user review score, e.g. 80 for 80%. |
venue_desc |
Name of the venue e.g. Sadler's Wells . |
venue_uri_desc |
URI encoded name of the venue e.g. Sadler%27s-Wells . |
The outer object also contains a paging_status object:
Attribute | Description |
---|---|
page_length |
The number of results per page. |
page_number |
The zero-based page number currently displayed. |
pages_remaining |
The number of pages that you need to request after the current page to retrieve all results. |
results_remaining |
The number of results in the remaining pages. |
total_unpaged_results |
The total number of results. |
Events by ID
Definition
GET https://api.ticketswitch.com/f13/events_by_id.v1?event_id_list={eventidlist}
This resource returns detail for one or more specific events by their ID. It
returns a dictionary of events keyed on the event’s event_id
.
Example request
curl https://api.ticketswitch.com/f13/events_by_id.v1 \
-u "demo:demopass" \
-d "event_id_list=6IF,6IE" \
--compressed \
-G
from pyticketswitch import Client
client = Client(user='demo', password='demopass')
events, meta = client.get_events(event_ids=['6IF'])
Example request - with add-on and upsell events included
curl https://api.ticketswitch.com/f13/events_by_id.v1 \
-i "demo:demopass" \
-d "event_id_list=7AB" \
-d "add_add_ons" \
-d "add_upsells" \
--compressed \
-G
from pyticketswitch import Client
client = Client(user='demo', password='demopass')
events, meta = client.get_events(
event_ids=['7AB'],
with_addons=True,
with_upsells=True,
)
Request
Parameter | Description |
---|---|
event_id_list |
A comma separated list of event IDs e.g. 25DR for a single event; 1VLG,1YYO,25DR for multiple events. |
add_add_ons |
(Optional) Include a list of add-on events per event (these are events or merchandise related to the event searched for that can be included in a trolley for upsell). It is more common to request these with add-ons |
add_upsells |
(Optional) Include a list of upsell events per event (these are related events that the customer may be interested in as well as the base event) |
These parameters can be passed in to request additional data for each event, and are described in more detail in the additional parameters section below:
Parameter | Description |
---|---|
req_avail_details |
Returns availability details - a cached list of unique ticket types and price bands available for this event across all performances. This parameter is not commonly used. |
req_avail_details_with_perfs |
This will add the list of available performance dates to each avail detail object. Only valid if used alongside req_avail_details. |
req_cost_range |
Returns cost ranges - a from price and offer detail for each event. Most partners include this parameter. |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. This is the most commonly used offer cost range. |
req_cost_range_details |
Returns a list of unique ticket types and price bands and their cost ranges across all performances. This parameter is not commonly used. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only 1 consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
req_extra_info |
Returns the descriptive info for the event, returned as individual sections (structured_info ) or as a single summary (event_info / event_info_html ). |
req_media_triplet_one |
Triplet one (jpg/png 520x390). See further detail on media. |
req_media_triplet_two |
Triplet two if available (jpg/png 520x390). |
req_media_triplet_three |
Triplet three if available (jpg/png 520x390). |
req_media_triplet_four |
Triplet four if available (jpg/png 520x390). |
req_media_triplet_five |
Triplet five if available (jpg/png 520x390). |
req_media_seating_plan |
Graphical seating plan of the venue if available (jpg/png varying size). |
req_media_square |
Small square image suitable for search or event avatar (jpg/png 140x140). |
req_media_landscape |
Small landscape banner suitable for search (jpg/png 220x115). |
req_media_marquee |
Large landscape banner suitable for a page heading, if available (jpg/png 700x300). |
req_media_supplier |
Logo of the supplier/producer, if available (jpg/png varying size). |
req_reviews |
Returns event reviews if available. |
req_video_iframe |
Returns video iframe information if available. |
Response
Example response
{
"events_by_id": {
"6IE": {
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"custom_filter": [],
"event_desc": "Matthew Bourne's Swan Lake test",
"event_id": "6IE",
"event_path": "/6IE-matthew-bourne-s-swan-lake-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IF",
"6KU",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Swan-Lake-test",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 90,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
],
"venue_is_enforced": true
},
"6IF": {
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
],
"venue_is_enforced": true
}
}
}
from pyticketswitch.event import Event
{
'6IF': Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_add_on=False,
is_auto_quantity_add_on=False,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
critic_review_percent=100,
valid_quantities=None,
)
}
Example response - with add-on and upsell events included
{
"events_by_id": {
"7AB": {
"add_ons": [
{
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"theatre": "Theatre"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"custom_filter": [],
"event_desc": "Unremarkable Cat Lunchbox",
"event_id": "7AC",
"event_path": "/7AC-unremarkable-cat-lunchbox/",
"event_status": "live",
"event_type": "misc_item",
"event_uri_desc": "Unremarkable-Cat-Lunchbox",
"geo_data": {
"latitude": 51.49306,
"longitude": -0.22639
},
"has_no_perfs": false,
"is_add_on": true,
"is_auto_quantity_add_on": true,
"is_seated": false,
"need_departure_date": false,
"need_duration": false,
"need_performance": false,
"postcode": "W6 7ES",
"show_perf_time": false,
"source_code": "ext_test1",
"source_desc": "External Test Backend 1",
"venue_desc": "Lyric Apollo",
"venue_uri_desc": "Lyric-Apollo"
}
],
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"theatre": "Theatre"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"custom_filter": [],
"event_desc": "The Unremarkable Incident of the Cat at Lunchtime",
"event_id": "7AB",
"event_path": "/7AB-the-unremarkable-incident-of-the-cat-at-lunchtime/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"7AA",
"6IF"
]
},
"event_uri_desc": "The-Unremarkable-Incident-of-the-Cat-at-Lunchtime",
"geo_data": {
"latitude": 51.49306,
"longitude": -0.22639
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 90,
"min_running_time": 90,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "W6 7ES",
"show_perf_time": true,
"source_code": "ext_test1",
"source_desc": "External Test Backend 1",
"venue_desc": "Lyric Apollo",
"venue_uri_desc": "Lyric-Apollo"
},
"upsells": [
{
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"opera": "Opera"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"custom_filter": [],
"event_desc": "Toy Story - The Opera",
"event_id": "7AA",
"event_path": "/7AA-toy-story-the-opera/",
"event_status": "live",
"event_type": "simple_ticket",
"event_uri_desc": "Toy-Story-The-Opera",
"geo_data": {
"latitude": 51.511556,
"longitude": -0.11975
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 90,
"min_running_time": 90,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "WC2E 7RQ",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"venue_desc": "Lyceum Theatre",
"venue_uri_desc": "Lyceum-Theatre"
},
{
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
}
],
"valid_quantities": [
1,
2,
3,
4
],
"venue_is_enforced": true
}
}
}
from pyticketswitch.event import Event
{
u'7AB': Event(
min_running_time=90,
event_type=u'simple_ticket',
has_performances=True,
venue_info_html=None,
critic_review_percent=None,
needs_departure_date=False,
valid_quantities=None,
addon_events=[
Event(
min_running_time=None,
event_type=u'misc_item',
has_performances=True,
venue_info_html=None,
critic_review_percent=None,
needs_departure_date=False,
valid_quantities=None,
addon_events=None,
availability_details=[],
postcode=u'W6 7ES',
country_code=u'uk',
id=u'7AC',
city=u'London',
filters=[],
media={},
is_seated=False,
upsell_events=None,
event_info=None,
content={},
source=u'External Test Backend 1',
max_running_time=None,
cost_range_details=[],
needs_performance=False,
latitude=51.49306,
upsell_list=[],
city_code=u'london-uk',
venue_addr=None,
status=u'live',
description=u'Unremarkable Cat Lunchbox',
venue_addr_html=None,
cost_range=None,
event_info_html=None,
source_code=u'ext_test1',
country=u'United Kingdom',
venue_info=None,
venue=u'Lyric Apollo',
longitude=-0.22639,
is_add_on=True,
is_auto_quantity_add_on=False,
reviews=[],
classes={
u'theatre': u'Theatre'
},
fields={},
needs_duration=False,
no_singles_cost_range=None,
component_events=[],
show_performance_time=False,
)
],
availability_details=[],
postcode=u'W6 7ES',
country_code=u'uk',
id=u'7AB',
city=u'London',
filters=[],
media={},
is_seated=True,
upsell_events=[
Event(
min_running_time=90,
event_type=u'simple_ticket',
has_performances=True,
venue_info_html=None,
critic_review_percent=None,
needs_departure_date=False,
valid_quantities=None,
addon_events=None,
availability_details=[],
postcode=u'WC2E 7RQ',
country_code=u'uk',
id=u'7AA',
city=u'London',
filters=[],
media={},
is_seated=True,
upsell_events=None,
event_info=None,
content={},
source=u'External Test Backend 0',
max_running_time=90,
cost_range_details=[],
needs_performance=False,
latitude=51.511556,
upsell_list=[],
city_code=u'london-uk',
venue_addr=None,
status=u'live',
description=u'Toy Story - The Opera',
venue_addr_html=None,
cost_range=None,
event_info_html=None,
source_code=u'ext_test0',
country=u'United Kingdom',
venue_info=None,
venue=u'Lyceum Theatre',
longitude=-0.11975,
is_add_on=False,
is_auto_quantity_add_on=False,
reviews=[],
classes={
u'opera': u'Opera'
},
fields={},
needs_duration=False,
no_singles_cost_range=None,
component_events=[],
show_performance_time=True,
),
Event(
min_running_time=120,
event_type=u'simple_ticket',
has_performances=True,
venue_info_html=None,
critic_review_percent=100,
needs_departure_date=False,
valid_quantities=None,
addon_events=None,
availability_details=[],
postcode=u'EC1R 4TN',
country_code=u'uk',
id=u'6IF',
city=u'London',
filters=[],
media={},
is_seated=True,
upsell_events=None,
event_info=None,
content={},
source=u'External Test Backend 0',
max_running_time=120,
cost_range_details=[],
needs_performance=False,
latitude=51.52961137,
upsell_list=[
u'6IE'
],
city_code=u'london-uk',
venue_addr=None,
status=u'live',
description=u"Matthew Bourne's Nutcracker TEST",
venue_addr_html=None,
cost_range=None,
event_info_html=None,
source_code=u'ext_test0',
country=u'United Kingdom',
venue_info=None,
venue=u"Sadler's Wells",
longitude=-0.10601562,
is_add_on=False,
is_auto_quantity_add_on=False,
reviews=[],
classes={
u'dance': u'Ballet & Dance'
},
fields={},
needs_duration=False,
no_singles_cost_range=None,
component_events=[],
show_performance_time=True,
)
],
event_info=None,
content={},
source=u'External Test Backend 1',
max_running_time=90,
cost_range_details=[],
needs_performance=False,
latitude=51.49306,
upsell_list=[
u'7AA',
u'6IF'
],
city_code=u'london-uk',
venue_addr=None,
status=u'live',
description=u'The Unremarkable Incident of the Cat at Lunchtime',
venue_addr_html=None,
cost_range=None,
event_info_html=None,
source_code=u'ext_test1',
country=u'United Kingdom',
venue_info=None,
venue=u'Lyric Apollo',
longitude=-0.22639,
is_add_on=False,
is_auto_quantity_add_on=False,
reviews=[],
classes={
u'theatre': u'Theatre'
},
fields={},
needs_duration=False,
no_singles_cost_range=None,
component_events=[],
show_performance_time=True,
)
}
Attributes
Attribute | Description |
---|---|
city_desc |
Name of the city where the event is taking place. |
class |
Array of class or category objects. |
country_code |
2-digit country code (using ISO 3166-1 alpha-2). |
country_desc |
Name of the country where the event is taking place. |
critic_review_percent |
The aggregate critic review score, e.g. 80 for 80%. |
custom_filter |
Array of custom filter codes. This can be ignored by partners. |
date_range_start |
A date/time object for the start of the run. |
date_range_end |
A date/time object for the end of the run. |
event_desc |
Name of the show or event e.g. The Lion King . |
event_id |
Unique identifier for the event. |
event_path |
If you also use a white label website this can be used to navigate to the event page, e.g. /2J5V-la-pedrera-skip-the-line/ . |
event_status |
Will be live for a normal event search. Other values are dead and pending but these will only be displayed when using the include_dead or include_non_live parameters. |
event_type |
Currently all events are of type simple_ticket . In future we may add hotel_room and misc_item . |
geo_data |
A block containing the following geo co-ordinates: |
geo_data.latitude |
Latitude of the event. |
geo_data.longitude |
Longitude of the event. |
has_no_perfs |
true if the event has no performances. For example some attraction tickets are valid for any date, so we do not present a list of performances to select. |
is_add_on |
true if this event is an add-on event. This means it can only be added to a trolley containing tickets for an event that lists this in its add_ons . |
is_seated |
true for seated events. |
min_running_time |
Minimum length / duration in minutes (not always present). |
max_running_time |
Maximum length / duration in minutes (not always present). |
need_departure_date |
Flag indicating whether the event needs a departure date specified. This is false for most events. |
need_duration |
Flag indicating whether the event needs duration (specific to hotel_room events only). |
need_performance |
Flag indicating if a performance must be selected in order to retrieve availability. |
postcode |
Postcode of the event location. |
show_perf_time |
false if the performance time is not relevant, for example some events use a performance description rather than specific times. |
source_desc |
Despription of the source supplier e.g. Nimax . |
user_review_percent |
The aggregate user review score, e.g. 80 for 80%. |
venue_desc |
Name of the venue e.g. Sadler's Wells . |
Additional attributes may be specified depending on the parameters used:
Attribute | Description |
---|---|
add_ons |
A list of events that can be sold as add-on events with this event |
upsells |
A list of related events that can be upsold against this event. |
— Additional parameters —
There are several additional parameters described below that can be provided to return additional data for each event.
These additional parameters require extra processing to retrieve the requested data, which will slow down the resource, sometimes substantially. They should therefore only be used where necessary.
Media
Most events include image URLs and a YouTube video. Almost all events will include the triplet_one, square and landscape images. In most cases the seating_plan, triplet_two and triplet_three images are also provided, along with a video_iframe (typically YouTube).
Request
There are several different types of media and they all need to be requested independently when using the API. When using one of the language wrappers all media requests are consolidated.
Example Request
curl https://api.ticketswitch.com/f13/events_by_id.v1 \
-u "demo:demopass" \
-d "event_id_list=6IF" \
-d "req_media_triplet_one" \
-d "req_media_triplet_two" \
-d "req_media_triplet_three" \
-d "req_media_triplet_four" \
-d "req_media_triplet_five" \
-d "req_media_seating_plan" \
-d "req_media_square" \
-d "req_media_landscape" \
-d "req_media_marquee" \
-d "req_media_supplier" \
-d "req_video_iframe" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
events, meta = client.get_events(['6IF'], media=True)
Parameter | Description |
---|---|
req_media_triplet_one |
Triplet one (jpg/png 520x390) - this is our most commonly used event image (ignore the “triplet” in the name which no longer makes sense…) |
req_media_triplet_two |
Triplet two if available (jpg/png 520x390) |
req_media_triplet_three |
Triplet three if available (jpg/png 520x390) |
req_media_triplet_four |
Triplet four if available (jpg/png 520x390) |
req_media_triplet_five |
Triplet five if available (jpg/png 520x390) |
req_media_seating_plan |
Graphical seating plan of the venue if available (jpg/png varying size) |
req_media_square |
Small square image suitable for search or event avatar (jpg/png 140x140) |
req_media_landscape |
Small landscape banner suitable for search (jpg/png 220x115) |
req_media_marquee |
Large landscape banner suitable for a page heading, if available (jpg/png 700x300) |
req_media_supplier |
Logo of the supplier/producer, if available (jpg/png varying size) |
req_video_iframe |
Returns video iframe information if available |
Response
Example Response
{
"events_by_id": {
"6IF": {
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"media": {
"media_asset": [
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/93/93c04bf0d24ef3d05e8fef4ba7709df0434ea13c.jpg",
"name": "landscape",
"path": "/shared/event_media/cropper/93/93c04bf0d24ef3d05e8fef4ba7709df0434ea13c.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/93/93c04bf0d24ef3d05e8fef4ba7709df0434ea13c.jpg",
"supports_http": false,
"supports_https": true
},
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/7e/7e048c655f79d1ae01419c92420861df156b83fc.jpg",
"name": "marquee",
"path": "/shared/event_media/cropper/7e/7e048c655f79d1ae01419c92420861df156b83fc.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/7e/7e048c655f79d1ae01419c92420861df156b83fc.jpg",
"supports_http": false,
"supports_https": true
},
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "http://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper_cloud/29/2974e58797af0d91752b73da390ae6f8fa6e4862.jpg",
"name": "seating_plan",
"path": "/shared/event_media/cropper_cloud/29/2974e58797af0d91752b73da390ae6f8fa6e4862.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper_cloud/29/2974e58797af0d91752b73da390ae6f8fa6e4862.jpg",
"supports_http": true,
"supports_https": true
},
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/5e/5e004f25b5aab6f432cd7e6839b70942d8a5f17b.jpg",
"name": "square",
"path": "/shared/event_media/cropper/5e/5e004f25b5aab6f432cd7e6839b70942d8a5f17b.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/5e/5e004f25b5aab6f432cd7e6839b70942d8a5f17b.jpg",
"supports_http": false,
"supports_https": true
},
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "http://d1wx4w35ubmdix.cloudfront.net/shared/event_media/ext_test0/+system_ext_test0/supplier.jpg",
"name": "supplier",
"path": "/shared/event_media/ext_test0/+system_ext_test0/supplier.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/ext_test0/+system_ext_test0/supplier.jpg",
"supports_http": true,
"supports_https": true
},
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/f9/f9aaf4bc04477c303d78bc5107cc0754df846ac8.jpg",
"name": "triplet_five",
"path": "/shared/event_media/cropper/f9/f9aaf4bc04477c303d78bc5107cc0754df846ac8.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/f9/f9aaf4bc04477c303d78bc5107cc0754df846ac8.jpg",
"supports_http": false,
"supports_https": true
},
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/f9/f9aaf4bc04477c303d78bc5107cc0754df846ac8.jpg",
"name": "triplet_four",
"path": "/shared/event_media/cropper/f9/f9aaf4bc04477c303d78bc5107cc0754df846ac8.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper/f9/f9aaf4bc04477c303d78bc5107cc0754df846ac8.jpg",
"supports_http": false,
"supports_https": true
},
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "http://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper_cloud/0e/0e255d4f96bd02baa7bfd22fd2cab90c8f6ced34.jpg",
"name": "triplet_one",
"path": "/shared/event_media/cropper_cloud/0e/0e255d4f96bd02baa7bfd22fd2cab90c8f6ced34.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper_cloud/0e/0e255d4f96bd02baa7bfd22fd2cab90c8f6ced34.jpg",
"supports_http": true,
"supports_https": true
},
{
"caption": "",
"caption_html": "",
"host": "d1wx4w35ubmdix.cloudfront.net",
"insecure_complete_url": "http://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper_cloud/ca/ca2d4589a89480514f0db6fcec8a982652280093.jpg",
"name": "triplet_two",
"path": "/shared/event_media/cropper_cloud/ca/ca2d4589a89480514f0db6fcec8a982652280093.jpg",
"secure_complete_url": "https://d1wx4w35ubmdix.cloudfront.net/shared/event_media/cropper_cloud/ca/ca2d4589a89480514f0db6fcec8a982652280093.jpg",
"supports_http": true,
"supports_https": true
}
]
},
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells",
"video_iframe": {
"video_iframe_caption": "",
"video_iframe_caption_html": "",
"video_iframe_height": 315,
"video_iframe_host": "www.youtube.com",
"video_iframe_path": "/embed/G1JpEHGizk4?rel=0",
"video_iframe_supports_http": false,
"video_iframe_supports_https": true,
"video_iframe_url_when_insecure": "https://www.youtube.com/embed/G1JpEHGizk4?rel=0",
"video_iframe_url_when_secure": "https://www.youtube.com/embed/G1JpEHGizk4?rel=0",
"video_iframe_width": 420
}
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
],
"venue_is_enforced": true
}
}
}
from pyticketswitch.media import Media
from pyticketswitch.event import Event
{
'6IF': Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_add_on=false,
is_auto_quantity_add_on=false,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
media={
'landscape': Media(
caption='',
caption_html='',
name='landscape',
url='https://d1wx4w35ubmdix.cloudfront.net/media/event/6IF/matthew-bournes-nutcracker-test-landscape-M2kz.jpg?versionId=C3UX_j98L2FWDOof4BCY15QyKrBJ0ZRR',
secure=True,
width=None,
height=None,
),
'marquee': Media(
caption='',
caption_html='',
name='marquee',
url='https://d1wx4w35ubmdix.cloudfront.net/media/event/6IF/matthew-bournes-nutcracker-test-marquee-bGIw.jpg?versionId=WwcyqyDnuxFwYgare_6Omy61AACpF8hG',
secure=True,
width=None,
height=None,
),
'seating_plan': Media(
caption='',
caption_html='',
name='seating_plan',
url='https://d1wx4w35ubmdix.cloudfront.net/media/event/6IF/matthew-bournes-nutcracker-test-seating-plan-dzJ3.jpg',
secure=True,
width=None,
height=None,
),
'square': Media(
caption='',
caption_html='',
name='square',
url='https://d1wx4w35ubmdix.cloudfront.net/media/event/6IF/matthew-bournes-nutcracker-test-square-Z0Jk.jpg?versionId=09daZJn.14RH7.84cRKXK2FfODDmFYpC',
secure=True,
width=None,
height=None,
),
'triplet_four': Media(
caption='',
caption_html='',
name='triplet_four',
url='https://d1wx4w35ubmdix.cloudfront.net/media/event/6IF/matthew-bournes-nutcracker-test-triplet-four-bndw.jpg?versionId=kz.Y.qd379E_wm2ZNWnGRMtLFu4Teqpu',
secure=True,
width=None,
height=None,
),
'triplet_one': Media(
caption='',
caption_html='',
name='triplet_one',
url='https://d1wx4w35ubmdix.cloudfront.net/media/event/6IF/matthew-bournes-nutcracker-test-triplet-one-eWVq.jpg?versionId=WewM3wJOwzhP.QOsJqDSBUDxBwimxNV_',
secure=True,
width=None,
height=None,
),
'triplet_three': Media(
caption='',
caption_html='',
name='triplet_three',
url='https://d1wx4w35ubmdix.cloudfront.net/media/event/6IF/matthew-bournes-nutcracker-test-triplet-three-U2Yz.jpg?versionId=MPJgrknmvajkTolWT55cmh7McDrI4PCD',
secure=True,
width=None,
height=None,
),
'triplet_two': Media(
caption='',
caption_html='',
name='triplet_two',
url='https://d1wx4w35ubmdix.cloudfront.net/media/event/6IF/matthew-bournes-nutcracker-test-triplet-two-d0xl.jpg?versionId=FpaMhCJw.gCmiOn598.m3OmtXJv5p0OM',
secure=True,
width=None,
height=None,
),
'video': Media(
caption='',
caption_html='',
name='video',
url='https://www.youtube.com/embed/G1JpEHGizk4?rel=0',
secure=True,
width=420,
height=315,
)
},
critic_review_percent=100,
)
}
Media Asset
Media assets provide both secure and insecure URLs where possible when either a secure or and insecure URL is not available, the other URL will be substituted. Generally speaking all our media assets at this point will be https with no http option, however this is not a universal rule.
Attribute | Description |
---|---|
name |
The name of the image, default names are `triple_{one |
caption |
any text related to the image in plain text |
caption_html |
any text related to the image in html |
host |
the hostname of server on which the image is hosted |
path |
the absolute path of the file on the host |
insecure_complete_url |
a complete http address |
secure_complete_url |
a complete https address |
supports_http |
indicates that the asset is accessible via http |
supports_https |
indicates that the asset is accessible via https |
Video iframe
The video iframe is a slightly different media asset that contains information about an embeddable video related to the event. It shares the same attributes with a regular media asset but also contains hints for iframe sizing.
Attribute | Description |
---|---|
video_iframe_height |
the suggested height of the iframe |
video_iframe_width |
the suggested width of the iframe |
video_iframe_caption |
any text related to the image in plain text |
video_iframe_caption_html |
any text related to the image in html |
video_iframe_host |
the hostname of server on which the image is hosted |
video_iframe_path |
the absolute path of the file on the host |
video_iframe_insecure_complete_url |
a complete http address |
video_iframe_secure_complete_url |
a complete https address |
video_iframe_supports_http |
indicates that the asset is accessible via http |
video_iframe_supports_https |
indicates that the asset is accessible via https |
Extra info
Most events will have additional information and content available. This data is not returned by default because it can slow down response time, especially when many events are being returned.
Request
Example request
curl https://api.ticketswitch.com/f13/events_by_id.v1 \
-u "demo:demopass" \
-d "event_id_list=6IF" \
-d "req_extra_info" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
events, meta = client.get_events(['6IF'], extra_info=True)
Parameter | Description |
---|---|
req_extra_info |
Returns the descriptive info for the event, returned as individual sections (structured_info ) and as a single summary (event_info / event_info_html ) |
Response
Example response
{
"events_by_id": {
"6IF": {
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_info": "Matthew Bourne's stunning production of Nutcracker! returns in 2008 to Sadler's Wells having broken all box office records during last year's sell-out season.\n\nThis festive treat is full of his trademark style of wit, pathos and theatrical magic. Nutcracker! follows Clara's journey from a bleak Christmas Eve at Dr.Dross' Orphanage, through a shimmering ice-skating wonderland and to the spectacular candy folk of Sweetieland.\n\nOliver award-winning designer Anthony Ward and Tchaikovsky's much-loved score combined with sizzling choreography guarantee that Matthew Bourne's Nutcracker! is a fresh, lip-smacking, serving of traditional Christmas fare.\n\nMatthew Bourne has achieved both artistic and commercial success with his imaginative new versions of classical ballets. Last year his Play Without Words made for the Royal National Theatre, received two Olivier Awards and is shortly to be revived.\n\nDuration\n\nA Goldilocks duration - not too long, not too short, just the right amount of time.\n\n\nPerformance Times\n\nAnytime you like! As long as there's a show on...\n\n\nWhere Do I Go\n\nTo Sadler's Wells of course!\n\n\nWhat's Included\n\nEverything you need.\n\n\nGood To Know\n\nWarning! Men in very tight tights.\n\n\nSuitable For Children\n\nSure, just be aware of the aforementioned tights.\n\n\nOffers Information\n\nThis is some offers information\n\n",
"event_info_html": "<div><p>Matthew Bourne's stunning production of Nutcracker! returns in 2008 to Sadler's Wells having broken all box office records during last year's sell-out season.</p>\r\n<p>This festive treat is full of his trademark style of wit, pathos and theatrical magic. Nutcracker! follows Clara's journey from a bleak Christmas Eve at Dr.Dross' Orphanage, through a shimmering ice-skating wonderland and to the spectacular candy folk of Sweetieland.</p>\r\n<p>Oliver award-winning designer Anthony Ward and Tchaikovsky's much-loved score combined with sizzling choreography guarantee that Matthew Bourne's Nutcracker! is a fresh, lip-smacking, serving of traditional Christmas fare.</p>\r\n<p>Matthew Bourne has achieved both artistic and commercial success with his imaginative new versions of classical ballets. Last year his Play Without Words made for the Royal National Theatre, received two Olivier Awards and is shortly to be revived.</p></div>\n\n<h4>Duration</h4>\n<div><p>A Goldilocks duration - not <em>too</em> long, not <em>too</em> short, just the right amount of time.</p></div>\n\n<h4>Performance Times</h4>\n<div><p>Anytime you like! As long as there's a show on...</p></div>\n\n<h4>Where Do I Go</h4>\n<div><p>To Sadler's Wells of course!</p></div>\n\n<h4>What's Included</h4>\n<div><p>Everything you need.</p></div>\n\n<h4>Good To Know</h4>\n<div><p>Warning! Men in very tight tights.</p></div>\n\n<h4>Suitable For Children</h4>\n<div><p>Sure, just be aware of the aforementioned tights.</p></div>\n\n<h4>Offers Information</h4>\n<div><p>This is some offers information</p></div>\n",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"structured_info": {
"address": {
"name": "Address",
"value": "Roseberry Avenue\r\nIslington\r\nLondon\r\nUK",
"value_html": "<p>Roseberry Avenue\r\nIslington\r\nLondon\r\nUK</p>"
},
"duration": {
"name": "Duration",
"value": "A Goldilocks duration - not too long, not too short, just the right amount of time.\n",
"value_html": "<p>A Goldilocks duration - not <em>too</em> long, not <em>too</em> short, just the right amount of time.</p>"
},
"good_to_know": {
"name": "Good To Know",
"value": "Warning! Men in very tight tights.\n",
"value_html": "<p>Warning! Men in very tight tights.</p>"
},
"offers": {
"name": "Offers Information",
"value": "This is some offers information\n",
"value_html": "<p>This is some offers information</p>"
},
"overview": {
"name": "Overview",
"value": "Matthew Bourne's stunning production of Nutcracker! returns in 2008 to Sadler's Wells having broken all box office records during last year's sell-out season.\n\nThis festive treat is full of his trademark style of wit, pathos and theatrical magic. Nutcracker! follows Clara's journey from a bleak Christmas Eve at Dr.Dross' Orphanage, through a shimmering ice-skating wonderland and to the spectacular candy folk of Sweetieland.\n\nOliver award-winning designer Anthony Ward and Tchaikovsky's much-loved score combined with sizzling choreography guarantee that Matthew Bourne's Nutcracker! is a fresh, lip-smacking, serving of traditional Christmas fare.\n\nMatthew Bourne has achieved both artistic and commercial success with his imaginative new versions of classical ballets. Last year his Play Without Words made for the Royal National Theatre, received two Olivier Awards and is shortly to be revived.\n",
"value_html": "<p>Matthew Bourne's stunning production of Nutcracker! returns in 2008 to Sadler's Wells having broken all box office records during last year's sell-out season.</p>\r\n<p>This festive treat is full of his trademark style of wit, pathos and theatrical magic. Nutcracker! follows Clara's journey from a bleak Christmas Eve at Dr.Dross' Orphanage, through a shimmering ice-skating wonderland and to the spectacular candy folk of Sweetieland.</p>\r\n<p>Oliver award-winning designer Anthony Ward and Tchaikovsky's much-loved score combined with sizzling choreography guarantee that Matthew Bourne's Nutcracker! is a fresh, lip-smacking, serving of traditional Christmas fare.</p>\r\n<p>Matthew Bourne has achieved both artistic and commercial success with his imaginative new versions of classical ballets. Last year his Play Without Words made for the Royal National Theatre, received two Olivier Awards and is shortly to be revived.</p>"
},
"pricing_details_info": {
"name": "Pricing details information",
"value": "Book by 30th April for performances from 10 July - 10 August and pay no booking fee on this show\n",
"value_html": "<p>Book by 30th April for performances from 10 July - 10 August and pay no booking fee on this show</p>"
},
"suitable_for_children": {
"name": "Suitable For Children",
"value": "Sure, just be aware of the aforementioned tights.\n",
"value_html": "<p>Sure, just be aware of the aforementioned tights.</p>"
},
"whats_included": {
"name": "What's Included",
"value": "Everything you need.\n",
"value_html": "<p>Everything you need.</p>"
},
"when_can_i_go": {
"name": "Performance Times",
"value": "Anytime you like! As long as there's a show on...\n",
"value_html": "<p>Anytime you like! As long as there's a show on...</p>"
},
"where_do_i_go": {
"name": "Where Do I Go",
"value": "To Sadler's Wells of course!\n",
"value_html": "<p>To Sadler's Wells of course!</p>"
}
},
"user_review_percent": 100,
"venue_addr": "Roseberry Avenue\r\nIslington\r\nLondon\r\nUK",
"venue_addr_html": "<div><p>Roseberry Avenue\r\nIslington\r\nLondon\r\nUK</p></div>\n",
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
],
"venue_is_enforced": true
}
}
}
from pyticketswitch.content import Content
from pyticketswitch.event import Event
{
'6IF': Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
filters=[
],
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_add_on=False,
is_auto_quantity_add_on=False,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
content={
'address': Content(
name='Address',
value='Roseberry Avenue Islington London UK\n',
value_html='<p>Roseberry Avenue Islington London UK</p>',
),
'duration': Content(
name='Duration',
value='A Goldilocks duration - not too long, not too short, just the right amount of time.\n',
value_html='<p>A Goldilocks duration - not <em>too</em> long, not <em>too</em> short, just the right amount of time.</p>',
),
'good_to_know': Content(
name='Good To Know',
value='Warning! Men in very tight tights.\n',
value_html='<p>Warning! Men in very tight tights.</p>',
),
'offers': Content(
name='Offers Information',
value='This is some offers information\n',
value_html='<p>This is some offers information</p>',
),
'overview': Content(
name='Overview',
value="Matthew Bourne's stunning production of Nutcracker! returns in 2008 to Sadler's Wells having broken all box office records during last year's sell-out season.\n\nThis festive treat is full of his trademark style of wit, pathos and theatrical magic. Nutcracker! follows Clara's journey from a bleak Christmas Eve at Dr.Dross' Orphanage, through a shimmering ice-skating wonderland and to the spectacular candy folk of Sweetieland.\n\nOliver award-winning designer Anthony Ward and Tchaikovsky's much-loved score combined with sizzling choreography guarantee that Matthew Bourne's Nutcracker! is a fresh, lip-smacking, serving of traditional Christmas fare.\n\nMatthew Bourne has achieved both artistic and commercial success with his imaginative new versions of classical ballets. Last year his Play Without Words made for the Royal National Theatre, received two Olivier Awards and is shortly to be revived.\n",
value_html="<p>Matthew Bourne's stunning production of Nutcracker! returns in 2008 to Sadler's Wells having broken all box office records during last year's sell-out season.</p>\r\n<p>This festive treat is full of his trademark style of wit, pathos and theatrical magic. Nutcracker! follows Clara's journey from a bleak Christmas Eve at Dr.Dross' Orphanage, through a shimmering ice-skating wonderland and to the spectacular candy folk of Sweetieland.</p>\r\n<p>Oliver award-winning designer Anthony Ward and Tchaikovsky's much-loved score combined with sizzling choreography guarantee that Matthew Bourne's Nutcracker! is a fresh, lip-smacking, serving of traditional Christmas fare.</p>\r\n<p>Matthew Bourne has achieved both artistic and commercial success with his imaginative new versions of classical ballets. Last year his Play Without Words made for the Royal National Theatre, received two Olivier Awards and is shortly to be revived.</p>",
),
'pricing_details_info': Content(
name='Pricing details information',
value='Book by 30th April for performances from 10 July - 10 August and pay no booking fee on this show\n',
value_html='<p>Book by 30th April for performances from 10 July - 10 August and pay no booking fee on this show</p>',
),
'suitable_for_children': Content(
name='Suitable For Children',
value='Sure, just be aware of the aforementioned tights.\n',
value_html='<p>Sure, just be aware of the aforementioned tights.</p>',
),
'whats_included': Content(
name="What's Included",
value='Everything you need.\n',
value_html='<p>Everything you need.</p>',
),
'when_can_i_go': Content(
name='Performance Times',
value="Anytime you like! As long as there's a show on...\n",
value_html="<p>Anytime you like! As long as there's a show on...</p>",
),
'where_do_i_go': Content(
name='Where Do I Go',
value="To Sadler's Wells of course!\n",
value_html="<p>To Sadler's Wells of course!</p>",
)
},
event_info="Matthew Bourne's stunning production of Nutcracker! returns in 2008 to Sadler's Wells having broken all box office records during last year's sell-out season.\n\nThis festive treat is full of his trademark style of wit, pathos and theatrical magic. Nutcracker! follows Clara's journey from a bleak Christmas Eve at Dr.Dross' Orphanage, through a shimmering ice-skating wonderland and to the spectacular candy folk of Sweetieland.\n\nOliver award-winning designer Anthony Ward and Tchaikovsky's much-loved score combined with sizzling choreography guarantee that Matthew Bourne's Nutcracker! is a fresh, lip-smacking, serving of traditional Christmas fare.\n\nMatthew Bourne has achieved both artistic and commercial success with his imaginative new versions of classical ballets. Last year his Play Without Words made for the Royal National Theatre, received two Olivier Awards and is shortly to be revived.\n\nDuration\n\nA Goldilocks duration - not too long, not too short, just the right amount of time.\n\n\nPerformance Times\n\nAnytime you like! As long as there's a show on...\n\n\nWhere Do I Go\n\nTo Sadler's Wells of course!\n\n\nWhat's Included\n\nEverything you need.\n\n\nGood To Know\n\nWarning! Men in very tight tights.\n\n\nSuitable For Children\n\nSure, just be aware of the aforementioned tights.\n\n\nOffers Information\n\nThis is some offers information\n\n",
event_info_html="<div><p>Matthew Bourne's stunning production of Nutcracker! returns in 2008 to Sadler's Wells having broken all box office records during last year's sell-out season.</p>\r\n<p>This festive treat is full of his trademark style of wit, pathos and theatrical magic. Nutcracker! follows Clara's journey from a bleak Christmas Eve at Dr.Dross' Orphanage, through a shimmering ice-skating wonderland and to the spectacular candy folk of Sweetieland.</p>\r\n<p>Oliver award-winning designer Anthony Ward and Tchaikovsky's much-loved score combined with sizzling choreography guarantee that Matthew Bourne's Nutcracker! is a fresh, lip-smacking, serving of traditional Christmas fare.</p>\r\n<p>Matthew Bourne has achieved both artistic and commercial success with his imaginative new versions of classical ballets. Last year his Play Without Words made for the Royal National Theatre, received two Olivier Awards and is shortly to be revived.</p></div>\n\n<h4>Duration</h4>\n<div><p>A Goldilocks duration - not <em>too</em> long, not <em>too</em> short, just the right amount of time.</p></div>\n\n<h4>Performance Times</h4>\n<div><p>Anytime you like! As long as there's a show on...</p></div>\n\n<h4>Where Do I Go</h4>\n<div><p>To Sadler's Wells of course!</p></div>\n\n<h4>What's Included</h4>\n<div><p>Everything you need.</p></div>\n\n<h4>Good To Know</h4>\n<div><p>Warning! Men in very tight tights.</p></div>\n\n<h4>Suitable For Children</h4>\n<div><p>Sure, just be aware of the aforementioned tights.</p></div>\n\n<h4>Offers Information</h4>\n<div><p>This is some offers information</p></div>\n",
venue_addr='Roseberry Avenue Islington London UK\n',
venue_addr_html='<div><p>Roseberry Avenue Islington London UK</p></div>\n',
critic_review_percent=100,
)
}
Attribute | Description |
---|---|
content |
this is miscellaneous textual content that can be used to populate an event page. |
event_info |
summary description of the event as plain text |
event_info_html |
summary description of the event as html |
venue_info |
summary description of the venue as plain text |
venue_info_html |
summary description of the venue as html |
venue_addr |
the address of the venue as plain text |
venue_addr_html |
the address of the venue as html |
Reviews
We expose critic reviews for events that have them.
Request
Example Request
curl https://api.ticketswitch.com/f13/events_by_id.v1 \
-u "demo:demopass" \
-d "event_id_list=6IF" \
-d "req_reviews" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
events, meta = client.get_events(['6IF'], reviews=True)
Parameter | Description |
---|---|
req_reviews |
Returns event reviews if available |
Response
Example Response
{
"events_by_id": {
"6IF": {
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"reviews": {
"review": [
{
"is_user_review": false,
"review_author": "The Times",
"review_body": "Cannot recommend this show enough!",
"review_date_desc": "Tue, 17th November 2015",
"review_iso8601_date_and_time": "2015-11-17T10:00:00Z",
"review_lang": "en",
"review_original_url": "",
"review_time_desc": "10.00 AM",
"review_title": "Unmissable!",
"star_rating": 5
},
{
"is_user_review": true,
"review_author": "Matt Allpress",
"review_body": "What a show! The mise-en-scène is magical, the choreography is wonderful, the story is magnificent and those tights... incredible. I'll be buying tickets for this show again and again",
"review_date_desc": "Thu, 28th August 2014",
"review_iso8601_date_and_time": "2014-08-28T10:00:00Z",
"review_lang": "en",
"review_original_url": "",
"review_time_desc": "10.00 AM",
"review_title": "Can't get enough!",
"star_rating": 5
}
]
},
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
],
"venue_is_enforced": true
}
}
}
from pyticketswitch.review import Review
from pyticketswitch.event import Event
{
'6IF': Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_add_on=False,
is_auto_quantity_add_on=False,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
reviews=[
Review(
body='Cannot recommend this show enough!',
date_time=datetime.datetime(2015, 11, 17, 10, 0, tzinfo=tzutc()),
star_rating=5,
language='en',
title='Unmissable!',
is_user=False,
author='The Times',
url='',
),
Review(
body="What a show! The mise-en-scène is magical, the choreography is wonderful, the story is magnificent and those tights... incredible. I'll be buying tickets for this show again and again",
date_time=datetime.datetime(2014, 8, 28, 10, 0, tzinfo=tzutc()),
star_rating=5,
language='en',
title="Can't get enough!",
is_user=True,
author='Matt Allpress',
url='',
)
],
critic_review_percent=100,
)
}
Attribute | Description |
---|---|
is_user_review |
false for critic reviews; true for user reviews |
review_author |
The reviewer - for critic reviews this is normally the name of a newspaper e.g. The Evening Standard |
review_body |
The main review content - for critic reviews this is typically a quote from the review |
review_date_desc |
Review date |
review_iso8601_date_and_time |
review date and time in ISO 8601 format |
review_lang |
The ISO 639 language code of the review |
review_original_url |
For critic reviews we sometimes record the original source of the review quote |
review_time_desc |
Review time |
review_title |
Review title, not always present |
star_rating |
A rating between 1 and 5 (5 is best) |
Cost range
Cost ranges are a cached summary of the pricing that has been seen for your username. They are primarily used to retrieve the minimum (or “from”) price for the event, along with detail of any offers or discounts. They allow you to display a from price and details of offers for your event, so most partners request cost ranges.
Cost ranges are generated from availability requests made either by end-users or by scheduled processes that Ingresso use to update cost range data. You should not attempt to make multiple availability requests in order to keep this data up to date - please contact us instead to discuss options. Cost ranges are only ever returned as part of a parent object (such as event).
Request
Example request
curl https://api.ticketswitch.com/f13/events_by_id.v1 \
-u "demo:demopass" \
-d "event_id_list=6L9" \
-d "req_cost_range" \
-d "req_cost_range_best_value_offer" \
-d "req_cost_range_max_saving_offer" \
-d "req_cost_range_min_cost_offer" \
-d "req_cost_range_top_price_offer" \
-d "req_cost_range_no_singles_data" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
events, meta = client.get_events(
event_ids=['6IF'],
cost_range=True,
best_value_offer=True,
max_saving_offer=True,
min_cost_offer=True,
top_price_offer=True,
no_singles_data=True,
)
On its own, req_cost_range
will add min and max prices only, however by
adding one of the other 5 parameters below you can receive additional data
(multiple parameters are provided because different partners can have different
definitions of the “best” offer). Most API users request cost ranges.
Parameter | Description |
---|---|
req_cost_range |
Returns cost ranges for each event. |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. This is the most commonly used offer cost range. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only one consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
Response
Example response
{
"currency_details": {
"usd": {
"currency_code": "usd",
"currency_factor": 100,
"currency_number": 840,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "$"
}
},
"events_by_id": {
"6L9": {
"event": {
"city_code": "las_vegas-us",
"city_desc": "Las Vegas",
"classes": {
"circuscabaret": "Circus, Cabaret & Variety"
},
"cost_range": {
"best_value_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"max_saving_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"max_seatprice": 68,
"max_surcharge": 3,
"min_cost_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"min_seatprice": 68,
"min_surcharge": 3,
"range_currency_code": "usd",
"top_price_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"valid_quantities": [
1,
2,
3,
4
]
},
"country_code": "us",
"country_desc": "United States of America",
"custom_filter": [],
"event_desc": "La Femme",
"event_id": "6L9",
"event_path": "/6L9-la-femme/",
"event_status": "live",
"event_type": "simple_ticket",
"event_uri_desc": "La-Femme",
"geo_data": {
"latitude": 36.1034,
"longitude": -115.1721
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 90,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "NV89109",
"show_perf_time": true,
"source_code": "ext_test1",
"source_desc": "External Test Backend 1",
"venue_desc": "MGM Grand Las Vegas",
"venue_uri_desc": "MGM-Grand-Las-Vegas"
},
"valid_quantities": [
1,
2,
3,
4
],
"venue_is_enforced": true
}
}
}
from pyticketswitch.cost_range import CostRange
from pyticketswitch.event import Event
{
'6IF': Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_add_on=False,
is_auto_quantity_add_on=False,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
cost_range=CostRange(
valid_quantities=[
1,
2,
3,
4,
5,
6
],
max_seatprice=47.0,
max_surcharge=5.0,
min_seatprice=18.0,
min_surcharge=3.0,
currency='gbp',
),
no_singles_cost_range=CostRange(
valid_quantities=[
1,
2,
3,
4,
5,
6
],
max_seatprice=47.0,
max_surcharge=5.0,
min_seatprice=18.0,
min_surcharge=3.0,
currency='gbp',
),
critic_review_percent=100,
)
}
Each event returned includes a cost_range
object with the following attributes:
Attribute | Description |
---|---|
best_value_offer |
The offer with the highest percentage saving. This is the most commonly used offer cost range. |
max_saving_offer |
The offer with the highest absolute saving. |
max_seatprice |
The per-ticket face value for the highest price (seatprice + surcharge) |
max_surcharge |
The per-ticket booking fee for the highest price (seatprice + surcharge) |
min_cost_offer |
The offer with the lowest cost. |
min_seatprice |
The per-ticket face value for the lowest price (seatprice + surcharge) |
min_surcharge |
The per-ticket booking fee for the lowest price (seatprice + surcharge) |
no_singles_cost_range |
This returns another cost range object that excludes availability with only one consecutive seat available. The prices in this cost range will therefore be the same as or higher than the outer cost range. |
range_currency_code |
The currency code for the cost range - further detail for the currency can be found in the currency_details object, described below. |
top_price_offer |
The offer with the highest cost. This is the least used offer cost range. |
valid_quantities |
An array of ticket quantities with availability. |
The offer objects contain the following attributes:
Attribute | Description |
---|---|
absolute_saving |
Defined as (full_seatprice + full_surcharge ) - (offer_seatprice + offer_surcharge ). |
full_seatprice |
The non-offer per-ticket face value. |
full_surcharge |
The non-offer per-ticket booking fee. |
offer_seatprice |
The offer per-ticket face value. |
offer_surcharge |
The offer per-ticket booking fee. |
percentage_saving |
Defined as absolute_saving / (full_seatprice + full_surcharge ) * 100. |
The outer object includes a currency_details object containing one currency object (indexed on the currency code) for every currency referenced in the JSON response. Each currency has the following attributes:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Cost range details
Cost range details presents a cost range for every available price band. They allow you for example display a list of price bands on a show page, before the customer begins to choose their tickets. This is not a commonly used feature.
A list of ticket types are returned; nested within each ticket type are the available price bands; nested within each price band is a cost range. Cost range details are only ever returned as part of the parent event object.
Request
Example request
curl https://api.ticketswitch.com/f13/events_by_id.v1 \
-u "demo:demopass" \
-d "event_id_list=6IF" \
-d "req_cost_range_details" \
--compressed \
-G
from pyticketickswitch import client
client = Client('demo', 'demopass')
events, meta = client.get_events(['6IF'], cost_range_details=True)
req_cost_range_details
is the main parameter that switches on cost range details.
The other parameters listed can also be included to return additional cost
range data.
Parameter | Description |
---|---|
req_cost_range_details |
Returns a list of unique ticket types and price bands and their cost ranges across all performances |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. This is the most commonly used offer cost range. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only one consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
Response
Example response
{
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"events_by_id": {
"6IF": {
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"cost_range_details": {
"ticket_type": [
{
"price_band": [
{
"cost_range": {
"max_seatprice": 47,
"max_surcharge": 5,
"min_seatprice": 47,
"min_surcharge": 5,
"range_currency_code": "gbp",
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
},
"price_band_code": "A",
"price_band_desc": ""
}
],
"ticket_type_code": "BALCONY",
"ticket_type_desc": "Balcony"
},
{
"price_band": [
{
"cost_range": {
"max_seatprice": 35,
"max_surcharge": 4,
"min_seatprice": 35,
"min_surcharge": 4,
"range_currency_code": "gbp",
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
},
"price_band_code": "A",
"price_band_desc": ""
},
{
"cost_range": {
"max_seatprice": 30,
"max_surcharge": 4,
"min_seatprice": 30,
"min_surcharge": 4,
"range_currency_code": "gbp",
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
},
"price_band_code": "B",
"price_band_desc": ""
},
{
"cost_range": {
"max_seatprice": 25,
"max_surcharge": 4,
"min_seatprice": 25,
"min_surcharge": 4,
"range_currency_code": "gbp",
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
},
"price_band_code": "C",
"price_band_desc": ""
}
],
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle"
},
{
"price_band": [
{
"cost_range": {
"max_seatprice": 21,
"max_surcharge": 3,
"min_seatprice": 21,
"min_surcharge": 3,
"range_currency_code": "gbp",
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
},
"price_band_code": "A",
"price_band_desc": ""
},
{
"cost_range": {
"max_seatprice": 18,
"max_surcharge": 3,
"min_seatprice": 18,
"min_surcharge": 3,
"range_currency_code": "gbp",
"valid_quantities": [
1,
2,
3
]
},
"price_band_code": "B",
"price_band_desc": ""
}
],
"ticket_type_code": "STALLS",
"ticket_type_desc": "Stalls"
}
]
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
],
"venue_is_enforced": true
}
}
}
from pyticketswitch.event import Event
from pyticketswitch.ticket_type import TicketType
from pyticketswitch.discount import Discount
from pyticketswitch.cost_range import CostRange
from pyticketswitch.price_band import PriceBand
{
'6IF': Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_add_on=False,
is_auto_quantity_add_on=False,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
cost_range_details=[
TicketType(
code='BALCONY',
description='Balcony',
price_bands=[
PriceBand(
code='A',
description='',
cost_range=CostRange(
valid_quantities=[
1,
2,
3,
4,
5,
6
],
max_seatprice=47.0,
max_surcharge=5.0,
min_seatprice=47.0,
min_surcharge=5.0,
currency='gbp',
),
allows_leaving_single_seats='always',
example_seats_are_real=True,
)
],
),
TicketType(
code='CIRCLE',
description='Upper circle',
price_bands=[
PriceBand(
code='A',
description='',
cost_range=CostRange(
valid_quantities=[
1,
2,
3,
4,
5,
6
],
max_seatprice=35.0,
max_surcharge=4.0,
min_seatprice=35.0,
min_surcharge=4.0,
currency='gbp',
),
allows_leaving_single_seats='always',
example_seats_are_real=True,
),
PriceBand(
code='B',
description='',
cost_range=CostRange(
valid_quantities=[
1,
2,
3,
4,
5,
6
],
max_seatprice=30.0,
max_surcharge=4.0,
min_seatprice=30.0,
min_surcharge=4.0,
currency='gbp',
),
allows_leaving_single_seats='always',
example_seats_are_real=True,
),
PriceBand(
code='C',
description='',
cost_range=CostRange(
valid_quantities=[
1,
2,
3,
4,
5,
6
],
max_seatprice=25.0,
max_surcharge=4.0,
min_seatprice=25.0,
min_surcharge=4.0,
currency='gbp',
),
allows_leaving_single_seats='always',
example_seats_are_real=True,
)
],
),
TicketType(
code='STALLS',
description='Stalls',
price_bands=[
PriceBand(
code='A',
description='',
cost_range=CostRange(
valid_quantities=[
1,
2,
3,
4,
5,
6
],
max_seatprice=21.0,
max_surcharge=3.0,
min_seatprice=21.0,
min_surcharge=3.0,
currency='gbp',
),
allows_leaving_single_seats='always',
example_seats_are_real=True,
),
PriceBand(
code='B',
description='',
cost_range=CostRange(
valid_quantities=[
1,
2,
3
],
max_seatprice=18.0,
max_surcharge=3.0,
min_seatprice=18.0,
min_surcharge=3.0,
currency='gbp',
),
allows_leaving_single_seats='always',
example_seats_are_real=True,
)
],
)
],
critic_review_percent=100,
)
}
The cost_range_details
object includes an array of ticket types that
describe a part of house or location within the venue.
Attribute | Description |
---|---|
ticket_type_code |
the identifier of the ticket type, this can be used later in the trolley or reserve resource. |
ticket_type_desc |
A human readable description of the ticket type if applicable |
price_band |
an array of price bands |
Price bands describe the different levels of pricing that are available within a ticket type. It’s important to note that a price band may not have a long term set price, and as such ticket prices and surcharges might change on a performance to performance basis.
Attribute | Description |
---|---|
price_band_code |
the identifier of the price band, this can be used later in the trolley or reserve resource. |
price_band_desc |
A human readable description of the price band if applicable |
cost_range |
The cost range for this price band. |
The cost range has the following attributes:
Attribute | Description |
---|---|
best_value_offer |
The offer with the highest percentage saving. This is the most commonly used offer cost range. |
max_saving_offer |
The offer with the highest absolute saving. |
max_seatprice |
The per-ticket face value for the highest price (seatprice + surcharge) |
max_surcharge |
The per-ticket booking fee for the highest price (seatprice + surcharge) |
min_cost_offer |
The offer with the lowest cost. |
min_seatprice |
The per-ticket face value for the lowest price (seatprice + surcharge) |
min_surcharge |
The per-ticket booking fee for the lowest price (seatprice + surcharge) |
no_singles_cost_range |
This returns another cost range object that excludes availability with only one consecutive seat available. The prices in this cost range will therefore be the same as or higher than the outer cost range. |
quantity_options |
The ticket quantities that have availability. |
range_currency_code |
The currency code for the cost range - further detail for the currency can be found in the currency_details object, described below. |
top_price_offer |
The offer with the highest cost. This is the least used offer cost range. |
The offer objects contain the following attributes:
Attribute | Description |
---|---|
absolute_saving |
Defined as (full_seatprice + full_surcharge ) - (offer_seatprice + offer_surcharge ). |
full_seatprice |
The non-offer per-ticket face value. |
full_surcharge |
The non-offer per-ticket booking fee. |
offer_seatprice |
The offer per-ticket face value. |
offer_surcharge |
The offer per-ticket booking fee. |
percentage_saving |
Defined as absolute_saving / (full_seatprice + full_surcharge ) * 100. |
The outer object includes a currency_details object containing one currency object (indexed on the currency code) for every currency referenced in the JSON response. Each currency has the following attributes:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Availability details
Availability details are a cached list of the price bands available for an event across all performances. They are cached from previous availability requests made via your username. This data can be useful for example if you wish to display a separate page with pricing detail for all price bands on sale.
Availability details are generated from availability requests made either by end-users or by scheduled processes that Ingresso use to update this data. You should not attempt to make multiple availability requests in order to keep this data up to date - please contact us instead to discuss options
Request
Example request
curl https://api.ticketswitch.com/f13/events_by_id.v1 \
-u "demo:demopass" \
-d "event_id_list=6IF" \
-d "req_avail_details" \
-d "req_avail_details_with_perfs" \
--compressed \
-G
from pyticketickswitch import client
client = Client('demo', 'demopass')
events, meta = client.get_events(['6IF'], availability=True, availability_with_performances=True)
Parameter | Description |
---|---|
req_avail_details |
Returns a list of unique ticket types and price bands that are available for this event across all performances. This parameter is not commonly used. |
req_avail_details_with_perfs |
This will add the list of available performance dates to each avail detail object. Only valid if used alongside req_avail_details |
Response
Example Response
{
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"events_by_id": {
"6IF": {
"event": {
"avail_details": {
"ticket_type": [
{
"price_band": [
{
"avail_detail": [
{
"avail_currency_code": "gbp",
"available_dates": {
"first_yyyymmdd": "20170309",
"last_yyyymmdd": "20170705",
"year_2017": {
"apr_bitmask": 803192702,
"jul_bitmask": 30,
"jun_bitmask": 1065287163,
"mar_bitmask": 2130574080,
"may_bitmask": 2079846367
}
},
"available_weekdays_bitmask": 63,
"seatprice": 47,
"surcharge": 5,
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
}
],
"price_band_code": "A",
"price_band_desc": ""
}
],
"ticket_type_code": "BALCONY",
"ticket_type_desc": "Balcony"
},
{
"price_band": [
{
"avail_detail": [
{
"avail_currency_code": "gbp",
"available_dates": {
"first_yyyymmdd": "20170309",
"last_yyyymmdd": "20170705",
"year_2017": {
"apr_bitmask": 803192702,
"jul_bitmask": 30,
"jun_bitmask": 1065287163,
"mar_bitmask": 2130574080,
"may_bitmask": 2079846367
}
},
"available_weekdays_bitmask": 63,
"seatprice": 35,
"surcharge": 4,
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
}
],
"price_band_code": "A",
"price_band_desc": ""
},
{
"avail_detail": [
{
"avail_currency_code": "gbp",
"available_dates": {
"first_yyyymmdd": "20170309",
"last_yyyymmdd": "20170705",
"year_2017": {
"apr_bitmask": 803192702,
"jul_bitmask": 30,
"jun_bitmask": 1065287163,
"mar_bitmask": 2130574080,
"may_bitmask": 2079846367
}
},
"available_weekdays_bitmask": 63,
"seatprice": 30,
"surcharge": 4,
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
}
],
"price_band_code": "B",
"price_band_desc": ""
},
{
"avail_detail": [
{
"avail_currency_code": "gbp",
"available_dates": {
"first_yyyymmdd": "20170309",
"last_yyyymmdd": "20170705",
"year_2017": {
"apr_bitmask": 803192702,
"jul_bitmask": 30,
"jun_bitmask": 1065287163,
"mar_bitmask": 2130574080,
"may_bitmask": 2079846367
}
},
"available_weekdays_bitmask": 63,
"seatprice": 25,
"surcharge": 4,
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
}
],
"price_band_code": "C",
"price_band_desc": ""
}
],
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle"
},
{
"price_band": [
{
"avail_detail": [
{
"avail_currency_code": "gbp",
"available_dates": {
"first_yyyymmdd": "20170309",
"last_yyyymmdd": "20170705",
"year_2017": {
"apr_bitmask": 803192702,
"jul_bitmask": 30,
"jun_bitmask": 1065287163,
"mar_bitmask": 2130574080,
"may_bitmask": 2079846367
}
},
"available_weekdays_bitmask": 63,
"seatprice": 21,
"surcharge": 3,
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
}
],
"price_band_code": "A",
"price_band_desc": ""
},
{
"avail_detail": [
{
"avail_currency_code": "gbp",
"available_dates": {
"first_yyyymmdd": "20170309",
"last_yyyymmdd": "20170705",
"year_2017": {
"apr_bitmask": 803192702,
"jul_bitmask": 30,
"jun_bitmask": 1065287163,
"mar_bitmask": 2130574080,
"may_bitmask": 2079846367
}
},
"available_weekdays_bitmask": 63,
"seatprice": 18,
"surcharge": 3,
"valid_quantities": [
1,
2,
3
]
}
],
"price_band_code": "B",
"price_band_desc": ""
}
],
"ticket_type_code": "STALLS",
"ticket_type_desc": "Stalls"
}
]
},
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
],
"venue_is_enforced": true
}
}
}
from pyticketswitch.availability import AvailabilityDetails
from pyticketswitch.event import Event
{
'6IF': Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_add_on=False,
is_auto_quantity_add_on=False,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
critic_review_percent=100,
availability_details=[
AvailabilityDetails(
ticket_type='BALCONY',
ticket_type_description='Balcony',
price_band='A',
price_band_description='',
seatprice=47.0,
surcharge=5.0,
full_seatprice=0.0,
full_surcharge=0.0,
percentage_saving=0.0,
absolute_saving=0.0,
currency='gbp',
first_date=datetime.date(2017, 5, 3),
last_date=datetime.date(2017, 8, 30),
),
AvailabilityDetails(
ticket_type='STALLS',
ticket_type_description='Stalls',
price_band='B',
price_band_description='',
seatprice=18.0,
surcharge=3.0,
full_seatprice=0.0,
full_surcharge=0.0,
percentage_saving=0.0,
absolute_saving=0.0,
currency='gbp',
first_date=datetime.date(2017, 5, 3),
last_date=datetime.date(2017, 8, 30),
),
AvailabilityDetails(
ticket_type='STALLS',
ticket_type_description='Stalls',
price_band='A',
price_band_description='',
seatprice=21.0,
surcharge=3.0,
full_seatprice=0.0,
full_surcharge=0.0,
percentage_saving=0.0,
absolute_saving=0.0,
currency='gbp',
first_date=datetime.date(2017, 5, 3),
last_date=datetime.date(2017, 8, 30),
),
AvailabilityDetails(
ticket_type='CIRCLE',
ticket_type_description='Upper circle',
price_band='C',
price_band_description='',
seatprice=25.0,
surcharge=4.0,
full_seatprice=0.0,
full_surcharge=0.0,
percentage_saving=0.0,
absolute_saving=0.0,
currency='gbp',
first_date=datetime.date(2017, 5, 3),
last_date=datetime.date(2017, 8, 30),
),
AvailabilityDetails(
ticket_type='CIRCLE',
ticket_type_description='Upper circle',
price_band='B',
price_band_description='',
seatprice=30.0,
surcharge=4.0,
full_seatprice=0.0,
full_surcharge=0.0,
percentage_saving=0.0,
absolute_saving=0.0,
currency='gbp',
first_date=datetime.date(2017, 5, 3),
last_date=datetime.date(2017, 8, 30),
),
AvailabilityDetails(
ticket_type='CIRCLE',
ticket_type_description='Upper circle',
price_band='A',
price_band_description='',
seatprice=35.0,
surcharge=4.0,
full_seatprice=0.0,
full_surcharge=0.0,
percentage_saving=0.0,
absolute_saving=0.0,
currency='gbp',
first_date=datetime.date(2017, 5, 3),
last_date=datetime.date(2017, 8, 30),
)
],
)
Ticket types describe a part of house or location within the venue.
Attribute | Description |
---|---|
ticket_type_code |
The identifier of the ticket type, this can be used later in the trolley or reserve resource. |
ticket_type_desc |
A human readable description of the price band if applicable. |
price_band |
A list of price bands. |
Price bands describe the different levels of pricing that are available within a ticket type. It’s important to note that a price band may not have a long term set price, and as such ticket prices and surcharges might change on a performance to performance basis.
Attribute | Description |
---|---|
price_band_code |
The identifier of the price band, this can be used later in the trolley or reserve resource. |
price_band_desc |
A human readable description of the price band if applicable. |
avail_details |
A list of the prices in this price band and when they are available. |
The avail details indicate which prices we have seen and when they are
expected to be available. If the req_avail_details_with_perfs
parameter was
included then the availability details will include information on what
performances where available with that price.
Attribute | Description |
---|---|
avail_currency_code |
The currency code for the price - further detail for the currency can be found in the currency_details object, described below. |
available_dates |
first_yyyymmdd and last_yyyymmdd for the range, and year_YYYY includes a bitmask for each month of the year (if, for example, the jan_bitmask is 1959 (i.e. “11110100111”) this means there is availability on the following days of the month only: 1,2,3,6,8,9,10,11). |
available_weekdays_bitmask |
The days of the week where we have seen availability - see the example in the bitmask fields explanation. |
seatprice |
The per-ticket face value. |
surcharge |
The per-ticket booking fee. |
valid_quantities |
An array of available quantities we have seen for this price band. |
The outer object includes a currency_details object containing one currency object (indexed on the currency code) for every currency referenced in the JSON response. Each currency has the following attributes:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Performances
A performance describes an instance of an event, for example the Saturday 21st January 7.30pm showing of The Lion King. This is the case for the majority of our product, however since not all events (and the systems we connect to) are the same, there are some exceptions:
- Some events have performances that do not have a time component - they are valid for the entire day
- Some events have performances with a performance name rather than a time
- Some events do not have performances - they are valid on all dates
- Departure and usage dates
An event is considered live when it has one or more future performances. The API will not return performances that are more than 2 years in the future by calendar date.
There are two performance-related resources:
Performances list: list performances for an event.
Performances by ID: return detail for one or more performances by their ID.
These two resources are described below, followed by detail of the extra parameters that can be passed in to each resource.
Performances list
Definition
GET https://api.ticketswitch.com/f13/performances.v1?event_id={eventid}
This call returns a list of performances for a particular event. The list is paged to avoid large volumes of data being accidentally returned.
Typical use cases:
- Request a list of performances to dynamically populate the calendar on your website
- Request performances on a regular basis (e.g. hourly) to add them to your system. Note that this is not necessary or recommended - performances is one of our faster calls and if you cache the list of performances in your own system pricing and offers can be out of date. This is a particular problem when an offer or price change goes live at a particular time - you then need to worry about refreshing your cache. Our own websites dynamically request performances when a user needs to select on a calendar.
Request
Example request
curl https://api.ticketswitch.com/f13/performances.v1 \
-u "demo:demopass" \
-d "event_id=6IF" \
-d "page_length=10" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
performances, meta = client.list_performances('6IF')
Parameter | Description |
---|---|
event_id |
Identifier of the event you want to see performances for. |
page_length |
Length of a page, default 50. |
page_number |
Page number, default 0, ignored if page_len is not present. |
date_range |
Date range in the form yyyymmdd:yyyymmdd (both are optional) |
These parameters can be passed in to request additional data for each performance, and are described in more detail in the extra parameters section below:
Parameter | Description |
---|---|
req_avail_details |
Returns availability details - a cached list of unique ticket types and price bands available for this performance. This parameter is not commonly used. |
req_avail_detail_discounts |
Adds non standard discounts to availability details Only valid when used alongside req_avail_details |
req_cost_range |
Returns cost ranges - a from price and offer detail for each event. Most partners include this parameter. |
req_cost_range_discounts |
Returns cost range discounts |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. This is the most commonly used offer cost range. |
req_cost_range_details |
Returns a list of unique ticket types and price bands and their cost ranges across all performances. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only 1 consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
Response
Example response
{
"results": {
"has_perf_names": true,
"paging_status": {
"page_length": 10,
"page_number": 0,
"pages_remaining": 10,
"results_remaining": 94,
"total_unpaged_results": 104
},
"performance": [
{
"date_desc": "Thu, 9th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-09T19:30:00Z",
"perf_id": "6IF-A94",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Fri, 10th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-10T19:30:00Z",
"perf_id": "6IF-A95",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Sun, 12th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-12T19:30:00Z",
"perf_id": "6IF-A97",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Mon, 13th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-13T19:30:00Z",
"perf_id": "6IF-A98",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Tue, 14th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-14T19:30:00Z",
"perf_id": "6IF-A99",
"perf_name": "Including back stage pass",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Wed, 15th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-15T19:30:00Z",
"perf_id": "6IF-A9A",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Thu, 16th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-16T19:30:00Z",
"perf_id": "6IF-A9B",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Fri, 17th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-17T19:30:00Z",
"perf_id": "6IF-A9C",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Sun, 19th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-19T19:30:00Z",
"perf_id": "6IF-A9E",
"running_time": 120,
"time_desc": "7.30 PM"
},
{
"date_desc": "Mon, 20th March 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-03-20T19:30:00Z",
"perf_id": "6IF-A9F",
"running_time": 120,
"time_desc": "7.30 PM"
}
]
}
}
from pyticketswitch.performance import Performance
[
Performance(
id='6IF-B0O',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 4, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Thu, 4th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
no_singles_cost_range=None,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0P',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 5, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Fri, 5th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0R',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 7, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Sun, 7th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0S',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 8, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Mon, 8th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0T',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 9, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Tue, 9th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0U',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 10, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Wed, 10th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0V',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 11, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Thu, 11th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0W',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 12, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Fri, 12th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0Y',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 14, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Sun, 14th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B0Z',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 15, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Mon, 15th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
Performance(
id='6IF-B10',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 16, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Tue, 16th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
)
]
Results
Attribute | Description |
---|---|
has_perf_names |
Whether the performances returned have performance names (human readable descriptions of the performance). Performance names are not always present but must be displayed when they are. Performance names are typically used where performances of an event differ significantly in more than just date and time (sometimes the supplier system will not return the time to us in a structured format but it will instead be included as part of the performance name). An example performance with a performance name is 6IF-A5R. |
paging_status |
Information regarding whether the data has been paged. |
performance |
An array of performance objects, described below. |
Paging Status
Attribute | Description |
---|---|
page_length |
The page length used for the response. This will either be the value set with the page_len parameter |
page_number |
The zero-based page number currently displayed. |
pages_remaining |
The number of pages that you need to request after the current page to retrieve all results. |
results_remaining |
The number of results in the remaining pages. |
total_unpaged_results |
The total number of results. |
Performance
Attribute | Description |
---|---|
date_desc |
human readable date description |
event_id |
Unique identifier for the event that this performance is an instance of |
has_pool_seats |
Whether this performance has tickets available from the general pool of tickets. This is ignored by most partners. |
is_ghost |
true when this performance is no longer on sale. When you request performances for an event we will only return performances that are on sale (so is_ghost will always be false ), however it is possible to request performances by ID for a ghost performance. |
is_limited |
Indicates whether the supply of tickets is known to be extremely limited. This is usually taken to be fewer than four remaining, though not all ticket sources provide this information. Where the information is not available the flag will always be set to false |
iso8601_date_and_time |
ISO 8601 date and time |
perf_id |
Unique identifier for the performance |
perf_name |
A human readable description of the performance. Performance names are not always present but must be displayed when they are. Performance names are typically used where performances of an event differ significantly in more than just date and time (sometimes the supplier system will not return the time to us in a structured format but it will instead be included as part of the performance name). Event ID 6IF includes some performances with names. |
running_time |
The length / duration of the performance in minutes |
time_desc |
A human readable time description |
cached_max_seats |
This should not be used. Earlier versions of the documentation implied that it held a meaningful value for the availability, but this is not true, and the attribute was not always present. If you are using it then you should stop, and switch to cost range data instead if you still want cached availability data. For the time being the value will be one million instead of being absent entirely if the data is not available. |
cached_max_seats_is_real |
A boolean indicating whether the data in the previous variable is actually real or not. Can be used whilst migrating away from using it. |
Performances by ID
Definition
GET https://api.ticketswitch.com/f13/performances_by_id.v1?perf_id_list={perfidlist}
This resource is used to return detail for one or more performances by their ID. It returns a dictionary of performances.
If you have a need to request availability for a subset of performances in a
guaranteed fast response time then one way to achieve it is to use this call
with the req_avail_details
parameter - this will return the list of available
price bands from Ingresso’s cached data. Note that the cached data can be out of
date or not present, and doesn’t return seating data, so we do not recommend
this in most cases.
Request
Example request
curl https://api.ticketswitch.com/f13/performances_by_id.v1 \
-u "demo:demopass" \
-d "perf_id_list=6IF-B2E,6IF-B2F" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
performances, meta = client.get_performances(['6IF-B2E', '6IF-B2F'])
Parameter | Description |
---|---|
perf_id_list |
A comma separated list of performance IDs e.g. 6IF-A5R for a single performance; 6IF-A5R,6IF-A5S for multiple performances. |
These parameters can be passed in to request additional data for each performance, and are described in more detail in the extra parameters section below:
Parameter | Description |
---|---|
req_avail_details |
Returns availability details - a cached list of unique ticket types and price bands available for this performance. This parameter is not commonly used. |
req_cost_range |
Returns cost ranges - a from price and offer detail for each event. Most partners include this parameter. |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. This is the most commonly used offer cost range. |
req_cost_range_details |
Returns a list of unique ticket types and price bands and their cost ranges across all performances. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only 1 consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
Response
Example response
{
"performances_by_id": {
"6IF-B2E": {
"date_desc": "Wed, 5th July 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-07-05T19:30:00+01:00",
"perf_id": "6IF-B2E",
"running_time": 120,
"time_desc": "7.30 PM"
},
"6IF-B2F": {
"date_desc": "Thu, 6th July 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-07-06T19:30:00+01:00",
"perf_id": "6IF-B2F",
"running_time": 120,
"time_desc": "7.30 PM"
}
}
}
from pyticketswitch.performance import Performance
{
'6IF-B2E': Performance(
id='6IF-B2E',
event_id='6IF',
date_time=datetime.datetime(2017, 7, 5, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Wed, 5th July 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
'6IF-B2F': Performance(
id='6IF-B2F',
event_id='6IF',
date_time=datetime.datetime(2017, 7, 6, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Thu, 6th July 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
)
}
Attribute | Description |
---|---|
date_desc |
human readable date description |
event_id |
Unique identifier for the event that this performance is an instance of |
has_pool_seats |
Whether this performance has tickets available from the general pool of tickets. This is ignored by most partners. |
is_ghost |
true when this performance is no longer on sale. When you request performances for an event we will only return performances that are on sale (so is_ghost will always be false ), however it is possible to request performances by ID for a ghost performance. |
is_limited |
Indicates whether the supply of tickets is known to be extremely limited. This is usually taken to be fewer than four remaining, though not all ticket sources provide this information. Where the information is not available the flag will always be set to false |
iso8601_date_and_time |
ISO 8601 date and time |
perf_id |
Unique identifier for the performance |
perf_name |
A human readable description of the performance. Performance names are not always present but must be displayed when they are. Performance names are typically used where performances of an event differ significantly in more than just date and time (sometimes the supplier system will not return the time to us in a structured format but it will instead be included as part of the performance name). Event ID 6IF includes some performances with names. |
running_time |
The length / duration of the performance in minutes |
time_desc |
human readable time description |
— Extra parameters —
There are several additional parameters described below that can be provided to return additional data for each performance.
These additional parameters require extra processing to retrieve the requested data, which will slow down the resource, sometimes substantially. They should therefore only be used where necessary.
Cost ranges
Cost ranges are a cached summary of the pricing that has been seen for your username. They are used to retrieve the minimum (or “from”) price for the performance, along with detail of any offers or discounts. They allow you to display a from price and whether there is an offer for each performance, so most partners request cost ranges.
Cost ranges are generated from availability requests made either by end-users or by scheduled processes that Ingresso use to update cost range data. You should not attempt to make multiple availability requests in order to keep this data up to date - please contact us instead to discuss options. Cost ranges are only ever returned as part of a parent object.
Request
Example request
curl https://api.ticketswitch.com/f13/performances_by_id.v1 \
-u "demo:demopass" \
-d "perf_id_list=6L9-M5P" \
-d "req_cost_range" \
-d "req_cost_range_best_value_offer" \
-d "req_cost_range_max_saving_offer" \
-d "req_cost_range_min_cost_offer" \
-d "req_cost_range_top_price_offer" \
-d "req_cost_range_no_singles_data" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
performances, meta = client.get_performances(
performance_ids=['6L9-M4C'],
cost_range=True,
best_value_offer=True,
max_saving_offer=True,
min_cost_offer=True,
top_price_offer=True,
no_singles_data=True,
)
On its own, req_cost_range
will add min and max prices only, however by
adding one of the other 5 parameters below you can receive additional data
(multiple parameters are provided because there can be multiple definitions of
the “best” offer). Most API users request cost ranges.
Parameter | Description |
---|---|
req_cost_range |
Returns cost ranges for each performance. |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. This is the most commonly used offer cost range. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only 1 consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
Response
Example response
{
"currency_details": {
"usd": {
"currency_code": "usd",
"currency_factor": 100,
"currency_number": 840,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "$"
}
},
"performances_by_id": {
"6L9-M2R": {
"cost_range": {
"best_value_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"max_saving_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"max_seatprice": 68,
"max_surcharge": 3,
"min_cost_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"min_seatprice": 68,
"min_surcharge": 3,
"no_singles_cost_range": {
"best_value_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"max_saving_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"max_seatprice": 68,
"max_surcharge": 3,
"min_cost_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"min_seatprice": 68,
"min_surcharge": 3,
"range_currency_code": "usd",
"top_price_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"valid_quantities": [
1,
2,
3,
4
]
},
"range_currency_code": "usd",
"top_price_offer": {
"absolute_saving": 9,
"full_seatprice": 75,
"full_surcharge": 5,
"offer_seatprice": 68,
"offer_surcharge": 3,
"percentage_saving": 11
},
"valid_quantities": [
1,
2,
3,
4
]
},
"date_desc": "Wed, 5th April 2017",
"event_id": "6L9",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-04-05T22:30:00-07:00",
"perf_id": "6L9-M2R",
"running_time": 120,
"time_desc": "10.30 PM"
}
}
}
FIXME: no cost ranges on this performance
from pyticketswitch.performance import Performance
{
'6L9-M2R': Performance(
id='6L9-M2R',
event_id='6L9',
date_time=datetime.datetime(2017, 4, 5, 22, 30, tzinfo=tzoffset(None, -25200)),
date_description='Wed, 5th April 2017',
time_description='10.30 PM',
has_pool_seats=False,
is_limited=False,
cost_range=None,
no_singles_cost_range=None,
is_ghost=True,
name=None,
running_time=None,
availability_details=[
],
)
}
Each performance returned includes a cost_range
object with the following attributes:
Attribute | Description |
---|---|
best_value_offer |
The offer with the highest percentage saving. This is the most commonly used offer cost range. |
max_saving_offer |
The offer with the highest absolute saving. |
max_seatprice |
The per-ticket face value for the highest price (seatprice + surcharge) |
max_surcharge |
The per-ticket booking fee for the highest price (seatprice + surcharge) |
min_cost_offer |
The offer with the lowest cost. |
min_seatprice |
The per-ticket face value for the lowest price (seatprice + surcharge) |
min_surcharge |
The per-ticket booking fee for the lowest price (seatprice + surcharge) |
no_singles_cost_range |
This returns another cost range object that excludes availability with only one consecutive seat available. The prices in this cost range will therefore be the same as or higher than the outer cost range. |
range_currency_code |
The currency code for the cost range - further detail for the currency can be found in the currency_details object, described below. |
top_price_offer |
The offer with the highest cost. This is the least used offer cost range. |
valid_quantities |
An array of ticket quantities with availability. |
The offer objects contain the following attributes:
Attribute | Description |
---|---|
absolute_saving |
Defined as (full_seatprice + full_surcharge ) - (offer_seatprice + offer_surcharge ). |
full_seatprice |
The non-offer per-ticket face value. |
full_surcharge |
The non-offer per-ticket booking fee. |
offer_seatprice |
The offer per-ticket face value. |
offer_surcharge |
The offer per-ticket booking fee. |
percentage_saving |
Defined as absolute_saving / (full_seatprice + full_surcharge ) * 100. |
The outer object includes a currency_details object containing one currency object (indexed on the currency code) for every currency referenced in the JSON response. Each currency has the following attributes:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Availability detail
Availability details are a cached list of the price bands for each performance. They are cached from previous availability requests made via your username. This data can be useful for example if you wish to display a separate page with pricing detail for all price bands on sale.
Availability details are generated from availability requests made either by end-users or by scheduled processes that Ingresso use to update this data. You should not attempt to make multiple availability requests in order to keep this data up to date - please contact us instead to discuss options
Request
Example request
curl https://api.ticketswitch.com/f13/performances_by_id.v1 \
-u "demo:demopass" \
-d "perf_id_list=6L9-M2R" \
-d "req_avail_details" \
--compressed \
-G
from pyticketickswitch import client
client = Client('demo', 'demopass')
performances, meta = client.get_performances(['6L9-M2R'], availability=True)
Parameter | Description |
---|---|
req_avail_details |
Returns a list of unique ticket types and price bands that are available for this performance. This parameter is not commonly used. |
Response
Example Response
{
"currency_details": {
"usd": {
"currency_code": "usd",
"currency_factor": 100,
"currency_number": 840,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "$"
}
},
"performances_by_id": {
"6L9-M2R": {
"avail_details": {
"ticket_type": [
{
"price_band": [
{
"avail_detail": [
{
"absolute_saving": 9,
"avail_currency_code": "usd",
"cached_number_available": 4,
"full_seatprice": 75,
"full_surcharge": 5,
"percentage_saving": 11,
"seatprice": 68,
"surcharge": 3,
"valid_quantities": [
1,
2,
3,
4
]
}
],
"price_band_code": "A",
"price_band_desc": ""
}
],
"ticket_type_code": "PREF",
"ticket_type_desc": "Preferred seating"
}
]
},
"date_desc": "Wed, 5th April 2017",
"event_id": "6L9",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-04-05T22:30:00-07:00",
"perf_id": "6L9-M2R",
"running_time": 120,
"time_desc": "10.30 PM"
}
}
}
{
'6IF-A8K': pyticketswitch.Performance(
id='6IF-A8K',
availabilty_details=[
pyticketswitch.AvailabilityDetails(
ticket_type='BALCONY',
ticket_type_description='Balcony',
price_band='A',
price_band_description='',
seatprice=47.0,
surcharge=0.0,
currency=pyticketswitch.Currency(
code='gbp',
),
valid_quantities=[2, 3, 4, 5, 6, 7],
),
pyticketswitch.AvailabilityDetails(
ticket_type='CIRCLE',
ticket_type_description='Upper circle',
price_band='A',
price_band_description='',
seatprice=35.0,
surcharge=0.0,
currency=pyticketswitch.Currency(
code='gbp',
),
valid_quantities=[2, 3, 4, 5, 6, 7],
),
pyticketswitch.AvailabilityDetails(
ticket_type='CIRCLE',
ticket_type_description='Upper circle',
price_band='B',
price_band_description='',
seatprice=30.0,
surcharge=0.0,
currency=pyticketswitch.Currency(
code='gbp',
),
valid_quantities=[2, 3, 4, 5, 6, 7],
),
pyticketswitch.AvailabilityDetails(
ticket_type='CIRCLE',
ticket_type_description='Upper circle',
price_band='C',
price_band_description='',
seatprice=25.0,
surcharge=0.0,
currency=pyticketswitch.Currency(
code='gbp',
),
valid_quantities=[2, 3, 4, 5, 6, 7],
),
pyticketswitch.AvailabilityDetails(
ticket_type='STALLS',
ticket_type_description='Stalls',
price_band='A',
price_band_description='',
seatprice=21.0,
surcharge=0.0,
currency=pyticketswitch.Currency(
code='gbp',
),
valid_quantities=[2, 3, 4, 5, 6, 7],
),
pyticketswitch.AvailabilityDetails(
ticket_type='STALLS',
ticket_type_description='Stalls',
price_band='B',
price_band_description='',
seatprice=18.0,
surcharge=0.0,
currency=pyticketswitch.Currency(
code='gbp',
),
valid_quantities=[2, 3, 4, 5, 6, 7],
),
],
)
}
Ticket types describe a part of house or location within the venue.
Attribute | Description |
---|---|
price_band |
A list of price bands, object described below. |
ticket_type_code |
The identifier of the ticket type, this can be used later in the trolley or reserve resource. |
ticket_type_desc |
A human readable description of the price band if applicable. |
Price bands describe the different levels of pricing that are available within a ticket type.
Attribute | Description |
---|---|
avail_details |
A list of the prices in this price band and when they are available. |
price_band_code |
The identifier of the price band, this can be used later in the trolley or reserve resource. |
price_band_desc |
A human readable description of the price band if applicable. |
The avail detail indicates what prices we have seen for this performance.
Attribute | Description |
---|---|
absolute_saving |
Defined as (full_seatprice + full_surcharge ) - (seatprice + surcharge ) |
avail_currency_code |
The currency code for the price - further detail for the currency can be found in the currency_details object, described below. |
cached_number_available |
The maximum number of consecutive tickets available. |
full_seatprice |
The per-ticket face value for the non-discounted ticket price. |
full_surcharge |
The per-ticket booking fee for the non-discounted ticket price. |
percentage_saving |
Defined as absolute_saving / (full_seatprice + full_surcharge ) * 100 |
seatprice |
The per-ticket face value. |
surcharge |
The per-ticket booking fee. |
valid_quantities |
An array of available quantities we have seen for this price band. |
The outer object includes a currency_details object containing one currency object (indexed on the currency code) for every currency referenced in the JSON response. Each currency has the following attributes:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Months
GET https://api.ticketswitch.com/f13/months.v1?event_id={eventid}
This resource gives a summary of the availability across calendar months
months
is provided for those who wish to display month-level summary data; for
example listing the available months in tabs above a calendar. This resource can
remove the need to summarise performance-level data in your application.
It is an optional resource that not all partners choose to use.
Example request
curl https://api.ticketswitch.com/f13/months.v1 \
-u "demo:demopass" \
-d "event_id=6IF" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
client.get_months('6IF')
Request
Parameter | Description |
---|---|
event_id |
Identifier of the event to summarise |
These parameters can be passed in to request additional data for each performance, and are described in more detail in the extra parameters section above for performances.
Parameter | Description |
---|---|
req_avail_details |
Returns availability details - a cached list of unique ticket types and price bands available for this event across all performances in the month. This parameter is not commonly used. |
req_cost_range |
Returns cost ranges - a from price and offer detail for each event. Most partners include this parameter. |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. This is the most commonly used offer cost range. |
req_cost_range_details |
Returns a list of unique ticket types and price bands and their cost ranges across all performances. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only 1 consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
Example Response
{
"results": {
"month": [
{
"month": "dec",
"month_dates_bitmask": 1065254912,
"month_desc": "December",
"month_weekdays_bitmask": 63,
"year": 2016
},
{
"month": "jan",
"month_dates_bitmask": 2012209087,
"month_desc": "January",
"month_weekdays_bitmask": 63,
"year": 2017
},
{
"month": "feb",
"month_dates_bitmask": 251526135,
"month_desc": "February",
"month_weekdays_bitmask": 63,
"year": 2017
},
{
"month": "mar",
"month_dates_bitmask": 2130574327,
"month_desc": "March",
"month_weekdays_bitmask": 63,
"year": 2017
},
{
"month": "apr",
"month_dates_bitmask": 16254,
"month_desc": "April",
"month_weekdays_bitmask": 63,
"year": 2017
}
]
}
}
from pyticketswitch.month import Month
[
Month(
month=5,
year=2017,
description='May',
_dates_bitmask=2079846360,
_weekday_bitmask=63,
),
Month(
month=6,
year=2017,
description='June',
_dates_bitmask=1065287163,
_weekday_bitmask=63,
),
Month(
month=7,
year=2017,
description='July',
_dates_bitmask=1876934526,
_weekday_bitmask=63,
),
Month(
month=8,
year=2017,
description='August',
_dates_bitmask=2113665007,
_weekday_bitmask=63,
)
]
Response
Attribute | Description |
---|---|
month |
Three-character code for the month. |
month_dates_bitmask |
Indicates which dates in the month have valid performances. |
month_desc |
Full month name. |
month_weekdays_bitmask |
Indicates which days of the week have valid performances for the month - see the example in the bitmask fields explanation. |
year |
The year. |
Availability
Definition
GET https://api.ticketswitch.com/f13/availability.v1?perf_id={performanceid}
availability
lists the tickets that are currently available for a performance.
In most cases the availability provided is in real time (although we do
sometimes cache availability) and represents the tickets available
at the time the request was made. There is therefore no guarantee that the
tickets will still be available to purchase at some future time. Tickets are
only guaranteed to be held after you reserve tickets.
We have a single availability resource that will return best available tickets by default. This resource is described first and is important to read. We then describe optional parameters that can be passed to request individual seats, example seats, commission, and discounts.
You should only send availability requests as a direct result of customers requesting availability. You should not automatically request availability to populate caches. Performances with availability detail is provided for this type of use case. If this doesn’t fit what you are trying to do contact us
Important: Ingresso offer an interactive seat map widget called Feather that can be embedded in your website, saving you development effort. This is an alternative to requesting availability via the API and displaying it yourself.
Availability
Request
Example request
curl https://api.ticketswitch.com/f13/availability.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B5P" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
ticket_types, meta = client.get_availability('6IF-B5P')
Attribute | Description |
---|---|
perf_id |
The identifier of the performance that you wish to request availability for. |
no_of_seats |
Optional. The number of tickets the customer would like. If this is specified then seated availability will only be shown for price bands with at least that many contiguous seats available. |
promo_code |
Optional. If the supplier supports a promo code this can be specified to unlock discounted pricing. This feature is not commonly used with partners. |
These parameters can be included to request additional data:
Parameter | Description |
---|---|
add_discounts |
discounts |
add_example_seats |
Include to retrieve example seats. These can be displayed alongside the ticket options when presenting availability to customers. The inclusion of this parameter does not guarantee that example seats data will be returned - this also depends on (a) whether the event is seated and (b) whether the supplier system returns seats at availability time. |
add_seat_blocks |
Include to retrieve individual seats (if, for example, you wish to offer seat selection to your customer). The inclusion of this parameter does not guarantee that individual seat data will be returned - this also depends on (a) whether the event is seated and (b) whether the supplier system supports seat selection. |
req_predicted_commission |
Include to retrieve commission data. For most partners this will include predicted_user_commission only (the predicted amount you earn per ticket). Some partners will also see predicted_gross_commission , which is the total commission available to be shared between Ingresso and our partner. By default you will see predicted_user_commission only - if you think you need to see predicted_gross_commission as well then please get in touch. |
Response
Example response
{
"availability": {
"ticket_type": [
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 35,
"non_offer_sale_surcharge": 4,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 35,
"sale_surcharge": 4
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 30,
"non_offer_sale_surcharge": 4,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 30,
"sale_surcharge": 4
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 25,
"non_offer_sale_surcharge": 4,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "C/pool",
"sale_seatprice": 25,
"sale_surcharge": 4
}
],
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle"
},
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 21,
"non_offer_sale_surcharge": 3,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 21,
"sale_surcharge": 3
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 18,
"non_offer_sale_surcharge": 3,
"number_available": 3,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 18,
"sale_surcharge": 3
}
],
"ticket_type_code": "STALLS",
"ticket_type_desc": "Stalls"
},
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 47,
"non_offer_sale_surcharge": 5,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 47,
"sale_surcharge": 5
}
],
"ticket_type_code": "BALCONY",
"ticket_type_desc": "Balcony"
}
]
},
"backend_is_broken": false,
"backend_is_down": false,
"backend_throttle_failed": false,
"contiguous_seat_selection_only": true,
"currency_code": "gbp",
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"max_bundle_size": 1,
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
}
from pyticketswitch.price_band import PriceBand
from pyticketswitch.discount import Discount
from pyticketswitch.ticket_type import TicketType
[
TicketType(
code='CIRCLE',
description='Upper circle',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=35.0,
surcharge=4.0,
non_offer_seatprice=35.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='B/pool',
is_offer=False,
seatprice=30.0,
surcharge=4.0,
non_offer_seatprice=30.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
),
PriceBand(
code='C/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='C/pool',
is_offer=False,
seatprice=25.0,
surcharge=4.0,
non_offer_seatprice=25.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
)
],
),
TicketType(
code='STALLS',
description='Stalls',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=21.0,
surcharge=3.0,
non_offer_seatprice=21.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='B/pool',
is_offer=False,
seatprice=18.0,
surcharge=3.0,
non_offer_seatprice=18.0,
non_offer_surcharge=3.0,
availability=3,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
)
],
),
TicketType(
code='BALCONY',
description='Balcony',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=47.0,
surcharge=5.0,
non_offer_seatprice=47.0,
non_offer_surcharge=5.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
)
],
)
]
Availability is divided into a set of ticket types, and each ticket type is subdivided into price bands. If you request individual seats for a seated event each price band includes seat blocks for the contiguous seats. The structure of the availability data returned is therefore:
This example response is for best available - following this there is an example response that includes seats.
Top-level attributes:
Attribute | Description |
---|---|
availability |
Contains ticket types, object described below. |
backend_is_broken |
If we see an unexpected error from the supplier system (for example a 500 error) we mark the system as “broken” for a period of time afterwards (the time can vary from nothing to 2 minutes). During this period of time this attribute will be true and we will return empty availability. This is an exceptional circumstance; to check if there is currently a supplier system issue you can check our status page. |
backend_is_down |
When true the supplier system cannot be contacted for some reason, for example they are having technical problems or scheduled maintenance. The response will include empty availability in this case. This is an exceptional circumstance; to check if there is currently a supplier system issue you can check our status page. |
backend_throttle_failed |
We allow a certain number of simultaneous requests to hit a supplier system and queue requests when the limit is reached. When this attribute is true your request has been sitting in our queue for a long time and we have timed out the request. This is an exceptional circumstance. |
contiguous_seat_selection_only |
If you have requested individual seats a value of true indicates that you can only select consecutive seats. false indicates that you can select seats without restriction within a single ticket type and price band. In most cases this will be false . If you would like to allow your customers to select seats without restriction across price bands and ticket types, you need to add multiple orders to a trolley, one order for each price band. However there are currently some restrictions enforced so if you want to do this you will need to contact us first |
currency_code |
The currency code for the availability. |
currency_details |
Further detail for the currency, object described below. |
max_bundle_size |
The maximum number of orders that can be added to a trolley for this event. Useful for buying tickets from different ticket types and price bands. If this isn’t present then there is no max bundle size. |
valid_quantities |
An array of valid quantities. |
The currency_details object containing one currency object (indexed on the currency code) for every currency referenced in the JSON response. Each currency has the following attributes:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Ticket type attributes:
Attribute | Description |
---|---|
price_band |
Object described below. |
ticket_type_code |
The unique identifier for the ticket type. For attractions this can refer to variations such as General Admission or Fast Track, and there is often only only. For seated events this normally refers to a part of house / seating area such as Grand Circle. |
ticket_type_desc |
The description for the ticket type. This should be displayed to the customer (if you are offering seat selection to your customer then you would typically hard-code the description when drawing a seating plan). |
Price band attributes:
Attribute | Description |
---|---|
absolute_saving |
Defined as (non_offer_sale_seatprice + non_offer_sale_surcharge ) - (sale_seatprice + sale_surcharge ) |
allows_leaving_single_seats |
In most cases this is always . When set to never , the supplier ticketing system does not allow us to leave single seats (which are difficult to sell). If you attempt to reserve when leaving a single seat the reserve will fail, so you should prevent your customer from making a selection that leaves a single seat. The other possible value is if_necessary : reservations will succeed if there is no other possible seat selection with the number of desired tickets that would not also leave a single seat (e.g. two tickets are requested and all available seat blocks are of size 3 or smaller). |
discount_code |
The unique identifier of the default discount. Each price band has a default discount, but additional discounts can be requested for a price band with list discounts. |
discount_desc |
The description of the default discount. We recommend to present this text to customers when is_offer is true to describe the offer. |
is_offer |
true if the ticket price is discounted below the full price, i.e. if absolute_saving is greater than zero. |
non_offer_sale_seatprice |
The per-ticket price for full-priced tickets. This will be the face value price when the market has such a concept (for example the London theatre market has this concept, but some New York theatre shows do not). This is the same as the sale_seatprice when the price band is not discounted. |
non_offer_sale_surcharge |
The per-ticket booking fee for full-priced tickets. To determine the total ticket price you must add together the non_offer_sale_seatprice and the non_offer_sale_surcharge . |
number_available |
This is the maximum number of contiguous seats that can be purchased. This applies to best available only - if you are using seat selection and contiguous_seat_selection_only is false it is possible to select above this number. |
percentage_saving |
Defined as absolute_saving / (non_offer_sale_seatprice + non_offer_sale_surcharge ) * 100 |
price_band_code |
The code for the price band, for example “C/pool”. To uniquely identify a price band you should take the combination of ticket_type_code and price_band_code . The price band code is generally made up of the code from the underlying supplier system, e.g. “C”, followed by a “/” separator then “pool” or “alloc”, indicating whether the price band is taken from the general pool of tickets or is from a ring-fenced allocation. Integrating partners should just work with the full price_band_code, ignoring the constituent parts. |
price_band_desc |
The description for the price band. This will often not be present (not all supplier ticketing systems provide it) but when it is present it should be displayed to the customer. |
sale_seatprice |
The per-ticket price. This will be the face value price when the market has such a concept (for example the London theatre market has this concept, but some New York theatre shows do not). This is the same as the non_offer_sale_seatprice when the price band is not discounted. |
sale_surcharge |
The per-ticket booking fee. To determine the total ticket price you must add together the sale_seatprice and the sale_surcharge . |
— Optional Parameters —
There are several additional parameters described below that can be provided to return additional availability data.
These additional parameters require extra processing to retrieve the requested data, which will slow down the resource, sometimes substantially. They should therefore only be used where necessary.
Individual Seats
The Ingresso API can return a list of all available seats, allowing you to give
your customers choice rather than forcing them to take the best available
seats. If you have included add_seat_blocks
in your request, the event
is seated, and the supplier system supports seat selection, then we will return
seat blocks containing seats. You can check for the presence of the seat blocks
to determine whether you can offer seat selection to your customer.
Note: Ingresso offer an interactive seat map widget called Feather that can be embedded in your website, saving you development effort. This is an alternative to requesting individual seats via the API and displaying them to customers yourself.
Request
Example request
curl https://api.ticketswitch.com/f13/availability.v1 \
-u "demo:demopass" \
-d "perf_id=7AB-5" \
-d "add_seat_blocks" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
ticket_types, meta = client.get_availability('7AB-5', seat_blocks=True)
Parameter | Description |
---|---|
add_seat_blocks |
Include to retrieve individual seats (if, for example, you wish to offer seat selection to your customer). The inclusion of this parameter does not guarantee that individual seat data will be returned - this also depends on (a) whether the event is seated and (b) whether the supplier system supports seat selection. |
Response
Example response
{
"availability": {
"ticket_type": [
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"free_seat_blocks": {
"blocks_by_row": {
"A": [
[
"A1",
"A2",
"A3",
"A4",
"A5",
"A6",
"A7",
"A8",
"A9",
"A10"
]
],
"B": [
[
"B2",
"B3",
"B4",
"B5",
"B6",
"B7",
"B8",
"B9"
]
]
},
"restricted_view_seats": [
"A1",
"A2",
"A10"
],
"seats_by_text_message": {
"Great seat": [
"A6"
]
},
"separators_by_row": {
"A": "",
"B": ""
}
},
"is_offer": false,
"non_offer_sale_seatprice": 50,
"non_offer_sale_surcharge": 5,
"number_available": 4,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 50,
"sale_surcharge": 5
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"free_seat_blocks": {
"blocks_by_row": {
"C": [
[
"C3",
"C4",
"C5",
"C6"
]
],
"D": [
[
"D2",
"D3",
"D4",
"D5",
"D6",
"D7"
]
]
},
"restricted_view_seats": [
"C5",
"C6"
],
"seats_by_text_message": {
"Haunted seat": [
"C6"
]
},
"separators_by_row": {
"C": "",
"D": ""
}
},
"is_offer": false,
"non_offer_sale_seatprice": 40,
"non_offer_sale_surcharge": 5,
"number_available": 4,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 40,
"sale_surcharge": 5
}
],
"ticket_type_code": "STALLS",
"ticket_type_desc": "Stalls"
},
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"free_seat_blocks": {
"blocks_by_row": {
"E": [
[
"E4",
"E5"
],
[
"E7",
"E8",
"E9"
]
],
"F": [
[
"F1",
"F2",
"F3"
]
]
},
"restricted_view_seats": [],
"seats_by_text_message": {},
"separators_by_row": {
"E": "",
"F": ""
}
},
"is_offer": false,
"non_offer_sale_seatprice": 35,
"non_offer_sale_surcharge": 5,
"number_available": 4,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 35,
"sale_surcharge": 5
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"free_seat_blocks": {
"blocks_by_row": {
"G": [
[
"G7",
"G8",
"G9",
"G10"
]
],
"H": [
[
"H1",
"H2",
"H3",
"H4"
],
[
"H7",
"H8",
"H9",
"H10"
]
]
},
"restricted_view_seats": [],
"seats_by_text_message": {},
"separators_by_row": {
"G": "",
"H": ""
}
},
"is_offer": false,
"non_offer_sale_seatprice": 30,
"non_offer_sale_surcharge": 5,
"number_available": 4,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 30,
"sale_surcharge": 5
}
],
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Dress Circle"
}
]
},
"backend_is_broken": false,
"backend_is_down": false,
"backend_throttle_failed": false,
"contiguous_seat_selection_only": false,
"currency_code": "gbp",
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"valid_quantities": [
1,
2,
3,
4
]
}
from pyticketswitch.discount import Discount
from pyticketswitch.ticket_type import TicketType
from pyticketswitch.seat import Seat
from pyticketswitch.seat import SeatBlock
from pyticketswitch.price_band import PriceBand
[
TicketType(
code='STALLS',
description='Stalls',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='NORMAL',
description='Regular Ticket',
price_band_code='A/pool',
is_offer=False,
seatprice=50.0,
surcharge=5.0,
non_offer_seatprice=50.0,
non_offer_surcharge=5.0,
availability=4,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
seat_blocks=[
SeatBlock(
length=10,
seats=[
Seat(
id='A1',
column='1',
row='A',
separator='',
is_restricted=True,
seat_text='',
),
Seat(
id='A2',
column='2',
row='A',
separator='',
is_restricted=True,
seat_text='',
),
Seat(
id='A3',
column='3',
row='A',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='A4',
column='4',
row='A',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='A5',
column='5',
row='A',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='A6',
column='6',
row='A',
separator='',
is_restricted=False,
seat_text='Great seat',
),
Seat(
id='A7',
column='7',
row='A',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='A8',
column='8',
row='A',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='A9',
column='9',
row='A',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='A10',
column='10',
row='A',
separator='',
is_restricted=True,
seat_text='',
)
],
),
SeatBlock(
length=8,
seats=[
Seat(
id='B2',
column='2',
row='B',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='B3',
column='3',
row='B',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='B4',
column='4',
row='B',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='B5',
column='5',
row='B',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='B6',
column='6',
row='B',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='B7',
column='7',
row='B',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='B8',
column='8',
row='B',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='B9',
column='9',
row='B',
separator='',
is_restricted=False,
seat_text='',
)
],
)
],
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='NORMAL',
description='Regular Ticket',
price_band_code='B/pool',
is_offer=False,
seatprice=40.0,
surcharge=5.0,
non_offer_seatprice=40.0,
non_offer_surcharge=5.0,
availability=4,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
seat_blocks=[
SeatBlock(
length=4,
seats=[
Seat(
id='C3',
column='3',
row='C',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='C4',
column='4',
row='C',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='C5',
column='5',
row='C',
separator='',
is_restricted=True,
seat_text='',
),
Seat(
id='C6',
column='6',
row='C',
separator='',
is_restricted=True,
seat_text='Haunted seat',
)
],
),
SeatBlock(
length=6,
seats=[
Seat(
id='D2',
column='2',
row='D',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='D3',
column='3',
row='D',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='D4',
column='4',
row='D',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='D5',
column='5',
row='D',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='D6',
column='6',
row='D',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='D7',
column='7',
row='D',
separator='',
is_restricted=False,
seat_text='',
)
],
)
],
)
],
),
TicketType(
code='CIRCLE',
description='Dress Circle',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='NORMAL',
description='Regular Ticket',
price_band_code='A/pool',
is_offer=False,
seatprice=35.0,
surcharge=5.0,
non_offer_seatprice=35.0,
non_offer_surcharge=5.0,
availability=4,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
seat_blocks=[
SeatBlock(
length=2,
seats=[
Seat(
id='E4',
column='4',
row='E',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='E5',
column='5',
row='E',
separator='',
is_restricted=False,
seat_text='',
)
],
),
SeatBlock(
length=3,
seats=[
Seat(
id='E7',
column='7',
row='E',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='E8',
column='8',
row='E',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='E9',
column='9',
row='E',
separator='',
is_restricted=False,
seat_text='',
)
],
),
SeatBlock(
length=3,
seats=[
Seat(
id='F1',
column='1',
row='F',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='F2',
column='2',
row='F',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='F3',
column='3',
row='F',
separator='',
is_restricted=False,
seat_text='',
)
],
)
],
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='NORMAL',
description='Regular Ticket',
price_band_code='B/pool',
is_offer=False,
seatprice=30.0,
surcharge=5.0,
non_offer_seatprice=30.0,
non_offer_surcharge=5.0,
availability=4,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
seat_blocks=[
SeatBlock(
length=4,
seats=[
Seat(
id='G7',
column='7',
row='G',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='G8',
column='8',
row='G',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='G9',
column='9',
row='G',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='G10',
column='10',
row='G',
separator='',
is_restricted=False,
seat_text='',
)
],
),
SeatBlock(
length=4,
seats=[
Seat(
id='H1',
column='1',
row='H',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='H2',
column='2',
row='H',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='H3',
column='3',
row='H',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='H4',
column='4',
row='H',
separator='',
is_restricted=False,
seat_text='',
)
],
),
SeatBlock(
length=4,
seats=[
Seat(
id='H7',
column='7',
row='H',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='H8',
column='8',
row='H',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='H9',
column='9',
row='H',
separator='',
is_restricted=False,
seat_text='',
),
Seat(
id='H10',
column='10',
row='H',
separator='',
is_restricted=False,
seat_text='',
)
],
)
],
)
],
)
]
The response includes the following attributes in the free_seat_blocks
:
Attribute | Description |
---|---|
blocks_by_row |
A list of the rows that contain seats. The row identifier is the key and the value is an array of contiguous seat blocks within that row. Within each contiguous seat block there is an array of seat IDs. These seat IDs all begin with the row identifier, and include the column identifier. The IDs should be displayed to the customer. Note that when contiguous_seat_selection_only = true then you can only reserve seats within a single seat block, and only in a consecutive order in the array. In most cases contiguous_seat_selection_only = false and you can select any seats from free_seat_blocks . |
restricted_view_seats |
A list of seat IDs that are classified as having a restricted view. You must indicate this to your customer before they purchase tickets. Note that it is possible for seats to be included in this array but to not have a seat message. Your application should still display a message to the customer in this case. |
seats_by_text_message |
A list of seat messages. The key is the seat message, and the value is an array of seat IDs that the message applies to. When you see a seat message you must display this to your customer. |
separators_by_row |
The row identifier is the key, the value is a separator. Separators are between the row ID and the column ID, for example seat ID A.10 has a separator of . , a row ID of A and a column ID of 10 . In most cases there is no separator, which is represented by an empty string. |
Example Seats
Example seats can be requested and displayed alongside the list of available ticket types and price bands. This is a simpler option to show seats to your customer alongside the list of price bands without needing to request individual seats and do the work to display them on a seating plan or similar. If you plan to display individual seats then there is no need to also request example seats.
Request
Example request
curl https://api.ticketswitch.com/f13/availability.v1 \
-u "demo:demopass" \
-d "perf_id=7AB-5" \
-d "no_of_seats=3" \
-d "add_example_seats" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
ticket_types, meta = client.get_availability('7AB-5', example_seats=True)
Parameter | Description |
---|---|
add_example_seats |
Include to retrieve example seats. These can be displayed alongside the ticket options when presenting availability to customers. The inclusion of this parameter does not guarantee that example seats data will be returned - this also depends on (a) whether the event is seated and (b) whether the supplier system returns seats at availability time. |
Response
Example response
{
"availability": {
"ticket_type": [
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"is_offer": false,
"non_offer_sale_seatprice": 50,
"non_offer_sale_surcharge": 5,
"number_available": 4,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 50,
"sale_surcharge": 5
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"is_offer": false,
"non_offer_sale_seatprice": 40,
"non_offer_sale_surcharge": 5,
"number_available": 4,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 40,
"sale_surcharge": 5
}
],
"ticket_type_code": "STALLS",
"ticket_type_desc": "Stalls"
},
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"example_seats": [
{
"col_id": "1",
"full_id": "F1",
"is_restricted_view": false,
"row_id": "F"
},
{
"col_id": "2",
"full_id": "F2",
"is_restricted_view": false,
"row_id": "F"
}
],
"example_seats_are_real": false,
"is_offer": false,
"non_offer_sale_seatprice": 35,
"non_offer_sale_surcharge": 5,
"number_available": 4,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 35,
"sale_surcharge": 5
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"is_offer": false,
"non_offer_sale_seatprice": 30,
"non_offer_sale_surcharge": 5,
"number_available": 4,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 30,
"sale_surcharge": 5
}
],
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Dress Circle"
}
]
},
"backend_is_broken": false,
"backend_is_down": false,
"backend_throttle_failed": false,
"contiguous_seat_selection_only": false,
"currency_code": "gbp",
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"valid_quantities": [
1,
2,
3,
4
]
}
from pyticketswitch.price_band import PriceBand
from pyticketswitch.discount import Discount
from pyticketswitch.ticket_type import TicketType
from pyticketswitch.seat import Seat
[
TicketType(
code='STALLS',
description='Stalls',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='NORMAL',
description='Regular Ticket',
price_band_code='A/pool',
is_offer=False,
seatprice=50.0,
surcharge=5.0,
non_offer_seatprice=50.0,
non_offer_surcharge=5.0,
availability=4,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats=[
Seat(
id='B2',
column='2',
row='B',
separator='',
is_restricted=False,
),
Seat(
id='B3',
column='3',
row='B',
separator='',
is_restricted=False,
)
],
example_seats_are_real=False,
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='NORMAL',
description='Regular Ticket',
price_band_code='B/pool',
is_offer=False,
seatprice=40.0,
surcharge=5.0,
non_offer_seatprice=40.0,
non_offer_surcharge=5.0,
availability=4,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
)
],
),
TicketType(
code='CIRCLE',
description='Dress Circle',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='NORMAL',
description='Regular Ticket',
price_band_code='A/pool',
is_offer=False,
seatprice=35.0,
surcharge=5.0,
non_offer_seatprice=35.0,
non_offer_surcharge=5.0,
availability=4,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='NORMAL',
description='Regular Ticket',
price_band_code='B/pool',
is_offer=False,
seatprice=30.0,
surcharge=5.0,
non_offer_seatprice=30.0,
non_offer_surcharge=5.0,
availability=4,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
)
],
)
]
If the event supports example seats the response includes several attributes in
example_seats
.
Attribute | Description |
---|---|
example_seats_are_real |
If true the example seats are taken from a list of available seats, and they are the seats the customer is likely to receive when they reserve tickets. This is the most common scenario. If false the example seats are taken from previous reservations and are therefore less reliable. |
id_details |
The description of an individual seat. |
id_details.col_id |
The column identifier, normally a number. |
id_details.full_id |
The unique identifier for the seat. |
id_details.is_restricted_view |
true if the seat is marked as having a restricted view. |
id_details.row_id |
The row identifier, normally a letter. |
id_details.seat_subdata |
Ignore - this will be removed soon. |
id_details.seat_text |
(Optional) A description of the seat that should be displayed to the customer. If the seat has a restricted view this text will normally be present to describe the restriction in more detail, but it should be displayed in all cases. |
id_details.seat_text_code |
Ignore - this will be removed soon. |
id_details.separator |
Sometimes a seat ID can include a separator character such as . , e.g. A.23 . |
Commission
Some partners wish to view the predicted commission they will earn on each ticket up front, before the sale is made. This could be to support agents that want to know what they will earn, or to support custom repricing.
Availability will return the predicted per ticket commission you will earn. If you
subtract commission from the total ticket price (sale_seatprice
+
sale_surcharge
) you have the net price of the ticket.
There are important caveats to note:
The price and commission is not guaranteed until tickets are reserved. Ingresso do not store the commission values returned in this availability request so we cannot refer to it later. Some suppliers have rules where the price will change after tickets are reserved (for example lowering the price to a family rate when 2 adults and 2 children are selected) - that would likely also affect commission. Similarly, the number of tickets can impact the commission but the number of tickets is normally unknown when requesting availability. It is also possible but unlikely for Ingresso’s commission configuration to change between you requesting availability and reserving. For these reasons commission values are marked as “predicted”.
It is possible for the commission currency to be different to the selling currency, since the commission currency usually relates to the supplier while the selling currency is targeted at the end customer. When the currencies are different you can’t simply subtract commission from total ticket price.
Request
Example request
curl https://api.ticketswitch.com/f13/availability.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B5P" \
-d "req_predicted_commission" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
ticket_types, meta = client.get_availability('6IF-B5P', user_commission=True)
Parameter | Description |
---|---|
req_predicted_commission |
Include to retrieve commission data. For most partners this will include predicted_user_commission only (the predicted amount you earn per ticket). Some partners will also see predicted_gross_commission , which is the total commission available to be shared between Ingresso and our partner. By default you will see predicted_user_commission only - if you think you need to see predicted_gross_commission as well then please get in touch. |
Response
Example response
{
"availability": {
"ticket_type": [
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"predicted_gross_commission": {
"amount_excluding_vat": 4.88,
"amount_including_vat": 5.85,
"commission_currency_code": "gbp"
},
"is_offer": false,
"non_offer_sale_seatprice": 35,
"non_offer_sale_surcharge": 4,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 35,
"sale_surcharge": 4,
"predicted_user_commission": {
"amount_excluding_vat": 2.19,
"amount_including_vat": 2.63,
"commission_currency_code": "gbp"
}
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"predicted_gross_commission": {
"amount_excluding_vat": 4.25,
"amount_including_vat": 5.1,
"commission_currency_code": "gbp"
},
"is_offer": false,
"non_offer_sale_seatprice": 30,
"non_offer_sale_surcharge": 4,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 30,
"sale_surcharge": 4,
"predicted_user_commission": {
"amount_excluding_vat": 1.91,
"amount_including_vat": 2.3,
"commission_currency_code": "gbp"
}
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"predicted_gross_commission": {
"amount_excluding_vat": 3.63,
"amount_including_vat": 4.35,
"commission_currency_code": "gbp"
},
"is_offer": false,
"non_offer_sale_seatprice": 25,
"non_offer_sale_surcharge": 4,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "C/pool",
"sale_seatprice": 25,
"sale_surcharge": 4,
"predicted_user_commission": {
"amount_excluding_vat": 1.63,
"amount_including_vat": 1.96,
"commission_currency_code": "gbp"
}
}
],
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle"
},
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"predicted_gross_commission": {
"amount_excluding_vat": 3,
"amount_including_vat": 3.6,
"commission_currency_code": "gbp"
},
"is_offer": false,
"non_offer_sale_seatprice": 21,
"non_offer_sale_surcharge": 3,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 21,
"sale_surcharge": 3,
"predicted_user_commission": {
"amount_excluding_vat": 1.35,
"amount_including_vat": 1.62,
"commission_currency_code": "gbp"
}
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"predicted_gross_commission": {
"amount_excluding_vat": 2.63,
"amount_including_vat": 3.15,
"commission_currency_code": "gbp"
},
"is_offer": false,
"non_offer_sale_seatprice": 18,
"non_offer_sale_surcharge": 3,
"number_available": 3,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 18,
"sale_surcharge": 3,
"predicted_user_commission": {
"amount_excluding_vat": 1.18,
"amount_including_vat": 1.42,
"commission_currency_code": "gbp"
}
}
],
"ticket_type_code": "STALLS",
"ticket_type_desc": "Stalls"
},
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"predicted_gross_commission": {
"amount_excluding_vat": 6.5,
"amount_including_vat": 7.8,
"commission_currency_code": "gbp"
},
"is_offer": false,
"non_offer_sale_seatprice": 47,
"non_offer_sale_surcharge": 5,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 47,
"sale_surcharge": 5,
"predicted_user_commission": {
"amount_excluding_vat": 2.93,
"amount_including_vat": 3.51,
"commission_currency_code": "gbp"
}
}
],
"ticket_type_code": "BALCONY",
"ticket_type_desc": "Balcony"
}
]
},
"backend_is_broken": false,
"backend_is_down": false,
"backend_throttle_failed": false,
"contiguous_seat_selection_only": true,
"currency_code": "gbp",
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
}
from pyticketswitch.commission import Commission
from pyticketswitch.ticket_type import TicketType
from pyticketswitch.discount import Discount
from pyticketswitch.price_band import PriceBand
[
TicketType(
code='CIRCLE',
description='Upper circle',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=35.0,
surcharge=4.0,
non_offer_seatprice=35.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
user_commission=Commission(
including_vat=2.63,
excluding_vat=2.19,
currency_code='gbp',
),
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='B/pool',
is_offer=False,
seatprice=30.0,
surcharge=4.0,
non_offer_seatprice=30.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
user_commission=Commission(
including_vat=2.3,
excluding_vat=1.91,
currency_code='gbp',
),
),
PriceBand(
code='C/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='C/pool',
is_offer=False,
seatprice=25.0,
surcharge=4.0,
non_offer_seatprice=25.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
user_commission=Commission(
including_vat=1.96,
excluding_vat=1.63,
currency_code='gbp',
),
)
],
),
TicketType(
code='STALLS',
description='Stalls',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=21.0,
surcharge=3.0,
non_offer_seatprice=21.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
user_commission=Commission(
including_vat=1.62,
excluding_vat=1.35,
currency_code='gbp',
),
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='B/pool',
is_offer=False,
seatprice=18.0,
surcharge=3.0,
non_offer_seatprice=18.0,
non_offer_surcharge=3.0,
availability=3,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
user_commission=Commission(
including_vat=1.42,
excluding_vat=1.18,
currency_code='gbp',
),
)
],
),
TicketType(
code='BALCONY',
description='Balcony',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=47.0,
surcharge=5.0,
non_offer_seatprice=47.0,
non_offer_surcharge=5.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
user_commission=Commission(
including_vat=3.51,
excluding_vat=2.93,
currency_code='gbp',
),
)
],
)
]
The response includes several attributes within the predicted_user_commission
dictionary. Some partners will also see predicted_gross_commission
which includes the
same attributes.
Attribute | Description |
---|---|
amount_excluding_vat |
The predicted commission you will earn per ticket, excluding sales tax. |
amount_including_vat |
The predicted commission you will earn per ticket, including sales tax. |
commission_currency_code |
The commission currency (note that this can be different to the currency of the price paid by the customer). |
Add Discounts
A discount
represents a price type or concession that is available for a set
of available tickets.
Request
Example request
curl https://api.ticketswitch.com/f13/availability.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B5P" \
-d "add_discounts" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
ticket_types, meta = client.get_availability('6IF-B5P', discounts=True)
Parameter | Description |
---|---|
add_discounts |
Response
Example response - including seat listing
{
"availability": {
"ticket_type": [
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 35,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"possible_discounts": {
"discount": [
{
"absolute_saving": 0,
"discount_code": "ADULT",
"discount_desc": "Adult standard",
"is_offer": false,
"non_offer_sale_seatprice": 35,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 35,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "CHILD",
"discount_desc": "Child rate",
"is_offer": false,
"non_offer_sale_seatprice": 18,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 18,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "STUDENT",
"discount_desc": "Student rate",
"is_offer": false,
"non_offer_sale_seatprice": 26,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 26,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "OAP",
"discount_desc": "Senior citizen rate",
"is_offer": false,
"non_offer_sale_seatprice": 28,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 28,
"sale_surcharge": 0
}
]
},
"price_band_code": "A/pool",
"sale_seatprice": 35,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 30,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"possible_discounts": {
"discount": [
{
"absolute_saving": 0,
"discount_code": "ADULT",
"discount_desc": "Adult standard",
"is_offer": false,
"non_offer_sale_seatprice": 30,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 30,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "CHILD",
"discount_desc": "Child rate",
"is_offer": false,
"non_offer_sale_seatprice": 15,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 15,
"sale_surcharge": 0
}
]
},
"price_band_code": "B/pool",
"sale_seatprice": 30,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 25,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"possible_discounts": {
"discount": [
{
"absolute_saving": 0,
"discount_code": "ADULT",
"discount_desc": "Adult standard",
"is_offer": false,
"non_offer_sale_seatprice": 25,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "C/pool",
"sale_seatprice": 25,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "CHILD",
"discount_desc": "Child rate",
"is_offer": false,
"non_offer_sale_seatprice": 13,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "C/pool",
"sale_seatprice": 13,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "STUDENT",
"discount_desc": "Student rate",
"is_offer": false,
"non_offer_sale_seatprice": 19,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "C/pool",
"sale_seatprice": 19,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "OAP",
"discount_desc": "Senior citizen rate",
"is_offer": false,
"non_offer_sale_seatprice": 20,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "C/pool",
"sale_seatprice": 20,
"sale_surcharge": 0
}
]
},
"price_band_code": "C/pool",
"sale_seatprice": 25,
"sale_surcharge": 0
}
],
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle"
},
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 21,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"possible_discounts": {
"discount": [
{
"absolute_saving": 0,
"discount_code": "ADULT",
"discount_desc": "Adult standard",
"is_offer": false,
"non_offer_sale_seatprice": 21,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 21,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "CHILD",
"discount_desc": "Child rate",
"is_offer": false,
"non_offer_sale_seatprice": 11,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 11,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "STUDENT",
"discount_desc": "Student rate",
"is_offer": false,
"non_offer_sale_seatprice": 16,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 16,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "OAP",
"discount_desc": "Senior citizen rate",
"is_offer": false,
"non_offer_sale_seatprice": 17,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 17,
"sale_surcharge": 0
}
]
},
"price_band_code": "A/pool",
"sale_seatprice": 21,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 18,
"non_offer_sale_surcharge": 0,
"number_available": 3,
"percentage_saving": 0,
"possible_discounts": {
"discount": [
{
"absolute_saving": 0,
"discount_code": "ADULT",
"discount_desc": "Adult standard",
"is_offer": false,
"non_offer_sale_seatprice": 18,
"non_offer_sale_surcharge": 0,
"number_available": 3,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 18,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "CHILD",
"discount_desc": "Child rate",
"is_offer": false,
"non_offer_sale_seatprice": 9,
"non_offer_sale_surcharge": 0,
"number_available": 3,
"percentage_saving": 0,
"price_band_code": "B/pool",
"sale_seatprice": 9,
"sale_surcharge": 0
}
]
},
"price_band_code": "B/pool",
"sale_seatprice": 18,
"sale_surcharge": 0
}
],
"ticket_type_code": "STALLS",
"ticket_type_desc": "Stalls"
},
{
"price_band": [
{
"absolute_saving": 0,
"allows_leaving_single_seats": "always",
"discount_code": "",
"discount_desc": "",
"is_offer": false,
"non_offer_sale_seatprice": 47,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"possible_discounts": {
"discount": [
{
"absolute_saving": 0,
"discount_code": "ADULT",
"discount_desc": "Adult standard",
"is_offer": false,
"non_offer_sale_seatprice": 47,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 47,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "CHILD",
"discount_desc": "Child rate",
"is_offer": false,
"non_offer_sale_seatprice": 24,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 24,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "STUDENT",
"discount_desc": "Student rate",
"is_offer": false,
"non_offer_sale_seatprice": 35,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 35,
"sale_surcharge": 0
},
{
"absolute_saving": 0,
"discount_code": "OAP",
"discount_desc": "Senior citizen rate",
"is_offer": false,
"non_offer_sale_seatprice": 38,
"non_offer_sale_surcharge": 0,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 38,
"sale_surcharge": 0
}
]
},
"price_band_code": "A/pool",
"sale_seatprice": 47,
"sale_surcharge": 0
}
],
"ticket_type_code": "BALCONY",
"ticket_type_desc": "Balcony"
}
]
},
"backend_is_broken": false,
"backend_is_down": false,
"backend_throttle_failed": false,
"contiguous_seat_selection_only": true,
"currency": {
"currency_code": "gbp"
},
"valid_quantities": [
1,
2,
3,
4,
5,
6
]
}
from pyticketswitch.price_band import PriceBand
from pyticketswitch.ticket_type import TicketType
from pyticketswitch.discount import Discount
[
TicketType(
code='CIRCLE',
description='Upper circle',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=35.0,
surcharge=4.0,
non_offer_seatprice=35.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
discounts=[
Discount(
code='ADULT',
description='Adult',
price_band_code='A/pool',
is_offer=False,
seatprice=35.0,
surcharge=4.0,
non_offer_seatprice=35.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='CHILD',
description='Child rate',
price_band_code='A/pool',
is_offer=False,
seatprice=18.0,
surcharge=3.0,
non_offer_seatprice=18.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='STUDENT',
description='Student rate',
price_band_code='A/pool',
is_offer=False,
seatprice=26.0,
surcharge=3.0,
non_offer_seatprice=26.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='OAP',
description='Senior citizen rate',
price_band_code='A/pool',
is_offer=False,
seatprice=28.0,
surcharge=3.0,
non_offer_seatprice=28.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
)
],
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='B/pool',
is_offer=False,
seatprice=30.0,
surcharge=4.0,
non_offer_seatprice=30.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
discounts=[
Discount(
code='ADULT',
description='Adult',
price_band_code='B/pool',
is_offer=False,
seatprice=30.0,
surcharge=4.0,
non_offer_seatprice=30.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='CHILD',
description='Child rate',
price_band_code='B/pool',
is_offer=False,
seatprice=15.0,
surcharge=3.0,
non_offer_seatprice=15.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
)
],
),
PriceBand(
code='C/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='C/pool',
is_offer=False,
seatprice=25.0,
surcharge=4.0,
non_offer_seatprice=25.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
discounts=[
Discount(
code='ADULT',
description='Adult',
price_band_code='C/pool',
is_offer=False,
seatprice=25.0,
surcharge=4.0,
non_offer_seatprice=25.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='CHILD',
description='Child rate',
price_band_code='C/pool',
is_offer=False,
seatprice=13.0,
surcharge=3.0,
non_offer_seatprice=13.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='STUDENT',
description='Student rate',
price_band_code='C/pool',
is_offer=False,
seatprice=19.0,
surcharge=3.0,
non_offer_seatprice=19.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='OAP',
description='Senior citizen rate',
price_band_code='C/pool',
is_offer=False,
seatprice=20.0,
surcharge=3.0,
non_offer_seatprice=20.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
)
],
)
],
),
TicketType(
code='STALLS',
description='Stalls',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=21.0,
surcharge=3.0,
non_offer_seatprice=21.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
discounts=[
Discount(
code='ADULT',
description='Adult',
price_band_code='A/pool',
is_offer=False,
seatprice=21.0,
surcharge=3.0,
non_offer_seatprice=21.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='CHILD',
description='Child rate',
price_band_code='A/pool',
is_offer=False,
seatprice=11.0,
surcharge=2.0,
non_offer_seatprice=11.0,
non_offer_surcharge=2.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='STUDENT',
description='Student rate',
price_band_code='A/pool',
is_offer=False,
seatprice=16.0,
surcharge=2.0,
non_offer_seatprice=16.0,
non_offer_surcharge=2.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='OAP',
description='Senior citizen rate',
price_band_code='A/pool',
is_offer=False,
seatprice=17.0,
surcharge=2.0,
non_offer_seatprice=17.0,
non_offer_surcharge=2.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
)
],
),
PriceBand(
code='B/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='B/pool',
is_offer=False,
seatprice=18.0,
surcharge=3.0,
non_offer_seatprice=18.0,
non_offer_surcharge=3.0,
availability=3,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
discounts=[
Discount(
code='ADULT',
description='Adult',
price_band_code='B/pool',
is_offer=False,
seatprice=18.0,
surcharge=3.0,
non_offer_seatprice=18.0,
non_offer_surcharge=3.0,
availability=3,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='CHILD',
description='Child rate',
price_band_code='B/pool',
is_offer=False,
seatprice=9.0,
surcharge=2.0,
non_offer_seatprice=9.0,
non_offer_surcharge=2.0,
availability=3,
percentage_saving=0,
absolute_saving=0.0,
)
],
)
],
),
TicketType(
code='BALCONY',
description='Balcony',
price_bands=[
PriceBand(
code='A/pool',
allows_leaving_single_seats='always',
default_discount=Discount(
code='',
description='',
price_band_code='A/pool',
is_offer=False,
seatprice=47.0,
surcharge=5.0,
non_offer_seatprice=47.0,
non_offer_surcharge=5.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
example_seats_are_real=True,
discounts=[
Discount(
code='ADULT',
description='Adult',
price_band_code='A/pool',
is_offer=False,
seatprice=47.0,
surcharge=5.0,
non_offer_seatprice=47.0,
non_offer_surcharge=5.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='CHILD',
description='Child rate',
price_band_code='A/pool',
is_offer=False,
seatprice=24.0,
surcharge=4.0,
non_offer_seatprice=24.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='STUDENT',
description='Student rate',
price_band_code='A/pool',
is_offer=False,
seatprice=35.0,
surcharge=4.0,
non_offer_seatprice=35.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='OAP',
description='Senior citizen rate',
price_band_code='A/pool',
is_offer=False,
seatprice=38.0,
surcharge=4.0,
non_offer_seatprice=38.0,
non_offer_surcharge=4.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
)
],
)
],
)
]
The response includes a possible_discounts
dictionary, that contains a list of
discounts (or concessions) that are available on each price band. Each discount
contains the same price band attributes that are returned in
availability.
Discounts
Definition
GET https://api.ticketswitchswitch.com/f13/discounts.v1?perf_id={performanceid}&price_band_code={pricebandcode}&ticket_type_code={tickettypecode}
A discount represents a price type or concession that is available for a price band. These are some examples:
- Adult
- Child
- Student
- Senior citizen
When retrieving availability for a performance we return the
default discount. This discounts
resource should then be used to get the full
list of available discounts. When multiple discounts are returned non-default
discounts typically have a lower price (for example Child pricing).
When multiple discounts
are returned, you should present the choice to your
user (we use a drop-down list). When there are multiple special offers available
on a single ticket these are also presented as discounts
so you can present
the choice of special offer to your user (multiple offers are rare though). It
is possible for you to ignore this call and just purchase the default discount
even when there are multiple discounts
, but that is not recommended.
Example request - price band
curl https://api.ticketswitchswitch.com/f13/discounts.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B0I" \
-d "price_band_code=A/pool" \
-d "ticket_type_code=CIRCLE" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
discounts, meta = client.get_discounts('6IF-B0O', 'STALLS', 'A/pool')
Request
Parameter | Description |
---|---|
perf_id |
The performance identifier. |
price_band_code |
The price band code you want to view discounts for. |
ticket_type_code |
The ticket type code you want to view discounts for. |
req_predicted_commission |
Optional. Include to retrieve commission data. For most partners this will include predicted_user_commission only (the predicted amount you earn per ticket). Some partners will also see predicted_gross_commission , which is the total commission available to be shared between Ingresso and our partner. By default you will see predicted_user_commission only - if you think you need to see predicted_gross_commission as well then please get in touch. |
no_of_seats |
Optional. The number of tickets the customer would like. If this is specified then only discounts valid for the number of tickets will be shown. |
promo_code |
Optional. If the supplier supports a promo code this can be specified to unlock a discount. This feature is not commonly used with partners. |
Response
Example response
{
"currency_code": "gbp",
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"discounts": {
"discount": [
{
"absolute_saving": 0,
"discount_code": "ADULT",
"discount_desc": "Adult",
"is_offer": false,
"non_offer_sale_seatprice": 35,
"non_offer_sale_surcharge": 4,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 35,
"sale_surcharge": 4
},
{
"absolute_saving": 0,
"discount_code": "CHILD",
"discount_desc": "Child rate",
"is_offer": false,
"non_offer_sale_seatprice": 18,
"non_offer_sale_surcharge": 3,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 18,
"sale_surcharge": 3
},
{
"absolute_saving": 0,
"discount_code": "STUDENT",
"discount_desc": "Student rate",
"is_offer": false,
"non_offer_sale_seatprice": 26,
"non_offer_sale_surcharge": 3,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 26,
"sale_surcharge": 3
},
{
"absolute_saving": 0,
"discount_code": "OAP",
"discount_desc": "Senior citizen rate",
"is_offer": false,
"non_offer_sale_seatprice": 28,
"non_offer_sale_surcharge": 3,
"number_available": 6,
"percentage_saving": 0,
"price_band_code": "A/pool",
"sale_seatprice": 28,
"sale_surcharge": 3
}
]
}
}
from pyticketswitch.discount import Discount
[
Discount(
code='ADULT',
description='Adult',
price_band_code='A/pool',
is_offer=False,
seatprice=21.0,
surcharge=3.0,
non_offer_seatprice=21.0,
non_offer_surcharge=3.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='CHILD',
description='Child rate',
price_band_code='A/pool',
is_offer=False,
seatprice=11.0,
surcharge=2.0,
non_offer_seatprice=11.0,
non_offer_surcharge=2.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='STUDENT',
description='Student rate',
price_band_code='A/pool',
is_offer=False,
seatprice=16.0,
surcharge=2.0,
non_offer_seatprice=16.0,
non_offer_surcharge=2.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
),
Discount(
code='OAP',
description='Senior citizen rate',
price_band_code='A/pool',
is_offer=False,
seatprice=17.0,
surcharge=2.0,
non_offer_seatprice=17.0,
non_offer_surcharge=2.0,
availability=6,
percentage_saving=0,
absolute_saving=0.0,
)
]
The following attributes are returned within the discount
dictionary. These
are the same attributes returned in the availability price band
dictionary.
Attribute | Description |
---|---|
absolute_saving |
Defined as (non_offer_sale_seatprice + non_offer_sale_surcharge ) - (sale_seatprice + sale_surcharge ) |
discount_code |
The unique identifier of the discount . This is unique to each supplier system, so you cannot assume that if the “ADULT” discount_code is available on one event that it will be available on other events. |
discount_desc |
The description of the default discount to present to users. |
is_offer |
true if the ticket price is discounted below the full price, i.e. if absolute_saving is greater than zero. |
non_offer_sale_seatprice |
The per-ticket price for full-priced tickets. This will be the face value price when the market has such a concept (for example the London theatre market has this concept, but some New York theatre shows do not). This is the same as the sale_seatprice when the price band is not discounted. |
non_offer_sale_surcharge |
The per-ticket booking fee for full-priced tickets. To determine the total ticket price you must add together the non_offer_sale_seatprice and the non_offer_sale_surcharge . |
number_available |
This is the maximum number of contiguous seats that can be purchased. This applies to best available only - if you are using seat selection and contiguous_seat_selection_only is false it is possible to select above this number. |
percentage_saving |
Defined as absolute_saving / (non_offer_sale_seatprice + non_offer_sale_surcharge ) * 100 |
price_band_code |
The code for a price band. To uniquely identify a price band you should take the combination of ticket_type_code and price_band_code . |
price_band_desc |
The description for the price band. This will often not be present (not all supplier ticketing systems provide it) but when it is present it should be displayed to the customer. |
sale_seatprice |
The per-ticket price. This will be the face value price when the market has such a concept (for example the London theatre market has this concept, but some New York theatre shows do not). This is the same as the non_offer_sale_seatprice when the price band is not discounted. |
sale_surcharge |
The per-ticket booking fee. To determine the total ticket price you must add together the sale_seatprice and the sale_surcharge . |
The outer object also includes a currency_code
and a currency_details
object
containing further currency detail:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Send Methods
GET https://api.ticketswitch.com/f13/send_methods.v1?perf_id={performanceid}
This section describes the available methods of delivery for a given performance. Each method in the list has an associated cost which will be added to the overall charge.
Send methods might change between performances and depending on times when they are requested. For example there might not be enough time to post a physical ticket to a customer before the performance starts, so those performances would not have that option available. As such it’s important that send methods are called as needed to ensure the user isn’t seeing options that are out of date.
Example request
curl https://api.ticketswitch.com/f13/send_methods.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B0I" \
--compressed \
-G
from pyticketswith import Client
client = Client('demo', 'demopass')
send_methods, meta = client.get_send_methods('6IF-B0O')
Request
Parameter | Description |
---|---|
perf_id |
The performance identifier that you want to display send methods for. |
Example response
{
"currency_code": "gbp",
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"send_methods": {
"send_method": [
{
"send_code": "COBO",
"send_cost": 1.5,
"send_desc": "Collect from the venue",
"send_type": "collect"
},
{
"permitted_countries": {
"country": [
{
"country_code": "ie",
"country_desc": "Ireland"
},
{
"country_code": "uk",
"country_desc": "United Kingdom"
}
]
},
"send_code": "POST",
"send_cost": 3.5,
"send_desc": "Post (UK & Ireland only)",
"send_type": "post",
"send_final_comment": "Please allow 3 working days to recieve your tickets."
}
]
}
}
from pyticketswitch.country import Country
from pyticketswitch.send_method import SendMethod
[
SendMethod(
code='COBO',
cost=1.5,
description='Collect from the venue',
type='collect',
),
SendMethod(
code='POST',
cost=3.5,
description='Post (UK & Ireland only)',
type='post',
final_comment='Please allow 3 working days to receive your tickets.'
permitted_countries=[
Country(
code='ie',
description='Ireland',
),
Country(
code='uk',
description='United Kingdom',
)
],
)
]
Response
Attribute | Description |
---|---|
send_code |
The identifier of this send method. |
send_cost |
Any additional cost that the customer will have to pay if they chose this send method. |
send_desc |
A human readable description of the send method. |
send_final_comment |
A human readable string containing information about posting times. |
send_type |
Can be collect which indicates that the ticket will have to be collected in person, either at the venue or from a confirmation email. A type of post indicates that a physical ticket will be posted to the delivery address given at purchase time. |
permitted_countries |
If this is returned it indicates that the send method is only available to addresses in the listed countries. |
permitted_countries.country_code |
2-digit country code (using ISO 3166-1 alpha-2). |
permitted_countries.country_description |
Human readable description of the country. |
The outer object also includes a currency_code
and a currency_details
object
containing further currency detail:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Trolley
Definition
GET https://api.ticketswitch.com/f13/trolley.v1
A trolley
allows multiple orders to be purchased in a single transaction.
If you only plan to purchase a single order at a time then there is no need to use a trolley - you should instead go straight to reserve.
The trolley itself should be considered a wish list. No tickets are reserved until the reserve call is made. Having a ticket in a trolley is not a guarantee that the ticket will still be available when you attempt to reserve the tickets.
Trolleys are identified by a trolley_token
, which is simply a hash of the
orders in the trolley. Every time a change is made to the trolley the hash
changes and so does the trolley_token
. An individual trolley_token
is
therefore an identifier for the current state of your trolley, and can not be
used to identify your trolley as you add or remove orders.
Request
Example request - adding best available tickets to a new trolley, specifying specific discount codes
curl https://api.ticketswitch.com/f13/trolley.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B1S" \
-d "ticket_type_code=CIRCLE" \
-d "price_band_code=C/pool" \
-d "no_of_seats=3" \
-d "disc0=ADULT" \
-d "disc1=CHILD" \
-d "disc2=CHILD" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
trolley, meta = client.get_trolley(
performance_id='6IF-B0O',
number_of_seats=2,
price_band_code='A/pool',
ticket_type_code='STALLS'
)
Example request - adding specific seats to an existing trolley
curl https://api.ticketswitch.com/f13/trolley.v1 \
-u "demo:demopass" \
-d "trolley_token=eTxD00cZU3ON_j1-lBBoshxPyWY6yaCmb-pMcqlk-jeh1lAc3XnbK8l3eTuhGw9GH9rNfeTuvLcd-NQfLdZxOpibtG3g_4E5ssrtUcZErxA5Er0kcCZHKvKjTPhuRY49j3mWYZivbGGIo9bh7ASnQBNIEkl98SXjzH_hy3w16p95Zb9Tbfat0Iq5CtE7SKFgZhXTaq5zzBPDB5aqhTEAzR87BahqzoIkHRnKylxRZbxYvqZyglaJ5j1HdisF8vDZLUKCb8h4mErsUvOirXXQBLMjglD1RgQQqYGc3bZc6pXrlmOOLWyKiPv97-Nnvu7I8laXEQevemDcJWiz3W-SwV-qhbPQj9NwT3lPWzoHnR_iTT6fAWRex_LTHXCRqs65IzXqsJrLlkzuO5E1k9WQJMpk0Jkj2Zinc3WjWPZZUOBNnAhWk1bSE1FUbd0UVsq0zr8MqX3td5vzwmaiWvgRTFs5MOM2aR6BAfWKmbnV7QLgMJCC-GCP2Rm4mwb5IxyhCWTEaosblz5zDEQuqqnPpWiOtt3qXMIxe0G7UTesRA2b42JIN9tmYc9Pn5x5Apd7MggfkrPX1ulS9kA4JPMkI6U-.Z" \
-d "perf_id=7AB-5" \
-d "ticket_type_code=STALLS" \
-d "price_band_code=A/pool" \
-d "no_of_seats=2" \
-d "seat0=A1" \
-d "seat1=A2" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
trolley, meta = client.get_trolley(
trolley_token='PcCSFHBD2pd49k5mYjpoBHjE25O7isjAQkGMqZF15oHLa0W0q-UDnwrAtc6aKmNsOnSBMD77u76gdqqgfJLwnWw6RRKjKJhRHiE0GgG0dN4RYdSTP3Hrw9lix6pj-mZ2m9vLF6tTZAUMTi0HjEc2s9MLo6xu2eVvg4zPKNZ0mr_MllWtiWRc4zMt-RDZy0QEqGb9mcA0GPbNJh3pnRd2Q5_ZgBJ21n8rSgTiKYj02AztAcfF8LcHVTPuldaCgyE_VHxZyW9djxPORTLBiPytBoPURku7bd5kn2w9XeXoHocsODU2yWJpPLrikKqGNHU13uH2LewpbOEnueFi4SVxUxZTG53pN_1tJ-nI3XtGGOHvWvnhode94YB-OJ2xnKy1R6P_OYq1uFH-vRl7fgXNwXdEzfu0yrf-4YLwahQKVUIxrdyswF6XYd-7PoBU3Aj1dDfbEXbm96l8JqKxiHTUM7U-.Z',
performance_id='7AB-5',
ticket_type_code='STALLS',
price_band_code='A/pool',
number_of_seats=2,
seats=['A1', 'A2'],
)
Example request - view the current state of the trolley
curl https://api.ticketswitch.com/f13/trolley.v1 \
-u "demo:demopass" \
-d "trolley_token=eTxD00cZU3ON_j1-lBBoshxPyWY6yaCmb-pMcqlk-jeh1lAc3XnbK8l3eTuhGw9GH9rNfeTuvLcd-NQfLdZxOpibtG3g_4E5ssrtUcZErxA5Er0kcCZHKvKjTPhuRY49j3mWYZivbGGIo9bh7ASnQBNIEkl98SXjzH_hy3w16p95Zb9Tbfat0Iq5CtE7SKFgZhXTaq5zzBPDB5aqhTEAzR87BahqzoIkHRnKylxRZbxYvqZyglaJ5j1HdisF8vDZLUKCb8h4mErsUvOirXXQBLMjglD1RgQQqYGc3bZc6pXrlmOOLWyKiPv97-Nnvu7I8laXEQevemDcJWiz3W-SwV-qhbPQj9NwT3lPWzoHnR_iTT6fAWRex_LTHXCRqs65IzXqsJrLlkzuO5E1k9WQJMpk0Jkj2Zinc3WjWPZZUOBNnAhWk1bSE1FUbd0UVsq0zr8MqX3td5vzwmaiWvgRTFs5MOM2aR6BAfWKmbnV7QLgMJCC-GCP2Rm4mwb5IxyhCWTEaosblz5zDEQuqqnPpWiOtt3qXMIxe0G7UTesRA2b42JIN9tmYc9Pn5x5Apd7MggfkrPX1ulS9kA4JPMkI6U-.Z" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
trolley, meta = client.get_trolley(
token='PcCSFHBD2pd49k5mYjpoBHjE25O7isjAQkGMqZF15oHLa0W0q-UDnwrAtc6aKmNsOnSBMD77u76gdqqgfJLwnWw6RRKjKJhRHiE0GgG0dN4RYdSTP3Hrw9lix6pj-mZ2m9vLF6tTZAUMTi0HjEc2s9MLo6xu2eVvg4zPKNZ0mr_MllWtiWRc4zMt-RDZy0QEqGb9mcA0GPbNJh3pnRd2Q5_ZgBJ21n8rSgTiKYj02AztAcfF8LcHVTPuldaCgyE_VHxZyW9djxPORTLBiPytBoPURku7bd5kn2w9XeXoHocsODU2yWJpPLrikKqGNHU13uH2LewpbOEnueFi4SVxUxZTG53pN_1tJ-nI3XtGGOHvWvnhode94YB-OJ2xnKy1R6P_OYq1uFH-vRl7fgXNwXdEzfu0yrf-4YLwahQKVUIxrdyswF6XYd-7PoBU3Aj1dDfbEXbm96l8JqKxiHTUM7U-.Z',
)
Example request - removing the first order from the trolley
curl https://api.ticketswitch.com/f13/trolley.v1 \
-u "demo:demopass" \
-d "trolley_token=eTxD00cZU3ON_j1-lBBoshxPyWY6yaCmb-pMcqlk-jeh1lAc3XnbK8l3eTuhGw9GH9rNfeTuvLcd-NQfLdZxOpibtG3g_4E5ssrtUcZErxA5Er0kcCZHKvKjTPhuRY49j3mWYZivbGGIo9bh7ASnQBNIEkl98SXjzH_hy3w16p95Zb9Tbfat0Iq5CtE7SKFgZhXTaq5zzBPDB5aqhTEAzR87BahqzoIkHRnKylxRZbxYvqZyglaJ5j1HdisF8vDZLUKCb8h4mErsUvOirXXQBLMjglD1RgQQqYGc3bZc6pXrlmOOLWyKiPv97-Nnvu7I8laXEQevemDcJWiz3W-SwV-qhbPQj9NwT3lPWzoHnR_iTT6fAWRex_LTHXCRqs65IzXqsJrLlkzuO5E1k9WQJMpk0Jkj2Zinc3WjWPZZUOBNnAhWk1bSE1FUbd0UVsq0zr8MqX3td5vzwmaiWvgRTFs5MOM2aR6BAfWKmbnV7QLgMJCC-GCP2Rm4mwb5IxyhCWTEaosblz5zDEQuqqnPpWiOtt3qXMIxe0G7UTesRA2b42JIN9tmYc9Pn5x5Apd7MggfkrPX1ulS9kA4JPMkI6U-.Z" \
-d "remove_items_list=1" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
trolley, meta = client.get_trolley(
token='PcCSFHBD2pd49k5mYjpoBHjE25O7isjAQkGMqZF15oHLa0W0q-UDnwrAtc6aKmNsOnSBMD77u76gdqqgfJLwnWw6RRKjKJhRHiE0GgG0dN4RYdSTP3Hrw9lix6pj-mZ2m9vLF6tTZAUMTi0HjEc2s9MLo6xu2eVvg4zPKNZ0mr_MllWtiWRc4zMt-RDZy0QEqGb9mcA0GPbNJh3pnRd2Q5_ZgBJ21n8rSgTiKYj02AztAcfF8LcHVTPuldaCgyE_VHxZyW9djxPORTLBiPytBoPURku7bd5kn2w9XeXoHocsODU2yWJpPLrikKqGNHU13uH2LewpbOEnueFi4SVxUxZTG53pN_1tJ-nI3XtGGOHvWvnhode94YB-OJ2xnKy1R6P_OYq1uFH-vRl7fgXNwXdEzfu0yrf-4YLwahQKVUIxrdyswF6XYd-7PoBU3Aj1dDfbEXbm96l8JqKxiHTUM7U-.Z',
item_numbers_to_remove=[1, 2, 3],
)
The single trolley call is used for multiple use cases such as:
- Add best available tickets to a new or existing trolley
- Add specific seats to a new or existing trolley
- View the items in the trolley
- Remove an order from the trolley
Note that adding an order will remove anything in the trolley which would
prevent it being added. Removed orders are listed as discarded_orders
. The
common reasons why two orders cannot sit alongside each other are:
We currently don’t allow a basket to contain multiple orders for the same performance. This is something we plan to change - if this is a problem for you please let us know.
Incompatible despatch methods for the same supplier. For example if you have specified “International Post” for one order, and “Collect From Box Office” for the next order, and they are both from the same supplier then these are incompatible and the first order will be removed from your trolley. This should be an uncommon occurrence.
Differing currencies - for example the first order added to the trolley uses the USD currency while the second order added uses the GBP currency. These are incompatible so the first order will be removed from your trolley.
Also note that when adding individual seats to a trolley, there are restrictions on the seats that can be added in a single order:
If the availability response includes
contiguous_seat_selection_only
=false
then any seats can be selected, provided they are within a singleticket_type_code
andprice_band_code
.If the availability response includes
contiguous_seat_selection_only
=true
then only contiguous seats within a singleticket_type_code
andprice_band_code
can be selected. Seats are contiguous based on the order of the id_details seat array.
If you would like to allow your customers to select seats without restriction across price bands and ticket types, you need to add multiple orders to a trolley, one order for each ticket type / price band. However there are currently some restrictions enforced so if you want to do this you will need to contact us first
Parameter | Description |
---|---|
discX |
Specify a discount code for ticket number X, with zero-based numbering (so to specify the CHILD discount code on the second ticket use disc1=CHILD ). Note that illegal discount codes are replaced with legal ones. |
no_of_seats |
The number of tickets you want to add to the trolley. It is optional to specify discount codes, however note that if you choose to specify them you must specify all of them. If you do not specify discount codes you will receive the default discount code - this will match what you are shown when you request availability. |
perf_id |
The performance identifier for the tickets that you want to add to your trolley. |
price_band_code |
The price band identifier for the tickets that you want to add to your trolley. |
remove_items_list |
A comma separated list of order item_number s that were previously added to the trolley and that you now want to remove. |
seatX |
Specify a specific seat for ticket number X, with zero-based numbering (so to specify seat A12 as the first ticket use seat0=A12 ). If seat numbers are not specified then when the trolley is later reserved you will receive best available tickets. |
X_send_code |
Specify a send / despatch method for supplier system X. If this is not present it will default to the first send method. For example, to specify the POST send method for the nimax supplier system, use nimax_send_code=POST . |
ticket_type_code |
The ticket type identifier for the tickets that you want to add to your trolley. |
trolley_token |
The identifier for the trolley. This is used to add additional orders to a trolley, or to remove orders in a trolley. |
req_predicted_commission |
Optional. Include to retrieve commission data. For most partners this will include predicted_user_commission only (the predicted amount you earn per ticket). Some partners will also see predicted_gross_commission , which is the total commission available to be shared between Ingresso and our partner. By default you will see predicted_user_commission only - if you think you need to see predicted_gross_commission as well then please get in touch. |
Additional parameters, primarily for internal use:
Parameter | Description |
---|---|
add_crypto_block |
cypto_block s are used in the old Ingresso XML API. To make migration away from the XML API easier, if you include add_crypto_block a crypto_block will be added to the response. You can then take the crypto_block and trolley_token and pass these in to the XML API call make_reservation to reserve and later purchase tickets (so that the JSON API is used up to the basket stage and the XML API is used to complete the purchase). |
departure_date |
Specify a departure date for example departure_date=20170214 . |
duration |
Specify a duration for hotel product, for example duration=3 . |
promo_code |
Specifying a promo codes can unlock a special offer discount code. If you have a promo code it can be specified like this: promo_code=FOO . Note that this feature is not commonly used with partners. |
All of the following parameters can also be used to request additional data for the event and performance in each order. These are described in more detail in the Events section here.
Parameter | Description |
---|---|
req_avail_details |
Returns availability details - a cached list of unique ticket types and price bands available for the event and performance in each order. This parameter is not commonly used. |
req_avail_details_with_perfs |
This will add the list of available performance dates to each avail detail object. Only valid if used alongside req_avail_details. |
req_cost_range |
Returns cost ranges - a from price and offer detail for the event and performance in each order. |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. |
req_cost_range_details |
Returns a list of unique ticket types and price bands and their cost ranges across all performances. This parameter is not commonly used. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only 1 consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
req_extra_info |
Returns the descriptive info for the event, returned as individual sections (structured_info ) or as a single summary (event_info / event_info_html ). |
req_media_triplet_one |
Triplet one (jpg/png 520x390). See further detail on media. |
req_media_triplet_two |
Triplet two if available (jpg/png 520x390). |
req_media_triplet_three |
Triplet three if available (jpg/png 520x390). |
req_media_triplet_four |
Triplet four if available (jpg/png 520x390). |
req_media_triplet_five |
Triplet five if available (jpg/png 520x390). |
req_media_seating_plan |
Graphical seating plan of the venue if available (jpg/png varying size). |
req_media_square |
Small square image suitable for search or event avatar (jpg/png 140x140). |
req_media_landscape |
Small landscape banner suitable for search (jpg/png 220x115). |
req_media_marquee |
Large landscape banner suitable for a page heading, if available (jpg/png 700x300). |
req_media_supplier |
Logo of the supplier/producer, if available (jpg/png varying size). |
req_reviews |
Returns event reviews if available. |
req_video_iframe |
Returns video iframe information if available. |
Response
Example response - adding specific seats to an existing trolley
{
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"discarded_orders": [],
"trolley_token": "k5--2fvf6Qc19ceQa4b9Kx4zIhDezG2yPzN71dEUmA8r3qFFCJJAQ3M3kYft_h9rzMAEBYyT0yNdS31HOv2WuYMbAbC8i49reKFaUu3esJckOm4cDipyTgQy3iekje0zgEM0MBSx1XY6t5bgbQ170iNxU2CLjUmZAT9K5iyqI-PN3hmJEpj0s5NMb31-THH8ufud82Mh2TeBP_c_e3_sabim1ftOfrnS6qPQAo9DF-Z1gXIXKLIzqCozRUwKqSOyLKbwAgfJSMi_2fQ_MhWMNkldjrfbOPpM0qKReJm8wPVW_zZNL_px_Mmg8LEIMgd5soJAa1edNePTrvSLppbDkevea-9Lr9UWERYKoSVXCsLSaEw2dGqaNJggpU6S_ksyduog3ALwStTJ6dr8dyGY5mImdVNcZhRepdmvKbRYNzBTDSxxY2n2LefoJkxc8bg-FxPacE9DRRNY_ZPl7f3fpa4a0Oq8j2DfrGxVcw0McxLoQ1E8XUkAH99LztF0qZN9RYuFwpQhoomgNOROf2M03DigA59j5ipO4Mg8p3iLKVndHJXS1SJfItBt1h86VXXUg0pkeZGn1e6TQkwx9m6t5faz4zuzGEg8XpuOXBxBqHrvQOFaFY5tDYYGr4x-uM2VowFCpM2c3-Aal3EeyjChHTycW---Z",
"trolley_token_contents": {
"bundle": [
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test0",
"bundle_source_desc": "External Test Backend 0",
"bundle_total_cost": 52.5,
"bundle_total_seatprice": 51,
"bundle_total_send_cost": 1.5,
"bundle_total_surcharge": 0,
"currency_code": "gbp",
"order": [
{
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"got_requested_seats": false,
"item_number": 1,
"performance": {
"date_desc": "Sun, 15th January 2017",
"event_id": "6IF",
"has_pool_seats": false,
"is_ghost": true,
"is_limited": false,
"iso8601_date_and_time": "2017-01-15T19:30:00Z",
"perf_id": "6IF-A7N",
"time_desc": "7.30 PM"
},
"price_band_code": "C/pool",
"ticket_orders": {
"ticket_order": [
{
"discount_code": "ADULT",
"discount_desc": "Adult standard",
"no_of_seats": 1,
"sale_seatprice": 25,
"sale_surcharge": 0,
"total_sale_seatprice": 25,
"total_sale_surcharge": 0
},
{
"discount_code": "CHILD",
"discount_desc": "Child rate",
"no_of_seats": 2,
"sale_seatprice": 13,
"sale_surcharge": 0,
"total_sale_seatprice": 26,
"total_sale_surcharge": 0
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle",
"total_no_of_seats": 3,
"total_sale_seatprice": 51,
"total_sale_surcharge": 0
}
]
},
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test1",
"bundle_source_desc": "External Test Backend 1",
"bundle_total_cost": 110,
"bundle_total_seatprice": 100,
"bundle_total_send_cost": 0,
"bundle_total_surcharge": 10,
"currency_code": "gbp",
"order": [
{
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"theatre": "Theatre"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"custom_filter": [],
"event_desc": "The Unremarkable Incident of the Cat at Lunchtime",
"event_id": "7AB",
"event_path": "/7AB-the-unremarkable-incident-of-the-cat-at-lunchtime/",
"event_status": "live",
"event_type": "simple_ticket",
"event_uri_desc": "The-Unremarkable-Incident-of-the-Cat-at-Lunchtime",
"geo_data": {
"latitude": 51.49306,
"longitude": -0.22639
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 90,
"min_running_time": 90,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "W6 7ES",
"show_perf_time": true,
"source_code": "ext_test1",
"source_desc": "External Test Backend 1",
"venue_desc": "Lyric Apollo",
"venue_uri_desc": "Lyric-Apollo"
},
"got_requested_seats": true,
"item_number": 2,
"performance": {
"date_desc": "Tue, 1st January 2019",
"event_id": "7AB",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2019-01-01T15:30:00Z",
"perf_id": "7AB-5",
"running_time": 90,
"time_desc": "3.30 PM"
},
"price_band_code": "A/pool",
"requested_seats": [
{
"col_id": "1",
"full_id": "A1",
"is_restricted_view": true,
"row_id": "A",
"seat_text": "Restricted View",
"seat_text_code": "A.1"
},
{
"col_id": "2",
"full_id": "A2",
"is_restricted_view": true,
"row_id": "A",
"seat_text": "Restricted View",
"seat_text_code": "A.2"
}
],
"ticket_orders": {
"ticket_order": [
{
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"no_of_seats": 2,
"sale_seatprice": 50,
"sale_surcharge": 5,
"total_sale_seatprice": 100,
"total_sale_surcharge": 10
}
]
},
"ticket_type_code": "STALLS",
"ticket_type_desc": "Stalls",
"total_no_of_seats": 2,
"total_sale_seatprice": 100,
"total_sale_surcharge": 10
}
]
}
],
"trolley_bundle_count": 2,
"trolley_order_count": 2
}
}
from pyticketswitch.event import Event
from pyticketswitch.bundle import Bundle
from pyticketswitch.performance import Performance
from pyticketswitch.order import TicketOrder
from pyticketswitch.trolley import Trolley
from pyticketswitch.order import Order
Trolley(
token='64--QVkNGtT6STKmvXGI1e3mnxGkt-myQ56VW_cMlAxai766x2C-ksxcll2pY7-AUFsdyzNivWoVuCVJUwUfaiSFUUPQN6ErqZeAM5hRX6KXIHy4eLuzeV6SX8PvZDsO0RScIwO54SNFcgIPHl9MEnl0F_amE0EPNPSqn7C9IZqBkERKUfoi-E9eysQlq-EiQUKZPxev24rAS9ASDZPkpQKY4-9zM-fF1DSLcic0uho5c3jFsajf8QTrD_Se9sUfy4OrATwTIVmRZXNyeTFZWTJji0HQg3HmATR5Xhe_BzuOwqvxLjyT65uEP3oStqo3RZ6o1HiMe3DxI9u5khAf3QrIrd0-3bS4JsAmm5JQiq_Vg2FqfJTf42Gipre9kcU8mnAVHjPvGgNyGpuG2fQHpTCd-Pd9jiDbC93ckOJ8DZN8FJZbbYWD82Ep_w90YlSug5uQ_vh2f54xgD2RQRyxpyTAeKegBI-YRtiolLgSnGfuVyFCWb0JHES4ZrQHBEuii5gnocURfBq9sL--Z',
bundles=[
Bundle(
source_code='ext_test0',
orders=[
Order(
item=1,
event=Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
critic_review_percent=100,
),
performance=Performance(
id='6IF-B0O',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 4, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Thu, 4th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='',
description='',
number_of_seats=2,
seatprice=21.0,
surcharge=3.0,
total_seatprice=42.0,
total_surcharge=6.0,
)
],
number_of_seats=2,
total_seatprice=42.0,
total_surcharge=6.0,
requested_seat_ids=[
],
)
],
description='External Test Backend 0',
total_seatprice=42.0,
total_surcharge=6.0,
total_send_cost=1.5,
total=49.5,
currency_code='gbp',
),
Bundle(
source_code='ext_test1',
orders=[
Order(
item=2,
event=Event(
id='7AB',
status='live',
description='The Unremarkable Incident of the Cat at Lunchtime',
source='External Test Backend 1',
source_code='ext_test1',
event_type='simple_ticket',
venue='Lyric Apollo',
classes={
'theatre': 'Theatre'
},
postcode='W6 7ES',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.49306,
longitude=-0.22639,
max_running_time=90,
min_running_time=90,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
),
performance=Performance(
id='7AB-5',
event_id='7AB',
date_time=datetime.datetime(2019, 1, 1, 15, 30, tzinfo=tzutc()),
date_description='Tue, 1st January 2019',
time_description='3.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=90,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='NORMAL',
description='Regular Ticket',
number_of_seats=2,
seatprice=50.0,
surcharge=5.0,
total_seatprice=100.0,
total_surcharge=10.0,
)
],
number_of_seats=2,
total_seatprice=100.0,
total_surcharge=10.0,
requested_seat_ids=[
'A1',
'A2'
],
)
],
description='External Test Backend 1',
total_seatprice=100.0,
total_surcharge=10.0,
total_send_cost=0.0,
total=110.0,
currency_code='gbp',
)
],
)
The trolley has three main structures:
A
bundle
represents all orders from a particular supplier. Orders are grouped like this so that all items are ordered from the supplier at once - if the supplier posts tickets on our behalf then separate orders will be posted together, and if the supplier processes payment all orders in the bundle will be paid for with a single payment. Reserving and purchasing orders will also succeed or fail together.An
order
represents a number of tickets to a particularprice band
andticket type
, for a particular performance of an event.An
order
will contain multipleticket_order
s when more than onediscount code
is used (for example ticket 1 and 2 have the ADULT discount code, and tickets 3 and 4 have the CHILD discount code). In this example there will be twoticket_order
s: one for ADULT and one for CHILD.
trolley
attributes:
Attribute | Description |
---|---|
discarded_orders |
As discussed above, adding an order will remove anything in the trolley which would prevent it being added. See below for detail of the order object. |
input_contained_unavailable_order |
This is a flag that will get set to true if part of the trolley request could not be added to the trolley. This occurs when we weren’t able to find any available products that matched the request and it usually means the user has passed in invalid parameters or is requesting an item that is sold out. |
trolley_token_contents |
See below for object detail. |
trolley_token |
The identifier for the trolley (this is an internal hash representing the items in the trolley, so the identifier will be the same for identical trolleys). |
trolley_token_contents
attributes:
Attribute | Description |
---|---|
bundle |
See below for object detail. |
trolley_bundle_count |
The number of bundles in the trolley. |
trolley_order_count |
The number of orders in the trolley. There will be at least one order for every bundle. |
bundle
attributes
Attribute | Description |
---|---|
bundle_order_count |
The number of orders in this bundle. |
bundle_source_code |
The code of the supplier system that this bundle will be purchased from. |
bundle_source_desc |
The name of the supplier system that this bundle will be purchased from. |
bundle_total_cost |
The total cost of this bundle. |
bundle_total_seatprice |
The total face value for this bundle. |
bundle_total_send_cost |
The despatch cost for this bundle (similar to a transaction fee). Orders within the same bundle will be sent together. |
bundle_total_surcharge |
The total booking fee for this bundle. |
currency_code |
The currency code for the price - further detail for the currency can be found in the currency_details object, described below. |
order |
See below for object detail. |
order
attributes:
Attribute | Description |
---|---|
event |
The event for this order. |
item_number |
A unique sequential number for the order . The second order added to the trolley will have item_number 2. The item_number remains constant as orders are added or removed, so if item_number 1 is removed, the first order will be item_number 2. |
performance |
The performance for this order. |
price_band_code |
The code for a price band, for example “C/pool”. The price band code is generally made up of the code from the underlying supplier system, e.g. “C”, followed by a “/” separator then “pool” or “alloc”, indicating whether the price band is taken from the general pool of tickets or is from a ring-fenced allocation. |
seat_request_status |
The status of your tickets after they have been reserved. Possible values are not_requested (specific seats not requested), got_none (you requested A13 and A14 but we gave you A15 and A16), got_partial (you requested A13 and A14 but we gave you A14 and A15), got_all (you requested A13 and A14 and you got A13 and A14 - by far the most common response when requesting specific seats). |
ticket_orders |
A number of ticket_order objects, details below. |
ticket_type_code |
The unique identifier for the ticket type. For attractions this can refer to variations such as General Admission or Fast Track, and there is often only only. For seated events this normally refers to a part of house / seating area such as Grand Circle. |
ticket_type_desc |
The description for the ticket type. This should be displayed to the customer |
total_no_of_seats |
The number of tickets for this order. |
total_sale_seatprice |
The total face value for this order. |
total_sale_surcharge |
The total booking fee for this order. |
ticket_order
attributes:
Attribute | Description |
---|---|
discount_code |
The discount code that applies to this ticket_order. |
discount_desc |
The description for the discount code. |
no_of_seats |
The number of tickets in this ticket_order. |
sale_seatprice |
The face value per ticket in this ticket_order. |
sale_surcharge |
The booking fee per ticket in this ticket_order. |
total_sale_seatprice |
The total face value of all tickets in this ticket_order. |
total_sale_surcharge |
The total booking fee of all tickets in this ticket_order. |
The outer object includes a currency_details
object containing one currency
object (indexed on the currency code) for every currency referenced in the
JSON response. Each currency has the following attributes:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Add-ons
Add-ons are items that can only be purchased alongside a normal event, for example The Lion King could have add-ons for ticket insurance, a Simba toy and a restaurant nearby the Lyceum Theatre.
Add-ons can only be added to a trolley already containing tickets for an event containing add-ons.
Definition
GET https://api.ticketswitch.com/f13/add_ons.v1
This resource returns detail for which add-on events may be added to a given trolley. The trolley token must be specified, or the parameters required to build a valid trolley must be specified, or both. This call is nullipotent, and will not change the state of any existing trolley.
Request
Example request
curl https://api.ticketswitch.com/f13/add_ons.v1 \
-u "demo:demopass" \
-d "trolley_token=M2--6TcZRZsfgZI0E8PmlGWqr5PQluhxE46Nqnno3Xa24lFuIKM_0IYJq40BDvisBRcXKsaGBdLfu8B5TfwI4s7jk7y7xRto_SwJL177u_vuvvq_Ynqnj64IfAHmItXxz_-xdTQGXh_G-BuPGxPXNY_Ycimiv1ZYlPFuPjsoVugnUnyu2F0TmpdztEtgI9PC1WhnTeHeRUDEBvVewOIf_PEJkPVR-UXFDg3gxbHYQBENW5XpkYnRhc22IqrB7eAoK0MbTLaPMk3uB1BKnz_B7fasSU_NU3nhXvmgHa4suvCT9oEaQSGvq4G0glOtyCiqL1FfVJ2R3KIgb2xC4NbAm4cNL5q22V_W0eYGmJ9DTBJ90UWvAWH7UeFLM1--Z" \
--compressed \
-G
from pyticketswitch import Client
client = Client(user='demo', password='demopass')
addon_events, addon_meta = client.get_addons(token="M2--6TcZRZsfgZI0E8PmlGWqr5PQluhxE46Nqnno3Xa24lFuIKM_0IYJq40BDvisBRcXKsaGBdLfu8B5TfwI4s7jk7y7xRto_SwJL177u_vuvvq_Ynqnj64IfAHmItXxz_-xdTQGXh_G-BuPGxPXNY_Ycimiv1ZYlPFuPjsoVugnUnyu2F0TmpdztEtgI9PC1WhnTeHeRUDEBvVewOIf_PEJkPVR-UXFDg3gxbHYQBENW5XpkYnRhc22IqrB7eAoK0MbTLaPMk3uB1BKnz_B7fasSU_NU3nhXvmgHa4suvCT9oEaQSGvq4G0glOtyCiqL1FfVJ2R3KIgb2xC4NbAm4cNL5q22V_W0eYGmJ9DTBJ90UWvAWH7UeFLM1--Z")
Either the trolley_token
parameter, and/or a valid set of parameters for a
trolley call must be supplied.
Parameter | Description |
---|---|
trolley_token |
A valid identifier for an existing trolley. |
——— | ———– |
discX |
A trolley with a discount code for added tickets. |
no_of_seats |
A trolley with a specified number of tickets added. |
perf_id |
A trolley with tickets for the specified performance added. |
price_band_code |
A trolley with tickets from the specified price band added. |
remove_items_list |
A trolley with the specified item_numbers removed. |
seatX |
A trolley with the specified seat ID added as one of the tickets. |
X_send_code |
A trolley with the specified send method for new tickets added. |
ticket_type_code |
A trolley with tickets of the specified ticket type added. |
The list of optional additional parameters specified can also be included and will add the details to the response.
Response
Example response
{
"results": {
"event": [
{
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"theatre": "Theatre"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"custom_filter": [],
"event_desc": "Unremarkable Cat Lunchbox",
"event_id": "7AC",
"event_path": "/7AC-unremarkable-cat-lunchbox/",
"event_status": "live",
"event_type": "misc_item",
"event_uri_desc": "Unremarkable-Cat-Lunchbox",
"geo_data": {
"latitude": 51.49306,
"longitude": -0.22639
},
"has_no_perfs": false,
"is_add_on": true,
"is_auto_quantity_add_on": true,
"is_seated": false,
"need_departure_date": false,
"need_duration": false,
"need_performance": false,
"postcode": "W6 7ES",
"show_perf_time": false,
"source_code": "ext_test1",
"source_desc": "External Test Backend 1",
"venue_desc": "Lyric Apollo",
"venue_uri_desc": "Lyric-Apollo"
}
],
"paging_status": {
"page_length": 50,
"page_number": 0,
"pages_remaining": 0,
"results_remaining": 0,
"total_unpaged_results": 1
}
}
}
from pyticketswitch.event import Event
[
Event(
min_running_time=None,
event_type=u'misc_item',
has_performances=True,
venue_info_html=None,
critic_review_percent=None,
needs_departure_date=False,
valid_quantities=None,
addon_events=None,
availability_details=[],
postcode=u'W6 7ES',
country_code=u'uk',
id=u'7AC',
city=u'London',
filters=[],
media={},
is_seated=False,
upsell_events=None,
event_info=None,
content={},
source=u'External Test Backend 1',
max_running_time=None,
cost_range_details=[],
needs_performance=False,
latitude=51.49306,
upsell_list=[],
city_code=u'london-uk',
venue_addr=None,
status=u'live',
description=u'Unremarkable Cat Lunchbox',
venue_addr_html=None,
cost_range=None,
event_info_html=None,
source_code=u'ext_test1',
country=u'United Kingdom',
venue_info=None,
venue=u'Lyric Apollo',
longitude=-0.22639,
is_add_on=True,
is_auto_quantity_add_on=True,
reviews=[],
classes={
u'theatre': u'Theatre'
},
fields={},
needs_duration=False,
no_singles_cost_range=None,
component_events=[],
show_performance_time=False,
)
]
The format of the response is identical to that of the events list.
Attribute | Description |
---|---|
city_code |
Code of the city where the event is taking place. |
city_desc |
Name of the city where the event is taking place. |
classes |
A collection of categories (a.k.a. “classes”) that this event belongs to. The index is the class code, the value is the class description. |
country_code |
2-digit country code (using ISO 3166-1 alpha-2) |
country_desc |
Name of the country where the event is taking place. |
critic_review_percent |
The aggregate critic review score, e.g. 80 for 80%. |
custom_filter |
Array of custom filter codes. This can be ignored by partners. |
event_desc |
Name of the show or event e.g. The Lion King . |
event_id |
Unique identifier for the event. |
event_path |
If you also use a white label website this can be used to navigate to the event page, e.g. /2J5V-la-pedrera-skip-the-line/ . |
event_status |
Will be live for a normal event search. Other values are dead and pending but these will only be displayed when using the include_dead or include_non_live parameters. |
event_type |
Currently all events are of type simple_ticket . In future we may add hotel_room and misc_item . |
geo_data |
A block containing the following geo co-ordinates: |
geo_data.latitude |
Latitude of the event. |
geo_data.longitude |
Longitude of the event. |
has_no_perfs |
true if the event has no performances. For example some attraction tickets are valid for any date, so we do not present a list of performances to select. |
is_add_on |
false if this event is an add-on event. This means it can only be added to a trolley containing tickets for an event that lists this in its add_ons . |
is_auto_quantity_add_on |
false Indicates whether add on quantity will be modified based on the number of ticket orders, if true number of addons will be equal to total number of tickets for all parent events in the trolley. |
is_seated |
true for seated events. |
max_running_time |
Maximum length / duration in minutes (not always present). |
min_running_time |
Minimum length / duration in minutes (not always present). |
need_departure_date |
Flag indicating whether the event needs a departure date specified. This is false for most events. Most partners can ignore this. |
need_duration |
Flag indicating whether the event needs duration (specific to hotel_room events only). Most partners can ignore this. |
need_performance |
Flag indicating if a performance must be selected in order to retrieve availability. For the vast majority of events this will be true . |
postcode |
Postcode of the event location. |
show_perf_time |
false if the performance time is not relevant, for example some events use a performance description rather than specific times. |
source_code |
Source supplier code e.g. nimax . |
source_desc |
Source supplier description e.g. Nimax . |
user_review_percent |
The aggregate user review score, e.g. 80 for 80%. |
venue_desc |
Name of the venue e.g. Sadler's Wells . |
venue_uri_desc |
URI encoded name of the venue e.g. Sadler%27s-Wells . |
The outer object also contains a paging_status object:
Attribute | Description |
---|---|
page_length |
The number of results per page. |
page_number |
The zero-based page number currently displayed. |
pages_remaining |
The number of pages that you need to request after the current page to retrieve all results. |
results_remaining |
The number of results in the remaining pages. |
total_unpaged_results |
The total number of results. |
Reserve
Definition
POST https://api.ticketswitch.com/f13/reserve.v1
Before purchasing tickets, you must first reserve
them. Reserving tickets will
put them on hold for a period of time, ensuring they cannot be purchased by
anyone else until you explicitly release them or until the hold time
expires when the tickets are automatically released. Reserve is typically called
immediately before displaying a checkout page to customers to collect contact
details. These details are then used as parameters when
purchasing the reservation.
There are two main use cases for calling reserve
:
You only want to purchase a single order at a time: call
reserve
with aperf_id
,ticket_type_code
,price_band_code
,no_of_seats
, and other optional parameters if necessary.You want to purchase multiple orders in a single transaction: first add orders to your trolley, then
reserve
the trolley by specifying atrolley_token
.
As with trolley there are restrictions on reserving individual seats:
If the availability response includes
contiguous_seat_selection_only
=false
then any seats can be selected, provided they are within a singleticket_type_code
andprice_band_code
.If the availability response includes
contiguous_seat_selection_only
=true
then only contiguous seats within a singleticket_type_code
andprice_band_code
can be selected. Seats are contiguous based on the order of the id_details seat array.
If you would like to allow your customers to select seats without restriction across price bands and ticket types, you need to add multiple orders to a trolley, one order for each ticket type / price band. However there are currently some restrictions enforced so if you want to do this you will need to contact us first.
Request
Example request - reserving best available tickets, specifying specific discount codes
curl https://api.ticketswitch.com/f13/reserve.v1 \
-u "demo:demopass" \
-d "perf_id=6IF-B1S" \
-d "ticket_type_code=CIRCLE" \
-d "price_band_code=C/pool" \
-d "no_of_seats=3" \
-d "disc0=ADULT" \
-d "disc1=CHILD" \
-d "disc2=CHILD" \
--compressed \
-X POST
from pyticketswitch import Client
client = Client('demo', 'demopass')
reservation, meta = client.make_reservation(
performance_id='6IF-A7N',
ticket_type_code='CIRCLE',
price_band_code='C/pool',
number_of_seats=3,
discounts=['ADULT', 'CHILD', 'CHILD']
)
Example request - reserving specific seats
curl https://api.ticketswitch.com/f13/reserve.v1 \
-u "demo:demopass" \
-d "perf_id=7AB-5" \
-d "ticket_type_code=STALLS" \
-d "price_band_code=A/pool" \
-d "no_of_seats=2" \
-d "seat0=A1" \
-d "seat1=A2" \
--compressed \
-X POST
from pyticketswitch import Client
client = Client('demo', 'demopass')
reservation, meta = client.make_reservation(
performance_id='7AB-5',
ticket_type_code='STALLS',
price_band_code='A/pool',
number_of_seats=2,
seats=['A1', 'A2']
)
Example request - reserving orders previously added to a trolley
curl https://api.ticketswitch.com/f13/reserve.v1 \
-u "demo:demopass" \
-d "trolley_token=s2--pFMaAzbxn3wG3zY-OAuclGgU9zzsUFJOLXpOquDKNGpwGn205i4_XzD6O6i8ZCqo2qxmA5QdvETbr7DlqTsbLayzHrvvf9zrz2NdGZuggwXHdx3cgPdbJzFeexIylGsxo7d3T9FWUkViv76Rz7qUH8qXeb9nWjF7ahrNsuHA8w_R63XmOQVNDIvJFS1hC6vFO3sD3t0MqKKguqRWuP4mM2vRN6BimgWYqrNqQw5D_-bfumE1Xl2vXu3FgSEp_N9dpsQ1fXK3qfoOiH-Hsd0F2Zh84IyMcrJkGZH8dlhdEWbvaMlu1rQ8Kw6hJMUigc31jbfHjuquCpDgI-OKyV8LQuQGz8wZsxj3jwWmLClcl50W7p1dTVLEYIW52jWqALRYFAresEGqzct0xDCeaoAjZ5vagMS2KXVmZ" \
--compressed \
-X POST
from pyticketswitch import Client
client = Client('demo', 'demopass')
reservation, meta = client.make_reservation(
token='s2--pFMaAzbxn3wG3zY-OAuclGgU9zzsUFJOLXpOquDKNGpwGn205i4_XzD6O6i8ZCqo2qxmA5QdvETbr7DlqTsbLayzHrvvf9zrz2NdGZuggwXHdx3cgPdbJzFeexIylGsxo7d3T9FWUkViv76Rz7qUH8qXeb9nWjF7ahrNsuHA8w_R63XmOQVNDIvJFS1hC6vFO3sD3t0MqKKguqRWuP4mM2vRN6BimgWYqrNqQw5D_-bfumE1Xl2vXu3FgSEp_N9dpsQ1fXK3qfoOiH-Hsd0F2Zh84IyMcrJkGZH8dlhdEWbvaMlu1rQ8Kw6hJMUigc31jbfHjuquCpDgI-OKyV8LQuQGz8wZsxj3jwWmLClcl50W7p1dTVLEYIW52jWqALRYFAresEGqzct0xDCeaoAjZ5vagMS2KXVmZ'
)
Note that the request parameters and response attributes are similar to trolley.
Parameter | Description |
---|---|
discX |
Specify a discount code for ticket number X, with zero-based numbering (so to specify the CHILD discount code on the second ticket use disc1=CHILD ). Note that illegal discount codes are replaced with legal ones. It is optional to specify discount codes, however note that if you choose to specify them you must specify all of them. If you do not specify discount codes you will receive the default discount code - this will match what you are shown when you request availability. |
no_of_seats |
The number of tickets you want to reserve. |
perf_id |
The performance identifier for the tickets that you want to reserve. |
price_band_code |
The price band identifier for the tickets that you want to reserve. |
remove_items_list |
A comma separated list of order item_number s that you want to remove from the trolley before reserving. |
seatX |
Specify a specific seat for ticket number X, with zero-based numbering (so to specify seat A12 as the first ticket use seat0=A12 ). If seat numbers are not specified then you will receive best available seats. |
X_send_code |
Specify a send / despatch method for supplier system X. If this is not present it will default to the first send method. For example, to specify the POST send method for the nimax supplier system, use nimax_send_code=POST . |
ticket_type_code |
The ticket type identifier for the tickets that you want to add to your trolley. |
trolley_token |
The identifier for a trolley. This is used to reserve multiple items at once. |
req_predicted_commission |
Optional. Include to retrieve commission data. For most partners this will include predicted_user_commission only (the predicted amount you earn per ticket). Some partners will also see predicted_gross_commission , which is the total commission available to be shared between Ingresso and our partner. By default you will see predicted_user_commission only - if you think you need to see predicted_gross_commission as well then please get in touch. |
Additional parameters, primarily for internal use:
Parameter | Description |
---|---|
departure_date |
Specify a departure date for example departure_date=20170214 . |
duration |
Specify a duration for hotel product, for example duration=3 . |
promo_code |
Specifying a promo codes can unlock a special offer discount code. If you have a promo code it can be specified like this: promo_code=FOO . Note that this feature is not commonly used with partners. |
All of the following parameters can also be used to request additional data for the event and performance in each order. These are described in more detail in the Events section here.
Parameter | Description |
---|---|
req_avail_details |
Returns availability details - a cached list of unique ticket types and price bands available for the event and performance in each order. This parameter is not commonly used. |
req_avail_details_with_perfs |
This will add the list of available performance dates to each avail detail object. Only valid if used alongside req_avail_details. |
req_cost_range |
Returns cost ranges - a from price and offer detail for the event and performance in each order. |
req_cost_range_best_value_offer |
Returns the offer with the highest percentage saving. |
req_cost_range_details |
Returns a list of unique ticket types and price bands and their cost ranges across all performances. This parameter is not commonly used. |
req_cost_range_max_saving_offer |
Returns the offer with the highest absolute saving. |
req_cost_range_min_cost_offer |
Returns the offer with the lowest cost. |
req_cost_range_top_price_offer |
Returns the offer with the highest cost. This is the least used offer cost range. |
req_cost_range_no_singles_data |
This returns another cost range object that excludes availability with only 1 consecutive seat available. The prices in this cost range will therefore be the same or higher than the outer cost range. It has the same structure as the main cost range (so if you want to see the “best value offer” in the no singles data, you need to add req_cost_range_best_value_offer and you will see this data in both cost ranges). |
req_extra_info |
Returns the descriptive info for the event, returned as individual sections (structured_info ) or as a single summary (event_info / event_info_html ). |
req_media_triplet_one |
Triplet one (jpg/png 520x390). See further detail on media. |
req_media_triplet_two |
Triplet two if available (jpg/png 520x390). |
req_media_triplet_three |
Triplet three if available (jpg/png 520x390). |
req_media_triplet_four |
Triplet four if available (jpg/png 520x390). |
req_media_triplet_five |
Triplet five if available (jpg/png 520x390). |
req_media_seating_plan |
Graphical seating plan of the venue if available (jpg/png varying size). |
req_media_square |
Small square image suitable for search or event avatar (jpg/png 140x140). |
req_media_landscape |
Small landscape banner suitable for search (jpg/png 220x115). |
req_media_marquee |
Large landscape banner suitable for a page heading, if available (jpg/png 700x300). |
req_media_supplier |
Logo of the supplier/producer, if available (jpg/png varying size). |
req_reviews |
Returns event reviews if available. |
req_video_iframe |
Returns video iframe information if available. |
Response
Example response - reserving orders previously added to a trolley
{
"allowed_countries": {
"ad": "Andorra",
"ae": "United Arab Emirates",
"af": "Afghanistan",
"ag": "Antigua and Barbuda",
....
"uk": "United Kingdom",
"um": "The United States Minor Outlying Islands",
"us": "United States of America",
"uy": "Uruguay"
},
"can_edit_address": true,
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"minutes_left_on_reserve": 15,
"needs_agent_reference": false,
"needs_email_address": false,
"needs_payment_card": false,
"prefilled_address": {
"country_code": "uk"
},
"trolley_contents": {
"bundle": [
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test0",
"bundle_source_desc": "External Test Backend 0",
"bundle_total_cost": 76.5,
"bundle_total_seatprice": 75,
"bundle_total_send_cost": 1.5,
"bundle_total_surcharge": 0,
"currency_code": "gbp",
"order": [
{
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"got_requested_seats": false,
"item_number": 1,
"performance": {
"date_desc": "Tue, 13th June 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-06-13T19:30:00+01:00",
"perf_id": "6IF-B1S",
"perf_name": "Including back stage pass",
"running_time": 120,
"time_desc": "7.30 PM"
},
"price_band_code": "C/pool",
"send_method": {
"send_code": "COBO",
"send_cost": 1.5,
"send_desc": "Collect from the venue",
"send_type": "collect"
},
"ticket_orders": {
"ticket_order": [
{
"discount_code": "ADULT",
"discount_desc": "Adult",
"no_of_seats": 3,
"sale_seatprice": 25,
"sale_surcharge": 0,
"seats": [
{
"col_id": "424",
"full_id": "GL424",
"is_restricted_view": false,
"row_id": "GL"
},
{
"col_id": "421",
"full_id": "GL421",
"is_restricted_view": false,
"row_id": "GL"
},
{
"col_id": "418",
"full_id": "GL418",
"is_restricted_view": false,
"row_id": "GL"
}
],
"total_sale_seatprice": 75,
"total_sale_surcharge": 0
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle",
"total_no_of_seats": 3,
"total_sale_seatprice": 75,
"total_sale_surcharge": 0
}
]
}
],
"transaction_uuid": "e18c20fc-042e-11e7-975c-002590326962",
"trolley_bundle_count": 1,
"trolley_order_count": 1
},
"unreserved_orders": []
}
from pyticketswitch.send_method import SendMethod
from pyticketswitch.country import Country
from pyticketswitch.seat import Seat
from pyticketswitch.address import Address
from pyticketswitch.event import Event
from pyticketswitch.bundle import Bundle
from pyticketswitch.performance import Performance
from pyticketswitch.reservation import Reservation
from pyticketswitch.order import TicketOrder
from pyticketswitch.trolley import Trolley
from pyticketswitch.order import Order
Reservation(
status='reserved',
reserved_at=datetime.datetime(2017, 5, 3, 15, 1, 45, tzinfo=tzutc()),
trolley=Trolley(
transaction_uuid='6d080a78-3011-11e7-b228-0025903268dc',
bundles=[
Bundle(
source_code='ext_test1',
orders=[
Order(
item=1,
event=Event(
id='7AB',
status='live',
description='The Unremarkable Incident of the Cat at Lunchtime'
,
source='External Test Backend 1',
source_code='ext_test1',
event_type='simple_ticket',
venue='Lyric Apollo',
classes={
'theatre': 'Theatre'
},
postcode='W6 7ES',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.49306,
longitude=-0.22639,
max_running_time=90,
min_running_time=90,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
),
performance=Performance(
id='7AB-5',
event_id='7AB',
date_time=datetime.datetime(2019, 1, 1, 15, 30, tzinfo=tzutc()) ,
date_description='Tue, 1st January 2019',
time_description='3.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=90,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='NORMAL',
seats=[
Seat(
id='A1',
column='1',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
),
Seat(
id='A2',
column='2',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
)
],
description='Regular Ticket',
number_of_seats=2,
seatprice=50.0,
surcharge=5.0,
total_seatprice=100.0,
total_surcharge=10.0,
)
],
number_of_seats=2,
total_seatprice=100.0,
total_surcharge=10.0,
seat_request_status='got_all',
requested_seat_ids=[
'A1',
'A2'
],
send_method=SendMethod(
code='VOUCH',
cost=0.0,
description='Printable eTicket',
type='selfprint',
can_generate_self_print=False,
),
)
],
description='External Test Backend 1',
total_seatprice=100.0,
total_surcharge=10.0,
total_send_cost=0.0,
total=110.0,
currency_code='gbp',
)
],
minutes_left=14.9833333333,
),
languages=[
'en'
],
needs_payment_card=False,
needs_email_address=False,
needs_agent_reference=False,
can_edit_address=True,
allowed_countries=[
Country(
code='uk',
description='United Kingdom',
)
],
minutes_left=14.9833333333,
)
Example response - one order - reserved failed
{
"input_contained_unavailable_order": false,
"unreserved_orders": [
{
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"theatre": "Theatre"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"custom_filter": [],
"event_desc": "TEST EVENT - The Unremarkable Incident of the Cat at Lunchtime",
"event_id": "7AB",
"event_path": "/7AB-test-event-the-unremarkable-incident-of-the-cat-at-lunchtime/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"7AA",
"6IF"
]
},
"event_uri_desc": "TEST-EVENT-The-Unremarkable-Incident-of-the-Cat-at-Lunchtime",
"geo_data": {
"latitude": 51.49306,
"longitude": -0.22639
},
"has_no_perfs": false,
"is_add_on": false,
"is_auto_quantity_add_on": false,
"is_date_matched_add_on": false,
"is_seated": true,
"is_time_matched_add_on": false,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "W6 7ES",
"show_perf_time": true,
"source_code": "ext_test1",
"source_desc": "External Test Backend 1",
"venue_desc": "Lyric Apollo",
"venue_uri_desc": "Lyric-Apollo"
},
"internal_reserve_sub_ref": "",
"internal_reserve_sub_ref2": "",
"item_number": 1,
"performance": {
"date_desc": "Sun, 1st January 2023",
"event_id": "7AB",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2023-01-01T15:30:00Z",
"perf_id": "7AB-9",
"time_desc": "3.30 PM"
},
"price_band_code": "B/pool",
"requested_seat_ids": [
"H9",
"H10"
],
"reserve_failure_comment": "Seat H10 causes failure.",
"seat_request_status": "got_none",
"send_method": {
"can_generate_self_print": false,
"has_html_page": true,
"send_code": "VOUCH",
"send_cost": 0.0,
"send_desc": "Printable E-Ticket (Test)",
"send_type": "selfprint"
},
"ticket_orders": {
"ticket_order": [
{
"discount_code": "NORMAL",
"discount_desc": "Regular Ticket",
"discount_semantic_type": "standard",
"no_of_seats": 2,
"sale_combined": 35.0,
"sale_seatprice": 30.0,
"sale_surcharge": 5.0,
"total_sale_combined": 70.0,
"total_sale_seatprice": 60.0,
"total_sale_surcharge": 10.0
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Dress Circle",
"total_no_of_seats": 2,
"total_sale_combined": 70.0,
"total_sale_seatprice": 60.0,
"total_sale_surcharge": 10.0
}
]
}
The response will include an identifier for the reserve, detail of the reserved items, detail of items that weren’t able to be reserved, and a set of flags that confirm the information you need to collect from your customer when purchasing tickets.
Attribute | Description |
---|---|
accepted_payment_cards |
This should not be present for partners and can be ignored. |
allowed_countries |
A list of country codes and human-readable descriptions. The country codes are ISO 3166-1 alpha-2 codes. This list is relevant when selecting a despatch method that is restricted to certain countries, for example a local post despatch method may only be available in the supplier’s country. These are typically presented to customers in a dropdown list on a checkout page. The customer’s country code is a required parameter when purchasing tickets. |
can_edit_address |
Indicates whether it is possible to change the non-blank prefilled_address data. This is primarily for internal use and can be ignored for normal use cases (it only applies to partners who have asked to have a prefilled address held in the Ingresso system). In most cases this will be true . If it is false the non-blank prefilled_address fields will be used when tickets are purchased and we will ignore the values in these fields if they are passed to us. |
input_contained_unavailable_order |
This is a flag that will get set to true if part of the reservation request could not be reserved. This occurs when we weren’t able to find any available products that matched the request and it usually means the user has passed in invalid parameters or is requesting an item that is sold out. |
needs_agent_reference |
For the vast majority of partners this will be false and can be ignored. However some partners ask to require that they specify their own reference when purchasing tickets - if this is true then the reference must be passed in. |
needs_email_address |
If true you must pass in an email address when purchasing tickets. We recommend that you always send us the customer’s email address. We guarantee to only use this if our customer service team need to contact your customer in an emergency or if our supplier needs to directly email confirmation to your customer (this is not used for any events as at Jan 2017, but is possible in future). If you cannot send the customer’s email address then we recommend that you don’t send an email address if needs_email_address is false ; if it is true then send an internal email address (for example your customer service email address) and it will be your responsibility to contact the customer or pass on booking confirmation. |
needs_payment_card |
This will be false for all partners so can be ignored. If this is true you need to collect card details from the customer and include them when purchasing. |
prefilled_address |
Some partners will have an address already held in the Ingresso system which should be prefilled for the user (by default this will not be enabled for partners - you will need to explicitly request it). The non-blank fields below should be prefilled. can_edit_address indicates whether the user can edit any of the prefilled fields. |
prefilled_address.address_line_one |
The first line of the address - if this is non-blank it should be prefilled. |
prefilled_address.address_line_two |
The second line of the address - if this is non-blank it should be prefilled. |
prefilled_address.country_code |
The country code of the address - if this is non-blank it should be prefilled. |
prefilled_address.email_address |
The email address - if this is non-blank it should be prefilled. |
prefilled_address.home_phone |
The home phone - if this is non-blank it should be prefilled. |
prefilled_address.postcode |
The postcode / zip code - if this is non-blank it should be prefilled. |
prefilled_address.town |
The town - if this is non-blank it should be prefilled. |
prefilled_address.work_phone |
The work phone - if this is non-blank it should be prefilled. |
trolley_contents |
See below for object detail. |
supports_billing_address |
For the vast majority of partners this can be ignored (it isn’t relevant to partners who purchase on-credit). When it is true a separate address may be provided when purchasing tickets, and this will be used to validate the payment card address for venue systems that perform address verification checks. |
unreserved_orders |
A list of orders that could not be reserved. |
trolley_contents
attributes:
Attribute | Description |
---|---|
bundle |
See below for object detail. |
minutes_left_on_reserve |
A numeric representation of the number of minutes that your reserve will be held open for. For example, 12.5 is 12 minutes and 30 seconds. |
transaction_uuid |
The unique reference for this reservation. This is needed for any further interactions with the reservation. |
trolley_bundle_count |
The number of bundles in the trolley. |
trolley_order_count |
The number of orders in the trolley. There will be at least one order for every bundle. |
As explained in more detail in trolley, a trolley contains three nested objects:
A
bundle
represents all orders from a particular supplier.An
order
represents a number of tickets to a particularprice band
andticket type
, for a particular performance of an event.An
order
will contain multipleticket_order
s when more than onediscount code
is used (for example ticket 1 and 2 have the ADULT discount code, and tickets 3 and 4 have the CHILD discount code). In this example there will be twoticket_order
s: one for ADULT and one for CHILD.
If you only plan to reserve
a single item at a time then a successful reserve
will contain a single order
within a single bundle
.
bundle
attributes
Attribute | Description |
---|---|
bundle_order_count |
The number of orders in this bundle. |
bundle_source_code |
The code of the supplier system that this bundle will be purchased from. |
bundle_source_desc |
The name of the supplier system that this bundle will be purchased from. |
bundle_total_cost |
The total cost of this bundle. |
bundle_total_cost_in_desired |
The total cost of this bundle, converted to your desired_currency . This field will not be present for most partners. |
bundle_total_seatprice |
The total face value for this bundle. |
bundle_total_seatprice_in_desired |
The total face value for this bundle, converted to your desired_currency . This field will not be present for most partners. |
bundle_total_send_cost |
The despatch cost for this bundle (similar to a transaction fee). Orders within the same bundle will be sent together. |
bundle_total_send_cost_in_desired |
The despatch cost for this bundle, converted to your desired_currency . This field will not be present for most partners. |
bundle_total_surcharge |
The total booking fee for this bundle. |
bundle_total_surcharge_in_desired |
The total booking fee for this bundle, converted to your desired_currency . This field will not be present for most partners. |
currency_code |
The currency code for the price - further detail for the currency can be found in the currency_details object, described below. |
debitor_choices |
A list of debitors. See below for object detail. |
desired_currency_code |
Most partners will not see a desired_currency_code , but it is possible for a partner to request to always view prices in a specific currency. For example if a product is supplied in GBP, but your desired_currency_code is set to USD, we will return prices in GBP along with _desired prices in USD. If you are taking payment using Ingresso’s Stripe connection, then payment will be taken in the default currency (GBP, in the example), and if you are being invoiced by Ingresso we will invoice you in the default currency (GBP, in the example). So the _desired prices are typically used to just display an indicative amount to the customer (in USD, in the example). Currency conversion rates are taken from a daily European Central Bank feed. |
order |
See below for object detail. |
Debitor data is returned when payment should be taken via Stripe. Stripe integration is described in detail within purchase.
debitor
attributes:
Attribute | Description |
---|---|
debitor_desc |
A human-readable description of the debitor. |
debitor_integration_data |
Data you will need t |
debitor_name |
The name of the debitor. For Stripe transactions this will be stripe . |
debitor_type |
The type of the debitor. For Stripe transactions this will be stripe . |
order
attributes:
Attribute | Description |
---|---|
event |
The event for this order. |
item_number |
A unique sequential number for the order . The second order added to the trolley will have item_number 2. The item_number remains constant as orders are added or removed, so if item_number 1 is removed, the first order will be item_number 2. |
performance |
The performance for this order. |
price_band_code |
The code for a price band, for example “C/pool”. The price band code is generally made up of the code from the underlying supplier system, e.g. “C”, followed by a “/” separator then “pool” or “alloc”, indicating whether the price band is taken from the general pool of tickets or is from a ring-fenced allocation. |
reserve_failure_comment |
A comment relating to why reserving this order failed. This field will appear when reserving the order failed and it lies in the unreserved_orders array. |
seat_request_status |
The status of your tickets after they have been reserved. Possible values are not_requested (specific seats not requested), got_none (you requested A13 and A14 but we gave you A15 and A16), got_partial (you requested A13 and A14 but we gave you A14 and A15), got_all (you requested A13 and A14 and you got A13 and A14 - by far the most common response when requesting specific seats). |
ticket_orders |
An array of ticket_order objects, one for each discount code. See below for detail. |
ticket_type_code |
The unique identifier for the ticket type. For attractions this can refer to variations such as General Admission or Fast Track, and there is often only only. For seated events this normally refers to a part of house / seating area such as Grand Circle. |
ticket_type_desc |
The description for the ticket type. This should be displayed to the customer |
total_no_of_seats |
The number of tickets for this order. |
total_sale_seatprice |
The total face value for this order. |
total_sale_seatprice_in_desired |
The total face value for this order, converted to your desired_currency . This field will not be present for most partners. |
total_sale_surcharge |
The total booking fee for this order. |
total_sale_surcharge_in_desired |
The total booking fee for this order, converted to your desired_currency . This field will not be present for most partners. |
ticket_order
attributes:
Attribute | Description |
---|---|
discount_code |
The discount code that applies to this ticket_order. |
discount_desc |
The description for the discount code. |
no_of_seats |
The number of tickets in this ticket_order. |
sale_seatprice |
The face value per ticket in this ticket_order. |
sale_seatprice_in_desired |
The face value per ticket in this ticket_order, converted to your desired_currency . This field will not be present for most partners. |
sale_surcharge |
The booking fee per ticket in this ticket_order. |
sale_surcharge_in_desired |
The booking fee per ticket in this ticket_order, converted to your desired_currency . This field will not be present for most partners. |
seats |
For seated events, an array of reserved seats. See below for detail. |
total_sale_seatprice |
The total face value of all tickets in this ticket_order. |
total_sale_seatprice_in_desired |
The total face value of all tickets in this ticket_order, converted to your desired_currency . This field will not be present for most partners. |
total_sale_surcharge |
The total booking fee of all tickets in this ticket_order. |
total_sale_surcharge_in_desired |
The total booking fee of all tickets in this ticket_order, converted to your desired_currency . This field will not be present for most partners. |
seats
attributes:
Attribute | Description |
---|---|
col_id |
The column identifier of the seat. |
full_id |
The ID of the seat - comprised of the col_id and the row_id , sometimes with a separator between them. |
is_restricted_view |
true if the seat is classified as having a restricted view. |
row_id |
The row identifier of the seat. |
seat_text |
A message about the seat that must be displayed to customers. |
seat_text_code |
An identifier for the seat text (only unique within the current bundle_source_code ). Not useful for most partners. |
The outer object includes a currency_details
object containing one currency
object (indexed on the currency code) for every currency referenced in the
JSON response. Each currency has the following attributes:
Attribute | Description |
---|---|
currency_code |
ISO 4217 three letter code |
currency_factor |
Multiply by this number to get values in the base unit (e.g. multiplying $47.11 by the currency_factor will give 4711 cents) |
currency_number |
ISO 4217 numeric identifier |
currency_places |
The number of decimal places to display (eg 45.5 usd should be displayed as 45.50) |
currency_post_symbol |
A symbol to display at the end of the price |
currency_pre_symbol |
A symbol to display in front of the price |
Release
Definition
POST https://api.ticketswitch.com/f13/release.v1?transaction_uuid={trans_uuid}
This resource allows you to release previously-reserved tickets. It is important that your integration releases tickets as soon as it is clear that they will not be purchased, either because your customer explicitly removes them from a basket or similar, or because they implicitly imply that they want to continue browsing, for example by pressing back on your checkout page (when a user presses back on sites developed by Ingresso we release their reservation then request availability to ensure the user is also able to select the just-released tickets). This is necessary to ensure that all end users have the best possible access to tickets (including your other customers).
Request
Example request
curl https://api.ticketswitch.com/f13/release.v1 \
-u "demo:demopass" \
-d "transaction_uuid=f2158be3-d29e-11e6-8aab-0025903268dc" \
--compressed \
-X POST
from pyticketswitch import Client
client = Client('demo', 'demopass')
released = client.release_reservation('f2158be3-d29e-11e6-8aab-0025903268dc')
Parameter | Description |
---|---|
transaction_uuid |
The unique identifier for a previous reserve. |
Response
Example response
{
"released_ok": true
}
True
This resource will return the same response when called multiple times.
Attribute | Description |
---|---|
released_ok |
true if the release succeeded. |
Purchase
Definition
POST https://api.ticketswitch.com/f13/purchase.v1
To purchase tickets you must first reserve them. You can then
attempt to purchase the reserved tickets at any time within the reserve time
(minutes_left_on_reserve
). A successful result from purchase
means that the
order has been confirmed in the supplier ticketing system. Note that if you have
attempted to purchase multiple events from a single trolley it is possible for a
purchase to partially succeed, with some events unable to be purchased from the
corresponding supplier ticketing system.
If a purchase fails due to incomplete or incorrect customer data then you can reattempt the purchase call with corrected data. If a purchase fails due to the reservation having timed out, then it is necessary to reserve tickets again. The output data is structured such that permanent failures are not reported as errors, but are reported as an actual result from a successful operation.
For purchases where a despatch method with a type of selfprint
was selected,
the URL returned should be presented to the customer.
Your payment option determines how you should call purchase. The two main options are:
On-credit purchasing
You take payment using a payment provider of your own choosing. When calling purchase you should just provide customer data, and the purchase call will return a success or failure.
Stripe
Stripe is a developer-friendly payment provider that is simple to integrate with. The Ingresso API provides a payment processing engine that gives you integration support for Stripe and other payment sources. You pass us a Stripe payment intent generated during your checkout, and we handle the rest. We support partners collecting payment via their own Stripe account or into Ingresso’s Stripe account.
In either case, you need integrate against Stripe.js and collect a Stripe token after your customer enters their payment details. The payment intent information is passed to Ingresso before making the purchase call.
If you want to collect payment via your own Stripe account you will need to get an agreement with us to sell tickets on credit, and we will invoice you for the ticket price less your commission. You will need to provide Ingresso your Stripe keys to allow us to process payment on your behalf.
If you wish to use Ingresso’s Stripe account we have some requirements to reduce fraud including implementing 3D Secure support and passing in the customer’s IP address, so please get in touch with us first. We however encourage partners to open their own Stripe account rather than use ours.
In the examples below we will describe how to purchase using the on-credit and Stripe options in more detail. We then describe how to handle generic redirects which are needed for other supported payment providers such as Global Collect. We recommend that all partners that wish to use Stripe also implement generic redirects - this is a small amount of additional development work that ensures you will be able to accept alternate payment methods both now and in future.
Notes on sending customer data
You must pass in the customer name, phone number and address for the purchase to succeed, and in some cases the email address is also required. Some partners do not wish to share customer data. At a minimum you should send us the customer name (first and last name) and phone number.
The customer name is used by the venue, in particular as a security measure when admitting customers, so this is essential.
The phone number can be used by Ingresso or the venue in emergency circumstances to contact the customer (for example if an evening performance is cancelled in the morning - this is not uncommon for theatre shows). It will not be used for any other reason. We therefore highly recommend that you provide the customer’s phone number to avoid a bad customer experience should they need to be contacted.
The email address is only required if
needs_email_address
=true
in the response from reserve. We recommend that you always send us the customer’s email address. We guarantee to only use this if our customer service team need to contact your customer or if our supplier needs to directly email confirmation to your customer (this is not used for any events as at March 2017, but is possible in future). If you cannot send the customer’s email address then we recommend that you don’t send any email address ifneeds_email_address
isfalse
; if it istrue
then send an internal email address (for example your customer service email address) and it will be your responsibility to contact the customer or pass on booking confirmation.Please note that some vendor systems require customer email addresses to be unique, as they create an internal customer object connected to the booking. In this case, subsequent purchases using the same email address may fail or overwrite customer names from previous purchases, so please let us know if you plan to use an internal email address and we will ensure that the purchases for these vendor systems use a unique email address per-transaction.
The address fields (for example
address_line_one
) need to be passed to us. The only use for these is for tickets that will be posted by Ingresso or the supplier, so it is possible to only pass the customer’s address when the customer has selected a despatch method withsend_type
=post
. In all other cases you can pass a default address such as your company headquarters (in case it turns out that tickets need to be unexpectedly posted). Note that if you are purchasing with Stripe and are using AVS (this is common) then you may wish to allow your customer to enter separate post or zip codes - one to submit to Ingresso (postal address) and one to submit to Stripe (billing address).If the
send_type
=post
and you are purchasing with Stripe you may wish to give customers the option of entering a separate billing address (if the zip or postal code passed to Stripe is not where the customer wants the tickets to be posted to). Note that you may not wish to support separate addresses to discourage fraud.
Confirmation Emails
After a successful purchase it is generally a good idea to send your customer a confirmation email reminding them of the items that they have purchased and including any relevant information such as directions or self print vouchers.
Ingresso can do this for you via the send_confirmation_email
flag on the
purchase call, or alternatively you can implement your own confirmation emails
using the results of the status.v1
call.
Ingresso can style these emails to conform with your businesses branding. For more information drop us an email at affiliate@ingresso.co.uk.
Purchasing on credit
Request
Example request - purchasing on-credit
curl https://api.ticketswitch.com/f13/purchase.v1 \
-u "demo:demopass" \
-d "transaction_uuid=61cfd4eb-1f5b-11e7-b228-0025903268dc" \
-d "first_name=Test" \
-d "last_name=Tester" \
-d "address_line_one=Metro Building" \
-d "address_line_two=1 Butterwick" \
-d "town=London" \
-d "county=London" \
-d "postcode=W6 8DL" \
-d "country_code=uk" \
-d "phone=0203 137 7420" \
-d "user_can_use_customer_data=true" \
-d "email_address=testing@gmail.com" \
-d "send_confirmation_email=true" \
-d "privacy_policy_version=2.2.1" \
--compressed \
-X POST
from pyticketswitch import Client
from pyticketswitch.customer import Customer
client = Client('demo', 'demopass')
customer = Customer(
first_name='Test',
last_name='Tester',
address_lines=['Metro Building', '1 Butterwick'],
town='London',
county='London',
post_code='W6 8DL',
country_code='uk',
phone='0203 137 7420',
email='testing@gmail.com',
user_can_use_customer_data=True,
)
status, callout, meta = client.make_purchase(
'61cfd4eb-1f5b-11e7-b228-0025903268dc',
customer,
send_confirmation_email=True,
)
This section describes how to purchase on credit.
Parameter | Description |
---|---|
address_line_one |
The first line of the customer’s address - required. Either pass your customer’s address or your head office address (see customer data note above). |
address_line_two |
The second line of the customer’s address. Optional if address_line_one is provided. |
agent_reference |
Partners can pass their own transaction reference to be stored in the Ingresso platform. Optional. |
country_code |
The ISO 3166-1 alpha-2 country code of the customer’s address - required. The country code must have been present in the allowed_countries list from reserve. |
county |
The county of region of the customer’s address. Optional. |
email_address |
The customer’s email address. Required when needs_email_address was true from the reserve response. We recommend this is provided - see customer data note above. |
first_name |
The customer’s first name - required. Used by venues as a security measure when admitting customers. |
home_phone |
The customer’s home phone number. Optional if phone is provided. |
initials |
The customer’s initials for their name. Optional. |
last_name |
The customer’s last name - required. Used by venues as a security measure when admitting customers. |
phone |
The customer’s phone number - required. Used by venues and Ingresso as a means to contact customers (see customer data note above). It is optional if you specify the work_phone and home_phone separately instead. |
postcode |
The ZIP or postal code of the customer’s address. Optional. |
suffix |
The suffix of the customer’s name, for example “Jr.” or “CPA” Optional. |
send_confirmation_email |
When set to true Ingresso will send your customer a confirmation email with details of their purchase (including a link to a self print voucher when applicable). If you would prefer to send your own confirmation emails then do not specify this flag. Requries the email_address parameter to be provided. |
supplier_can_use_customer_data |
Data protection question - set this to true if the customer has opted in to receiving marketing emails from the ticket supplier. Optional - it will default to false. |
title |
The title of the customer’s name, for example “Mr.” or “Dr.” Optional. |
town |
The city or town of the customer’s address. Optional. |
transaction_uuid |
The unique reference for the reserved tickets, taken from the reserve response. |
user_can_use_customer_data |
Data protection question - set this to true if the customer has opted in to receiving marketing emails from you. Most partners manage marketing opt-ins themselves so do not provide this. Ingresso will never send marketing communications to your customers based on this parameter. Optional - it will default to false. |
work_phone |
The customer’s work phone number. Optional if phone is provided. |
world_can_use_customer_data |
Data protection question - set this to true if the customer has opted in to receiving marketing emails communication from you and third-parties. Optional - it will default to false. |
privacy_policy_version |
The version of your website privacy policy that the customer has agreed to. This is freeform text, not necessarily a number. Optional - it will default to blank. |
All of the parameters used to request additional data for events can also be added.
Response
Example response - purchasing on-credit
{
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"customer": {
"addr_line_one": "Metro Building",
"addr_line_one_latin": "Metro Building",
"addr_line_two": "1 Butterwick",
"addr_line_two_latin": "1 Butterwick",
"agent_ref": "",
"country": "United Kingdom",
"country_code": "uk",
"country_latin": "United Kingdom",
"county": "",
"county_latin": "",
"email_addr": "testing@gmail.com",
"first_name": "Test",
"first_name_latin": "Test",
"home_phone": "0203 137 7420",
"initials": "",
"initials_latin": "",
"last_name": "Tester",
"last_name_latin": "Tester",
"postcode": "W6 8DL",
"postcode_latin": "W6 8DL",
"privacy_policy_version": "2.2.1",
"suffix": "",
"suffix_latin": "",
"supplier_can_use_customer_data": false,
"title": "",
"title_latin": "",
"town": "London",
"town_latin": "London",
"user_can_use_customer_data": true,
"work_phone": "0203 137 7420",
"world_can_use_customer_data": false
},
"language_list": [
"en-gb",
"en",
"en-us",
"nl"
],
"purchase_iso8601_date_and_time": "2017-04-12T08:38:35Z",
"reserve_iso8601_date_and_time": "2017-04-12T08:38:20Z",
"transaction_status": "purchased",
"trolley_contents": {
"bundle": [
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test0",
"bundle_source_desc": "External Test Backend 0",
"bundle_total_cost": 62.5,
"bundle_total_seatprice": 51,
"bundle_total_send_cost": 1.5,
"bundle_total_surcharge": 10,
"currency_code": "gbp",
"order": [
{
"backend_purchase_reference": "PURCHASE-6710-1",
"backend_cancellation_reference": "",
"cancellation_comment" : "",
"cancellation_status" : "possible",
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"got_requested_seats": false,
"gross_commission": {
"amount_excluding_vat": 7.13,
"amount_including_vat": 8.55,
"commission_currency_code": "gbp"
},
"item_number": 1,
"performance": {
"date_desc": "Tue, 13th June 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-06-13T19:30:00+01:00",
"perf_id": "6IF-B1S",
"perf_name": "Including back stage pass",
"running_time": 120,
"time_desc": "7.30 PM"
},
"price_band_code": "C/pool",
"send_method": {
"send_code": "COBO",
"send_cost": 1.5,
"send_desc": "Collect from the venue",
"send_final_type": "collect",
"send_type": "collect"
},
"supported_barcode_types": [
"qr_code"
],
"ticket_orders": {
"ticket_order": [
{
"discount_code": "ADULT",
"discount_desc": "Adult",
"no_of_seats": 1,
"sale_seatprice": 25,
"sale_surcharge": 4,
"seats": [
{
"col_id": "386",
"full_id": "NM386",
"is_restricted_view": false,
"row_id": "NM"
}
],
"total_sale_seatprice": 25,
"total_sale_surcharge": 4
},
{
"discount_code": "CHILD",
"discount_desc": "Child rate",
"no_of_seats": 2,
"sale_seatprice": 13,
"sale_surcharge": 3,
"seats": [
{
"col_id": "383",
"full_id": "NM383",
"is_restricted_view": false,
"row_id": "NM"
},
{
"col_id": "380",
"full_id": "NM380",
"is_restricted_view": false,
"row_id": "NM"
}
],
"total_sale_seatprice": 26,
"total_sale_surcharge": 6
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle",
"total_no_of_seats": 3,
"total_sale_seatprice": 51,
"total_sale_surcharge": 10,
"user_commission": {
"amount_excluding_vat": 3.21,
"amount_including_vat": 3.85,
"commission_currency_code": "gbp"
}
}
],
"purchase_result": {
"is_semi_credit": false,
"success": true
}
}
],
"purchase_result": {
"is_partial": false,
"success": true
},
"transaction_id": "T000-0000-8RGW-3619",
"transaction_uuid": "61cfd4eb-1f5b-11e7-b228-0025903268dc",
"trolley_bundle_count": 1,
"trolley_order_count": 1
}
}
from pyticketswitch.send_method import SendMethod
from pyticketswitch.purchase_result import PurchaseResult
from pyticketswitch.seat import Seat
from pyticketswitch.event import Event
from pyticketswitch.status import Status
from pyticketswitch.customer import Customer
from pyticketswitch.bundle import Bundle
from pyticketswitch.performance import Performance
from pyticketswitch.order import TicketOrder
from pyticketswitch.trolley import Trolley
from pyticketswitch.order import Order
# An on credit purchase should always return a status object and will never
# return a callout.
Status(
status='purchased',
reserved_at=datetime.datetime(2017, 5, 3, 15, 1, 45, tzinfo=tzutc()),
purchased_at=datetime.datetime(2017, 5, 3, 15, 14, 5, tzinfo=tzutc()),
trolley=Trolley(
transaction_uuid='6d080a78-3011-11e7-b228-0025903268dc',
transaction_id='T000-0000-8ZVV-2E78',
bundles=[
Bundle(
source_code='ext_test1',
orders=[
Order(
item=1,
cancellation_comment='',
cancellation_status='possible',
event=Event(
id='7AB',
status='live',
description='The Unremarkable Incident of the Cat at Lunchtime',
source='External Test Backend 1',
source_code='ext_test1',
event_type='simple_ticket',
venue='Lyric Apollo',
classes={
'theatre': 'Theatre'
},
postcode='W6 7ES',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.49306,
longitude=-0.22639,
max_running_time=90,
min_running_time=90,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
),
performance=Performance(
id='7AB-5',
event_id='7AB',
date_time=datetime.datetime(2019, 1, 1, 15, 30, tzinfo=tzutc()) ,
date_description='Tue, 1st January 2019',
time_description='3.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=90,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='NORMAL',
seats=[
Seat(
id='A1',
column='1',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
),
Seat(
id='A2',
column='2',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
)
],
description='Regular Ticket',
number_of_seats=2,
seatprice=50.0,
surcharge=5.0,
total_seatprice=100.0,
total_surcharge=10.0,
)
],
number_of_seats=2,
total_seatprice=100.0,
total_surcharge=10.0,
seat_request_status='got_all',
requested_seat_ids=[
'A1',
'A2'
],
backend_purchase_reference='PURCHASE-DA6E-0',
backend_cancellation_reference='',
send_method=SendMethod(
code='VOUCH',
cost=0.0,
description='Printable eTicket',
type='selfprint',
can_generate_self_print=False,
self_print_voucher_url='https://api.ticketswitch.com/tickets/web_self_print.buy/demo?crypto_block=M_--R-aJRIR74rjx8gM2szdo9BEJZ8oV6wfGukxyZGDA2_DU2K3w-Y8L_3LWvIgKO_QxwMN8WmasaUuL_WpzKS-q2roXIWxXqjTxyDYZdge-wjDI0RZ8NpBAS0--Y',
),
)
],
description='External Test Backend 1',
total_seatprice=100.0,
total_surcharge=10.0,
total_send_cost=0.0,
total=110.0,
currency_code='gbp',
)
],
purchase_result=PurchaseResult(
success=True,
),
),
languages=[
'en'
],
customer=Customer(
first_name='Test',
first_name_latin='Test',
last_name='Tester',
last_name_latin='Tester',
address_lines=[
'Metro Building',
'1 Butterwick'
],
address_lines_latin=[
'Metro Building',
'1 Butterwick'
],
title='',
title_latin='',
initials='',
initials_latin='',
suffix='',
suffix_latin='',
country_code='uk',
post_code='W6 8DL',
post_code_latin='W6 8DL',
town='London',
town_latin='London',
county='London',
county_latin='London',
country='United Kingdom',
country_latin='United Kingdom',
email='',
home_phone='0203 137 7420',
work_phone='0203 137 7420',
agent_reference='',
supplier_can_use_data=False,
user_can_use_data=True,
world_can_use_data=False,
),
)
Attribute | Description |
---|---|
customer |
See below for object detail. |
language_list |
Not useful for most partners, can be ignored. |
purchase_iso8601_date_and_time |
The purchase time in ISO 8601 format. |
reserve_iso8601_date_and_time |
The reserve time in ISO 8601 format. |
transaction_status |
purchased , failed or attempting (will only be seen if the customer is being redirected to a payment page - most partners will not see this). |
trolley_contents |
See below for object detail. |
customer
attributes:
Attribute | Description |
---|---|
addr_line_one |
The first line of the customer’s address. |
addr_line_one_latin |
The first line of the customer’s address, converted to Latin characters (this should allow a European latin alphabet language speaker to read an address containing only Japanese or Chinese characters, for example). |
addr_line_two |
The second line of the customer’s address, if provided. |
addr_line_two_latin |
The second line of the customer’s address, if provided, converted to Latin characters. |
agent_ref |
A partner transaction reference, if this was passed in as a parameter. |
country |
The country from the customer’s address. |
country_code |
The ISO 3166-1 alpha-2 country code of the customer’s address. |
country_latin |
The country, converted to Latin characters. |
county |
The county from the customer’s address, if provided. |
county_latin |
The county, converted to Latin characters. |
dp_supplier |
Has the customer opted in to receiving marketing emails from the ticket supplier. |
dp_user |
Has the customer opted in to receiving marketing emails from you. |
dp_world |
Has the customer opted in to receiving marketing emails communication from you and third-parties. |
email_addr |
The customer’s email address, if provided. |
first_name |
The customer’s first name. |
first_name_latin |
The customer’s first name, converted to Latin characters. |
home_phone |
The customer’s home phone number. |
initials |
The initials of the customer’s name, if provided. |
initials_latin |
The customer’s initials, converted to Latin characters. |
last_name |
The customer’s surname. |
last_name_latin |
The customer’s surname, converted to Latin characters. |
postcode |
The customer’s postcode, if provided. |
postcode_latin |
The customer’s postcode, converted to Latin characters. |
suffix |
The suffix of the customer’s name, if provided. |
suffix_latin |
The customer’s suffix, converted to Latin characters. |
title |
The title of the customer’s name, if provided. |
title_latin |
The customer’s title, converted to Latin characters. |
town |
The customer’s town or city, if provided. |
town_latin |
The customer’s town, converted to Latin characters. |
work_phone |
The customer’s work phone number. |
trolley_contents
attributes:
Attribute | Description |
---|---|
bundle |
An array of bundles. A bundle is a group of orders purchased from a single supplier ticketing system. See below for object detail. |
purchase_result.is_partial |
true if you attempted to purchase items from more than one supplier ticketing system (therefore you attempted to purchase multiple bundles), but only some of the purchases were successful. |
purchase_result.success |
true if the purchase succeeded if at least one of the bundles succeeded. |
transaction_id |
The primary Ingresso transaction reference. |
transaction_uuid |
The secondary Ingresso transaction reference. |
trolley_bundle_count |
The number of bundles in the trolley (a bundle is a group of orders purchased from a single supplier ticketing system). |
trolley_order_count |
The number of orders in the trolley (an order is tickets for a single event). |
bundle
attributes:
Attribute | Description |
---|---|
bundle_order_count |
The number of orders (i.e. events) in this bundle. |
bundle_source_code |
The code Ingresso use to identify the supplier ticketing system. |
bundle_source_desc |
The description of the supplier ticketing system. |
bundle_total_cost |
bundle_total_seatprice + bundle_total_surcharge + bundle_total_send_cost . |
bundle_total_cost_in_desired |
bundle_total_seatprice_in_desired + bundle_total_surcharge_in_desired + bundle_total_send_cost_in_desired . |
bundle_total_seatprice |
The total face value. |
bundle_total_seatprice_in_desired |
The total face value in your desired currency. This field won’t be present unless you have requested a desired currency. |
bundle_total_send_cost |
The total cost for despatching tickets. |
bundle_total_send_cost_in_desired |
The total despatch cost in your desired currency. |
bundle_total_surcharge |
The total booking fee. |
bundle_total_surcharge_in_desired |
The total booking fee in your desired currency. |
currency |
The currency of the costs. |
desired_currency |
Your desired currency, if this has been requested. |
order |
See below for object detail. |
purchase_result.is_semi_credit |
Legacy - can be ignored. |
purchase_result.success |
true if the purchase succeeded for this bundle. |
order
attributes:
Attribute | Description |
---|---|
backend_purchase_reference |
The purchase reference from the supplier ticketing system. This reference should be included on customer confirmation emails and self-print vouchers as this is the only reference that the venue will recognise. |
backend_cancellation_reference |
The cancellation reference from the supplier ticketing system. This will usually be empty until a cancellation has been attempted. |
cancellation_comment |
A comment from the cancellation attempt. |
cancellation_status |
If this is not_permitted then it is not possible to cancel this order, if it is possible then it is possible to cancel this order, see cancellations. |
event |
The event object, with the same format as for the events endpoint. |
gross_commission |
The total commission available to both Ingresso and the partner. This will only be visible for partners on margin share agreements or where Ingresso take a fixed fee. If you believe you should have gross_commission visible please contact us |
gross_commission.amount_excluding_vat |
The total commission amount excluding sales tax. |
gross_commission.amount_including_vat |
The total commission amount including sales tax. |
gross_commission.commission_currency |
The commission currency (note that this can be different to the currency seen by the customer). |
item_number |
Each order item within a transaction has an item_number, starting at 1. |
performance |
The performance object, with the same format as for the performances endpoint. |
price_band_code |
The code for a price band, for example “C/pool”. The price band code is generally made up of the code from the underlying supplier system, e.g. “C”, followed by a “/” separator then “pool” or “alloc”, indicating whether the price band is taken from the general pool of tickets or is from a ring-fenced allocation. |
seat_request_status |
The status of your tickets after they have been reserved. Possible values are not_requested (specific seats not requested), got_none (you requested A13 and A14 but we gave you A15 and A16), got_partial (you requested A13 and A14 but we gave you A14 and A15), got_all (you requested A13 and A14 and you got A13 and A14 - by far the most common response when requesting specific seats). |
send_method |
See below for object detail. |
supported_barcode_types |
An array of strings. See below for possible values |
ticket_orders |
An array of ticket_order objects, one for each discount code. See below for detail. |
ticket_type_code |
The unique identifier for the ticket type. For attractions this can refer to variations such as General Admission or Fast Track, and there is often only only. For seated events this normally refers to a part of house / seating area such as Grand Circle. |
ticket_type_desc |
The description for the ticket type. This should be displayed to the customer |
total_no_of_seats |
The number of tickets for this order. |
total_sale_seatprice |
The total face value for this order. |
total_sale_seatprice_in_desired |
The total face value for this order, converted to your desired_currency . This field will not be present for most partners. |
total_sale_surcharge |
The total booking fee for this order. |
total_sale_surcharge_in_desired |
The total booking fee for this order, converted to your desired_currency . This field will not be present for most partners. |
user_commission |
The commission you earn from this transaction. |
user_commission.amount_excluding_vat |
Your commission excluding sales tax. |
user_commission.amount_excluding_vat |
Your commission excluding sales tax. |
user_commission.amount_including_vat |
Your commission including sales tax. |
user_commission.commission_currency |
The commission currency (note that this can be different to the currency seen by the customer). |
send_method
attributes:
Attribute | Description |
---|---|
can_generate_self_print |
true if you are allowed up to produce your own self print vouchers (eTickets), false if you have to use the voucher URL below. |
has_html_page |
true if an HTML voucher is returned. |
self_print_voucher_url |
The voucher / eTicket URL. This should be displayed to your customer. |
send_code |
The code for this send method. |
send_cost |
The despatch cost for the chosen send method. |
send_cost_in_desired |
The despatch cost for the chosen send method, converted to your desired currency if you have one (in most cases this won’t be present). |
send_desc |
The description for this send method. |
send_final_comment |
. Will not always be present. |
send_final_type |
The classification of send method: one of selfprint , collect or post . The final_type should be the same as the type. |
send_type |
The classification of send method: one of selfprint , collect or post . |
supported_barcode_types
values:
An array of strings with the following possible values:
code128
qr_code
pdf417
aztec
aztec_small
datamatrix
code39
code93
ticket_order
attributes:
Attribute | Description |
---|---|
discount_code |
The discount code that applies to this ticket_order. |
discount_desc |
The description for the discount code. |
no_of_seats |
The number of tickets in this ticket_order. |
sale_seatprice |
The face value per ticket in this ticket_order. |
sale_seatprice_in_desired |
The face value per ticket in this ticket_order, converted to your desired_currency . This field will not be present for most partners. |
sale_surcharge |
The booking fee per ticket in this ticket_order. |
sale_surcharge_in_desired |
The booking fee per ticket in this ticket_order, converted to your desired_currency . This field will not be present for most partners. |
seats |
For seated events, an array of reserved seats. See below for detail. |
total_sale_seatprice |
The total face value of all tickets in this ticket_order. |
total_sale_seatprice_in_desired |
The total face value of all tickets in this ticket_order, converted to your desired_currency . This field will not be present for most partners. |
total_sale_surcharge |
The total booking fee of all tickets in this ticket_order. |
total_sale_surcharge_in_desired |
The total booking fee of all tickets in this ticket_order, converted to your desired_currency . This field will not be present for most partners. |
seats
attributes:
Attribute | Description |
---|---|
col_id |
The column identifier of the seat. |
full_id |
The ID of the seat - comprised of the col_id and the row_id , sometimes with a separator between them. |
is_restricted_view |
true if the seat is classified as having a restricted view. |
row_id |
The row identifier of the seat. |
seat_text |
A message about the seat that must be displayed to customers. |
seat_text_code |
An identifier for the seat text (only unique within the current bundle_source_code ). Not useful for most partners. |
barcode |
The barcode data for the ticket if returned by the supplier system. |
Purchasing with Stripe
Ingresso have an integration with Stripe for credit card processing, and can accept payment on your behalf from your customers. Ingresso Payments has a completed PCI-DSS SAQ-D and attestation of compliance as a payment service provider and our card payments solution uses Stripe to ensure no cardholder data goes through our systems.
There are two ways that you can integrate with Ingresso using Stripe. The Ingresso white label is fully integrated on the front- and back-end with Stripe and is EU PSD2-compliant with support for Strong Customer Authentication, Apple Pay and Google Pay and mobile-ready. This is our recommended approach to integrating using Ingresso’s payment services as this integration is well-tested, has thorough error handling for when payments or bookings fail and can be styled to match your branding while also keeping the booking flow and post-checkout flow on your own platform - you can simply redirect the customer to the Ingresso checkout page, and have them redirected back to you once payment has been taken.
The other way is to do the work of integrating with Stripe on your own site and sending tokenised payment information to Ingresso with the purchase request, and implementing all of the error handling and compliance support on your own platform - this gives you the greatest level of control over the user experience, but is a somewhat complex undertaking, which is why Ingresso recommends leveraging the white label solution for most partners.
Purchasing with Stripe requires your API user to be set up to use the Ingresso
Payments service, which will require contacting us. If you are interested in
testing this functionality, the demo-stripe
user has been created which is
already set up this way. The password is the same as for the demo
user.
After creating a reservation with this user, you can proceed to test purchasing
with Stripe, as outlined below.
Purchasing with a Stripe payment intent
In order to purchase with Stripe you need the following steps:
- Create a Stripe payment intent and collect payment information (further detail below).
- Save the Stripe payment intent in our payment processing engine, which will return a unique token as a reference
- Call
purchase.v1
passing in the payment engine reference from step 2.
Note that you need to retrieve and pass in one payment engine token for each bundle
that you
reserve. If you only support the purchase of one item at a time, or if you don’t
use the Ingresso API to help manage basketing then you can ignore this.
Generating a Stripe payment intent
Stripe allows you to create a payment intent at the start of a customer checkout and use this to collect payment information on your behalf. The payment information can either be collected on your own checkout page in a PCI-compliant manner (“Elements”), with a mobile-friendly form (“Checkout”), or via their mobile SDKs. See Stripe’s Quickstart guide.
You will need to provide Stripe with the appropriate publishable key - this is returned by Ingresso in the reserve call as bundle.debitor.debitor_integration_data.stripe.publishable_key.
Using Stripe payment intents ensures that you are able to meet the European Strong Customer Authentication (SCA) regulation when processing payments.
When creating a Stripe payment intent you’ll need to set its capture_method
to
'manual'
. This will allow Stripe’s Elements or SDKs used within your checkout page
to handle any customer verification needed for 3D Secure 2 while still allowing
Ingresso to process payments on your behalf.
See Stripe’s ‘Creating Payment Intents’ docs
for more info on this.
Saving the Stripe payment intent in the Ingresso Payments system
Example saving payment details
curl https://payments.ingresso.co.uk/api/save-details \
-H "Content-Type: application/json" \
-H "Authorization: Bearer key_XYZ789123" \
-X POST \
-d @- << EOF
{
"stripe_payment_intent": "pi_ABCD1234",
"stripe_meta_email_address": "customer@example.com",
"stripe_meta_event_ids": "6IF",
"stripe_meta_send_methods": "collect",
"stripe_meta_days_to_performance": 37,
"stripe_meta_user_id": "demo",
"stripe_meta_ip_address": "101.102.103.104"
}
EOF
# We suggest Javascript integration on the front end, but you can use
# a HTTP requests library if you'd prefer.
const integration_data = {
cider_api_endpoint: "https://payments.ingresso.co.uk/api",
cider_api_token: "key_XYZ789123",
};
// get Stripe token
let stripePaymentIntent = "pi_ABCD1234";
const http = new XMLHttpRequest();
http.open('POST', integration_data.cider_api_endpoint + '/save-details', true);
http.setRequestHeader('Content-type', 'application/json');
http.setRequestHeader('Authorization', 'Bearer ' + integration_data.cider_api_key);
http.onload = () => {
if (http.status === 200) {
// get token from response
} else {
// handle error
}
};
http.onerror = () => console.log("Unable to connect");
http.ontimeout = () => console.log("Connection timed out.");
http.send(JSON.stringify({ stripe_payment_intent: stripePaymentIntent }));
Example response
{"token": "cider_XYZ789123"}
Once you have a Stripe payment intent, you must save it in Ingresso’s payment
processing Engine (called Cider). The API endpoint you can use is also found in
the reserve call integration data, as
bundle.debitor.debitor_integration_data.cider_api_endpoint
. You will need to
use a unique key per reservation, found at
debitor_integration_data.cider_api_token
.
The API endpoint will look something like https://payments.ingresso.co.uk/api
and you can save the stripe payment intent generated above by making a HTTP
POST
request to this endpoint + /save-details
, and authenticating with the
key provided in the integration data.
In addition to saving Stripe payment intents, you can also save metadata about the purchase to this endpoint, which will be saved in Stripe against the purchase record. This is very important for anti-fraud rules when using the Ingresso Stripe account, and may be useful for your own account too.
You must pass in the actual customer’s remote_ip
if you are taking payment via
Ingresso’s Stripe account - we use this for fraud checks. It is also useful to
pass in the remote_site
so we know which website the customer purchased on.
One primary advantage of saving the details in this way is that it will not appear in Ingresso’s logs or database, and is only used as metadata in Stripe, so it reduces the spread of personally identifiable information. Please note that the call must include a valid Authorization header with the key included in the reservation response debitor integration data, and should be well-formed JSON, as per the examples.
Making the purchase call
Creating a Stripe payment intent is the first half of the payment process - further server-side code is required to complete the second half. You don’t need to worry about this as Ingresso’s payment processor takes care of it. Once you have saved the Stripe payment intent and retrieved the cider token, we will handle the following steps:
Authorise the payment with Stripe (if necessary).
Purchase your reserved tickets with the supplier ticketing system. If this step fails we automatically refund the Stripe payment.
Capture the payment with Stripe.
Purchase request
Example purchase request - Stripe
curl https://demo.ticketswitch.com/f13/purchase.v1 \
-u "demo-stripe:demopass" \
-d "transaction_uuid=2e740db5-1b65-11e7-9e97-002590326932" \
-d "first_name=Test" \
-d "last_name=Tester" \
-d "address_line_one=Metro Building" \
-d "address_line_two=1 Butterwick" \
-d "town=London" \
-d "county=London" \
-d "postcode=W6 8DL" \
-d "country_code=uk" \
-d "phone=0203 137 7420" \
-d "email_address=tester@gmail.com" \
-d "ext_test0_callback/cider_token=cider_XYZ789123" \
-d "send_confirmation_email=yes" \
-d "remote_ip=101.102.103.104" \
-d "remote_site=www.myticketshop.com" \
--compressed \
-X POST
from pyticketswitch import Client
from pyticketswitch.customer import Customer
from pyticketswitch.payment_methods import CiderDetails
client = Client('demo-stripe', 'demopass')
customer = Customer(
first_name='Test',
last_name='Tester',
address_lines=['Metro Building', '1 Butterwick'],
town='London',
county='London',
post_code='W6 8DL',
country_code='uk',
phone='0203 137 7420',
email='testing@gmail.com',
user_can_use_customer_data=True,
)
cider_details = CiderDetails(
{'cider_token': 'cider_XYZ789123'},
['ext_test0'],
)
status, callout, meta = client.make_purchase(
'7150d25f-301b-11e7-bede-0025903268a0',
customer,
payment_method=cider_details,
send_confirmation_email=True,
)
To complete a test Stripe purchase:
- Call reserve
- Create a Stripe payment intent
- Enter and handle test card details with the Stripe Elements example form using the
Stripe payment intent’s
client_secret
. - Save the Stripe payment intent ID in the Ingresso Payments processing service (Cider)
- Call purchase, replacing the transaction_uuid and ext_test0_callback/cider_token with the values from the 4 steps above.
All of the parameters mentioned above in the purchasing on credit section are used. In addition the following parameter should be specified:
Parameter | Description |
---|---|
remote_ip |
The end customer’s IP address. |
remote_site |
The website the end customer is purchasing from, not including https:// or http:// . |
X_callback/cider_token |
The single-use token retrieved from Cider after saving the stripe payment intent being used. You should replace X with the source_code returned by reserve . So for source_code=ext_test0 the parameter name used is ext_test0_callback/cider_token . If you support basketing and your customer is attempting to purchase items across multiple bundles, you should provide the same Cider token for each bundle (each bundle has a unique source_code ). |
Purchase response
Example purchase response - Stripe
{
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"customer": {
"addr_line_one": "Metro Building",
"addr_line_one_latin": "Metro Building",
"addr_line_two": "1 Butterwick",
"addr_line_two_latin": "1 Butterwick",
"agent_ref": "",
"country": "United Kingdom",
"country_code": "uk",
"country_latin": "United Kingdom",
"county": "",
"county_latin": "",
"dp_supplier": false,
"dp_user": false,
"dp_world": false,
"email_addr": "tester@gmail.com",
"first_name": "Test",
"first_name_latin": "Test",
"home_phone": "0203 137 7420",
"initials": "",
"initials_latin": "",
"last_name": "Tester",
"last_name_latin": "Tester",
"postcode": "W6 8DL",
"postcode_latin": "W6 8DL",
"suffix": "",
"suffix_latin": "",
"title": "",
"title_latin": "",
"town": "London",
"town_latin": "London",
"work_phone": "0203 137 7420"
},
"language_list": "en-gb,en,en-us,nl",
"purchase_iso8601_date_and_time": "2017-03-03T15:58:26Z",
"reserve_iso8601_date_and_time": "2017-03-03T15:58:01Z",
"transaction_status": "purchased",
"trolley_contents": {
"bundle": [
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test0",
"bundle_source_desc": "External Test Backend 0",
"bundle_total_cost": 62.5,
"bundle_total_seatprice": 51,
"bundle_total_send_cost": 1.5,
"bundle_total_surcharge": 10,
"currency_code": "gbp",
"order": [
{
"backend_purchase_reference": "PURCHASE-17BB2-1",
"cancellation_comment" : "",
"cancellation_status" : "possible",
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"got_requested_seats": false,
"gross_commission": {
"amount_excluding_vat": 7.13,
"amount_including_vat": 8.55,
"commission_currency_code": "gbp"
},
"item_number": 1,
"performance": {
"date_desc": "Tue, 13th June 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-06-13T19:30:00+01:00",
"perf_id": "6IF-B1S",
"perf_name": "Including back stage pass",
"running_time": 120,
"time_desc": "7.30 PM"
},
"price_band_code": "C/pool",
"send_method": {
"send_code": "COBO",
"send_cost": 1.5,
"send_desc": "Collect from the venue",
"send_final_type": "collect",
"send_type": "collect"
},
"ticket_orders": {
"ticket_order": [
{
"discount_code": "ADULT",
"discount_desc": "Adult",
"no_of_seats": 1,
"sale_seatprice": 25,
"sale_surcharge": 4,
"seats": [
{
"col_id": "419",
"full_id": "OR419",
"is_restricted_view": false,
"row_id": "OR"
}
],
"total_sale_seatprice": 25,
"total_sale_surcharge": 4
},
{
"discount_code": "CHILD",
"discount_desc": "Child rate",
"no_of_seats": 2,
"sale_seatprice": 13,
"sale_surcharge": 3,
"seats": [
{
"col_id": "416",
"full_id": "OR416",
"is_restricted_view": false,
"row_id": "OR"
},
{
"col_id": "413",
"full_id": "OR413",
"is_restricted_view": false,
"row_id": "OR"
}
],
"total_sale_seatprice": 26,
"total_sale_surcharge": 6
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle",
"total_no_of_seats": 3,
"total_sale_seatprice": 51,
"total_sale_surcharge": 10,
"user_commission": {
"amount_excluding_vat": 0,
"amount_including_vat": 0,
"commission_currency_code": "gbp"
}
}
],
"purchase_result": {
"is_semi_credit": false,
"success": true
}
}
],
"purchase_result": {
"is_partial": false,
"success": true
},
"transaction_id": "T000-0000-8N66-K30B",
"transaction_uuid": "2dac0d00-002a-11e7-975c-002590326962",
"trolley_bundle_count": 1,
"trolley_order_count": 1
}
}
from pyticketswitch.customer import Customer
from pyticketswitch.trolley import Trolley
from pyticketswitch.debitor import Debitor
from pyticketswitch.status import Status
from pyticketswitch.seat import Seat
from pyticketswitch.performance import Performance
from pyticketswitch.order import TicketOrder
from pyticketswitch.purchase_result import PurchaseResult
from pyticketswitch.event import Event
from pyticketswitch.send_method import SendMethod
from pyticketswitch.order import Order
from pyticketswitch.bundle import Bundle
# stripe purchases should always return a status object, and no callout.
Status(
status='purchased',
reserved_at=datetime.datetime(2017, 5, 3, 16, 13, 28, tzinfo=tzutc()),
purchased_at=datetime.datetime(2017, 5, 3, 16, 14, 19, tzinfo=tzutc()),
trolley=Trolley(
transaction_uuid='7150d25f-301b-11e7-bede-0025903268a0',
transaction_id='T000-0000-8ZW5-68A8',
bundles=[
Bundle(
source_code='ext_test0',
orders=[
Order(
item=1,
cancellation_comment='',
cancellation_status='possible',
event=Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
filters=[
],
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
critic_review_percent=100,
),
performance=Performance(
id='6IF-B0O',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 4, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Thu, 4th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='',
seats=[
Seat(
id='JM189',
column='189',
row='JM',
separator='',
is_restricted=False,
),
Seat(
id='JM190',
column='190',
row='JM',
separator='',
is_restricted=False,
)
],
description='',
number_of_seats=2,
seatprice=21.0,
surcharge=3.0,
total_seatprice=42.0,
total_surcharge=6.0,
)
],
number_of_seats=2,
total_seatprice=42.0,
total_surcharge=6.0,
seat_request_status='not_requested',
requested_seat_ids=[
],
backend_purchase_reference='PURCHASE-11F22-1',
send_method=SendMethod(
code='COBO',
cost=1.5,
description='Collect from the venue',
type='collect',
),
)
],
description='External Test Backend 0',
total_seatprice=42.0,
total_surcharge=6.0,
total_send_cost=1.5,
total=49.5,
currency_code='gbp',
debitor=Debitor(
type='cider',
name='cider',
description='Cider',
integration_data={
'cider_api_token': 'key_XYZ789123',
'cider_api_endpoint': 'https://payments.ingresso.co.uk/api',
'cider_js': 'https://payments.ingresso.co.uk/static/js/cider/cider.js',
'merchant_group_country_code': 'gb',
'stripe': {
'publishable_key': 'pk_test_b7N9DOwbo4B9t6EqCf9jFzfa',
'payment_sources_enabled': true,
'required': true,
},
},
),
)
],
discarded_orders=[
],
purchase_result=PurchaseResult(
success=True,
),
),
languages=[
'en'
],
customer=Customer(
first_name='Test',
first_name_latin='Test',
last_name='Tester',
last_name_latin='Tester',
address_lines=[
'Metro Building',
'1 Butterwick'
],
address_lines_latin=[
'Metro Building',
'1 Butterwick'
],
title='',
title_latin='',
initials='',
initials_latin='',
suffix='',
suffix_latin='',
country_code='uk',
post_code='W6 8DL',
post_code_latin='W6 8DL',
town='London',
town_latin='London',
county='London',
county_latin='London',
country='United Kingdom',
country_latin='United Kingdom',
email='testing@gmail.com',
home_phone='0203 137 7420',
work_phone='0203 137 7420',
agent_reference='',
),
)
The response is identical to the purchase
response described in purchasing on credit.
Using the Ingresso white label
To use the Ingresso white label solution only for the checkout functionality,
you will need at a minimum the transaction_uuid
from the reserve
step. However, for optimal customer experience it is also highly recommended
that you provide a trolley_token
that was used to create the reservation as
well.
For your live integration you will need to contact us to get a white label
created for you that has your branding and configuration created, but for the
purposes of integration you can test against the white label at
https://demo-stripe.ticketswitch.com/
using the demo-stripe
user as above.
Create a 302 redirect to the white label complete_booking
API:
GET https://demo-stripe.ticketswitch.com/api/complete_booking/<transaction_uuid>/?trolley_token=<token>&referer_url=<referer_url>
Parameter | Description |
---|---|
transaction_uuid |
The unique reference for the reserved tickets, taken from the reserve response. May also be provided as a GET query string parameter. |
trolley_token |
The trolley_token used to create the reservation. Optional. |
referer_url |
The URL of the page from which your customer is coming (mispelling in line with the HTTP specification). If not specified it will be taken from the request header. Used to send the customer back to you if they request a change in their booking details. Optional. |
After the purchase has completed, on the demo-stripe
white label the customer
is taken to the White Label’s confirmation page at
https://demo-stripe.ticketswitch.com/confirmation/<transaction_uuid>/
- this
behaviour is customisable and we can redirect the customer to any URL containing
the transaction_uuid
as a parameter.
Direct integration to the Ingresso payments API
In order to purchase with Stripe directly you need the following steps:
- Retrieve the Stripe PaymentIntent ID and client secret from the reservation
response in the
bundle.debitor.debitor_integration_data.stripe
section - Update the PaymentIntent as per the Stripe API docs
- Call
purchase.v1
passing in the PaymentIntent reference from step 2.
Note that you need to retrieve and pass in one payment parameter for each bundle
that you
reserve. If you only support the purchase of one item at a time, or if you don’t
use the Ingresso API to help manage basketing then you can ignore this but it is
a requirement for proper bundling support.
Updating the Stripe PaymentIntent
You will need to provide Stripe with the appropriate publishable key -
this is returned by Ingresso in the reserve call as
bundle.debitor.debitor_integration_data.stripe.publishable_key
.
Follow the Stripe PaymentIntents Guide for how to use a PaymentIntent with Stripe.js to ensure your integration is compatible with PCI-DSS and customer payment card information is kept secure.
EOF “`
# We suggest Javascript integration on the front end, but you can use
# a HTTP requests library if you'd prefer.
const integration_data = {
cider_api_endpoint: "https://payments.ingresso.co.uk/api",
cider_api_token: "key_XYZ789123",
stripe: {
payment_intent: "pi_test",
client_secret: "secret"
}
};
// get Stripe PaymentIntent and update it using the Stripe.js API
let stripePaymentIntent = integration_data.stripe.payment_intent;
const http = new XMLHttpRequest();
http.open('POST', integration_data.cider_api_endpoint + '/save-details', true);
http.setRequestHeader('Content-type', 'application/json');
http.setRequestHeader('Authorization', 'Bearer ' + integration_data.cider_api_key);
http.onload = () => {
if (http.status === 200) {
// get token from response
} else {
// handle error
}
};
http.onerror = () => console.log("Unable to connect");
http.ontimeout = () => console.log("Connection timed out.");
http.send(JSON.stringify({ stripe_payment_intent: stripePaymentIntent }));
Example response
{"token": "cider_XYZ789123"}
Once you have updated the Stripe PaymentIntent, you must save it in Ingresso’s
payment processing Engine (called Cider). The API endpoint you can use is also
found in the reserve call integration data, as
bundle.debitor.debitor_integration_data.cider_api_endpoint
. You will need to
use a unique key per reservation, found at
debitor_integration_data.cider_api_token
.
The API endpoint will look something like https://payments.ingresso.co.uk/api
and you can save the stripe payment intent generated above by making a HTTP
POST
request to this endpoint + /save-details
, and authenticating with the
key provided in the integration data.
In addition to saving stripe data and payment sources, you can also save metadata about the purchase to this endpoint, which will be saved in Stripe against the purchase record. This is very important for anti-fraud rules when using the Ingresso Stripe account, and may be useful for your own account too.
You must pass in the actual customer’s remote_ip
if you are taking payment via
Ingresso’s Stripe account - we use this for fraud checks. It is also useful to
pass in the remote_site
so we know which website the customer purchased on.
One primary advantage of saving the details in this way is that it will not appear in Ingresso’s logs or database, and is only used as metadata in Stripe, so it reduces the spread of personally identifiable information. Please note that the call must include a valid Authorization header with the key included in the reservation response debitor integration data, and should be well-formed JSON, as per the examples.
Making the purchase call
Updating the Stripe PaymentIntent is the first half of the payment process - further server-side code is required to complete the second half. You don’t need to worry about this as Ingresso’s payment processor takes care of it. Once you have saved the Stripe token and retrieved the cider token, we will handle the following steps:
Authorise the payment with Stripe (validate that the PaymentIntent is chargeable and of sufficient value to account for the transaction)
Purchase your reserved tickets with the supplier ticketing system. If this step fails we automatically refund the Stripe payment.
Capture the payment from Stripe.
Purchase request
Example purchase request - Stripe
curl https://api.ticketswitch.com/f13/purchase.v1 \
-u "demo-stripe:demopass" \
-d "transaction_uuid=2e740db5-1b65-11e7-9e97-002590326932" \
-d "first_name=Test" \
-d "last_name=Tester" \
-d "address_line_one=Metro Building" \
-d "address_line_two=1 Butterwick" \
-d "town=London" \
-d "county=London" \
-d "postcode=W6 8DL" \
-d "country_code=uk" \
-d "phone=0203 137 7420" \
-d "email_address=tester@gmail.com" \
-d "ext_test0_callback/cider_token=cider_XYZ789123" \
-d "send_confirmation_email=yes" \
-d "remote_ip=101.102.103.104" \
-d "remote_site=www.myticketshop.com" \
--compressed \
-X POST
from pyticketswitch import Client
from pyticketswitch.customer import Customer
from pyticketswitch.payment_methods import CiderDetails
client = Client('demo-stripe', 'demopass')
customer = Customer(
first_name='Test',
last_name='Tester',
address_lines=['Metro Building', '1 Butterwick'],
town='London',
county='London',
post_code='W6 8DL',
country_code='uk',
phone='0203 137 7420',
email='testing@gmail.com',
user_can_use_customer_data=True,
)
cider_details = CiderDetails(
{'cider_token': 'cider_XYZ789123'},
['ext_test0'],
)
status, callout, meta = client.make_purchase(
'7150d25f-301b-11e7-bede-0025903268a0',
customer,
payment_method=cider_details,
send_confirmation_email=True,
)
To complete a test Stripe purchase:
- Call reserve
- Enter test card details into the Stripe Elements example form and copy the Stripe token returned.
- Save the Stripe token in the Ingresso Payments processing service (Cider)
- Call purchase, replacing the transaction_uuid and ext_test0_callback/cider_token with the values from the 3 steps above.
All of the parameters mentioned above in the purchasing on credit section are used. In addition the following parameter should be specified:
Parameter | Description |
---|---|
remote_ip |
The end customer’s IP address. |
remote_site |
The website the end customer is purchasing from, not including https:// or http:// . |
X_callback/cider_token |
The single-use token retrieved from Cider after saving the Stripe payment intent being used. You should replace X with the source_code returned by reserve . So for source_code=ext_test0 the parameter name used is ext_test0_callback/cider_token . If you support basketing and your customer is attempting to purchase items across multiple bundles, you should provide the same Cider token for each bundle (each bundle has a unique source_code ). |
Purchase response
Example purchase response - Stripe
{
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"customer": {
"addr_line_one": "Metro Building",
"addr_line_one_latin": "Metro Building",
"addr_line_two": "1 Butterwick",
"addr_line_two_latin": "1 Butterwick",
"agent_ref": "",
"country": "United Kingdom",
"country_code": "uk",
"country_latin": "United Kingdom",
"county": "",
"county_latin": "",
"dp_supplier": false,
"dp_user": false,
"dp_world": false,
"email_addr": "tester@gmail.com",
"first_name": "Test",
"first_name_latin": "Test",
"home_phone": "0203 137 7420",
"initials": "",
"initials_latin": "",
"last_name": "Tester",
"last_name_latin": "Tester",
"postcode": "W6 8DL",
"postcode_latin": "W6 8DL",
"suffix": "",
"suffix_latin": "",
"title": "",
"title_latin": "",
"town": "London",
"town_latin": "London",
"work_phone": "0203 137 7420"
},
"language_list": "en-gb,en,en-us,nl",
"purchase_iso8601_date_and_time": "2017-03-03T15:58:26Z",
"reserve_iso8601_date_and_time": "2017-03-03T15:58:01Z",
"transaction_status": "purchased",
"trolley_contents": {
"bundle": [
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test0",
"bundle_source_desc": "External Test Backend 0",
"bundle_total_cost": 62.5,
"bundle_total_seatprice": 51,
"bundle_total_send_cost": 1.5,
"bundle_total_surcharge": 10,
"currency_code": "gbp",
"order": [
{
"backend_purchase_reference": "PURCHASE-17BB2-1",
"cancellation_comment" : "",
"cancellation_status" : "possible",
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"got_requested_seats": false,
"gross_commission": {
"amount_excluding_vat": 7.13,
"amount_including_vat": 8.55,
"commission_currency_code": "gbp"
},
"item_number": 1,
"performance": {
"date_desc": "Tue, 13th June 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-06-13T19:30:00+01:00",
"perf_id": "6IF-B1S",
"perf_name": "Including back stage pass",
"running_time": 120,
"time_desc": "7.30 PM"
},
"price_band_code": "C/pool",
"send_method": {
"send_code": "COBO",
"send_cost": 1.5,
"send_desc": "Collect from the venue",
"send_final_type": "collect",
"send_type": "collect"
},
"supported_barcode_types": [
"qr_code"
],
"ticket_orders": {
"ticket_order": [
{
"discount_code": "ADULT",
"discount_desc": "Adult",
"no_of_seats": 1,
"sale_seatprice": 25,
"sale_surcharge": 4,
"seats": [
{
"col_id": "419",
"full_id": "OR419",
"is_restricted_view": false,
"row_id": "OR"
}
],
"total_sale_seatprice": 25,
"total_sale_surcharge": 4
},
{
"discount_code": "CHILD",
"discount_desc": "Child rate",
"no_of_seats": 2,
"sale_seatprice": 13,
"sale_surcharge": 3,
"seats": [
{
"col_id": "416",
"full_id": "OR416",
"is_restricted_view": false,
"row_id": "OR"
},
{
"col_id": "413",
"full_id": "OR413",
"is_restricted_view": false,
"row_id": "OR"
}
],
"total_sale_seatprice": 26,
"total_sale_surcharge": 6
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle",
"total_no_of_seats": 3,
"total_sale_seatprice": 51,
"total_sale_surcharge": 10,
"user_commission": {
"amount_excluding_vat": 0,
"amount_including_vat": 0,
"commission_currency_code": "gbp"
}
}
],
"purchase_result": {
"is_semi_credit": false,
"success": true
}
}
],
"purchase_result": {
"is_partial": false,
"success": true
},
"transaction_id": "T000-0000-8N66-K30B",
"transaction_uuid": "2dac0d00-002a-11e7-975c-002590326962",
"trolley_bundle_count": 1,
"trolley_order_count": 1
}
}
from pyticketswitch.customer import Customer
from pyticketswitch.trolley import Trolley
from pyticketswitch.debitor import Debitor
from pyticketswitch.status import Status
from pyticketswitch.seat import Seat
from pyticketswitch.performance import Performance
from pyticketswitch.order import TicketOrder
from pyticketswitch.purchase_result import PurchaseResult
from pyticketswitch.event import Event
from pyticketswitch.send_method import SendMethod
from pyticketswitch.order import Order
from pyticketswitch.bundle import Bundle
# stripe purchases should always return a status object, and no callout.
Status(
status='purchased',
reserved_at=datetime.datetime(2017, 5, 3, 16, 13, 28, tzinfo=tzutc()),
purchased_at=datetime.datetime(2017, 5, 3, 16, 14, 19, tzinfo=tzutc()),
trolley=Trolley(
transaction_uuid='7150d25f-301b-11e7-bede-0025903268a0',
transaction_id='T000-0000-8ZW5-68A8',
bundles=[
Bundle(
source_code='ext_test0',
orders=[
Order(
item=1,
cancellation_comment='',
cancellation_status='possible',
event=Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
filters=[
],
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
critic_review_percent=100,
),
performance=Performance(
id='6IF-B0O',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 4, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Thu, 4th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='',
seats=[
Seat(
id='JM189',
column='189',
row='JM',
separator='',
is_restricted=False,
),
Seat(
id='JM190',
column='190',
row='JM',
separator='',
is_restricted=False,
)
],
description='',
number_of_seats=2,
seatprice=21.0,
surcharge=3.0,
total_seatprice=42.0,
total_surcharge=6.0,
)
],
number_of_seats=2,
total_seatprice=42.0,
total_surcharge=6.0,
seat_request_status='not_requested',
requested_seat_ids=[
],
backend_purchase_reference='PURCHASE-11F22-1',
send_method=SendMethod(
code='COBO',
cost=1.5,
description='Collect from the venue',
type='collect',
),
)
],
description='External Test Backend 0',
total_seatprice=42.0,
total_surcharge=6.0,
total_send_cost=1.5,
total=49.5,
currency_code='gbp',
debitor=Debitor(
type='cider',
name='cider',
description='Cider',
integration_data={
'cider_api_token': 'key_XYZ789123',
'cider_api_endpoint': 'https://payments.ingresso.co.uk/api',
'cider_js': 'https://payments.ingresso.co.uk/static/js/cider/cider.js',
'merchant_group_country_code': 'gb',
'stripe': {
'publishable_key': 'pk_test_b7N9DOwbo4B9t6EqCf9jFzfa',
'payment_sources_enabled': true,
'required': true,
},
},
),
)
],
discarded_orders=[
],
purchase_result=PurchaseResult(
success=True,
),
),
languages=[
'en'
],
customer=Customer(
first_name='Test',
first_name_latin='Test',
last_name='Tester',
last_name_latin='Tester',
address_lines=[
'Metro Building',
'1 Butterwick'
],
address_lines_latin=[
'Metro Building',
'1 Butterwick'
],
title='',
title_latin='',
initials='',
initials_latin='',
suffix='',
suffix_latin='',
country_code='uk',
post_code='W6 8DL',
post_code_latin='W6 8DL',
town='London',
town_latin='London',
county='London',
county_latin='London',
country='United Kingdom',
country_latin='United Kingdom',
email='testing@gmail.com',
home_phone='0203 137 7420',
work_phone='0203 137 7420',
agent_reference='',
),
)
The response is identical to the purchase
response described in
purchasing on credit, with some additional information
about the debitor result to aid with handling payment failures.
As the process and certification of an integration with Ingresso Payments and Stripe can be quite challenging, it is highly recommended that partners use the Ingresso White Label checkout component as part of their solution as this is tested and maintained.
Purchasing with redirect
This section describes how to handle generic redirects which are needed for other supported payment providers such as Global Collect. The vast majority of partners are either on-credit or Stripe, and so will use the payment methods mentioned above, but this supporting this method is recommended where possible.
Redirects are required when:
- Payment is taken on a third party payment page such as PayPal (customers are redirected to that page)
- 3D Secure is used (Verified by Visa or MasterCard SecureCode)
To support generic redirects you should use the following sequence:
- Call the
purchase
endpoint - The Ingresso platform will determine whether you need to redirect your customer. If so the response will include a
callout
section with the information you need to redirect your customer. - Redirect your customer to
callout_destination_url
, including thecallout_parameters
in the query string (they must be URL encoded). - After the redirect your customer will arrive back at your
return_url
, and you may receive query string or post parameters. - You should then call the
callback
endpoint, passing in verbatim all query string and post parameters you have received. These are needed by Ingresso to for example finalise the payment collection. - If any further redirects are required, the
callback
response will include acallout
section. You should continue to follow steps 3, 4 and 5 until thecallback
response no longer includes acallout
section. At this point the purchase will be complete (it will have either succeeded or failed).
Please note as an alternative to the integration steps above, the Ingresso Payments solution may also be used as a generic redirect, in which case the payment page will be presented by the Ingresso payment service directly.
Purchase request
Example purchase request - generic redirects
curl https://api.ticketswitch.com/f13/purchase.v1 \
-u "demo-redirect:demopass" \
-d "transaction_uuid=a75a03c3-efc2-11e6-a96d-d0bf9c45f5c0" \
-d "first_name=Test" \
-d "last_name=Tester" \
-d "address_line_one=Metro Building" \
-d "address_line_two=1 Butterwick" \
-d "town=London" \
-d "county=London" \
-d "postcode=W6 8DL" \
-d "country_code=uk" \
-d "phone=0203 137 7420" \
-d "email_address=tester@gmail.com" \
-d "return_token=FIRST_RANDOM_TOKEN" \
-d "return_url=https://www.yourticketingsite.com/token.FIRST_RANDOM_TOKEN/return.php" \
-d "client_http_user_agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.4.8 (KHTML, like Gecko) Version/10.0.3 Safari/602.4.8" \
-d "client_http_accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \
-d "send_confirmation_email=yes" \
-d "privacy_policy_version=2.2.1" \
-X POST
import uuid
from pyticketswitch import Client
from pyticketswitch.customer import Customer
from pyticketswitch.payment_methods import RedirectionDetails
client = Client('demo-redirect', 'demopass')
customer = Customer(
first_name='Test',
last_name='Tester',
address_lines=['Metro Building', '1 Butterwick'],
town='London',
county='London',
post_code='W6 8DL',
country_code='uk',
phone='0203 137 7420',
email='testing@gmail.com',
user_can_use_customer_data=True,
)
token = uuid.uuid4()
redirect_details = RedirectionDetails(
token=token,
url='https://www.fromtheboxoffice.com/callback/{}'.format(token),
user_agent='Mozilla/5.0 (X11; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0',
accept='text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
remote_site='www.fromtheboxoffice.com',
)
status, callout, meta = client.make_purchase(
'7150d25f-301b-11e7-bede-0025903268a0',
customer,
payment_method=redirect_details,
send_confirmation_email=True,
)
All of the parameters mentioned above in the purchasing on credit section are used. In addition the following parameters must be specified:
Parameter | Description |
---|---|
return_token |
This token must be alphanumeric with - , _ and . also allowed. We recommend that partners generate a UUID for this token. |
return_url |
The URL that your customer should arrive back to after being redirected. The return_token also has to be present in the path for the return_url and no query string parameters are allowed in the return_url. |
client_http_user_agent |
The user agent, taken from the headers of your customer’s web browser. This and client_http_accept are required because the payment provider that generates the callout may need to know detail of the browser, for example to serve a mobile-optimised page. |
client_http_accept |
The accept content types, from the headers of your customer’s web browser. |
Purchase response
Example purchase response - generic redirects
{
"callout": {
"callout_destination_url": "https://api.ticketswitch.com/tickets/dummy_redirect.buy/demo-redirect",
"callout_parameters": {
"return_url": "https://www.yourticketingsite.com/token.FIRST_UNIQUE_TOKEN/return.php",
"title": "Dummy external card details page for debit on system 'ext_test0'"
},
"callout_parameters_order": [],
"callout_type": "get",
"debitor_integration_data": {
"debit_amount": 62.5,
"debit_base_amount": 6250,
"debit_currency": "gbp",
"debitor_specific_data": {
"is_dummy_3d_secure": false
},
"debitor_type": "dummy"
}
},
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
}
}
from pyticketswitch.debitor import Debitor
from pyticketswitch.callout import Callout
# redirect purchases may return either a status object or a callout object
# when they requirement more information from the user.
Callout(
code='ext_test0',
description='External Test Backend 0',
total=49.5,
type='get',
destination='https://www.fromtheboxoffice.com/tickets/dummy_redirect.buy/demo-redirect',
parameters={
'return_url': 'https://www.fromtheboxoffice.com/callback/64e8a0d8-ca3a-4a3b-8a39-597ee66acdd0',
'title': "Dummy external card details page for debit on system 'ext_test0'"
},
integration_data={
'is_dummy_3d_secure': False
},
debitor=Debitor(
type='dummy',
name='dummy',
description='The Dummy Card Debitor',
integration_data={},
),
currency_code='gbp',
return_token='64e8a0d8-ca3a-4a3b-8a39-597ee66acdd0',
)
Attribute | Description |
---|---|
callout |
See below for object detail. |
currency_details |
Further details of the currencies found in the callout data. |
callout
attributes:
Attribute | Description |
---|---|
callout_destination_url |
The URL you should redirect your customer to. |
callout_parameters |
The parameters that should be passed. The callout_type will specify whether to use GET or POST. |
callout_parameters_order |
In most cases this will be blank, and it can be ignored. In very rare cases, for callout_type=get , it will include all callout_parameters in a specific order - you should then specify the parameters in that order. |
callout_type |
Whether you should make a GET or POST request. |
debitor_integration_data |
This data is not needed when redirecting (so is not of use to most partners). It provides information needed to avoid redirecting. |
Callback request
Example callback request - generic redirects
curl https://api.ticketswitch.com/f13/callback.v1/this.FIRST_UNIQUE_TOKEN/next.NEXT_UNIQUE_TOKEN \
-u "demo-redirect:demopass" \
-d "param1=asdfasdfsdfasdff" \
-r "https://www.thepaymentpage.com/asdfsadfsdafasdf" \
--compressed
-X POST
import uuid
from pyticketswitch import Client
client = Client('demo-redirect', 'demopass')
returned_data = {'success': 'yes'}
next_token = uuid.uuid4()
status, callout, meta = client.next_callout(
'64e8a0d8-ca3a-4a3b-8a39-597ee66acdd0',
next_token,
returned_data,
)
If the purchase
response received includes callout
data then you need to
redirect your customer and afterwards use the callback
endpoint.
Note that the URL structure is
callback.v1/this.[previous token used]/next.[new token]
.
If purchase
was the last endpoint hit, then the “previous token used” is
the return_token
that was passed in to purchase
. If the last endpoint hit
was callback
then “previous token used” is the “new token” you generated for
the previous callback
.
You should pass the payment page URL you have been referred from as the Referrer in the headers.
You should pass in verbatim all query string and post parameters you have received. These are needed by Ingresso to for example finalise the payment collection.
The callback
response will either:
- include further
callout
data, as in thepurchase
response example above, in which case you should redirect your customer and callcallback
again; or - include similar data to the
purchase
response described in purchasing on credit - the purchase is complete and has either succeeded or failed.
You should continue to call callback
until you no longer see callout
data.
Reserve Page Archive
Definition
GET https://api.ticketswitch.com/f13/reserve_page_archive.v1
This API call does not get an up to date status of the reservation, it is simply retrieving the previously sent reservation response, verbatim.
Reservation responses are held for 24 hours, this exceeds the length of time that reservations are valid for.
Do not interpret this response as meaning that a reservation is still being held as it is simply a verbatim copy of the original reservation response.
This means that you can access all the data that you would normally require from a status call, except that the status and the amount of time left on the reservation will not have been updated (as it will be exactly the same as the original reservation response).
As this is simply returning a verbatim copy of the original reservation response, HTTP content negotiation and any of the usually recognised req_
variables will be ignored.
If the original reservation response was an error then the same error will be returned when you request the reserve page archive.
If the reservation is not found then you will get an 400 error with error_code: 8
.
If the reservation is no longer being stored (i.e. more than 24 hours have passed since the original reservation was made) you will get a 410 Gone error with error_code: 8
.
Request
Example request
curl https://api.ticketswitch.com/f13/reserve_page_archive.v1 \
-u "demo:demopass" \
-d "transaction_uuid=U-986E1961-F8B7-11E8-8434-AC1F6B465FBC-C7DCDC47-LDNX" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
reservation, meta = client.get_reservation(
transaction_uuid="U-986E1961-F8B7-11E8-8434-AC1F6B465FBC-C7DCDC47-LDNX"
)
Parameter | Description |
---|---|
transaction_uuid |
The unique identifier returned by a previous reserve. |
Response
Example response - get a previously made reserve response
{
"needs_payment_card" : false,
"unreserved_orders" : [],
"allowed_countries" : {
"uk" : "United Kingdom"
},
"reserve_iso8601_date_and_time" : "2018-12-05T18:00:05Z",
"transaction_status" : "reserved",
"language_list" : [
"en"
],
"input_contained_unavailable_order" : false,
"needs_agent_reference" : false,
"minutes_left_on_reserve" : 15,
"currency_details" : {
"gbp" : {
"currency_number" : 826,
"currency_factor" : 100,
"currency_code" : "gbp",
"currency_pre_symbol" : "£",
"currency_post_symbol" : "",
"currency_places" : 2
}
},
"needs_email_address" : false,
"trolley_contents" : {
"trolley_bundle_count" : 1,
"transaction_uuid" : "U-986E1961-F8B7-11E8-8434-AC1F6B465FBC-C7DCDC47-LDNX",
"bundle" : [
{
"bundle_total_send_cost" : 1,
"bundle_source_code" : "ext_test1",
"currency_code" : "gbp",
"order" : [
{
"internal_reserve_sub_ref" : "",
"total_no_of_seats" : 3,
"total_sale_seatprice" : 150,
"item_number" : 1,
"ticket_orders" : {
"ticket_order" : [
{
"sale_surcharge" : 5,
"sale_seatprice" : 50,
"total_sale_seatprice" : 150,
"total_sale_surcharge" : 15,
"discount_desc" : "Regular Ticket",
"no_of_seats" : 3,
"discount_code" : "NORMAL",
"seats" : [
{
"col_id" : "2",
"full_id" : "B2",
"is_restricted_view" : false,
"row_id" : "B",
"seat_text_code" : "B.2"
},
{
"is_restricted_view" : false,
"col_id" : "3",
"full_id" : "B3",
"seat_text_code" : "B.3",
"row_id" : "B"
},
{
"col_id" : "4",
"full_id" : "B4",
"is_restricted_view" : false,
"seat_text_code" : "B.4",
"row_id" : "B"
}
]
}
]
},
"price_band_code" : "A/pool",
"ticket_type_desc" : "Stalls",
"event" : {
"is_auto_quantity_add_on" : false,
"city_code" : "london-uk",
"event_type" : "simple_ticket",
"custom_filter" : [],
"need_duration" : false,
"event_uri_desc" : "TEST-EVENT-The-Unremarkable-Incident-of-the-Cat-at-Lunchtime",
"venue_uri_desc" : "Lyric-Apollo",
"venue_desc" : "Lyric Apollo",
"event_id" : "7AB",
"event_desc" : "TEST EVENT - The Unremarkable Incident of the Cat at Lunchtime",
"is_seated" : true,
"postcode" : "W6 7ES",
"event_upsell_list" : {
"event_id" : [
"7AA",
"6IF"
]
},
"country_code" : "uk",
"need_departure_date" : false,
"classes" : {
"tours" : "Tours"
},
"min_running_time" : 90,
"event_status" : "live",
"source_code" : "ext_test1",
"city_desc" : "London",
"has_no_perfs" : false,
"show_perf_time" : true,
"is_add_on" : false,
"need_performance" : true,
"country_desc" : "United Kingdom",
"max_running_time" : 90,
"source_desc" : "External Test Backend 1",
"geo_data" : {
"latitude" : 51.49306,
"longitude" : -0.22639
},
"event_path" : "/7AB-test-event-the-unremarkable-incident-of-the-cat-at-lunchtime/"
},
"performance" : {
"time_desc" : "3.30 PM",
"has_pool_seats" : true,
"is_limited" : false,
"iso8601_date_and_time" : "2020-01-01T15:30:00Z",
"is_ghost" : false,
"event_id" : "7AB",
"date_desc" : "Wed, 1st January 2020",
"running_time" : 90,
"perf_id" : "7AB-6"
},
"send_method" : {
"can_generate_self_print" : false,
"send_desc" : "Printable eTicket",
"send_cost" : 1,
"has_html_page" : true,
"send_type" : "selfprint",
"send_code" : "VOUCH"
},
"seat_request_status" : "not_requested",
"total_sale_surcharge" : 15,
"ticket_type_code" : "STALLS",
"requested_seat_ids" : []
}
],
"bundle_total_cost" : 166,
"bundle_total_surcharge" : 15,
"bundle_order_count" : 1,
"bundle_total_seatprice" : 150,
"bundle_source_desc" : "External Test Backend 1"
}
],
"trolley_order_count" : 1
},
"can_edit_address" : true,
"prefilled_address" : {
"country_code" : "uk"
}
}
from pyticketswitch.send_method import SendMethod
from pyticketswitch.country import Country
from pyticketswitch.seat import Seat
from pyticketswitch.address import Address
from pyticketswitch.event import Event
from pyticketswitch.bundle import Bundle
from pyticketswitch.performance import Performance
from pyticketswitch.reservation import Reservation
from pyticketswitch.order import TicketOrder
from pyticketswitch.trolley import Trolley
from pyticketswitch.order import Order
Reservation(
status='reserved',
reserved_at=datetime.datetime(2017, 5, 3, 15, 1, 45, tzinfo=tzutc()),
trolley=Trolley(
transaction_uuid='U-986E1961-F8B7-11E8-8434-AC1F6B465FBC-C7DCDC47-LDNX',
bundles=[
Bundle(
source_code='ext_test1',
orders=[
Order(
item=1,
event=Event(
id='7AB',
status='live',
description='The Unremarkable Incident of the Cat at Lunchtime'
,
source='External Test Backend 1',
source_code='ext_test1',
event_type='simple_ticket',
venue='Lyric Apollo',
classes={
'theatre': 'Theatre'
},
postcode='W6 7ES',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.49306,
longitude=-0.22639,
max_running_time=90,
min_running_time=90,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
),
performance=Performance(
id='7AB-5',
event_id='7AB',
date_time=datetime.datetime(2019, 1, 1, 15, 30, tzinfo=tzutc()) ,
date_description='Tue, 1st January 2019',
time_description='3.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=90,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='NORMAL',
seats=[
Seat(
id='A1',
column='1',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
),
Seat(
id='A2',
column='2',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
)
],
description='Regular Ticket',
number_of_seats=2,
seatprice=50.0,
surcharge=5.0,
total_seatprice=100.0,
total_surcharge=10.0,
)
],
number_of_seats=2,
total_seatprice=100.0,
total_surcharge=10.0,
seat_request_status='got_all',
requested_seat_ids=[
'A1',
'A2'
],
send_method=SendMethod(
code='VOUCH',
cost=0.0,
description='Printable eTicket',
type='selfprint',
can_generate_self_print=False,
),
)
],
description='External Test Backend 1',
total_seatprice=100.0,
total_surcharge=10.0,
total_send_cost=0.0,
total=110.0,
currency_code='gbp',
)
],
minutes_left=14.9833333333,
),
languages=[
'en'
],
needs_payment_card=False,
needs_email_address=False,
needs_agent_reference=False,
can_edit_address=True,
allowed_countries=[
Country(
code='uk',
description='United Kingdom',
)
],
minutes_left=14.9833333333,
)
The returned attributes are identical to the original reserve response, even if the reservation has timed out or has been bought, this response will stay the same.
Attribute | Description |
---|---|
reserve_iso8601_date_and_time |
The time the tickets were successfully reserved. |
transaction_status |
Will always be reserved as that is what it was at the time of the reservation, even if the transaction has since expired or been purchased. |
trolley |
The trolley object, the trolley attributes are as described in the reserve response. Note that the value of minutes_left_on_reserve will be out of date as it will be the same as it was at reserve time. |
Purchase Page Archive
Definition
GET https://api.ticketswitch.com/f13/purchase_page_archive.v1
This API call does not get an up to date status of the purchase, it is simply retrieving the previously sent purchase response, verbatim.
This means that you can access all the data that you would normally require from a purchase call, except that the status could be out of date (as it will be exactly the same as the original purchase response).
As this is simply returning a verbatim copy of the original purchase response, HTTP content negotiation and any of the usually recognised req_
variables will be ignored.
If the original purchase response was an error then the same error will be returned when you request the purchase page archive.
The purchase responses are kept for at least a year.
If the purchase is not found then you will get an 400 error with error_code: 8
.
If the purchase is no longer being stored (i.e. more than a year has passed since the original purchase was made) you will get a 410 Gone error with error_code: 8
.
Request
Example request
curl https://api.ticketswitch.com/f13/purchase_page_archive.v1 \
-u "demo:demopass" \
-d "transaction_uuid=U-986E1961-F8B7-11E8-8434-AC1F6B465FBC-C7DCDC47-LDNX" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
reservation, meta = client.get_purchase(
transaction_uuid="U-986E1961-F8B7-11E8-8434-AC1F6B465FBC-C7DCDC47-LDNX"
)
Parameter | Description |
---|---|
transaction_uuid |
The unique identifier returned by a previous purchase. |
Response
Example response - a previously purchased transaction
{
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"customer": {
"addr_line_one": "Metro Building",
"addr_line_one_latin": "Metro Building",
"addr_line_two": "1 Butterwick",
"addr_line_two_latin": "1 Butterwick",
"agent_ref": "",
"country": "United Kingdom",
"country_code": "uk",
"country_latin": "United Kingdom",
"county": "",
"county_latin": "",
"email_addr": "testing@gmail.com",
"first_name": "Test",
"first_name_latin": "Test",
"home_phone": "0203 137 7420",
"initials": "",
"initials_latin": "",
"last_name": "Tester",
"last_name_latin": "Tester",
"postcode": "W6 8DL",
"postcode_latin": "W6 8DL",
"suffix": "",
"suffix_latin": "",
"supplier_can_use_customer_data": false,
"title": "",
"title_latin": "",
"town": "London",
"town_latin": "London",
"user_can_use_customer_data": true,
"work_phone": "0203 137 7420",
"world_can_use_customer_data": false
},
"language_list": [
"en-gb",
"en",
"en-us",
"nl"
],
"purchase_iso8601_date_and_time": "2017-04-12T08:38:35Z",
"reserve_iso8601_date_and_time": "2017-04-12T08:38:20Z",
"transaction_status": "purchased",
"trolley_contents": {
"bundle": [
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test0",
"bundle_source_desc": "External Test Backend 0",
"bundle_total_cost": 62.5,
"bundle_total_seatprice": 51,
"bundle_total_send_cost": 1.5,
"bundle_total_surcharge": 10,
"currency_code": "gbp",
"order": [
{
"backend_purchase_reference": "PURCHASE-6710-1",
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"got_requested_seats": false,
"gross_commission": {
"amount_excluding_vat": 7.13,
"amount_including_vat": 8.55,
"commission_currency_code": "gbp"
},
"item_number": 1,
"performance": {
"date_desc": "Tue, 13th June 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-06-13T19:30:00+01:00",
"perf_id": "6IF-B1S",
"perf_name": "Including back stage pass",
"running_time": 120,
"time_desc": "7.30 PM"
},
"price_band_code": "C/pool",
"send_method": {
"send_code": "COBO",
"send_cost": 1.5,
"send_desc": "Collect from the venue",
"send_final_type": "collect",
"send_type": "collect"
},
"ticket_orders": {
"ticket_order": [
{
"discount_code": "ADULT",
"discount_desc": "Adult",
"no_of_seats": 1,
"sale_seatprice": 25,
"sale_surcharge": 4,
"seats": [
{
"col_id": "386",
"full_id": "NM386",
"is_restricted_view": false,
"row_id": "NM"
}
],
"total_sale_seatprice": 25,
"total_sale_surcharge": 4
},
{
"discount_code": "CHILD",
"discount_desc": "Child rate",
"no_of_seats": 2,
"sale_seatprice": 13,
"sale_surcharge": 3,
"seats": [
{
"col_id": "383",
"full_id": "NM383",
"is_restricted_view": false,
"row_id": "NM"
},
{
"col_id": "380",
"full_id": "NM380",
"is_restricted_view": false,
"row_id": "NM"
}
],
"total_sale_seatprice": 26,
"total_sale_surcharge": 6
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle",
"total_no_of_seats": 3,
"total_sale_seatprice": 51,
"total_sale_surcharge": 10,
"user_commission": {
"amount_excluding_vat": 3.21,
"amount_including_vat": 3.85,
"commission_currency_code": "gbp"
}
}
],
"purchase_result": {
"is_semi_credit": false,
"success": true
}
}
],
"purchase_result": {
"is_partial": false,
"success": true
},
"transaction_id": "T000-0000-8RGW-3619",
"transaction_uuid": "61cfd4eb-1f5b-11e7-b228-0025903268dc",
"trolley_bundle_count": 1,
"trolley_order_count": 1
}
}
from pyticketswitch.send_method import SendMethod
from pyticketswitch.purchase_result import PurchaseResult
from pyticketswitch.seat import Seat
from pyticketswitch.event import Event
from pyticketswitch.status import Status
from pyticketswitch.customer import Customer
from pyticketswitch.bundle import Bundle
from pyticketswitch.performance import Performance
from pyticketswitch.order import TicketOrder
from pyticketswitch.trolley import Trolley
from pyticketswitch.order import Order
# An on credit purchase should always return a status object and will never
# return a callout.
Status(
status='purchased',
reserved_at=datetime.datetime(2017, 5, 3, 15, 1, 45, tzinfo=tzutc()),
purchased_at=datetime.datetime(2017, 5, 3, 15, 14, 5, tzinfo=tzutc()),
trolley=Trolley(
transaction_uuid='6d080a78-3011-11e7-b228-0025903268dc',
transaction_id='T000-0000-8ZVV-2E78',
bundles=[
Bundle(
source_code='ext_test1',
orders=[
Order(
item=1,
event=Event(
id='7AB',
status='live',
description='The Unremarkable Incident of the Cat at Lunchtime',
source='External Test Backend 1',
source_code='ext_test1',
event_type='simple_ticket',
venue='Lyric Apollo',
classes={
'theatre': 'Theatre'
},
postcode='W6 7ES',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.49306,
longitude=-0.22639,
max_running_time=90,
min_running_time=90,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
),
performance=Performance(
id='7AB-5',
event_id='7AB',
date_time=datetime.datetime(2019, 1, 1, 15, 30, tzinfo=tzutc()) ,
date_description='Tue, 1st January 2019',
time_description='3.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=90,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='NORMAL',
seats=[
Seat(
id='A1',
column='1',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
),
Seat(
id='A2',
column='2',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
)
],
description='Regular Ticket',
number_of_seats=2,
seatprice=50.0,
surcharge=5.0,
total_seatprice=100.0,
total_surcharge=10.0,
)
],
number_of_seats=2,
total_seatprice=100.0,
total_surcharge=10.0,
seat_request_status='got_all',
requested_seat_ids=[
'A1',
'A2'
],
backend_purchase_reference='PURCHASE-DA6E-0',
send_method=SendMethod(
code='VOUCH',
cost=0.0,
description='Printable eTicket',
type='selfprint',
can_generate_self_print=False,
self_print_voucher_url='https://api.ticketswitch.com/tickets/web_self_print.buy/demo?crypto_block=M_--R-aJRIR74rjx8gM2szdo9BEJZ8oV6wfGukxyZGDA2_DU2K3w-Y8L_3LWvIgKO_QxwMN8WmasaUuL_WpzKS-q2roXIWxXqjTxyDYZdge-wjDI0RZ8NpBAS0--Y',
),
)
],
description='External Test Backend 1',
total_seatprice=100.0,
total_surcharge=10.0,
total_send_cost=0.0,
total=110.0,
currency_code='gbp',
)
],
purchase_result=PurchaseResult(
success=True,
),
),
languages=[
'en'
],
customer=Customer(
first_name='Test',
first_name_latin='Test',
last_name='Tester',
last_name_latin='Tester',
address_lines=[
'Metro Building',
'1 Butterwick'
],
address_lines_latin=[
'Metro Building',
'1 Butterwick'
],
title='',
title_latin='',
initials='',
initials_latin='',
suffix='',
suffix_latin='',
country_code='uk',
post_code='W6 8DL',
post_code_latin='W6 8DL',
town='London',
town_latin='London',
county='London',
county_latin='London',
country='United Kingdom',
country_latin='United Kingdom',
email='',
home_phone='0203 137 7420',
work_phone='0203 137 7420',
agent_reference='',
supplier_can_use_data=False,
user_can_use_data=True,
world_can_use_data=False,
),
)
The returned attributes are identical to the original purchase response, even if the purchase has since been cancelled, this response will still be the same verbatim copy of the original purchase call.
Attribute | Description |
---|---|
customer |
The customer object, the customer attributes are as described in the purchase response. |
language_list |
Not useful for most partners, can be ignored. |
purchase_iso8601_date_and_time |
The purchase time in ISO 8601 format. |
reserve_iso8601_date_and_time |
The reserve time in ISO 8601 format. |
transaction_status |
This will be the original status that was reported at purchase, time (i.e. purchased , failed or attempting ) and it will not change because this is a verbatim copy of the original purchase call. |
trolley_contents |
The trolley object, the trolley attributes are as described in the purchase response. |
Status
Definition
GET https://api.ticketswitch.com/f13/status.v1?transaction_uuid={trans_uuid}
This resource allows you to view the details and status of a transaction. A transaction is created when tickets are reserved, and it changes status if it is purchased or released. Status can be called on transactions in any state. As the status call is a blocking call, only call the status if you require an up to date status, if you simply want the result of the reserve or purchase you just made then please use the Reserve Page Archive or Purchase Page Archive API calls.
Note that transactions that have been cancelled still have a transaction_status
of purchased
— you must check the cancellation_status
at the order level to know if a transaction (or orders within) have been cancelled.
See the cancel docs for more information on this point.
Request
Example request
curl https://api.ticketswitch.com/f13/status.v1 \
-u "demo:demopass" \
-d "transaction_uuid=284d9c3a-d698-11e6-be8c-002590326962" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
status, meta = client.get_status(transaction_uuid='6d080a78-3011-11e7-b228-0025903268dc')
Parameter | Description |
---|---|
add_customer |
Retrieve customer data (only applies to purchased transactions) |
add_external_sale_page |
Retrieve the HTML for the confirmation page, if you requested Ingresso to save this when purchasing (only applies to purchased transactions). Primarily for internal use. |
transaction_uuid |
The unique identifier returned by a previous reserve. |
Response
Example response
{
"language_list": "en-gb,en,en-us,nl",
"minutes_left_on_reserve": 14.3,
"moneyflow_channel_code": "demo",
"remote_site": "",
"reserve_iso8601_date_and_time": "2017-01-09T18:19:27Z",
"reserve_user": {
"backend_group": "demo_internal_credit_group",
"content_group": "",
"default_country_code": "uk",
"is_b2b": true,
"real_name": "Demonstration User",
"statement_descriptor": "",
"style": "fixed-tabs",
"sub_style": "styled-aff-default",
"sub_sub_style": "ingresso-generic",
"sub_user": "",
"user_id": "demo"
},
"transaction_status": "reserved",
"trolley": {
"bundle": [
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test0",
"bundle_source_desc": "External Test Backend 0",
"bundle_total_cost": 71.5,
"bundle_total_seatprice": 70,
"bundle_total_send_cost": 1.5,
"bundle_total_surcharge": 0,
"currency": {
"currency_code": "gbp"
},
"order": [
{
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"item_number": 1,
"performance": {
"date_desc": "Tue, 9th May 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-05-09T19:30:00+01:00",
"perf_id": "6IF-B0T",
"perf_name": "Including back stage pass",
"time_desc": "7.30 PM"
},
"price_band_code": "A/pool",
"seat_request_status": "not_requested",
"ticket_orders": {
"ticket_order": [
{
"discount_code": "",
"discount_desc": "",
"no_of_seats": 2,
"sale_seatprice": 35,
"sale_surcharge": 0,
"seats": [
{
"col_id": "144",
"full_id": "FN144",
"is_restricted_view": false,
"row_id": "FN"
},
{
"col_id": "143",
"full_id": "FN143",
"is_restricted_view": false,
"row_id": "FN"
}
],
"total_sale_seatprice": 70,
"total_sale_surcharge": 0
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle",
"total_no_of_seats": 2,
"total_sale_seatprice": 70,
"total_sale_surcharge": 0
}
]
}
],
"minutes_left_on_reserve": 14.3,
"transaction_uuid": "284d9c3a-d698-11e6-be8c-002590326962",
"trolley_bundle_count": 1,
"trolley_order_count": 1
}
}
from pyticketswitch.country import Country
from pyticketswitch.trolley import Trolley
from pyticketswitch.status import Status
from pyticketswitch.seat import Seat
from pyticketswitch.performance import Performance
from pyticketswitch.order import TicketOrder
from pyticketswitch.event import Event
from pyticketswitch.send_method import SendMethod
from pyticketswitch.order import Order
from pyticketswitch.address import Address
from pyticketswitch.bundle import Bundle
Status(
status='reserved',
reserved_at=datetime.datetime(2017, 5, 3, 17, 2, 17, tzinfo=tzutc()),
trolley=Trolley(
transaction_uuid='43768b36-3022-11e7-979f-002590326962',
bundles=[
Bundle(
source_code='ext_test0',
orders=[
Order(
item=1,
event=Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
filters=[
],
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
critic_review_percent=100,
),
performance=Performance(
id='6IF-B0O',
event_id='6IF',
date_time=datetime.datetime(2017, 5, 4, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Thu, 4th May 2017',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='',
seats=[
Seat(
id='HJ401',
column='401',
row='HJ',
separator='',
is_restricted=False,
),
Seat(
id='HJ402',
column='402',
row='HJ',
separator='',
is_restricted=False,
)
],
description='',
number_of_seats=2,
seatprice=21.0,
surcharge=3.0,
total_seatprice=42.0,
total_surcharge=6.0,
)
],
number_of_seats=2,
total_seatprice=42.0,
total_surcharge=6.0,
seat_request_status='not_requested',
requested_seat_ids=[
],
send_method=SendMethod(
code='COBO',
cost=1.5,
description='Collect from the venue',
type='collect',
),
)
],
description='External Test Backend 0',
total_seatprice=42.0,
total_surcharge=6.0,
total_send_cost=1.5,
total=49.5,
currency_code='gbp',
)
],
discarded_orders=[
],
minutes_left=14.5,
),
languages=[
'en'
],
needs_payment_card=False,
needs_email_address=False,
needs_agent_reference=False,
can_edit_address=True,
allowed_countries=[
Country(
code='uk',
description='United Kingdom',
)
],
minutes_left=14.5,
)
The returned attributes are dependent on the status of the transaction. For example a purchased transaction will appear differently to a released transaction.
Attribute | Description |
---|---|
customer |
Detail of the purchasing customer; only included when the add_customer parameter is present and the transaction_status is purchased . The fields returned are as described in purchase. |
external_sale_page |
The detail of the confirmation page that was displayed to customers. Only included when the add_external_sale_page parameter is present and the transaction_status is purchased . |
purchase_iso8601_date_and_time |
The time the tickets were successfully purchased. |
reserve_iso8601_date_and_time |
The time the tickets were successfully reserved. |
transaction_status |
One of reserved , released , purchased , failed , or attempting (will only be seen if the customer is being redirected to a payment page - most partners will not see this). |
trolley |
The trolley object. If the transaction_status is reserved or released , the trolley attributes are as described in the reserve response. If the transaction_status is purchased the trolley attributes are as described in the purchase response. Note that if the transaction_status is released you should ignore the value of minutes_left_on_reserve . |
Trans ID Status
Definition
GET https://api.ticketswitch.com/f13/trans_id_status.v1?transaction_id={trans_id}
This resource is to provide legacy API support. In the old XML API after
reserving tickets a transaction ID was returned. This has been replaced with
a transaction UUID. If you have made purchases using the old XML API and you
need to retrieve details of the transaction then you can use
trans_id_status
lets you request status for a particular transaction_id
.
If you have only used this JSON API then there is no need to use
trans_id_status
.
Request
Example request
curl https://api.ticketswitch.com/f13/trans_id_status.v1 \
-u "demo:demopass" \
-d "transaction_id=T000-0000-8LZT-WA8D" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
status, meta = client.get_status(transaction_id='T000-0000-8ZVV-2E78')
Parameter | Description |
---|---|
add_customer |
Retrieve customer data (only applies to purchased transactions) |
add_external_sale_page |
Retrieve the HTML for the confirmation page, if you requested Ingresso to save this when purchasing (only applies to purchased transactions). Primarily for internal use. |
transaction_id |
The unique identifier returned by a previous reserve. |
Response
Example response
{
"currency_details": {
"gbp": {
"currency_code": "gbp",
"currency_factor": 100,
"currency_number": 826,
"currency_places": 2,
"currency_post_symbol": "",
"currency_pre_symbol": "£"
}
},
"language_list": [
"en"
],
"purchase_iso8601_date_and_time": "2017-02-20T19:42:55Z",
"reserve_iso8601_date_and_time": "2017-02-20T19:42:55Z",
"transaction_status": "purchased",
"trolley_contents": {
"bundle": [
{
"bundle_order_count": 1,
"bundle_source_code": "ext_test0",
"bundle_source_desc": "External Test Backend 0",
"bundle_total_cost": 71.5,
"bundle_total_seatprice": 70,
"bundle_total_send_cost": 1.5,
"bundle_total_surcharge": 0,
"currency_code": "gbp",
"order": [
{
"backend_purchase_reference": "PURCHASE-1445-1",
"event": {
"city_code": "london-uk",
"city_desc": "London",
"classes": {
"dance": "Ballet & Dance"
},
"country_code": "uk",
"country_desc": "United Kingdom",
"critic_review_percent": 100,
"custom_filter": [],
"event_desc": "Matthew Bourne's Nutcracker TEST",
"event_id": "6IF",
"event_path": "/6IF-matthew-bourne-s-nutcracker-test/",
"event_status": "live",
"event_type": "simple_ticket",
"event_upsell_list": {
"event_id": [
"6IE",
"MH0"
]
},
"event_uri_desc": "Matthew-Bourne%27s-Nutcracker-TEST",
"geo_data": {
"latitude": 51.52961137,
"longitude": -0.10601562
},
"has_no_perfs": false,
"is_seated": true,
"max_running_time": 120,
"min_running_time": 120,
"need_departure_date": false,
"need_duration": false,
"need_performance": true,
"postcode": "EC1R 4TN",
"show_perf_time": true,
"source_code": "ext_test0",
"source_desc": "External Test Backend 0",
"user_review_percent": 100,
"venue_desc": "Sadler's Wells",
"venue_uri_desc": "Sadler%27s-Wells"
},
"got_requested_seats": false,
"gross_commission": {
"amount_excluding_vat": 0.25,
"amount_including_vat": 0.3,
"commission_currency_code": "gbp"
},
"item_number": 1,
"performance": {
"date_desc": "Thu, 23rd February 2017",
"event_id": "6IF",
"has_pool_seats": true,
"is_ghost": false,
"is_limited": false,
"iso8601_date_and_time": "2017-02-23T19:30:00Z",
"perf_id": "6IF-A8Q",
"running_time": 120,
"time_desc": "7.30 PM"
},
"price_band_code": "A/pool",
"send_method": {
"send_code": "COBO",
"send_cost": 1.5,
"send_desc": "Collect from the venue",
"send_final_type": "collect",
"send_type": "collect"
},
"ticket_orders": {
"ticket_order": [
{
"discount_code": "ADULT",
"discount_desc": "Adult",
"no_of_seats": 2,
"sale_seatprice": 35,
"sale_surcharge": 0,
"seats": [
{
"col_id": "140",
"full_id": "SQ140",
"is_restricted_view": false,
"row_id": "SQ"
},
{
"col_id": "139",
"full_id": "SQ139",
"is_restricted_view": false,
"row_id": "SQ"
}
],
"total_sale_seatprice": 70,
"total_sale_surcharge": 0
}
]
},
"ticket_type_code": "CIRCLE",
"ticket_type_desc": "Upper circle",
"total_no_of_seats": 2,
"total_sale_seatprice": 70,
"total_sale_surcharge": 0,
"user_commission": {
"amount_excluding_vat": 0.11,
"amount_including_vat": 0.14,
"commission_currency_code": "gbp"
}
}
],
"purchase_result": {
"is_semi_credit": false,
"success": true
}
}
],
"purchase_result": {
"is_partial": false,
"success": true
},
"transaction_id": "T000-0000-8LZT-WA8D",
"transaction_uuid": "c6335e88-f7a4-11e6-b286-0025903268dc",
"trolley_bundle_count": 1,
"trolley_order_count": 1
}
}
from pyticketswitch.trolley import Trolley
from pyticketswitch.status import Status
from pyticketswitch.seat import Seat
from pyticketswitch.performance import Performance
from pyticketswitch.order import TicketOrder
from pyticketswitch.purchase_result import PurchaseResult
from pyticketswitch.event import Event
from pyticketswitch.send_method import SendMethod
from pyticketswitch.order import Order
from pyticketswitch.bundle import Bundle
Status(
status='purchased',
reserved_at=datetime.datetime(2017, 5, 3, 15, 1, 45, tzinfo=tzutc()),
purchased_at=datetime.datetime(2017, 5, 3, 15, 14, 5, tzinfo=tzutc()),
trolley=Trolley(
transaction_uuid='6d080a78-3011-11e7-b228-0025903268dc',
transaction_id='T000-0000-8ZVV-2E78',
bundles=[
Bundle(
source_code='ext_test1',
orders=[
Order(
item=1,
event=Event(
id='7AB',
status='live',
description='The Unremarkable Incident of the Cat at Lunchtime',
source='External Test Backend 1',
source_code='ext_test1',
event_type='simple_ticket',
venue='Lyric Apollo',
classes={
'theatre': 'Theatre'
},
postcode='W6 7ES',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.49306,
longitude=-0.22639,
max_running_time=90,
min_running_time=90,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
),
performance=Performance(
id='7AB-5',
event_id='7AB',
date_time=datetime.datetime(2019, 1, 1, 15, 30, tzinfo=tzutc()),
date_description='Tue, 1st January 2019',
time_description='3.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=90,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='NORMAL',
seats=[
Seat(
id='A1',
column='1',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
),
Seat(
id='A2',
column='2',
row='A',
separator='',
is_restricted=True,
seat_text='Restricted View',
)
],
description='Regular Ticket',
number_of_seats=2,
seatprice=50.0,
surcharge=5.0,
total_seatprice=100.0,
total_surcharge=10.0,
)
],
number_of_seats=2,
total_seatprice=100.0,
total_surcharge=10.0,
seat_request_status='got_all',
requested_seat_ids=[
'A1',
'A2'
],
backend_purchase_reference='PURCHASE-DA6E-0',
send_method=SendMethod(
code='VOUCH',
cost=0.0,
description='Printable eTicket',
type='selfprint',
can_generate_self_print=False,
self_print_voucher_url='https://api.ticketswitch.com/tickets/web_self_print.buy/demo?crypto_block=U_--z_v1JesEuC-2FgKkj4LEhJdbZVhIdnBp3b0sP0uh1KqsYF_fumHhC_IFKIXh471k1Del_9Wi0W8_8Ay7xJNhbK299MEf-wLwbOmtNBdnzh8BZ9icsINHBS0w5gNCc7zbY',
),
)
],
description='External Test Backend 1',
total_seatprice=100.0,
total_surcharge=10.0,
total_send_cost=0.0,
total=110.0,
currency_code='gbp',
)
],
purchase_result=PurchaseResult(
success=True,
),
),
languages=[
'en'
],
)
The returned attributes are dependent on the status of the transaction. For example a purchased transaction will appear differently to a released transaction.
Attribute | Description |
---|---|
customer |
Detail of the purchasing customer; only included when the add_customer parameter is present and the transaction_status is purchased . The fields returned are as described in purchase. |
external_sale_page |
The detail of the confirmation page that was displayed to customers. Only included when the add_external_sale_page parameter is present and the transaction_status is purchased . |
purchase_iso8601_date_and_time |
The time the tickets were successfully purchased. |
reserve_iso8601_date_and_time |
The time the tickets were successfully reserved. |
transaction_status |
One of reserved , released , purchased , failed , or attempting (will only be seen if the customer is being redirected to a payment page - most partners will not see this). |
trolley |
The trolley object. If the transaction_status is reserved or released , the trolley attributes are as described in the reserve response. If the transaction_status is purchased the trolley attributes are as described in the purchase response. Note that if the transaction_status is released you should ignore the value of minutes_left_on_reserve . |
Cancel
Definition
POST https://api.ticketswitch.com/f13/cancel.v1?transaction_uuid={trans_uuid}&cancel_items_list=1,2
This endpoint allows users to attempt to cancel purchased transactions (there is no guarantee that cancellations will succeed). By default, users are unable to cancel transactions. If you believe that you should be able to cancel transactions then contact us
If you would like to attempt to cancel a transaction, follow these steps:
1. Check if the order items within the transaction are cancellable by looking at the cancellation_status
of each of the order items in the purchase or status response (they are cancellable if cancellation_status
is possible
).
2. Attempt the cancellation of the "cancellation_status": "possible"
order items. You can specify which order items to cancel in the transaction with the optional list, cancel_items_list
. If you don’t specify any order items to cancel then it will be assumed that the whole transaction should be cancelled (Ingresso will then attempt to cancel all items that can be cancelled).
3. Check the response to see if the cancellation worked as you expected, for example some order items may not succeed in getting cancelled, whereas others might. Cancelling some items may cause other items to be cancelled. Check both the high level cancelled_item_numbers
and the updated cancellation_status
on each of the orders within the trolley. There might be a charge for the cancellation.
Request
Example request - cancel entire transaction
curl https://api.ticketswitch.com/f13/cancel.v1 \
-u "demo:demopass" \
-d "transaction_uuid=284d9c3a-d698-11e6-be8c-002590326962" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
status, meta = client.cancel_purchase(transaction_uuid='284d9c3a-d698-11e6-be8c-002590326962')
Example request - specify order items to cancel by item number
curl https://api.ticketswitch.com/f13/cancel.v1 \
-u "demo:demopass" \
-d "transaction_uuid=284d9c3a-d698-11e6-be8c-002590326962" \
-d "cancel_items_list=1,3" \
--compressed \
-G
from pyticketswitch import Client
client = Client('demo', 'demopass')
status, meta = client.cancel_purchase(transaction_uuid='284d9c3a-d698-11e6-be8c-002590326962', cancel_items_list=[1,3])
Parameter | Description |
---|---|
transaction_uuid |
The unique identifier returned by a previous purchase. |
cancel_items_list |
An optional parameter that may be included in the request. It is a list of items to cancel in the transaction (note that cancelling some items may cause other items to be cancelled as well). |
Response
Example response – successful cancellation
{
"trolley_contents" : {
"trolley_bundle_count" : 1,
"trolley_order_count" : 1,
"bundle" : [
{
"bundle_total_seatprice" : 32,
"bundle_total_send_cost" : 1.5,
"order" : [
{
"price_band_code" : "A/pool",
"internal_reserve_sub_ref2" : "NUT SUB 2",
"backend_cancellation_reference" : "ATTEMPT-482281",
"total_sale_surcharge" : 5,
"item_number" : 1,
"performance" : {
"running_time" : 120,
"has_pool_seats" : true,
"event_id" : "6IF",
"time_desc" : "7.30 PM",
"is_limited" : false,
"perf_id" : "6IF-D9P",
"is_ghost" : false,
"iso8601_date_and_time" : "2019-04-26T19:30:00+01:00",
"date_desc" : "Fri, 26th April 2019"
},
"backend_purchase_reference" : "PURCHASE-286D",
"user_commission" : {
"amount_including_vat" : 11.4,
"commission_currency_code" : "gbp",
"amount_excluding_vat" : 9.5
},
"send_method" : {
"send_cost" : 1.5,
"send_desc" : "Collect from venue",
"send_final_comment" : "Instructions for collecting tickets at the venue box office:\n- Tickets must be collected by the cardholder with valid photo identification and the payment card.\n- The cardholderâs signature will be required on receipt of these tickets.\n- Tickets are only available for collection on the day of the performance.\n- Guests are advised to arrive at least 30 minutes before the performance time.\n- If the cardholder is unable to collect these tickets please contact Guest Services on 0800 640 8101.\n\nCan we help?\nIf you require further information please contact our Guest Services team:\nLive chat or call 0800 640 8101 (Monday â Sunday, 9am â 9pm GMT/BST)",
"send_type" : "collect",
"send_code" : "COBO",
"send_final_type" : "collect"
},
"ticket_type_desc" : "Stalls",
"gross_commission" : {
"amount_including_vat" : 11.4,
"amount_excluding_vat" : 9.5,
"commission_currency_code" : "gbp"
},
"cancellation_status" : "cancelled",
"ticket_orders" : {
"ticket_order" : [
{
"total_sale_seatprice" : 21,
"sale_surcharge" : 3,
"total_sale_combined" : 24,
"sale_seatprice" : 21,
"seats" : [
{
"full_id" : "YG167",
"is_restricted_view" : false,
"col_id" : "167",
"row_id" : "YG"
}
],
"discount_code" : "ADULT",
"discount_desc" : "Adult standard",
"sale_combined" : 24,
"total_sale_surcharge" : 3,
"no_of_seats" : 1
},
{
"total_sale_surcharge" : 2,
"sale_combined" : 13,
"discount_desc" : "Adult 18+ including behind the scenes tour",
"discount_code" : "CHILD",
"no_of_seats" : 1,
"sale_surcharge" : 2,
"total_sale_seatprice" : 11,
"seats" : [
{
"row_id" : "YG",
"col_id" : "168",
"is_restricted_view" : false,
"full_id" : "YG168"
}
],
"sale_seatprice" : 11,
"total_sale_combined" : 13
}
]
},
"cancellation_comment" : "",
"total_sale_combined" : 37,
"total_no_of_seats" : 2,
"price_band_desc" : "Top price (band A)",
"seat_request_status" : "not_requested",
"ticket_type_code" : "STALLS",
"total_sale_seatprice" : 32,
"event" : {
"has_no_perfs" : false,
"min_running_time" : 120,
"need_departure_date" : false,
"need_duration" : false,
"city_code" : "london-uk",
"show_perf_time" : true,
"is_seated" : true,
"event_uri_desc" : "Matthew-Bourne%27s-Nutcracker%21",
"source_code" : "ext_test0",
"source_desc" : "Test SystemZero for on-credit backend group",
"event_desc" : "Matthew Bourne's Nutcracker!",
"event_type" : "simple_ticket",
"event_status" : "live",
"event_upsell_list" : {
"event_id" : [
"6IE",
"6KU"
]
},
"venue_uri_desc" : "Sadler%27s-Wells",
"critic_review_percent" : 80,
"country_desc" : "United Kingdom",
"venue_desc" : "Sadler's Wells",
"max_running_time" : 120,
"geo_data" : {
"latitude" : 51.5,
"longitude" : -0.15
},
"event_id" : "6IF",
"need_performance" : true,
"postcode" : "EC1R 4TN",
"city_desc" : "London",
"is_add_on" : false,
"country_code" : "uk",
"classes" : {
"theatre" : "Theatre"
},
"is_auto_quantity_add_on" : false,
"custom_filter" : []
},
"internal_reserve_sub_ref" : "NUT SUB 1",
"requested_seat_ids" : [],
"internal_purchase_sub_ref" : "SUBREF-1:NUT SUB 2:NUT SUB 1"
}
],
"purchase_result" : {
"can_cancel_individual_orders" : false,
"success" : true,
"backend_purchase_reference" : "PURCHASE-286D",
"is_semi_credit" : false
},
"bundle_total_surcharge" : 5,
"bundle_order_count" : 1,
"bundle_source_code" : "ext_test0",
"bundle_total_cost" : 38.5,
"bundle_source_desc" : "Test SystemZero for on-credit backend group",
"currency_code" : "gbp"
}
],
"transaction_uuid" : "284d9c3a-d698-11e6-be8c-002590326962",
"purchase_result" : {
"success" : true,
"is_partial" : false
},
"transaction_id" : "U000-0000-2M96-DEVX"
},
"currency_details" : {
"gbp" : {
"currency_pre_symbol" : "£",
"currency_post_symbol" : "",
"currency_factor" : 100,
"currency_code" : "gbp",
"currency_number" : 826,
"currency_places" : 2
}
},
"cancelled_item_numbers" : [
1
]
}
from pyticketswitch.trolley import Trolley
from pyticketswitch.cancellation import CancellationResult
from pyticketswitch.seat import Seat
from pyticketswitch.performance import Performance
from pyticketswitch.purchase_result import PurchaseResult
from pyticketswitch.order import TicketOrder
from pyticketswitch.event import Event
from pyticketswitch.send_method import SendMethod
from pyticketswitch.order import Order
from pyticketswitch.bundle import Bundle
CancellationResult(
cancelled_item_numbers=[1],
trolley=Trolley(
transaction_uuid='284d9c3a-d698-11e6-be8c-002590326962',
bundles=[
Bundle(
source_code='ext_test0',
orders=[
Order(
item=1,
backend_cancellation_reference='ATTEMPT-482281',
backend_purchase_reference='PURCHASE-286D',
cancellation_comment='',
cancellation_status='cancelled',
event=Event(
id='6IF',
status='live',
description="Matthew Bourne's Nutcracker TEST",
source='External Test Backend 0',
source_code='ext_test0',
event_type='simple_ticket',
venue="Sadler's Wells",
classes={
'dance': 'Ballet & Dance'
},
postcode='EC1R 4TN',
city='London',
city_code='london-uk',
country='United Kingdom',
country_code='uk',
latitude=51.52961137,
longitude=-0.10601562,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
upsell_list=[
'6IE',
'MH0'
],
critic_review_percent=100,
),
performance=Performance(
id='6IF-D9P',
event_id='6IF',
date_time=datetime.datetime(2019, 4, 26, 19, 30, tzinfo=tzoffset(None, 3600)),
date_description='Fri, 26th April 2019',
time_description='7.30 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
price_band_code='A/pool',
ticket_type_code='STALLS',
ticket_type_description='Stalls',
ticket_orders=[
TicketOrder(
code='',
seats=[
Seat(
id='YG167',
column='167',
row='YG',
separator='',
is_restricted=False,
),
],
description='',
number_of_seats=1,
seatprice=21.0,
surcharge=3.0,
total_seatprice=21.0,
total_surcharge=3.0,
),
TicketOrder(
code='',
seats=[
Seat(
id='YG168',
column='168',
row='YG',
separator='',
is_restricted=False,
),
],
description='',
number_of_seats=1,
seatprice=11.0,
surcharge=2.0,
total_seatprice=11.0,
total_surcharge=2.0,
)
],
number_of_seats=2,
total_seatprice=32.0,
total_surcharge=5.0,
seat_request_status='not_requested',
send_method=SendMethod(
code='COBO',
cost=1.5,
description='Collect from the venue',
type='collect',
),
)
],
description='External Test Backend 0',
total_seatprice=32.0,
total_surcharge=5.0,
total_send_cost=1.5,
total=38.5,
currency_code='gbp',
purchase_result=PurchaseResult(
success=True,
can_cancel_individual_orders=False,
backend_purchase_reference="PURCHASE-286D",
is_semi_credit=False
),
)
],
purchase_result=PurchaseResult(
success=True,
is_partial=False,
),
),
)
Example response – must also cancel
{
"must_also_cancel" : [
{
"cancellation_comment" : "",
"send_method" : {
"send_cost_in_desired" : 8.76,
"send_type" : "post",
"send_final_type" : "post",
"send_desc" : "Post worldwide",
"send_cost" : 10,
"send_code" : "POST"
},
"ticket_orders" : {
"ticket_order" : [
{
"seats" : [
{
"is_restricted_view" : false,
"row_id" : "YC",
"full_id" : "YC472",
"col_id" : "472"
},
{
"full_id" : "YC473",
"col_id" : "473",
"row_id" : "YC",
"is_restricted_view" : false
},
{
"col_id" : "474",
"full_id" : "YC474",
"row_id" : "YC",
"is_restricted_view" : false
}
],
"sale_combined_in_desired" : 135.75,
"sale_surcharge_in_desired" : 13.14,
"sale_seatprice" : 140,
"total_sale_surcharge" : 45,
"total_sale_combined" : 465,
"discount_desc" : "",
"total_sale_combined_in_desired" : 407.24,
"sale_surcharge" : 15,
"total_sale_surcharge_in_desired" : 39.41,
"no_of_seats" : 3,
"total_sale_seatprice" : 420,
"sale_combined" : 155,
"sale_seatprice_in_desired" : 122.61,
"total_sale_seatprice_in_desired" : 367.83,
"discount_code" : ""
}
]
},
"total_sale_combined_in_desired" : 407.24,
"total_sale_seatprice" : 420,
"seat_request_status" : "not_requested",
"backend_cancellation_reference" : "",
"requested_seat_ids" : [],
"internal_purchase_sub_ref" : "",
"ticket_type_desc" : "Menu French Cancan",
"internal_reserve_sub_ref" : "",
"price_band_code" : "A/pool",
"user_commission" : {
"commission_currency_code" : "eur",
"amount_including_vat" : 0,
"amount_excluding_vat" : 0
},
"total_sale_combined" : 465,
"backend_purchase_reference" : "PURCHASE-3AFD",
"event" : {
"custom_filter" : [],
"min_running_time" : 120,
"geo_data" : {
"latitude" : 0,
"longitude" : 0
},
"postcode" : "75018",
"event_id" : "BPT",
"venue_uri_desc" : "Bal-du-Moulin-Rouge",
"has_no_perfs" : false,
"need_performance" : true,
"source_code" : "ext_test1",
"event_uri_desc" : "Moulin-Rouge-%28Dinner-Show%29",
"event_type" : "simple_ticket",
"is_auto_quantity_add_on" : false,
"country_code" : "fr",
"venue_desc" : "Bal du Moulin Rouge",
"show_perf_time" : true,
"classes" : {
"attract" : "Attractions",
"theatre" : "Theatre"
},
"source_desc" : "Test System One",
"max_running_time" : 120,
"event_status" : "live",
"need_departure_date" : false,
"need_duration" : false,
"event_desc" : "Moulin Rouge (Dinner Show)",
"country_desc" : "France",
"is_seated" : true,
"is_add_on" : false
},
"gross_commission" : {
"amount_including_vat" : 60,
"amount_excluding_vat" : 50,
"commission_currency_code" : "eur"
},
"total_no_of_seats" : 3,
"ticket_type_code" : "CANCAN",
"performance" : {
"is_limited" : false,
"running_time" : 120,
"iso8601_date_and_time" : "2019-04-01T19:00:00+02:00",
"event_id" : "BPT",
"perf_id" : "BPT-E6P",
"date_desc" : "Mon, 1st April 2019",
"has_pool_seats" : true,
"is_ghost" : false,
"time_desc" : "7.00 PM"
},
"total_sale_surcharge_in_desired" : 39.41,
"internal_reserve_sub_ref2" : "",
"cancellation_status" : "possible",
"total_sale_seatprice_in_desired" : 367.83,
"item_number" : 2,
"total_sale_surcharge" : 45
}
],
"currency_details" : {
"eur" : {
"currency_pre_symbol" : "â¬",
"currency_post_symbol" : "",
"currency_number" : 978,
"currency_code" : "eur",
"currency_places" : 2,
"currency_factor" : 100
}
}
}
from pyticketswitch.cancellation import CancellationResult
...
CancellationResult(
must_also_cancel=[Order(
item=2,
backend_purchase_reference='PURCHASE-286D',
cancellation_comment='',
cancellation_status='possible',
event=Event(
id='BPT',
status='live',
description="Moulin Rouge (Dinner Show)",
source='External Test Backend 1',
source_code='ext_test1',
event_type='simple_ticket',
venue='Bal du Moulin Rouge',
classes={
'attract' : 'Attractions',
'theatre' : 'Theatre'
},
postcode='75018',
country='France',
country_code='fr',
latitude=0,
longitude=0,
max_running_time=120,
min_running_time=120,
show_performance_time=True,
has_performances=True,
is_seated=True,
needs_departure_date=False,
needs_duration=False,
needs_performance=False,
),
performance=Performance(
id='BPT-E6P',
event_id='BPT',
date_time=datetime.datetime(2019, 4, 01, 19, 00, tzinfo=tzoffset(None, 7200)),
date_description='Mon, 1st April 2019',
time_description='7.00 PM',
has_pool_seats=True,
is_limited=False,
is_ghost=False,
running_time=120,
),
price_band_code='A/pool',
ticket_type_code='CANCAN',
ticket_type_description='Menu French Cancan',
ticket_orders=[
TicketOrder(
code='',
seats=[
Seat(
id='YC472',
column='472',
row='YC',
separator='',
is_restricted=False,
),
Seat(
id='YC473',
column='473',
row='YC',
separator='',
is_restricted=False,
),
Seat(
id='YC474',
column='474',
row='YC',
separator='',
is_restricted=False,
),
],
description='',
number_of_seats=3,
seatprice=140.0,
surcharge=15.0,
total_seatprice=420.0,
total_surcharge=15.0,
),
],
number_of_seats=3,
total_seatprice=420.0,
total_surcharge=45.0,
seat_request_status='not_requested',
send_method=SendMethod(
code='POST',
cost=10,
description='Post worldwide',
type='post',
),
)]
)
The cancellation_status
for each order item will become cancelled
if it has been cancelled.
Some items are not cancellable, their cancellation_status
will be not_permitted
in the API requests before cancellation (e.g. purchase and status) and after the cancel API request.
If the cancellation of an order item is tried and fails then the order item cancellation_status
will become tried_and_failed
.
In some circumstances the call might return the must_also_cancel
list, which means that you must also specify the items in that list in order to cancel the items that you requested to cancel originally.
Attribute | Description |
---|---|
cancelled_items_list |
This will list the items that were cancelled in this API request (note that this is not idempotent: items will only appear in this list the first time they are cancelled). |
must_also_cancel |
This is a list of order items that must also be cancelled in order to sucessfully cancel the transaction. |
trolley_contents |
The trolley object. The trolley attributes are as described in the purchase response. Note that if the transaction_status is released you should ignore the value of minutes_left_on_reserve . |
Suppliers
Definition
GET https://api.ticketswitch.com/f13/sources.v1
Retrieve the list of supplier systems that are used to source the events
you have access to. Events can then be filtered by using e.g.
https://api.ticketswitch.com/f13/events.v1?s_src=ext_test1
.
Cities
Definition
GET https://api.ticketswitch.com/f13/cities.v1
This call is not currently available - it will be added soon.
Classes
Definition
GET https://api.ticketswitch.com/f13/classes.v1
This call is not currently available - it will be added soon.
Bitmask Fields
This section describes the bitmasks fields returned in response to some API calls and explains how to decode their data.
The ‘bitmask’ fields are compact representations of arrays of flags, where the binary digits of the number represent true and false flags as 0 and 1.
We number our bits in the conventional way with the least significant bit being bit zero.
The correspondance between bits numbers and actual things is:
For weekdays, 0 = Sunday, 1 = Monday, 2 = Tuesday etc…
For months 0 is not used, 1 = 1st, 2 = 2nd, 3 = 3rd etc. (Note that this means all month bitmasks will be even numbers).
For tickets, 0 = first ticket, 1 = second ticket, like an array index
Check check one of the bits in the bitmask you can use the following syntax in
most languages:
((1 << bit_number) & bitmask)
For example if the API returns 91
as a weekday bitmask you could make the
following checks in Python.
There is availability on Sunday:
>>> ((1 << 0) & 91)
1
There isn’t availability on Tuesday:
>>> ((1 << 2) & 91)
0
There is availability on Saturday:
>>> ((1 << 6) & 91)
1
Caching
Ingresso cache data at these levels:
- Events
- Performances
- Availability
Caching for events and performances
Ingresso cache two data sets for events and performances:
a) Approximately every hour Ingresso request events and performances from the individual supplier ticketing systems - any new events or performances are automatically added to the Ingresso database. New events are supplemented with images, descriptive content etc by our setup team and then go live, but performances automatically go live. When you request events or performances this request is answered directly from the Ingresso database; we do not pass the request on to the supplier ticketing system.
b) Every time an availability request is made, Ingresso recalculate cost ranges. Cost ranges include a minimum and maximum price and details of any offers. Since they are built from availability requests, they are not necessarily accurate (for example if a new cheaper performance is added but availability hasn’t yet been requested for that performance, then the cost range for the event will not be accurate. We have processes to keep these up to date in some cases, but they are not guaranteed to be present. Cost ranges are described in more detail for example in the event cost range section.
Caching for availability
Availability is cached for a short period of time (usually 90 seconds). If for example your end customer selected the 1st March 7.30pm performance, then selected 2nd March 7.30pm, then selected 1st March 7.30pm again at this point the availability cache would be hit (assuming it was within 90 seconds of the first request). This is to avoid overloading the supplier ticketing systems during periods of high demand, for example an on-sale. The availability cache is cleared when tickets are reserved, so the cached availability is unlikely to be inaccurate.
Other caching requirements
If the above caching does not solve your problem, or if you have other caching requirements, please get in touch!
Do not go away and implement your own caching system that continuously makes availability requests to Ingresso, without discussing this with us in advance. This puts more load than necessary on the supplier ticketing systems, and can therefore reduce the throughput that we can offer. It is more complex than partners often first anticipate, for example it normally takes a lot longer to scan all performances for all events than partners imagine, and there are a number of edge cases that are easy to miss, e.g. avoiding retrying when a supplier system is under load or returning errors. We will consider closing the API accounts of anyone doing this without prior approval.
Transaction Reporting
Definition
GET https://api.ticketswitch.io/transactions.v0?from=2017-06-01
The transaction reporting resource allow you to retrieve, filter and order your transactions. This can be used, for example, to regularly populate your own database of Ingresso transactions.
Pagination
Definition
GET https://api.ticketswitch.io/transactions.v0?page_number={page_number}&page_length={num_items}
By default the returned dataset is paginated and limited to 10 records per page. To iterate over the pages supply a page_number=x
query parameter where x
is an unsigned integer. If this parameter is not passed the page will be set to 0 by default. To change number of records returned per page pass page_length=y
, y
being an integer. The maximum number of records per page is 100.
Example request
curl https://api.ticketswitch.io/transactions.v0?page_number=2&page_length=20&from=2017-06-01\
-u "demo:demopass" \
-X GET
Time Filters
Definition
GET https://api.ticketswitch.io/transactions.v0?from={date}&to={date}
The transactions API allows from
and to
query parameters to be passed to filter by the purchase time (purchase_time_utc
). The time values supplied can either be passed as UTC timestamp or as a more human readable format in simplified ISO 8601 in a form of <YYYY>-<MM>-<dd>T<hh>:<mm>:<ss>
(also in UTC timezone) where hours, minutes and seconds are optional and will default to either 00, 00, 00 in the case of from
parameter or 23, 59, 59 in case of to
if not passed.
For example to retrieve the records from
September 29th 2017 at midnight (00:00:00) the following time parameter values are valid:
1506643200
2017-09-29T00:00:00
2017-09-29T00:00
2017-09-29T00
2017-09-29
For partners using this resource to maintain a full database of Ingresso transactions we recommend that you:
- Look up the maximum
purchase_time_utc
in your database, add one second, and pass this as thefrom
parameter. If you haven’t previously downloaded transactions then set thefrom
date well in the pass, for example 01/01/2000 - Do not pass a
to
parameter - this will ensure all missing records up to 10 minutes ago are returned - Order by purchase time ascending (
$purchase_time_utc
) - Loop through the pages and results adding them to your database
Example requests
curl https://api.ticketswitch.io/transactions.v0?from=2016-01-02T14:33:22&to=2016-06-03T14:25:21\
-u "demo:demopass" \
-X GET
curl https://api.ticketswitch.io/transactions.v0?from=1506623211&to=1507643200\
-u "demo:demopass" \
-X GET
Other Filters
Definition
GET https://api.ticketswitch.io/transactions.v0/filter:{filter_options}'
The API allows you to use filters besides the purchase time. Currently the following filters are available:
event_id
- filter by Event’s IDsupplier_code
- Filter by name of supplier’s codebillable
- (booleantrue
orfalse
) If set totrue
will only return records for which will be applied a charge by Ingresso (or was applied in the past), iffalse
only not billable records will be returned. By default both types of transactions are returned in the query.
If you would find other filters useful please contact us
To pass a filter option insert /filter:{filter_options}
after /transactions.v0
. All options are passed as key=value
separated by ,
. For example: /filter:event_id=44AP,supplier_code=nimax
. The comma separator corresponds to the AND
logical statement; so in the above example only records with event_id
equal to 44AP
and
supplier_code
equal to nimax
will be returned. If the value contains white space then enclose it in single quotes '
.
Example request
curl https://api.ticketswitch.io/transactions.v0/filter:event_id='44AP'\
-u "demo:demopass" \
-X GET
curl https://api.ticketswitch.io/transactions.v0/filter:event_id='44AP',supplier_code=nimax\
-u "demo:demopass" \
-X GET
Ordering options
Definition
GET https://api.ticketswitch.io/transactions.v0/order:{order_options}
To order returned data insert /order:<order_options>
after /transactions.v0
using the set of fields you want to order by. A list of ordering fields should correspond to keys in the returned transaction records separated by ,
. By default the data is ordered descending, if you wish to order it ascending prepend the field name with a $
character, for example $event_id,purchase_time_utc
will order the data alphabetically by event id. If there are 2 records with same id those records will be ordered descending by purchase time. The following ordering options are supported:
event_id
supplier_code
purchase_time_utc
purchase_time_london
Example request
curl https://api.ticketswitch.io/transactions.v0/order:event_id,supplier_code?from=2017-06-01\
-u "demo:demopass" \
-X GET
Response
Example API reponse
{
"status": "success",
"count": 10,
"message": "",
"data": [
{
"transaction_id": "T000-0000-ABCD-EFGH",
"item_number": 1,
"user_id": "demo",
"backend_purchase_reference": "123456",
"event_id": "2GXJ",
"event_desc": "Wicked",
"event_country_code": "uk",
"venue_desc": "Apollo Victoria",
"supplier_code": "atg",
"purchase_time_utc": "2017-01-01T09:58:40Z",
"purchase_time_london": "2017-01-01T09:58:40Z",
"performance_local_time": "2017-01-02T19:30:00Z",
"perf_type_code": "748418",
"ticket_type_code": "CIR",
"ticket_type_desc": "Dress Circle",
"price_band_code": "A",
"discount_desc": "Regular Price",
"send_code": "H",
"send_desc": "E-ticket (print at home yourself)",
"seat_ids": [
"J20",
"J21",
"J22",
"J23"
],
"trans_status": "normal",
"sale_mode": "internal_credit",
"debitor_reference": null,
"user_can_use_customer_data": false,
"supplier_can_use_customer_data": false,
"num_tickets": 4,
"num_transactions": 1,
"sale_currency_code": "gbp",
"sale_seatprice": 278,
"sale_surcharge": 13.8,
"ticket_price": 291.8,
"send_cost": 0,
"commision_currency_code": "gbp",
"user_commission_inc_vat": 9.66,
"gross_commission_inc_vat": 13.8,
"inside_commision_inc_vat": 0,
"supplier_levy": 7,
"supplier_fee": 0,
"supplier_rebate": 0,
"surcharge_non_commissionable_postage": 0,
"surcharge_commissionable_postage": 0,
"processing_fee": 0,
"supplier_uplift": 0,
"user_uplift": 0,
"customer": {
"first_name": "John",
"last_name": "Doe",
"address_line_one": "Butterwick 1",
"address_line_two": "Hammersmith",
"town": "London",
"county": "Greater London",
"country_code": "uk",
"postcode": "W68DL",
"work_phone": 1234567,
"home_phone": 1234567,
"email": "customerservices@ingresso.co.uk"
}
}
],
"timestamp": "20171004150512",
"_meta": null
}
Results
Attribute | Description |
---|---|
status |
String representing the status of the response (along with an HTTP status code). Can have following values: success , error , warning , debug |
message |
Optional message, usually contains detailed error information if status is set to error . |
count |
Number of transaction records returned. |
timestamp |
UTC time in a form of YYYYMMddhhmmss . |
_meta |
Object containing additional data, if supplied. |
data |
List of objects containing transaction records, defined below. |
Each transaction record returned from the API will have the following keys set:
Name | Description |
---|---|
transaction_id |
The primary Ingresso transaction reference. |
item_number |
A unique sequential number for the order. The second order added to the trolley will have item_number 2. The combination of transaction_id and item_number is unique. |
user_id |
The user for which the transaction was made. |
backend_purchase_ref |
The purchase reference from the supplier ticketing system. |
event_id |
Unique identifier for the event. |
event_desc |
Name of the show or event e.g. The Lion King. |
event_country_code |
Code for the event’s country. |
venue_desc |
Description of the event’s venue. |
supplier_code |
Name of the backend system purchase was made with. |
purchase_time_utc |
Purchase time (UTC). |
purchase_time_london |
Purchase time (London timezone). |
performance_local_time |
Performance time in the timezone local to the event. |
perf_type_code |
Internal code. |
ticket_type_code |
The unique identifier for the ticket type. For attractions this can refer to variations such as General Admission or Fast Track, and there is often only only. For seated events this normally refers to a part of house / seating area such as Grand Circle. |
ticket_type_desc |
The description for the ticket type displayed to the customer. |
send_code |
Send method code. |
send_desc |
Description for the send method. |
seat_ids |
Array containing list of purchased seats. |
trans_status |
Status of the transaction - one of normal , test , refunded , partially-refunded , exchanged-original , exchanged-replacement (for exchanges the old booking is marked exchanged-original and the new booking marked exchanged-replacement ), cancelled-performance , exchanged-venue-system-only (this is rare but covers the case when a booking is exchanged within the venue system so there is no record of the new tickets within the Ingresso Platform). |
sale_mode |
The mode used to purchase tickets. Will be internal_credit if the sale was made on credit or external_redirect if the sale was made using Stripe or with a redirect. |
debitor_reference |
If using Stripe this will be Stripe’s Charge ID. |
user_can_use_customer_data |
Data protection question - set to true if the customer has opted in to receiving marketing emails from you. |
supplier_can_use_customer_data |
Data protection question - set to true if the customer has opted in to receiving marketing emails from the event provider. |
num_tickets |
Number of purchased tickets. |
num_transactions |
This will be 1 for the first item in the order and 0 for the rest. |
sale_currency_code |
ISO 4217 three letter code that applies to the sale_seatprice , sale_surcharge , ticket_price , send_cost . |
sale_seatprice |
The total face value for this order. |
sale_surcharge |
The total booking fee for this order. |
ticket_price |
sale_seatprice + sale_surcharge |
send_cost |
Send method cost. |
commission_currency_code |
ISO 4217 three letter code that applies to all of the following commission attributes. |
user_commission_inc_vat |
The commission earned for this transaction (all commission amounts are totals, not an amount per ticket). |
billable |
Whether or not a charge was or will be applied to the transaction |
The following fields are only returned for users that have permission to view detailed commission information:
Name | Description |
---|---|
gross_commission_inc_vat |
The total commission available (Ingresso’s commission + user_commission_inc_vat). |
inside_commision_inc_vat |
The total inside commission (commission paid by a supplier from the sale_seatprice ). |
supplier_levy |
The total restoration levy or venue facility fee. |
supplier_fee |
A fee paid to the supplier. |
supplier_rebate |
Another type of fee paid to the supplier. |
surcharge_non_commissionable_postage |
A postage fee that is added as part of the sale_surcharge and excluded from commission calculations, not used by most partners. |
surcharge_commissionable_postage |
A postage fee that is added as part of the sale_surcharge and included within commission calculations, not used by most partners. |
processing_fee |
A processing fee, not used by most partners. |
supplier_uplift |
Uplift is an additional charge on top of the ticket price for an upgraded experience. This is the uplift component earned by the supplier. |
user_uplift |
This is the uplift component earned by the partner. |
The customer fields are only returned for users which have permissions to see detailed customer data - by default these fields won’t be included - if you would like them included please contact us
For testing you can use the user demo-customerdata
(password demopass
). You can purchase with this user the same way you can with demo
, however note that any customer data you enter when purchasing will be visible by everyone, so do not enter any data you do not want the internet to see.
Name | Description |
---|---|
first_name |
First name of the customer |
last_name |
Last name of the customer |
address_line_one |
First line of customer’s address |
address_line_two |
Second line of customer’s address |
town |
Address’ city |
county |
Address’ county |
country |
Customer’s country |
postcode |
Customer’s postcode |
home_phone |
Customer’s home phone |
work_phone |
Customer’s work phone |
email |
Customer’s email |