We currently have our Rental Karting data exposed and documented below.
Currently, no requests are cached.
The API is not currently rate limited. Please use good judgment when designing your application.
We currently support JSON, JSONP & XML (plus iCal on Events).
Email us with any API questions or requests.
Questions requiring in-depth technical consultation from a Clubspeed API subject matter expert are subject to consulting services billingThis icon represents a private call. When making a private call, either the private api key or an administrator username and password is required.
By using our API, you are consenting to follow our Terms and Conditions
Use these methods to retrieve rental karting data.
You will need a key to access the Karting API. Email us to obtain your own.
Use these methods to find a racer's "racer_id" which can be used to get information on both the racer and the races they have participated in. Without a field parameter this is a wildcard match across First Name, Last Name, Racer Name and Email. It is possible to specify a specific field. "field=email" is currently supported. See email example below for usage.
/racers/search?query=Wes Ratcliff
(JSON, JSONP, XML)/racers/search?field=email&query=wes@nolamotor.com
(JSON, JSONP, XML)/racers/1000002
(JSON, JSONP, XML)/racers/1000002/races
(JSON, JSONP, XML)/racers/toprpm?limit=5
(JSON, JSONP, XML)/racers/toprpm?gender=m
(JSON, JSONP, XML)/racers/most_improved_rpm?range=month&month=6&year=2014&limit=5
(JSON,
JSONP,
XML)
/racers/most_improved_rpm?start=2016-09-09&end=2016-10-02
(JSON,
JSONP,
XML)
/racers/last_updated?start=2012-09-01+00:00:00&limit=1000&end=2019-11-01+00:00:00&startCustId=1000000&endCustId=1999999
(JSON, JSONP, XML)Get information on races and laps. Can use "next" or "current" in place of the race_id to pull information from the next or currently running race.
heat_status_id
: 0 = Not Started; 1 = Currently Running; 2 = Auto Stopped; 3 = Manually Stopped; 4 = Closed
There are two ways to win, stored as win_by
in the race -- by "position" or by fastest "laptime". Races by position's timing is started when the first person crosses the start/finish line. This is the lowest amb_time
in the laps returned. Gaps to the leader and position in the race may be calculated by taking the racer's time and subtracting out the lowest amb_time
.
/races/races
(JSON, JSONP, XML)/races/upcoming
(JSON, JSONP, XML)/races/races.json?start=2014-01-01&end=2014-01-01
(JSON, JSONP, XML)/races/next
(JSON, JSONP, XML)/races/previous
(JSON, JSONP, XML)/races/current_race_id
(JSON, JSONP, XML)/races/9829
(JSON, JSONP, XML)/races/9829/number_of_laps
(JSON, JSONP, XML)/races/9829/laps.json?racer_id=1000002&lap_id=584079
(JSON, JSONP, XML)/races/upcoming_heat_types
(JSON, JSONP, XML)Get the scoreboard for a specific heat or track
Find out some interesting info about the laps run during races
/races/total_laps
(JSON, JSONP, XML)/races/lap_number/500000
(JSON, JSONP, XML)Get a list of completed heats after a specific date and time
/races/since?&date=2014-04-01 09:00:00&limit=200
Find out the final positions for each racer in a finished heat
Find the fastest laps. Results have many options for filtering and sorting. Supports a maximum of 100 per query.
/races/fastest?track=1
/races/fastest?speed_level=1
/races/fastest?limit=5
/races/fastest?gender=m
/races/fastest?exclude_employees=1
/races/fastest?only_employees=1
/races/fastest?exclude_employees=0
/races/fastest?weight=light
/races/fastest?start_birthdate=1982-01-01&end_birthdate=1982-12-31
Discover all tracks at a venue
Get the current version of Club Speed
/version/current
(JSON, JSONP, XML)/version/api
(JSON, JSONP, XML)/version/os
(JSON, JSONP, XML)/version/sql
(JSON, JSONP, XML)Get the configuration for a "Speed Screen" channel
Attempt to login a user
/users/login
(JSON, JSONP, XML)/users/login
(JSON, JSONP, XML)Tie into Club Speed's translation database. Translations are grouped by "namespaces".
/translations/getNamespace
(JSON, JSONP, XML)/translations/getTranslations
(JSON, JSONP, XML)/translations/translate
(JSON, JSONP, XML)Retrieve settings from Club Speed (most settings require a private key). Settings are grouped and may be accessed by the entire group or by a specific group/setting pair.
A special group entitled "kiosk" exists that presents a consolidated registration kiosk setting group regardless of the version of Club Speed.
Other supported groups: "decoders"
/settings/get
(JSON, JSONP, XML)/settings/get
(JSON, JSONP, XML)Retrieve images from Club Speed (requires private key). Settings are grouped by app.
Currently supported apps: kiosk
The ClubSpeed API requires one of three types of authentication:
Public and private key authentication are handled by including the key query string in any API call:
/api/index.php/resource?key=TODAYS_PUBLIC_KEY
/api/index.php/resource?key=MY_SECRET_PRIVATE_KEY
Basic authentication can also be used by including a basic authorization header where the data following the word Basic is a ClubSpeed username and password concatenated with a colon for a delimiter and converted to base64.
GET https://sirtigard.clubspeedtiming.com/api/index.php/resource HTTP/1.1 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
For the purposes of authentication, the ClubSpeed API has two levels: Public and Private. Public and Private keys line up respectively, and Basic authentication has Private access.
The ClubSpeed API implements a RESTful set of interfaces.
For almost every resource detailed below (with a few exceptions, such as resetting passwords, processing payments, and read-only resources), the following calls can be made.
Method | Route | Action | Request Body | Response Body |
---|---|---|---|---|
GET | /api/index.php/resource | List all records | Object or array representation of records | |
GET | /api/index.php/resource/:id | Get single record | Object representation of record | |
POST | /api/index.php/resource | Create single record | Object to be created | ID of the created object |
PUT | /api/index.php/resource/:id | Update single record | Object containing updates | |
DELETE | /api/index.php/resource/:id | Delete single record | ||
GET | /api/index.php/resource/count | Count of records | Number representing record count |
Wherever a word prefixed with :
appears in a URL, such as
:variable
, you should replace
:variable
with its corresponding value.
If a resource is noted to be read-only,
then you should assume that only GET
methods are available.
Also note that some resources make use of composite primary keys.
When a composite key is being used, then each piece of the composite key
will correspond to one :id
in the route,
placed in the order they appear in the documentation.
For example, to
GET
,
PUT
,
or DELETE
a HeatDetail record,
the relevant route will be:
/api/index.php/heatdetails/:heatId/:customerId
An HTTP response containing a status code in the 2XX range, typically 200 OK
,
indicates that the ClubSpeed API call was made successfully.
HTTP/1.1 200 OK
Any other response codes, typically in the 4XX or 5XX range, should be considered a failed API call.
In the case of a failed API call, the response body will contain an error in the following format, where error.code is a copy of the HTTP status code, and error.message contains a readable error message indicating an accidental logical error (attempting to finalize an unbalanced check, not providing a required field on create, etc) or an expected server error.
HTTP/1.1 500 Internal Server Error { "error": { "code": 500, "message": "Internal Server Error: Unable to make connection to mail server!" } }
At the current point in time, the ClubSpeed API has added a modified querying system in order to improve functionality available with each standard resource endpoint (excluding extensions such as processing payments and resetting passwords). This includes improved support for complex filtering logic, and adds pagination and ordering to the system.
For simplicity, we will refer to the new calls as V2
methods,
and previously existing methods as V1
.
The new V2 querying syntax, as well as pagination and ordering will all be available with all resource calls. The original V1 syntax for Record Filtering and Property Matching will remain intact for previously existing calls in order to prevent breaking changes. However, it will not work for any newly added calls, and we strongly suggest using the new syntax to avoid potential future breaking changes, and in order to support fuller querying capabilities.
Each call specified below will notate which version it falls under, which will indicate which type of querying will be available to the call.
The ClubSpeed API has functionality for selecting specific columns / properties for GET operations. If only certain properties of a JSON object are desired, the client can handle their selection by appending the following query string to any GET operation:
/api/index.php/resource?select=column1, column2, column3
For example, if we want to select paymentId
,
payDate
, payAmount
,
and payTax
from the Payments resource,
the following call could be made.
GET https://sirtigard.clubspeedtiming.com/api/index.php/payments?select=paymentId,payDate,payAmount,payTax HTTP/1.1
HTTP/1.1 200 OK [ { "paymentId": 5048, "payDate": "2016-03-07T11:46:22.00", "payAmount": 2, "payTax": 0.14 }, { "paymentId": 5049, "payDate": "2016-03-07T11:46:25.00", "payAmount": 2, "payTax": 0.14 } ]
The suggested syntax for ClubSpeed API filtering for GET operations uses a JSON object syntax to declare the desired filter. The syntax is as below, and must be valid, parseable JSON. Note that the examples given in this documentation will not be URI encoded for readability, but JSON encoding then URI encoding is the suggested way of sending this information.
/api/index.php/resource?where={ "column1": "value" }
/api/index.php/resource?where={ "column1": { "comparator": "value" }
The syntax we use here is modelled and influenced by other libraries such as Sequelize and MongoDB.
Property | Example | Parsed | Notes |
---|---|---|---|
$lt | {"col":{"$lt":1}} |
[col] < 1 |
|
$lte | {"col":{"$lte":1}} |
[col] <= 1 |
|
$eq | {"col":{"$eq":1}} |
[col] = 1 |
If a value is used in place of a comparison object, then an implicit $eq will be applied to it (see first example). |
$gt | {"col":{"$gt":1}} |
[col] > 1 |
|
$gte | {"col":{"$gte":1}} |
[col] >= 1 |
|
$ne, $neq | {"col":{"$ne":1}} |
[col] != 1 |
|
$is | {"col":{"$is":null}} |
[col] IS NULL |
To be used with NULL |
$isnot | {"col":{"$isnot":null}} |
[col] IS NOT NULL |
To be used with NULL |
$lk, $like | {"col":{"$lk":"s%"}} |
[col] LIKE 's%' |
|
$nlk, $notlike | {"col":{"$nlk":"s%"}} |
[col] NOT LIKE 's%' |
|
$in | {"col":{"$in":[1,2]}} |
[col] IN (1, 2) |
To be used with arrays of values |
$nin, $notin | {"col":{"$nin":[1,2]}} |
[col] NOT IN (1, 2) |
To be used with arrays of values |
$has, $contains | {"col":{"$has":"s"}} |
[col] LIKE '%s%' |
Automatically surrounds value with % signs, then uses LIKE operator |
Property | Example | Parsed | Notes |
---|---|---|---|
$and | {"$and": [{"col1":1},{"col2":2}]} |
[col1] = 1 AND [col2] = 2 |
Note that if multiple comparators are provided in the same object, then an implicit $and grouping will be applied to them. See below for examples. |
$or | {"$or": [{"col1":1},{"col2":2}]} |
[col1] = 1 OR [col2] = 2 |
|
$not | {"$not": { "col": 1 } } |
NOT ( [col] = 1 ) |
?where={ "amount": 43.2 }
[amount] = 43.2
?where={ "amount": 43.2, "type": 2 }
[amount] = 43.2 AND [type] = 2
?where={ "amount": null }
[amount] IS NULL
?where={ "amount": { "$gte": 43.2 } }
[amount] >= 43.2
?where={ "amount": { "$gte": 43.2, "$lte": 55.7 } }
([amount] >= 43.2 AND [amount] <= 55.7)
?where={ "amount": 43.2, "timestamp": { $gte: "2016-01-01T00:00:00" } }
([amount] = 43.2 AND [timestamp] >= '2016-01-01T00:00:00')
?where={ "$or": [ { "amount": 43.2 }, { "userId" : { "$nin": [ 1, 2, 3 ] } } ] }
([amount] = 43.2) OR ([userId] NOT IN (1, 2, 3))
?where={ "$or": [ { "amount": 43.2, "type": 2 }, { "userId" : { "$nin": [ 1, 2, 3 ] } } ] }
([amount] = 43.2 AND [type] = 2) OR ([userId] NOT IN (1, 2, 3))
?where={ "notes": { "$has": "Last Tuesday" } }
[notes] LIKE '%Last Tuesday%'
?where={ "$not": { "$or": [ { "transaction": null }, { "$and": [ { "payType": 3 }, { "payStatus": { "$neq": 2 } } ]} ] } }
NOT ( [transaction] IS NULL OR ( [payType] = 3 AND [payStatus] != 2 ) )
ClubSpeed API calls have the ability to apply orders for GET operations, by supplying a comma delimited string of columns and their directions.
The syntax is as below:
/api/index.php/resource?order=column1
/api/index.php/resource?order=column1 DIRECTION
/api/index.php/resource?order=column1 DIRECTION, column2 DIRECTION
Note that direction can be one of either ASC
or DESC
.
If a direction is not provided, then ASC
is used as a default.
?order=column1
ORDER BY [column1] ASC
?order=column1 DESC
ORDER BY [column1] DESC
?order=column1,column2
ORDER BY [column1] ASC, [column2] ASC
?order=column1 ASC, column2 DESC
ORDER BY [column1] ASC, [column2] DESC
ClubSpeed API calls have multiple parameters which can be used to paginate results for GET operations.
The syntax is as below:
/api/index.php/resource?limit=NUMBER
/api/index.php/resource?skip=NUMBER
limit
will take up to the provided number of records.
If the limit goes beyond the available number of records,
then all available records will be returned. If no limit is provided,
then a default of 100 will be used. Note that for V1 calls,
this limit is not imposed for backwards compatibility
with existing code.
skip
will offset by up to the provided number of records.
Note that if the offset moves beyond the available number of records,
an empty result will be returned. This parameter is entirely optional.
Note that offset
can be used as an alias for skip
,
and take
can be used as an alias for limit
These pagination parameters work in tandem with Record Filtering and Ordering.
?limit=50
?limit=50&skip=50
?where={"amount":{"$gte":50}}&skip=50&take=10
?limit=10&order=recordId DESC
For any response which returns a response body, the output can be formatted as either JSON or XML.
In order to pick the response body content type, you can do one of two things:
Accept
header.json
or .xml
to the resource route
We recommend using the Accept
header for both performance and standards compliance, but both methods are functional.
For example, the next two code blocks show HTTP calls which request a JSON
encoded response body
GET /api/index.php/payments HTTP/1.1 Accept: application/json
GET /api/index.php/payments.json HTTP/1.1
And the response would look similar to this:
[ { "paymentId": 1, "payDate": "2006-05-24T16:58:18.00", "payAmount": 20, "payTax": 0 }, { "paymentId": 2, "payDate": "2006-05-24T16:59:29.00", "payAmount": 20, "payTax": 0 } ]
Whereas the next two code blocks show HTTP calls which request an XML
encoded response body
GET /api/index.php/payments HTTP/1.1 Accept: application/xml
GET /api/index.php/payments.xml HTTP/1.1
And the response would look similar to this:
HTTP/1.1 200 OK Content-Type: application/xml <?xml version="1.0"?> <response> <item> <paymentId>1</paymentId> <payDate>2006-05-24T16:58:18.00</payDate> <payAmount>20</payAmount> <payTax>0</payTax> </item> <item> <paymentId>2</paymentId> <payDate>2006-05-24T16:59:29.00</payDate> <payAmount>20</payAmount> <payTax>0</payTax> </item> </response>
The ClubSpeed API has functionality for filtering data sets by using grouped comparators for GET operations. If only certain records from the database are desired, the client may filter out those records by appending any of the following query strings to any GET operation. This type of call can be used in tandem with Column Selection but may not be used at the same time as Property Matching.
Note that this method of record filtering is only available to any call marked as V1, and will not be supported on any new endpoints moving forward.
The syntax is as below:
/api/index.php/resource?filter=column1 {comparator} value1
/api/index.php/resource?filter=column1 {comparator} column2
/api/index.php/resource?filter=column1 {comparator} value1 {connector} column2 {comparator} value2
<
<=
>
>=
=
!=
<>
IS
IS NOT
IN
%lt; ( equivalent to < )
%lte; ( equivalent to <= )
%gt; ( equivalent to > )
%gte; ( equivalent to >= )
%eq; ( equivalent to = )
%neq; ( equivalent to != )
$lt ( equivalent to < )
$lte ( equivalent to <= )
$gt ( equivalent to > )
$gte ( equivalent to >= )
$eq ( equivalent to = )
$neq ( equivalent to != )
$in ( equivalent to IN )
AND
OR
?filter=amount $eq 43.2
[amount] = 43.2
?filter=amount = 43.2 AND type = 2
[amount] = 43.2 AND [type] = 2
?filter=amount IS NULL
[amount] IS NULL
?filter=amount >= 43.2
[amount] >= 43.2
?filter=amount >= 43.2 AND amount <= 55.7
[amount] >= 43.2 AND [amount] <= 55.7
?filter=amount = 43.2 OR timestamp >= 2016-01-01T00:00:00
[amount] = 43.2 OR [timestamp] >= '2016-01-01T00:00:00'
Property matching is a shortcut version of the V1 record filtering. The functionality is the same, but can only be used for matching property values by equivalence. This type of call may be used on GET operations, and can be used in tandem with Column Selection but may not be used at the same time as Record Filtering. The syntax is as below:
/api/index.php/resource?column1=value1
/api/index.php/resource?column1=value1&column2=value2
For example, to collect all screenTemplateDetail records which have a parent screenTemplateId of 3, we could make the following call (note the screenTemplateId= portion of the query string):
GET https://sirtigard.clubspeedtiming.com/api/index.php/screenTemplateDetail?screenTemplateId=3&select=screenTemplateId,screenTemplateDetailId,trackNo,timeInSecond,seq HTTP/1.1
HTTP/1.1 200 OK { "channelDetail": [ { "screenTemplateDetailId": 21, "screenTemplateId": 3, "seq": 4, "timeInSecond": 30, "trackNo": 1 }, { "screenTemplateDetailId": 65, "screenTemplateId": 3, "seq": 3, "timeInSecond": 15, "trackNo": 1 } ] }
This section is a collection and description of the API methods which are expected to be called in order to use a custom front-end with ClubSpeed's Online booking.
heatId
in the response,
as it will be needed when the customer checks out by using Process Payment.
A Booking
is a record designed to expose a Heat
to the Online Booking interface.
To make a booking available, create a record with a HeatMain.heatId
and Product.productsId
pairing,
which will indicate that a place in the Heat
can be purchased by buying one of the connected Product
.
Url | /booking |
Version | V1 |
Access | Private |
{ "bookings": [ { "onlineBookingsId": 4, "heatId": 4344, "productsId": 5, "isPublic": true, "quantityTotal": 5 } ] }
Name | Type | Default | Description |
---|---|---|---|
onlineBookingsId | Integer | {Generated} | The primary key for the record |
heatId | Integer | The ID of the heat for the booking | |
productsId | Integer | The ID of the product for the booking | |
isPublic | Boolean | true | The flag indicating whether or not to make this booking available to the online booking interface |
quantityTotal | Integer | The total number of booking reservations to make available. This must be a positive integer |
BookingAvailability
is a helper, read-only resource designed
to handle collecting the current availability for an online Booking
,
which takes into account both online and local bookings and reservations.
Url | /bookingAvailability |
Version | V1 |
Access | Private |
{ "bookings": [ { "heatId": 4344, "heatDescription": "12 Minute Session", "heatStartsAt": "2014-10-08T20:20:00.00", "heatSpotsTotalActual": 22, "heatSpotsAvailableCombined": 21, "heatSpotsAvailableOnline": 21, "heatTypeId": 23, "isPublic": true, "products": [ { "onlineBookingsId": 4, "price1": 35, "productDescription": "SK 10 Minutes", "productsId": 5, "productSpotsAvailableOnline": 5, "productSpotsTotal": 5, "productType": "PointItem" } ] } ] }
Name | Type | Default | Description |
---|---|---|---|
heatId | Integer | The ID of the heat for the booking. | |
heatDescription | String | The description of the heat. | |
heatStartsAt | DateTime | The start time for the heat. | |
heatSpotsTotalActual | Integer | The original total spots for the heat. | |
heatSpotsAvailableCombined | Integer | The ID of the heat for the booking. | |
heatSpotsAvailableOnline | Integer | The number of spots intended to be exposed to the online interface for the entire heat. | |
products | Array<Products> | The container for Products objects. | |
products.onlineBookingsId | Integer | The ID for the booking. | |
products.price1 | Double | The price of the product for the booking. | |
products.productDescription | String | The description of the product for the booking. | |
products.productsId | Integer | The ID of the product for the booking. | |
products.productSpotsAvailableOnline | Integer | The number of spots intended to be exposed to the online interface for this specific product. | |
products.productSpotsTotal | Integer | The total number of spots originally made available through this product pairing. | |
products.productType | Integer | The ID of the type for the product. |
BookingTypeLinksBriq
are the records which save the Briq Booking Key IDs
for the related Event Reservation, Heat or Event.
Url | /BookingTypeLinksBriq |
Version | V2 |
Access | Private |
{ "bookingTypeLinksBriqId": 7, "briqObjectKey": "E71DB4EF78BD40ED9C79A375F20A0F20", "eventReservationId": null, "heatNo": 36480, "eventId": null, "createdDate": "2020-01-27T06:38:24.72", "productQuantity": null }
Name | Type | Default | Description |
---|---|---|---|
bookingTypeLinksBriqId | Integer | {Generated} | The primary key for the record. |
briqObjectKey | String | The object key provided by Briq is used to create the Event Reservation and Heat or Event. | |
eventReservationID | Integer | Event Reservation id for the related Event Reservation record. | |
HeatNo | Integer | HeatNo for the related HeatMain record. | |
EventId | Integer | EventId for the related Event record. | |
CreatedDate | DateTime | The date the booking type link for Briq was created. | |
ProductQuantity | Integer | Original Quantity booked for reservation. |
A CheckDetail
record represents a line item and quantity
attached to a Check
.
To attach a new line item to a check, insert a CheckDetail
using the relevant checkId
, productId
, and qty
,
typically allowing the API to auto-populate the remainder of the information from the Product
definition.
Url | /checkDetails |
Version | V1 |
Access | Private |
{ "checkDetails": [ { "checkDetailId": 12863, "checkId": 6779, "status": 1, "type": 1, "productId": 1002, "productName": "Rotax Helmet Case", "createdDate": "2015-09-08T09:17:05.00", "qty": 1, "unitPrice": 30000, "unitPrice2": 0, "discountApplied": 0, "taxId": 1, "taxPercent": 0, "gst": 0, "voidNotes": "", "p_Points": 0, "p_CustId": null, "r_Points": null, "discountUserId": null, "discountDesc": null, "calculateType": null, "discountId": null, "discountNotes": null, "g_Points": 0, "g_CustId": null, "m_DaysAdded": null, "s_SaleBy": null, "s_NoOfLapsOrSeconds": null, "s_CustId": null, "s_Vol": null } ] }
Name | Type | Default | Description |
---|---|---|---|
checkDetailId | Integer | {Generated} | The primary key for the record |
calculateType | Integer | The type of application for an applied discount | |
checkId | Integer | The ID for the parent check of the check detail | |
createdDate | DateTime | {Now} | The timestamp at which the check detail was created |
discountApplied | Double | The amount of the discount which was applied | |
discountDesc | String | The description of the discount which was applied | |
discountId | Integer | The ID of the discount which was applied | |
discountNotes | String | Notes regarding the application of the discount | |
discountUserId | Integer | The ID for the user who applied the discount | |
g_CustId | Integer | The ID of the customer on which to apply points on purchase. Note that this ID may reference a gift card | |
g_Points | Double | The amount of money to be given to CheckDetail.g_CustId at purchase / check finalize. This value typically corresponds to Product.g_Points |
|
gst | Double | The percent of the tax to be applied as GST, which corresponds to Tax.gst |
|
p_CustId | Integer | The ID of the customer on which to apply points on purchase | |
p_Points | Double | The number of points to be applied on purchase, which corresponds to Product.p_Points |
|
productId | Integer | The ID for the product on the check detail | |
productName | String | The name of the product on the check detail | |
qty | Integer | The quantity of the product on the check detail | |
r_Points | Double | The number of reservation points to be applied on purchase, which corresponds to Product.r_Points |
|
status | Integer | 1 |
The status of the check detail
|
taxId | Integer | The ID for the tax to be applied | |
taxPercent | Double | The percent of the tax to be applied, which corresponds to Tax.amount |
|
type | Integer |
The type of the product, which corresponds to Product.productType
|
|
unitPrice | Double | The unitPrice of the product, which corresponds to Product.price1 |
|
voidNotes | String | Any notes which were added while voiding the check detail |
A Check
record is a representation of a financial invoice.
Note that Checks
cannot be deleted through typical REST functionality,
and instead should be voided.
Url | /checks |
Version | V1 |
Access | Private |
{ "checks": [ { "checkId": 1234, "customerId": 0, "type": 1, "status": 1, "name": "", "userId": 6, "total": 16, "broker": "", "notes": "", "gratuity": 0, "fee": 0, "openedDate": "2014-03-22T11:50:28.68", "closedDate": "2014-03-22T11:56:04.82", "isTaxExempt": false, "discount": 0, "discountId": 0, "discountNotes": "", "discountUserId": 0, "invoiceDate": null } ] }
Name | Type | Default | Description |
---|---|---|---|
checkId | Integer | {Generated} | The primary key for the record |
customerId | Integer | 0 | The ID of the customer for the check, where available |
type | Integer | 1 |
The type of the check
|
status | Integer | 0 |
The status of the check
|
name | String | The name of the check | |
userId | Integer | The ID of the user who created the check | |
total | Double | The applied total for the check. This calculated field includes all underlying check details, taxes, discounts, fees, and gratuity | |
broker | String | The name of the check broker | |
notes | String | Any additional notes for the check | |
gratuity | Double | 0.00 | Any additional gratuity to be applied for the whole check |
fee | Double | 0.00 | Any additional fee to be applied for the whole check |
openedDate | DateTime | {Now} | The timestamp on which the check was opened |
closedDate | DateTime | The timestamp on which the check was closed | |
isTaxExempt | Boolean | An override flag stating whether or not the entire check is exempt from taxation | |
discount | Double | 0.00 | Any discount to be applied for the whole check |
discountNotes | String | Any additional notes for the discount | |
discountUserId | Integer | The ID of the user who added the discount | |
invoiceDate | DateTime | The timestamp on which the invoice was handled |
Url | /checks/:id/void |
Verb | POST |
Access | Private |
This extension method will close the Check
and void any existing CheckDetails
.
Any Payment
attached to the Check
will remain untouched,
and should be handled separately.
Url | /checks/:id/finalize |
Verb | POST |
Access | Private |
This extension method will close the Check
,
running any additional requirements such as creating and assigning gift cards,
sending receipt emails, or adding customers and reservations to heats,
which is pre-determined by the productType
of the Products
attached through each CheckDetail
.
Note that the balance of the Check
must be 0
before finalize
can be run.
One caveat is that if there is a reservation Product
attached to the Check
,
then finalize needs to know to which Heat
the purchasing Customer
should be added.
To do that, post a request body as follows, where checkDetailId
is the id of the line item containing the reservation Product
,
and heatId
is the id of the Heat
to which the Customer
should be added.
This information is required
for any check which contains a
reservation Product
.
POST https://sirtigard.clubspeedtiming.com/api/index.php/checks/:id/finalize { "details": [ { "checkDetailId": 13385, "heatId": 113 } ] }
If you do not wish to have ClubSpeed send receipt emails for you, you may pass in the following flag in the request body to disable automatic emailing of the receipt.
POST https://sirtigard.clubspeedtiming.com/api/index.php/checks/:id/finalize { "sendCustomerReceiptEmail": false }
If you wish to disable sending a gift card email for a specific check detail, you can override the default emailing behavior by sending a sendEmail flag alongside a gift card check detail.
Default behavior is to send a separate email for each gift card check detail.
POST https://sirtigard.clubspeedtiming.com/api/index.php/checks/:id/finalize { "details": [ { "checkDetailId": 13386, "sendEmail": false }, { "checkDetailId": 13387 } ] }
Information which can be used to build a receipt will be returned in the response body in the following format.
HTTP/1.1 200 OK { "checkId": 7561, "customer": "Jim Joe", "email": "bob155711@clubspeed.com", "business": "My Karting Business", "checkSubtotal": "£15.00", "checkTotal": "£15.75", "checkTax": "£0.75", "balance": "£0.00", "details": [ { "checkDetailId": 13863, "note": "Heat #329710 scheduled at 23-03-2016 10:48", "productName": "Reservation Product for API Unit Testing", "description": "Reservation Product for API Unit Testing: Heat #329710 scheduled at 23-03-2016 10:48", "quantity": 5, "price": "£2.00", "heatId": 329710, "scheduledTime": "23-03-2016 10:48", "trackName": "Adults " }, { "checkDetailId": 13864, "note": "#1752589499", "productName": "Gift Card", "description": "Gift Card: #1752589499", "quantity": 1, "price": "£5.00", "heatId": null, "scheduledTime": null, "trackName": null } ], "payments": [ { "type": "External", "amount": "£15.75" } ] }
Url | /checkTotals |
Version | V1 |
Access | Private |
Name | Type | Default | Description |
---|---|---|---|
checks | Array<Check> | The container for check objects | |
Check.customerId | Integer | The id of the customer for the check | |
Check.userId | Integer | The id for the user who is creating the check | |
Check.checkType | Integer | The type of the check | |
Check.checkStatus | Integer | The status of the check | |
Check.name | String | The name of the check | |
Check.checkTotalApplied | String | The total stored on the check | |
Check.broker | String | The name of the broker for the check | |
Check.notes | String | The name for the check | |
Check.gratuity | Double | The gratuity to be applied to the check | |
Check.fee | Double | The fee to be applied to the check | |
Check.openedDate | Double | The date on which the check was opened | |
Check.closedDate | Double | The date on which the check was closed | |
Check.isTaxExempt | Boolean | The override for the tax exemption of the check | |
Check.discount | Decimal | The calculated discount amount which was applied to the check. Note that this is not a summation which includes the check detail discounts. That information will be reflected in the check total | |
Check.checkDiscountId | Integer | The discount for the check | |
Check.checkDiscountNotes | String | The notes for the discount on the check | |
Check.checkDiscountUserId | Integer | The id for the user that applied the discount to the check | |
Check.checkSubtotal | Double | The calculated subtotal for the entire check. Note that this calculation will use live product values | |
Check.checkTax | Double | The calculated tax for the entire check. Note that this calculation will use live tax values | |
Check.checkTotal | Double | The calculated total for the entire check. Note that this calculation will use live tax and product values | |
Check.checkPaidTax | Double | The amount of tax which has already been paid for this check | |
Check.checkPaidTotal | Double | The amount of tax which has already been paid for this check | |
Check.checkRemainingTax | Double | The remaining tax to be paid for this check | |
Check.checkRemainingTotal | Double | The remaining total to be paid for this check | |
Check.details | Array<CheckDetail> | The container for check detail objects | |
CheckDetail.checkDetailId | Integer | The unique identifier for the check detail, which represents a line item for the check | |
CheckDetail.checkDetailStatus | Integer | The status for the check detail | |
CheckDetail.checkDetailType | Integer | The type of the check detail | |
CheckDetail.productId | Integer | The id for the product for the check detail | |
CheckDetail.productName | Integer | The name of the product | |
CheckDetail.qty | Integer | The quantity of the product for the check detail | |
CheckDetail.checkDetailDiscountId | Integer | The id for the discount which was applied to the check detail | |
CheckDetail.checkDetailDiscountUserId | Integer | The id for the user who applied the check detail discount | |
CheckDetail.checkDetailDiscountDesc | String | The description for the check detail discount | |
CheckDetail.checkDetailDiscountCalculateType | String | The calculation type for the check detail discount | |
CheckDetail.discountApplied | Integer | The calculated amount of the discount applied to this check detail | |
CheckDetail.checkDetailSubtotal | Integer | The calculated subtotal for the check detail items. Note that this calculation will use live product values | |
CheckDetail.checkDetailTax | Integer | The calculated tax for the check detail items. Note that this calculation will use live tax values | |
CheckDetail.checkDetailTotal | Integer | The calculated total for the check detail items. Note that this calculation will use live tax and product values |
Url | /checkTotals |
Verb | POST |
Access | Private |
Required |
checks
Check.customerId
Check.details
CheckDetail.productId
CheckDetail.qty
|
Available |
Check.userId
Check.checkDiscountId
CheckDetail.checkDetailDiscountId
|
Unavailable |
Check.checkType
Check.checkStatus
Check.name
Check.checkTotalApplied
Check.broker
Check.notes
Check.gratuity
Check.fee
Check.openedDate
Check.closedDate
Check.isTaxExempt
Check.discount
Check.checkDiscountNotes
Check.checkDiscountUserId
Check.checkSubtotal
Check.checkTax
Check.checkTotal
Check.checkPaidTax
Check.checkPaidTotal
Check.checkRemainingTax
Check.checkRemainingTotal
CheckDetail.checkDetailId
CheckDetail.checkDetailStatus
CheckDetail.checkDetailType
CheckDetail.productName
CheckDetail.checkDetailDiscountUserId
CheckDetail.checkDetailDiscountDesc
CheckDetail.checkDetailDiscountCalculateType
CheckDetail.discountApplied
CheckDetail.checkDetailSubtotal
CheckDetail.checkDetailTax
CheckDetail.checkDetailTotal
|
While CheckTotals
is technically a read-only
set of Check
information from the database,
posting to /checkTotals is available as an extension method
to dynamically create and populate all relevant Check
and CheckDetails
records
by using the customerId
, productId
,
and qty
fields.
To apply a discount at the Check
level,
include a checkDiscountId
which corresponds to a Discount
.
To apply a discount at the Check Detail
level,
include a checkDetailDiscountId
,
which again corresponds to a Discount
.
Note that if you apply a Check
level
Discount
through this endpoint,
then make modifications to related Check Details
by deleting, adding, or modifying existing line items,
the Check
level Discount
will not be recalculated, and instead will still reflect
the original amount which was calculated. As such, care should be taken to
apply any Discounts
as part of the last
operation before accepting payment and closing the check.
POST https://sirtigard.clubspeedtiming.com/api/index.php/checkTotals?debug=1 HTTP/1.1 { "checks": [ { "customerId": 1000001, "checkDiscountId": 1, "details": [ { "productId": 3, "qty": 1 }, { "productId": 5, "qty": 2, "checkDetailDiscountId": 5 } ] } ] }
HTTP/1.1 200 OK { "checkId": 2361 }
Url | /checkTotals/virtual |
Verb | POST |
Access | Private |
Required |
checks
Check.customerId
Check.details
CheckDetail.productId
CheckDetail.qty
|
Available |
Check.userId
Check.checkDiscountId
CheckDetail.checkDetailDiscountId
|
Unavailable |
Check.checkType
Check.checkStatus
Check.name
Check.checkTotalApplied
Check.broker
Check.notes
Check.gratuity
Check.fee
Check.openedDate
Check.closedDate
Check.isTaxExempt
Check.discount
Check.checkDiscountNotes
Check.checkDiscountUserId
Check.checkSubtotal
Check.checkTax
Check.checkTotal
Check.checkPaidTax
Check.checkPaidTotal
Check.checkRemainingTax
Check.checkRemainingTotal
CheckDetail.checkDetailId
CheckDetail.checkDetailStatus
CheckDetail.checkDetailType
CheckDetail.productName
CheckDetail.checkDetailDiscountUserId
CheckDetail.checkDetailDiscountDesc
CheckDetail.checkDetailDiscountCalculateType
CheckDetail.discountApplied
CheckDetail.checkDetailSubtotal
CheckDetail.checkDetailTax
CheckDetail.checkDetailTotal
|
The virtual checkTotals call does not create a check in the database.
Instead, the virtual call is a way to determine subtotals, taxes, and totals without needing to create the underlying check records by posting the same data structure for Create to the /virtual route.
If you are unable to map the return data by productId
due to a repeat in product,
then the details array will also accept fake and temporary checkDetailId
properties
to assist with mapping the return data.
Please note that the Query Operations for Column Selection
are available for this query. To add a column to the select list, add the name of the property only.
This includes any properties which are part of the details
array.
See the example request and response below for a full example.
POST https://sirtigard.clubspeedtiming.com/api/index.php/checkTotals/virtual?select=customerId,checkSubtotal,checkTax,checkTotal,checkDetailSubtotal,checkDetailTax,checkDetailTotal,discount,discountApplied HTTP/1.1 { "checks": [ { "customerId": 1000001, "checkDiscountId": 1, "details": [ { "productId": 3, "qty": 1 }, { "productId": 5, "qty": 2, "checkDetailDiscountId": 5 } ] } ] }
HTTP/1.1 200 OK { "checks": [ { "checkId": 0, "customerId": 1000001, "checkSubtotal": 85, "checkTax": 17.85, "checkTotal": 102.85, "discount": 1, "details": [ { "checkDetailSubtotal": 15, "checkDetailTax": 3.15, "checkDetailTotal": 18.15 }, { "checkDetailSubtotal": 70, "checkDetailTax": 14.7, "checkDetailTotal": 84.7, "discountApplied": 2.3 } ] } ] }
Url | /clover/pre_auth |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/pre_auth HTTP/1.1 { "amount": 0.21, "checkId": 2020122302, "terminalName": "POS1", "transactionId": "W7TDN5N7M9KDC:6AZG7EZSM3A1C", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/capture_pre_auth |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/capture_pre_auth HTTP/1.1 { "amount": 20.00, "checkId": 2020122, "terminalName": "POS1", "transactionId": "0", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/tip_adjust_auth |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/tip_adjust_auth HTTP/1.1 { "amount": 0.01, "checkId": 2020122302, "terminalName": "POS1", "transactionId": "W7TDN5N7M9KDC:6AZG7EZSM3A1C", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/charge |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/charge HTTP/1.1 { "amount": 20.00, "checkId": 2020122, "terminalName": "POS1", "transactionId": "0", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/auth |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/auth HTTP/1.1 { "amount": 20.00, "checkId": 2020122, "terminalName": "POS1", "transactionId": "0", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/refund |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/refund HTTP/1.1 { "amount": 0.20, "checkId": 20210104, "terminalName": "POS1", "transactionId": "HB3R5ZFE78CQP:S2AT3BJJDZ5Y4", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/manual_refund |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/manual_refund HTTP/1.1 { "amount": 0.20, "checkId": 20210104, "terminalName": "POS1", "transactionId": "HB3R5ZFE78CQP:S2AT3BJJDZ5Y4", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/void |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/void HTTP/1.1 { "amount": 20.00, "checkId": 2020122, "terminalName": "POS1", "transactionId": "0", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/dummy |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/dummy HTTP/1.1 { "amount": 20.00, "checkId": 2020122, "terminalName": "POS1", "transactionId": "0", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
Url | /clover/query |
Verb | POST |
Access | Private |
Required |
amount
checkId
terminalName
transactionId
payType
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/clover/query HTTP/1.1 { "amount": 20.00, "checkId": 2020122, "terminalName": "POS1", "transactionId": "0", "payType": "SWIPEONLY" }
HTTP/1.1 200 OK { }
The Customers
resource is a direct link to the list of customers for a location.
Note that the term Customer
and Racer
are typically used interchangably
throughout the ClubSpeed API, but the /customers
endpoint should be considered
the direct window into the resource.
Url | /customers |
Version | V2 |
Access | Private |
{ "customerId": 1002001, "accountCreated": "2014-04-16T00:00:00.00", "Address": "123 Billing Street", "Address2": "Billpartment 1", "birthdate": "2001-05-10T00:00:00.00", "cardId": 123456, "City": "Billstown", "company": "", "Country": "US", "creditLimit": 0, "creditOnHold": false, "Custom1": "", "Custom2": "", "Custom3": "", "Custom4": "1", "deleted": false, "donotemail": false, "email": "someone@mail.com", "fax": "", "firstname": "Real", "gender": 1, "generalNotes": "" "howdidyouhearaboutus": 0, "ignoreDOB": false, "isEmployee": false, "isGiftCard": false, "lastname": "Fakerson", "lastVisited": "2014-04-16T00:00:00.00", "LicenseNumber": "", "membershipStatus": 0, "membershipText": "", "memberShipTextLong": "", "mobilephone": "", "originalId": 0, "phoneNumber": "123-456-7890", "phoneNumber2": "", "priceLevel": 1, "privacy1": false, "proskill": 1200, "racername": "the_real_faker", "State": "CA", "status1": 1, "status2": 0, "status3": 0, "status4": 0, "totalRaces": 3, "totalVisits": 1, "waiver": 1, "waiver2": 7, "webUserName": "", "Zip": "12345", }
Name | Type | Default | Description |
---|---|---|---|
customerId | Integer | The primary key for the record | |
accountCreated | DateTime | The timestamp when the customer record was created | |
Address | String | The first address line for the customer | |
Address2 | String | The second address line for the customer | |
birthdate | DateTime | The birthdate of the customer | |
City | String | The city of residence for the customer | |
company | String | The company of the customer | |
Country | String | The country of residence for the customer | |
cardId | Integer | -1 | The membership card number for the customer |
creditLimit | Double | 0 | The credit limit for the customer |
creditOnHold | Boolean | false | Flag indicating whether the customer's credit is on hold |
Custom1 | String | Custom data holder 1 | |
Custom2 | String | Custom data holder 2 | |
Custom3 | String | Custom data holder 3 | |
Custom4 | String | Custom data holder 4 | |
deleted | Boolean | false | Flag indicating whether the customer has been soft deleted |
donotmail | Boolean | false | Flag indicating whether the customer does not wish to receive mail |
String | The email address for the customer | ||
fax | String | The fax number for the customer | |
firstname | String | The first name of the customer | |
gender | Integer | 0 |
The gender of the customer
|
generalNotes | String | Any notes about the customer | |
ignoreDOB | Boolean | Flag indicating whether or not the birthdate of the customer can be ignored | |
isEmployee | Boolean | Flag indicating whether the customer record is also an employee | |
isGiftCard | Boolean | Flag indicating whether the customer record should be considered a gift card | |
lastVisited | DateTime | The date at which the customer last visited | |
LicenseNumber | String | The license number for the customer | |
lastname | String | The last name of the customer | |
membershipStatus | Integer | Denormalized | |
membershipText | String | Abbreviation of the membership for the customer | |
memberShipTextLong | String | Description of the membership for the customer | |
mobilephone | String | The mobile phone for the customer | |
phoneNumber | String | The phone number for the customer | |
phoneNumber2 | String | The alternate phone number for the customer | |
privacy1 | Boolean | false | Flag indicating whether the name of the customer should be hidden from race results |
racername | String | The nickname for the customer | |
proskill | Integer | 1200 | The current proskill for the customer |
howdidyouhearaboutus | Integer | 0 | The ID of the source for the customer |
State | String | The state of residence for the customer | |
status1 | Integer | Integer flag indicating a specific status. This is customizable per venue to handle indicators such as Customer added from POS, Customer added from Online Event Registration, Customer signed secondary waiver, etc. These are typically handled automatically, and should most likely be left alone while using the API | |
status2 | Integer | See Status1 | |
status3 | Integer | See Status1 | |
status4 | Integer | See Status1 | |
totalRaces | Integer | 0 | Denormalized count of the total number of times this customer has raced |
totalVisits | Integer | 0 | Denormalized count of the total number of times this customer has visited |
waiver | Integer | Integer flag indicating which primary waiver the customer has signed | |
waiver2 | Integer | Integer flag indicating which secondary waiver the customer has signed | |
Zip | String | The post code for the address of the customer |
Discount Types
contains a list
of discounts which can be utilized by the Check Totals
Create and
Virtual API calls.
Note that these automated calculations of discounts are only available
with the Check Totals endpoints, and they will not be automatically calculated
when attempting to work with the Checks or Check Details endpoints.
Url | /discountType |
Version | V2 |
Access | Private |
{ "discountId": 1, "description": "$1 Race Discount", "calculateType": 1, "amount": 1, "enabled": false, "needApproved": false, "productClassId": 1, "deleted": true }
Name | Type | Default | Description |
---|---|---|---|
discountId | Integer | {Generated} | The primary key for the record |
amount | Double | The amount of the discount. See calculateType for usage |
|
calculateType | Integer |
The calculation type for the discount. This determines how
|
|
deleted | Boolean | Flag indicating whether the discount has been soft deleted | |
description | String | The description for the discount | |
enabled | Boolean | Flag indicating whether the discount type is currently enabled | |
needApproved | Boolean | Flag indicating whether the discount should require manager approval | |
productClassId | Integer | The product class for which the discount should be applicable. Note that this is not hard enforced by the API |
An EventHeatDetails
record
is a reference to a Customer
who has been placed in a queue
for a specific Event
.
Url | /eventHeatDetails |
Version | V2 |
Access | Private |
{ "eventId": 3, "customerId": 1000007, "proskill": 1200, "added": "2013-05-29T11:35:33.23", "roundLoseNum": 0, "totalRaces": 1 }
Name | Type | Default | Description |
---|---|---|---|
customerId | Integer | Part of the composite primary key for the record, the id of the customer in the queue | |
eventId | Integer | Part of the composite primary key for the record, the id of the parent event | |
dateAdded | DateTime | The date at which the customer was added to the event queue | |
roundLoseNum | Integer | The round at which the customer dropped out of the event, where relevant. Provide 99 as the value when first creating the EventHeatDetails record. | |
proskill | Integer | The proskill for the customer | |
totalRacesInEvent | Integer | The total number of races in the event |
Event Heat Types
contains information grouped by
Event Type
designed to be a lookup for creating
Event Rounds
when creating an
Event
.
Url | /eventHeatTypes |
Version | V2 |
Access | Private |
{ "eventHeatTypeId": 1, "cadetsPerHeat": 0, "description": "5 Minute Qualifying", "eventTypeId": 1, "heatsPerRacer": 1, "heatTypeId": 17, "racersPerHeat": 22, "roundNumber": 1 }
Name | Type | Default | Description |
---|---|---|---|
eventHeatTypeId | Integer | {Generated} | The primary key for the record |
cadetsPerHeat | Integer | The maximum number of cadet racers for an event round | |
description | String | The description of the event round | |
eventTypeId | Integer | The event type for this default event round information | |
heatsPerRacer | Integer | The number of heats in which each racer will participate | |
heatTypeId | Integer | The heat type to be used with the resulting heat | |
racersPerHeat | Integer | The maximum number of racers for this event round | |
roundNumber | Integer | The ordered round number in the event |
An EventReservationLink
record
is a cross reference allowing specific Check
records to be linked to
specific EventReservation
records, which in turn are linked to specific Events
.
Url | /eventReservationLinks |
Version | V2 |
Access | Private |
{ "eventReservationLinkId": 1, "checkId": 4, "reservationId": 1 }
Name | Type | Default | Description |
---|---|---|---|
eventReservationLinkId | Integer | {Generated} | The primary key for the record |
checkId | Integer | The ID for the check to be linked to an event reservation | |
reservationId | Integer | The ID for the event reservation to which the check should be linked |
An EventReservation
is paired
to an Event
as a way of storing
and indicating specific reservation values for an Event
.
Url | /eventReservations |
Version | V2 |
Access | Private |
{ "eventReservationId": 1, "allowOnlineReservation": false, "deleted": true, "description": "Reservation description", "endTime": "2013-11-26T19:00:00.00", "eventTypeId": 1, "isEventClosure": false, "isMixed": null, "mainId": null, "minNoOfAdultsPerBooking": 0, "noOfRacers": 22, "notes": "Notes!", "ptsPerReservation": 1, "repId": 3, "startTime": "2013-11-26T18:30:00.00", "status": 3, "subject": "", "typeId": 1, "userId": 5, "externalSystemId": null }
Name | Type | Default | Description |
---|---|---|---|
eventReservationId | Integer | {Generated} | The ID for the event reservation |
allowOnlineReservation | Boolean | Flag indicating whether reservations can be made online. | |
deleted | Boolean | false | Flag indicating whether or not the reservation has been soft deleted |
description | String | The description for the event reservation | |
endTime | DateTime | The time at which the event reservation is expected to end | |
eventTypeId | Integer | The ID for the event type of the event | |
mainId | int | The ID for the parent event reservation, where relevant | |
minNoOfAdultsPerBooking | Integer | The minimum number of customers per booking | |
noOfRacers | Integer | The current number of booked customers | |
notes | String | The notes for the event reservation | |
ptsPerReservation | Integer | The number of points required to make a reservation | |
startTime | Integer | The expected start time of the event reservation | |
status | Integer | The index for the event status of the event reservation. Please see here for additional information | |
subject | String | The name for the event reservation | |
typeId | Integer | The ID for the event reservation type | |
userId | Integer | The ID for the user that made the event reservation | |
externalSystemId | String | A field for storing an external reference for the event reservation. Not utilized internally by ClubSpeed |
Url | /eventReservations/:id |
Verb | PUT |
Access | Private |
The EventReservation
expects a linked
EventReservation.status
to be in a specific format.
Namely, the status
field should be set to be the index of the given
EventStatus
when ordered by EventStatus.seq ASC, EventStatus.status ASC
.
For example, assume the following example response:
GET https://sirtigard.clubspeedtiming.com/api/index.php/eventstatuses?order=seq,status HTTP/1.1 [ { "eventStatusId": 1, "colorId": -16711898, "seq": 1, "status": "Race Paid" }, { "eventStatusId": 2, "colorId": -37120, "seq": 3, "status": "A&D Paid" } ]
In order to give an EventReservation a status of "A&D Paid", the following call should be made:
PUT https://sirtigard.clubspeedtiming.com/api/index.php/eventreservations/:id HTTP/1.1 { "status": 1 }
Take special note that the EventReservation.status
value is of the array index of the original return,
and not the same value as the EventStatus.eventStatusId
.
Event Reservation Types holds a description for the reservation type.
Note that an Event Reservation Type can be considered a grouping, or header, for what appears on the ClubSpeed event calendars. These descriptions may correspond to resources at the venue, including resources such as party rooms.
Url | /eventReservationTypes |
Version | V2 |
Access | Private |
[ { "eventReservationTypeId": 1, "description": "Indoor Track" }, { "eventReservationTypeId": 2, "description": "Outdoor Track" }, { "eventReservationTypeId": 3, "description": "Party Room 1" } ]
Name | Type | Default | Description |
---|---|---|---|
eventReservationTypeId | Integer | {Generated} | The primary key for the record |
description | String | The description of the event reservation type |
An Event Round
is the link between
Events
and their
corresponding rounds in the Heat Main
,
through HeatMain.eventRound
.
Url | /eventRounds |
Version | V2 |
Access | Private |
{ "eventRoundId": 31, "cadetsPerHeat": 0, "eventId": 15, "heatDescription": "10 Minute Qualifying", "heatsPerRacer": 1, "heatTypeId": 1, "racersPerHeat": 22, "roundNumber": 1 }
Name | Type | Default | Description |
---|---|---|---|
eventRoundId | Integer | {Generated} | The primary key for the record |
cadetsPerHeat | Integer | The maximum number of cadet racers for this event round | |
eventId | Integer | The id for the parent event | |
heatDescription | String | The description of the heat | |
heatsPerRacer | Integer | The number of heats in which each racer will participate | |
heatTypeId | Integer | The heat type of the heat | |
racersPerHeat | Integer | The maximum number of racers for this event round | |
roundNumber | Integer | The ordered round number in the event |
An Event
is the parent record
for all event specific information.
Url | /events |
Version | V2 |
Access | Private |
{ "eventId": 1, "createdHeatSpots": 2, "createdHeatTime": "2013-11-25T23:12:42.87", "eventDesc": "sprinter", "eventDuration": 30, "eventNotes": "", "eventScheduledTime": "2013-11-25T23:30:00.00", "eventTheme": -16776961, "eventTypeId": 1, "eventTypeName": "Sprint Race", "memberOnly": false, "reservationId": 0, "totalRacers": 2, "trackNo": 1 }
Name | Type | Default | Description |
---|---|---|---|
eventId | Integer | {Generated} | The primary key for the record |
createdHeatSpots | Integer | The number of heat spots which have been created for this event | |
createdHeatTime | DateTime | The time at which the relevant heat will start | |
eventDesc | String | The description for the event | |
eventDuration | Integer | The expected duration of the event in minutes | |
eventNotes | String | The notes for the event | |
eventScheduledTime | DateTime | The scheduled time for the event | |
eventTheme | Integer | The theme for the event | |
eventTypeId | Integer | The ID for the type of the event | |
eventTypeName | String | The name of the type of the event | |
memberOnly | Boolean | false | Flag indicating whether entry into the event should require a membership |
reservationId | Integer | 0 | The ID for the reservation container for the event |
totalRacers | Integer | The total number of racers for the event | |
trackNo | Integer | The number of the track to be used for the event | |
roundNum | Integer | The current event round. Provide -1 for the value when first creating the event. | |
onlineCode | String | The online registration code for the event. |
Event statuses are end-user defined statuses to be assigned to an EventReservation
.
An eventStatusId
should be stored with EventReservation.status
in order to signify
the current status of an EventReservation
.
Url | /eventStatuses |
Version | V2 |
Access | Private |
{ "eventStatusId": 1, "colorId": -16711936, "seq": 1, "status": "Unconfirmed" }
Name | Type | Default | Description |
---|---|---|---|
eventStatusId | Integer | {Generated} | The primary key for the record |
colorId | Integer | The ID of the color which will be used to highlight the event when given this status. | |
seq | Integer | The order in which the event status appears in dropdowns. | |
status | String | The readable description of the status. |
A list of the tasks to be completed for a given event reservation. If a task has been completed, completedBy and completedAt will not be null. Information such as task name and description can be found with the EventTaskTypes records.
Url | /eventTasks |
Version | V2 |
Access | Private |
{ "eventTaskId": 128, "eventReservationId": 28, "completedBy": 1, "completedAt": "2016-01-01T00:00:00.00", "eventTaskTypeId": 4 }
Name | Type | Default | Description |
---|---|---|---|
eventTaskId | Integer | {Generated} | The primary key for the record |
eventReservationId | Integer | The id of the event reservation | |
completedBy | Integer | The id of the user that completed the task | |
completedAt | DateTime | The date at which the task was completed | |
eventTaskTypeId | Integer | The id of the event task type to be completed |
Event task types is a container of task types to be tracked for completion, where the tracking information is stored with the EventTasks.
Url | /eventTaskTypes |
Version | V2 |
Access | Private |
{ "eventTaskTypeId": 1, "deleted": false, "seq": 2, "description": "", "name": "Confirmation Email Sent" }
Name | Type | Default | Description |
---|---|---|---|
eventTaskTypeId | Integer | {Generated} | The primary key for the record |
deleted | Boolean | A soft delete flag for the record | |
seq | Integer | The sequence in which the task types should appear | |
description | String | The description of the task type | |
name | String | The name of the task type |
Url | /eventTypes |
Version | V2 |
Access | Private |
{ "eventTypeId": 1, "deleted": false, "description": "Sprint Race", "displayAtRegistration": true, "enabled": true, "eventTypeName": "Sprint Race", "eventTypeTheme": -20304, "memberOnly": false, "onlineProductId": 0, "ptsPerReservation": 1, "trackId": 1 }
Name | Type | Default | Description |
---|---|---|---|
eventTypeId | Integer | {Generated} | The primary key for the record |
deleted | Boolean | Flag indicating whether the record has been soft deleted | |
description | String | The description of the event type | |
displayAtRegistration | Boolean | Flag indicating whether the event type should show during registration | |
enabled | Boolean | Flag indicating whether or not the event type is currently enabled | |
eventTypeName | String | The name of the event type | |
eventTypeTheme | Integer | The theme of the event type | |
memberOnly | Boolean | Flag indicating whether or not a membership is required for this event type | |
onlineProductId | Integer | The ID of the product which is used to purchase this event | |
ptsPerReservation | Integer | The number of points required per reservation | |
trackId | Integer | The ID of the track for which this event can be added |
A rolling transactional log keeping track of each change that occurs with gift cards.
Note that in ClubSpeed, each gift card is registered as a Customer
,
and so the gift card identifier should be considered customerId
in this dataset.
To get the gift card number, the jump needs to be made from GiftCardHistory.customerId
to Customers.cardId
Also note that this resource is where balances and changes for a customer account can be found as well.
Url | /giftCardHistory |
Version | V2 |
Access | Private |
{ "giftCardHistoryId": 27611, "customerId": 1314321, "userId": 0, "points": 10, "type": 0, "notes": "Reload at Check ID 17346", "checkId": 17346, "checkDetailId": 35161, "ipAddress": "", "transactionDate": "2015-12-02T09:01:46.00" }
Name | Type | Default | Description |
---|---|---|---|
giftCardHistoryId | Integer | {Generated} | The primary key for the record |
checkDetailId | Integer | The check line item which resulted in this change | |
checkId | Integer | The check which resulted in this change | |
customerId | Integer | The holder of the card. Note that this may correspond to either a standard gift card or member card on a customer account | |
ipAddress | String | The IP address of the machine from which the change originated | |
notes | String | Any notes for the transaction | |
points | Double | The number of changed points (which can be considered currency / money) for this transaction. Note that a summation of this field, excluding any records which have a voided type, can be considered the current balance for the card | |
transactionDate | DateTime | The date at which the transaction occurred | |
type | Integer |
The type of the transaction
|
|
userId | Integer | The id of the user which recorded the transaction |
A record in HeatDetails
is representative of a Customer
being entered into a Heat
.
In order to add a Customer
to a Heat
, insert a HeatDetails
record containing a primary key pair
of the Heat
ID and the Customer
ID.
To remove a Customer
from a Heat
,
simply delete the HeatDetails
record.
Note that the count of HeatDetails
grouped by heatId
plus the HeatMain.numberOfReservation
for that heatId
can be considered the total number of racers in a Heat
.
Url | /heatDetails |
Version | V2 |
Access | Private |
{ "heatId": 3, "customerId": 1000001, "autoNo": null, "finishPosition": null, "firstTime": true, "groupFinishPosition": null, "groupId": 0, "lineUpPosition": 2, "pointHistoryId": 0, "positionEditedDate": null, "proskill": 1200, "proskillDiff": null, "scores": 0, "timeAdded": "2013-11-26T00:18:42.43", "userId": 5, }
Name | Type | Default | Description |
---|---|---|---|
heatId | Integer | Part of the composite primary key for the record | |
customerId | Integer | Part of the composite primary key for the record | |
autoNo | Integer | The kart number for the customer. Note that this will not be assigned until during / after the heat | |
finishPosition | Integer | The finish position for the customer | |
firstTime | Boolean | Denormalized flag indicating whether or not this is the first race of the customer | |
groupFinishPosition | Integer | The finish position of the customer relative to their group, where applicable | |
groupId | Integer | The ID of the group to which the racer belongs, where applicable | |
lineUpPosition | Integer | The line up position selected for the customer | |
pointHistoryId | Integer | The ID of the point history utilized to add this customer to the heat, where applicable | |
positionEditedDate | DateTime | The timestamp at which the position was edited | |
proskill | Integer | The denormalized proskill of the customer | |
proskillDiff | Integer | The amount at which the proskill of the customer changed as an outcome of the heat | |
timeAdded | DateTime | The time at which the customer was added to the heat | |
userId | Integer | The ID of the user that added the customer to the heat |
A HeatMain
record represents an instance of a race on the standard venue calendar. This resource may be utilized
to look up base information about races such as begin and finish times, or to add or remove races from the calendar.
Url | /heatMain |
Version | V2 |
Access | Private |
{ "heatId": 2, "beginning": null, "eventRound": null, "finish": null, "heatColor": -2302756, "lapsOrMinutes": 600, "memberOnly": false, "notes": "", "numberOfReservation": 7, "pointsNeeded": 10, "raceBy": 0, "racersPerHeat": 16, "scheduledTime": "2013-11-26T00:15:00.00", "scheduleDuration": 10, "speedLevel": 1, "status": 0, "track": 1, "type": 1, "winBy": 0 }
Name | Type | Default | Description |
---|---|---|---|
heatId | Integer | {Generated} | The primary key for the record |
beginning | DateTime | The actual start time of the heat | |
eventRound | Integer | The event round which corresponds to the heat, where applicable | |
finish | DateTime | The actual finish time of the heat | |
heatColor | Integer | An integer representation of the color to be used on the heat calendar | |
lapsOrMinutes | Integer | {Lookup} | Quantity of laps or minutes (depending on the heat type) required for the heat to finish, defaults to a lookup from type |
memberOnly | Boolean | Flag indicating whether a heat should only allow entrance to members | |
notes | String | Notes for the heat | |
numberOfReservation | Integer | 0 | Number of additional reservations for the heat. Note that these typically represent purchased slots in a heat. The sum of this field and the count of heat detail records can be considered the number of slots used for the heat |
pointsNeeded | Integer | Number of points required to enter the heat, where applicable. Set this value to 0 where not applicable | |
raceBy | Integer | {Lookup} |
The indication of whether the heat will treat the value at lapsOrMinutes as laps or minutes, defaults to a lookup from type
|
racersPerHeat | Integer | {Lookup} | Total number of racers available for the heat, defaults to a lookup from type |
scheduledTime | DateTime | The scheduled start time of the heat | |
scheduleDuration | Integer | {Lookup} | The expected duration of the heat, defaults to a lookup from type |
speedLevel | Integer | The speed level for the heat | |
status | Integer | 0 |
The status of the heat
|
track | Integer | 1 | The ID for the track for the heat |
type | Integer | The heat type for the heat | |
winBy | Integer | {Lookup} |
The indication of whether the heat is won by laps or position, defaults to a lookup from type
|
A HeatType is treated as a default template
Url | /heatTypes |
Version | V2 |
Access | Private |
{ "heatTypesId": 1, "cannotBelow": 35000, "cannotExceed": 1000000, "cost": 10, "deleted": false, "enabled": true, "isEventHeatOnly": false, "isPracticeHeat": false, "lapsOrMinutes": 600, "memberOnly": false, "name": "Arrive and Drive 10 Min", "raceBy": 0, "racersPerHeat": 10, "scheduleDuration": 10, "speedLevel": 1, "trackId": 1, "winBy": 0 }
Name | Type | Default | Description |
---|---|---|---|
heatTypesId | Integer | {Generated} | The primary key for the record |
cannotBelow | Integer | The minimum cut off for lap times (in milliseconds) | |
cannotExceed | Integer | The maximum cut off for lap times (in milliseconds) | |
cost | Integer | 0 | The number of points required for this heat type, where applicable |
deleted | Boolean | false | Flag indicating whether this heat type has been soft deleted |
enabled | Boolean | true | Flag indicating whether this heat type is currently enabled |
heatTypeName | String | The name of the heat type | |
isEventHeatOnly | Boolean | false | Flag indicating whether this heat type is meant only for events |
isPracticeHeat | Boolean | false | Flag indicating whether this heat type is meant to be a practice round |
lapsOrMinutes | Integer | 10 | Quantity of laps or minutes (depending on the heat type) required for the heat type to finish |
memberOnly | Boolean | false | Flag indicating whether a heat type should only allow entrance to members |
raceBy | Integer | 0 |
The indication of whether the heat type should treat the value at lapsOrMinutes as laps or minutes
|
racersPerHeat | Integer | 12 | Total number of racers available for the heat type |
scheduleDuration | Integer | 12 | The expected duration of the heat type |
speedLevel | Integer | 1 | The speed level for the heat type |
trackId | Integer | NULL | The default track ID for the heat type |
winBy | Integer | 0 |
The indication of whether the heat is won by laps or position
|
A Membership
is a pairing
of Customer
and MembershipType
,
representing a membership which the customer either has or had up until the expiration date.
Url | /memberships |
Version | V2 |
Access | Private |
{ "customerId": 1000001, "membershipTypeId": 105, "byUserId": 1 "changed": "2014-06-17T00:00:00.00", "expiration": "2015-06-17T00:00:00.00", "notes": "", }
Name | Type | Default | Description |
---|---|---|---|
customerId | Integer | {Generated} | Part of the composite primary key for the record, references a customer |
membershipTypeId | Integer | {Generated} | Part of the composite primary key for the record, references a membership type |
byUserId | Integer | 1 | The ID of the user that created the membership |
changed | DateTime | The date at which the membership last changed | |
expiration | DateTime | The date at which the membership will expire | |
notes | String | Any notes for the membership |
A MembershipType
contains the relevant definition for a type of membership.
An instance of this membership type can be given to a customer
through the use of Membership.membershipTypeId
.
Url | /membershipTypes |
Version | V2 |
Access | Private |
{ "membershipTypeId": 1, "description": "Annual Membership", "enabled": true, "expirationType": 365, "expires": true, "priceLevel": 1 "seq": 1, }
Name | Type | Default | Description |
---|---|---|---|
membershipTypeId | Integer | {Generated} | The primary key for the record |
description | String | The description of the membership type | |
enabled | Boolean | true | Flag indicating whether this membership type is currently enabled |
expirationType | Integer | 365 | The number of days when this membership will expire, where applicable |
expires | Boolean | A flag indicating whether or not the membership should ever expire | |
priceLevel | Integer | 1 | The price level that this membership type would grant to a customer |
seq | Integer | The sequence in which the membership types should appear in a dropdown |
Url | /omnipay |
Verb | GET |
Access | Private |
ClubSpeed utilizes a subset of vendors available through the Omnipay library. To get a list of these vendors, call the method detailed here.
The response will be an array of objects containing available payment processor information,
which will each contain name
,
type
,
and options
.
name
will be the name of the payment processor to be used when accepting a payment.
type
will be one of either
direct
or redirect
.
direct
indicates that the payment may be taken directly through the API.
and should not require you to redirect a user to a separate off-site endpoint to input payment information.
redirect
, on the other hand, indicates that your website
will need to redirect the customer to an offsite payment processor to enter their personal and credit card information.
Additional info on how to handle this can be found at Accept Payment
and Complete Payment.
options
array is an array of strings indicating which keys the payment processor
expects. What appears here will be entirely dependent on the payment processor selected.
At least some of these keys may be required or optional, again, depending on the payment processor.
See Accept Payment for more information and examples of
how to provide these options.
GET https://sirtigard.clubspeedtiming.com/api/index.php/omnipay HTTP/1.1
HTTP/1.1 200 OK [ { "name": "AuthorizeNet_AIM", "type": "direct", "options": [ "apiLoginId", "transactionKey", "testMode", "developerMode" ] }, { "name": "Dummy", "type": "direct", "options": [] }, { "name": "PayPal_Express", "type": "redirect", "options": [ "username", "password", "signature", "testMode", "solutionType", "landingPage", "brandName", "headerImageUrl" ] }, { "name": "PayPal_Pro", "type": "direct", "options": [ "username", "password", "signature", "testMode" ] }, { "name": "SagePay_Direct", "type": "direct", "options": [ "vendor", "testMode", "referrerId" ] }, { "name": "Stripe", "type": "direct", "options": [ "apiKey" ] } ]
Url | /omnipay/purchase |
Verb | POST |
Access | Private |
The Accept Payment call can be used to accept a payment using a provided third party processor.
Please note that this is simply a method of accepting payments through your third party payment processor. This does not insert a payment record into ClubSpeed, or update a check in any way. To indicate payments or check changes in ClubSpeed, you should use the corresponding API calls directly.
The request body accepts the following items:
name
,
options
,
amount
,
transactionId
,
currency
,
returnUrl
,
and card
.
name
will indicate which payment processor to use.options
needs to be an object containing the key/value pairs for the payment processor
as determined by the list of keys in List Vendors
and the values provided by your payment processor.
amount
is the monetary amount for which you wish to accept a payment.transactionId
is a way to connect the transaction you are about to process
with a predetermined connection. We suggest using a checkId
from the relevant check. This property
is not always required, depending on the payment processor.
currency
is a way to tell the processor
which currency you are currently accepting. Most payment processors do not require or respect this setting,
and instead require the currency to be set up in their own admin panels ahead of time.
returnUrl
is used with redirect processors
to tell the external website to which url the customer should be redirected to
once their payment is complete (or canceled, or errored). This should typically
be an endpoint on your website and should include collecting response data
and making an additional call to Complete Payment.
card
is an object containing credit card information.
This piece is required on direct processors, and may or may not be required for redirect processors.
The response you receive will depend on whether or not your payment processor
is of type direct
or redirect
.
For direct payments, you will receive type
,
code
,
message
,
reference
,
and data
in the response body.
These returns will hold information which varies from processor to processor,
but a status returned of 200 OK
can be considered a successful payment.
Any status codes in 4XX-5XX should check the response body
for an encoded error.message
.
The reference
will typically be a unique identifier generated by the payment processor.
We recommend storing this in the follow up ClubSpeed payment creation
as Payment.transactionReference
For redirect payments, you will receive type
,
redirectUrl
,
redirectMethod
,
and redirectData
in the response body.
Using that information, you should redirect the customer to the
redirectUrl
using
redirectMethod
(one of GET
,
POST
) and supplying
redirectData
(url encoded in the querystring for GET
,
in the request body for POST
) to the external site.
In this case, an additional call to Complete Payment
will need to be made through the API once the customer
has been returned to your website after entering their information on the payment processor's website.
POST https://sirtigard.clubspeedtiming.com/api/index.php/omnipay HTTP/1.1 { "name": "AuthorizeNet_AIM", "options": { "apiLoginId": "supersecretlogin", "transactionKey": "supersecretkey", "testMode": true, "developerMode": true }, "amount": 2.00, "transactionId": 123456, "card": { "firstName": "Bob", "lastName": "Bobbinson", "number": "4242424242424242", "expiryMonth": "7", "expiryYear": "2019", "startMonth": "", "startYear": "", "cvv": "162", "issueNumber": "", "address1": "123 Billing St", "address2": "Billpartment 1", "city": "Billstown", "postcode": "12345", "state": "CA", "country": "US", "phone": "(555) 123-4567", "email": "" } }
HTTP/1.1 200 OK { "type": "success", "code": "1", "message": "This transaction has been approved.", "reference": "2254355152", "data": [ "1", "1", "1", "This transaction has been approved.", "HV78IK", "Y", "2254355152", "123456", "", "2.00", "CC", "auth_capture", "", "Bob", "Bobbinson", "", "123 Billing St Billpartment 1", "Billstown", "CA", "12345", "US", "(555) 123-4567", "", "", "Bob", "Bobbinson", "", "123 Billing St Billpartment 1", "Billstown", "CA", "12345", "US", "", "", "", "", "", "B29B6129C7E5A1B6A4104546B69AB5FC", "P", "2", "", "", "", "", "", "", "", "", "", "", "XXXX4242", "Visa", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ] }
Url | /omnipay/complete |
Verb | POST |
Access | Private |
The complete payment method is only relevant for redirect payment processors, and should be used to pass information back to the payment processor once the user is returned to your site after an offsite payment attempt.
The full application flow is as follows:
The data which should be posted to /omnipay/complete will, again, completely depend on the type of payment processor being used, and the response will take the same format as Accept Payment.
Url | /passwords |
Verb | POST |
Access | Private |
The method detailed below will generate and send a password reset token to a provided email address. This email will contain a provided url with appended token and instructions for the end-user to reset their password.
POST https://sirtigard.clubspeedtiming.com/api/index.php/passwords HTTP/1.1 { "email": "bob@gmail.com", "url": "http://link/to/append/token/to.html" }
HTTP/1.1 200 OK
Url | /passwords |
Verb | PUT |
Access | Private |
The call detailed below will consume a password reset token and update the customer's password using a lookup based on the token.
PUT https://sirtigard.clubspeedtiming.com/api/index.php/passwords HTTP/1.1 { "token": "81f6fde27692402fb2139f971b8accb29b1b20c6", "password": "some_new_password" }
HTTP/1.1 200 OK
Url | /payments |
Version | V2 |
Access | Private |
{ "paymentId": 3391, "cardType": null, "checkId": 3467, "customerId": 1, "extCardType": "AUTHORIZENET_AIM", "payAmount": 21.24, "payDate": "2014-12-05T11:46:28.00", "payStatus": 2, "payTax": 1.24, "payTerminal": "api", "payType": 3, "transaction": null, "userId": 1, "voidDate": "2015-07-02T15:39:52.00", "voidNotes": "", "voidTerminal": "", "voidUser": 1 }
Name | Type | Default | Description |
---|---|---|---|
paymentId | Integer | {Generated} | The primary key for the record |
cardType | String | The type of the credit card used to make the payment, typically only filled out where payType is Credit |
|
checkId | Integer | The ID of the check for which the payment was applied | |
customerId | Integer | The ID of the customer that has made the payment | |
extCardType | String | The card or payment processor type for the payment, where applicable | |
payAmount | Double | The monetary amount of the payment | |
payDate | DateTime | {Now} | The timestamp at which the payment was collected |
payStatus | Integer | 1 |
The status of the payment
|
payTax | Double | {Calculated} | The monetary amount of the payment which was applied to tax. Note that payAmount is inclusive of this value |
payTerminal | String | The terminal at which the payment was collected | |
payType | Integer |
The type of the payment which was collected
|
|
transaction | String | A reference to a transaction number, typically one which was returned from a third party processor | |
userId | Integer | The id of the user that created the payment | |
voidDate | DateTime | The timestamp at which the payment was voided | |
voidNotes | String | The notes as to why the payment was voided | |
voidTerminal | String | The terminal where the payment was voided | |
voidUser | Integer | The id of the user that voided the payment |
Url | /processPayment |
Version | V1 |
Access | Private |
Name | Type | Default | Description |
---|---|---|---|
name | String | The name of the Omnipay payment processor. | |
options | Object | The object containing Omnipay payment processor options. Note that these properties will vary based on the selected payment processor. | |
check | Object | The object containing Check properties. | |
check.checkId | Integer | The ID for the Check to be paid. | |
check.details | Array<Detail> | The array of details objects to be processed at the same time as the Check Payment is completed. | |
check.checkId | Integer | The ID for the Check to be paid. | |
card | Object | The credit card object. | |
card.firstName | String | The first name on the credit card. | |
card.lastName | String | The last name on the credit card. | |
card.number | Integer | The credit card number. | |
card.expiryMonth | Integer | The expiration month for the credit card. Can be 1 or 2-digit. | |
card.expiryYear | Integer | The card's 4-digit expiration year. | |
card.cvv | Integer | The cvv for the credit card. | |
card.address1 | Integer | The first address line for the credit card. | |
card.address2 | Integer | The second address line for the credit card. | |
card.city | Integer | The city for the credit card. | |
card.postcode | Integer | The post/zip code for the credit card. | |
card.state | String | The state code for the credit card. | |
card.country | String | The country code for the credit card. | |
card.phone | String | The phone number for the credit card. |
Url | /processPayment |
Verb | POST |
Access | Private |
Required |
name
options
check
check.checkId
|
Available |
card
|
Executing this method will attempt to pay for all items on the provided checkId
using the provided credit card.
This payment processor will accept a number of processors based on the Omnipay library. Each of these processors will require a different set of options, usually including a set of credentials, keys, or tokens.
If a reservation product is being purchased (Online Booking, for example),
then additional information will be needed in the check.details
array.
For example, if a user has purchased a reservation product, then the API needs to receive an object
containing the checkDetailId
for the check line item containing the reservation products,
as well as the heatId
which was originally selected by the customer from the
Booking Availability list.
If the additional booking processing object is provided, the purchaser will be automatically added to the race where possible, and extra reservations will be made if multiple quantities were purchased.
See the example below for a representation of what the additional processing objects should look like in the case of a race purchase for a specific heat.
If other settings need to be passed along, such as disabling receipt emails
or disabling gift card emails, this can be done in the check
property of the request body. The format of these options in the check
property
will match with and are documented in the Checks Finalize request body.
POST https://sirtigard.clubspeedtiming.com/api/index.php/processPayment HTTP/1.1 { "name": "SagePay_Direct", "options": { "vendor": "my_sagepay_vendor_name", "simulatorMode": true }, "check": { "checkId": 2439, "sendCustomerReceiptEmail": false, "details": [ { "checkDetailId": 7763, "heatId": 13 }, { "checkDetailId": 7764, "sendEmail": false }, ] }, "card": { "firstName": "Jim", "lastName": "Bob", "number": "4111111111111111", "expiryMonth": "7", "expiryYear": "2015", "startMonth": "", "startYear": "", "cvv": "162", "issueNumber": "", "address1": "123 Billing St", "address2": "Billpartment 1", "city": "Billstown", "postcode": "12345", "state": "CA", "country": "US", "phone": "(555) 123-4567", "email": "" } }
HTTP/1.1 200 OK
To make a payment using Simple Pay processor.
There are three steps required to complete the payment process:
shopperResultUrl
.
Make a POST request to Complete Payment endpoint with the required data.
For more detail please see the Simple Pay documentation.
Url | /processPayment/preparesimplepay & /processPayment/completesimplepay |
Version | V1 |
Access | Private |
Name | Type | Default | Description |
---|---|---|---|
name | String | SimplePay | The name of the payment processor. |
id | String | This field only required when make complete payment request. | |
options | Object | The object containing entityId, token, host and testMode | |
check | Object | The object containing Check properties. | |
check.checkId | Integer | The ID for the Check to be paid. | |
check.sendCustomerReceiptEmail | Boolean | Send the customer receipt email |
Url | /processPayment/preparesimplepay & /processPayment/completesimplepay/preparesimplepay |
Verb | POST |
Access | Private |
The request body accepts the following items:
name
,
options
,
and check
.
name
has to be set to SimplePayoptions
needs to be an object containing the key/value pairs for the payment processor:
entityId
, token
and host
and the values provided by your payment processor.
testMode
indicates in test or production mode.
check
is an object containing the key/value pairs containing
checkId
and sendCustomerReceiptEmail
.
The response you receive will include:
id
and scriptUrl
.
After received the response from /processPayment/preparesimplepay
,
please create the payment form by using the Payment Form Template below and:
scriptUrl
from prepare payment call to src attribute of script
.
shopperResultUrl
, which is the page on your site where the customer should be redirected to after the payment is processed.
You will need to make the Complete Payment request in this page to finalize the payment.
shopperResultUrl
must end in a "/", e.g. "https://test.simplepays.com/".
<!doctype html> <html> <head> <script src="{scriptUrl}"></script> </head> <body> <form action="{shopperResultUrl}" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form> </body> </html>
POST https://sirtigard.clubspeedtiming.com/api/index.php/processPayment/preparesimplepay HTTP/1.1 { "name": "SimplePay", "options": { "entityId": "8a8294184e542a5c014e691d33f808c8", "token": "OGE4Mjk0MTg0ZTU0MmE1YzAxNGU2OTFkMzQwNzA4Y2N8MmdtWkhBZVNXSw==", "host": "test.simplepays.com", "testMode": true }, "check": { "checkId": 31613, "sendCustomerReceiptEmail": false } }
HTTP/1.1 200 OK { "id": "FDA182F0AF233B0AA1CB19AAFCDBE9B6.uat01-vm-tx04", "scriptUrl": "https://test.simplepays.com/v1/paymentWidgets.js?checkoutId=FDA182F0AF233B0AA1CB19AAFCDBE9B6.uat01-vm-tx04" }
Url | /processPayment/preparesimplepay & /processPayment/completesimplepay/completesimplepay |
Verb | POST |
Access | Private |
In the shopperResultUrl
page, make a complete payment call.
In the request
body, add id
value received from prepare payment.
POST https://sirtigard.clubspeedtiming.com/api/index.php/processPayment/completesimplepay HTTP/1.1 { "name": "SimplePay", "id":"ABB0AC2840630999E13498179F72C8CA.uat01-vm-tx03", "options": { "entityId": "8a8294184e542a5c014e691d33f808c8", "token": "OGE4Mjk0MTg0ZTU0MmE1YzAxNGU2OTFkMzQwNzA4Y2N8MmdtWkhBZVNXSw==", "host": "test.simplepays.com", "testMode": true }, "check": { "checkId": 31613, "sendCustomerReceiptEmail": false } }
HTTP/1.1 200 OK { "id": "8ac7a4a16cd6d04a016cd97499590770", "paymentType": "DB", "paymentBrand": "VISA", "amount": "92.00", "currency": "AUD", "descriptor": "7612.6254.9524 OPP_Channel", "result": { "code": "000.100.110", "description": "Request successfully processed in 'Merchant in Integrator Test Mode'" }, "card": { "bin": "411111", "last4Digits": "1111", "holder": "Casper", "expiryMonth": "12", "expiryYear": "2022" }, "customer": { "ip": "12.167.48.66" }, "threeDSecure": { "eci": "00", "verificationId": "", "xid": "CAACCVVUlwCXUyhQNlSXAAAAAAA=", "paRes": "pares" }, "customParameters": { "SHOPPER_EndToEndIdentity": "1c57dc003241ad20b62f4fd06a869c0e7adcde93701498a85b1e81cfce0fe253", "CTPE_DESCRIPTOR_TEMPLATE": "" }, "risk": { "score": "100" }, "buildNumber": "cc791180e3209ea916774f9df3662864f2398844@2019-08-27 03:42:20 +0000", "timestamp": "2019-08-28 18:20:10+0000", "ndc": "ABB0AC2840630999E13498179F72C8CA.uat01-vm-tx03" }
ProductClasses
are the records which determine how
a Product
should be aggregated in the reporting system.
To apply a ProductClass
to a Product
,
set Product.productClassId
to be ProductClass.productClassId
, and all reports will update accordingly.
Url | /productClasses |
Version | V2 |
Access | Private |
{ "productClassId": 16, "description": "Karting", "deleted": false, "exportName": "kartexport_123" }
Name | Type | Default | Description |
---|---|---|---|
productClassId | Integer | {Generated} | The primary key for the record |
deleted | Boolean | false | A flag indicating whether this record has been soft deleted. For reporting purposes, the product classes should not be hard deleted. |
description | String | The description of the product class | |
exportName | String | The export name to be used when building exports from reports |
Url | /products |
Version | V1 |
Access | Private |
{ "products": [ { "productId": 14416, "productType": 4, "description": "Reservation Product for API Unit Testing", "price1": 2, "price2": 0, "taxId": 3459, "productClassId": 1, "enabled": true, "deleted": false, "p_Points": null, "r_Points": 10, "g_Points": null, "priceCadet": 0, } ] }
Name | Type | Default | Description |
---|---|---|---|
productId | Integer | {Generated} | The primary key for the record |
deleted | Boolean | false | Flag indicating whether the product has been soft deleted |
description | String | Description for the product | |
enabled | Boolean | true | Flag indicating whether the product is currently enabled |
g_Points | Double | The amount of gift card points provided when this product is purchased | |
p_Points | Double | The number of points provided when this product is purchased | |
price1 | Double | The price of the product | |
productClassId | Integer | The ID of the reporting product class for the product | |
productType | Integer |
The type of the product
|
|
r_Points | Double | The amount of reservation points provided when this product is purchased | |
taxId | Integer | The ID of the tax for the product |
Url | /racers/create |
Verb | POST |
Access | Private |
Required |
racername
email
password
donotemail
firstname
lastname
birthdate
gender
mobilephone
Address
Address2
City
Country
howdidyouhearaboutus
State
Zip
|
Parameter requirements will vary from track to track, based on sp_admin control panel settings.
If a password is provided, it will be hashed before being placed in the database.
POST https://sirtigard.clubspeedtiming.com/api/index.php/racers/create HTTP/1.1 { "racername": "JimBobbyJoe", "email": "bob@clubspeed.com", "password": "bobssupersecretpassword", "donotemail": false, "firstname": "Jim", "lastname": "Joe", "birthdate": "1952-01-01", "gender": "male", "mobilephone": "123-456-7890", "Address": "123 Somewhere St", "Address2": "Apartment 1", "City": "Timbucktu", "Country": "Mali", "howdidyouhearaboutus": 1, "State": "CA", "Zip": 12345 }
HTTP/1.1 200 OK { "customerId": 1000001, "token": "1bf4e5844129d1fa84110e7aca16ca50576182c72bc3111dba60d615d0f9eb03" }
Url | /racers/login |
Verb | POST |
Access | Private |
Required |
username
password
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/racers/login HTTP/1.1 { "username": "bob@clubspeed.com", "password": "bobssupersecretpassword" }
HTTP/1.1 200 OK { "customerId": 1000001, "token": "1bf4e5844129d1fa84110e7aca16ca50576182c72bc3111dba60d615d0f9eb03" }
Url | /racers/fb_login |
Verb | POST |
Access | Private |
Required |
email
facebookId
facebookToken
facebookAllowEmail
facebookAllowPost
facebookEnabled
|
Available |
facebookExpiresIn
racername
email
password
donotemail
firstname
lastname
birthdate
gender
mobilephone
Address
Address2
City
Country
howdidyouhearaboutus
State
Zip
|
Note that Facebook Login has the capability to upsert a customer record, if one does not exist. If this call is intended to be used to create customer records where they don't exist, then parameters taken from the Customer Create call should be included as parameters here.
POST https://sirtigard.clubspeedtiming.com/api/index.php/racers/fb_login HTTP/1.1 { "email": "bob@clubspeed.com", "facebookId": "652712592679", "facebookToken":"AVNAWIVYANIWVUDBAWKUGDVBAWIDVYNLAWDVHNAWILDVHUNAWIULDVHNLAWIDVHUNAWUILDVHNAWILDVHN", "facebookExpiresIn": 9999, "facebookAllowEmail": true, "facebookAllowPost": true, "facebookEnabled": true }
HTTP/1.1 200 OK { "customerId": 1000001, "token": "1bf4e5844129d1fa84110e7aca16ca50576182c72bc3111dba60d615d0f9eb03" }
Url | /racers/racer_id/customer_picture |
Verb | POST |
Access | Private |
Required |
customerImage
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/racers/racer_id/customer_picture HTTP/1.1 { "customerimage": "data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+..." } Ad
HTTP/1.1 200 OK { }
Url | /racers/racer_id/adult_waiver |
Verb | POST |
Access | Private |
Required |
signature
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/racers/racer_id/adult_waiver HTTP/1.1 { "signature": "data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+..." }
HTTP/1.1 200 OK { }
Url | /racers/racer_id/minor_waiver |
Verb | POST |
Access | Private |
Required |
guardiancustid
guardiansignature
|
POST https://sirtigard.clubspeedtiming.com/api/index.php/racers/racer_id/minor_waiver HTTP/1.1 { "guardiancustid": 1000010, "guardiansignature": "data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+goOXMv8+fhw/v739/f+8PD98fH/8mJl+..." }
HTTP/1.1 200 OK { }
A Reservation
is an indication that a Customer
is either
looking to purchase a spot in a Booking, or has already purchased a spot in a Booking
.
Reservations
should be used by creating a new temporary Reservation
whenever a Customer
adds a Booking
to their kart,
and then updated to be made permanent whenever the purchase has been successfully made.
Please note that a Reservation
does not
correspond directly to HeatMain.numberOfReservation
. A Reservation
corresponds directly to a Booking
and represents either a permanent or temporary hold
on a Booking
.
Url | /reservations |
Version | V2 |
Access | Private |
{ "reservations": [ { "onlineBookingReservationsId": 428, "onlineBookingsId": 514, "customersId": 1232722, "sessionId": "3e123f90551bf2feaadce4ea53482f4fa23f6cc5", "quantity": 1, "createdAt": "2015-12-09T16:19:05.17", "expiresAt": "2016-12-09T17:19:05.17", "onlineBookingReservationStatusId": 1, "checkId": 17349 } ] }
Name | Type | Default | Description |
---|---|---|---|
onlineBookingReservationId | Integer | {Generated} | The primary key for the record |
checkId | Integer | The ID of the check for the reservation, where applicable. If a relevant checkId is available, it should be set, as this enables auto-voiding abandoned checks with offsite payment processors. | |
createdAt | DateTime | {Now} | The timestamp at which the reservation was created |
customersId | Integer | The ID of the customer for the reservation | |
expiresAt | DateTime | {Now + default length from control panel} | The timestamp at which the reservation will be automatically expired, if status is not set to Permanent |
onlineBookingReservationStatusId | Integer | 1 |
The ID for the status of the reservation. Statuses should be set to Temporary while the underlying kart is open, and set to Permanent after the purchase has been made
|
onlineBookingsId | Integer | The ID of the booking for the reservation | |
quantity | Integer | The quantity of reservations to hold | |
sessionId | String | An optional session identifier to be used for documentation and debugging purposes, typically generated by an external website |
A Source
is linked to a Customer
by way of Customer.howdidyouhearaboutus
.
A Source
is a way to declare
how a Customer
could find and register at a venue,
such as the result of a marketing campaign, word of mouth, newspaper ad, etc.
Url | /sources |
Version | V2 |
Access | Private |
{ "sourceId": 1, "deleted": false, "enabled": true, "locationId": 1 "name": "Radio Advertisement", "seq": 9, }
Name | Type | Default | Description |
---|---|---|---|
sourceId | Integer | {Generated} | The primary key for the record |
deleted | Boolean | false | Flag indicating whether the source has been soft deleted |
enabled | Boolean | true | Flag indicating whether or not the source is currently enabled |
locationId | Integer | 1 | The ID of the venue location which this source applies to, where applicable |
name | String | The name of the source | |
seq | Integer | The sequence in which the sources should display in a dropdown |
A Tax
record is a way to define how tax calculations should be applied,
typically to a Product
.
To use a Tax
record, Tax.taxId
should be linked by setting it as Product.taxId
,
and the values will be automatically calculated
during Check
calculation time.
Url | /taxes |
Version | V1 |
Access | Private |
{ "taxes": [ { "taxId": 2, "description": "Sales Taxes", "amount": 6.25, "deleted": false, "gst": 0 } ] }
Name | Type | Default | Description |
---|---|---|---|
taxId | Integer | {Generated} | The primary key for the record |
amount | Double | The percentage of the tax, where 6.25 would indicate 6.25% |
|
deleted | Boolean | false | A flag indicating whether the tax has been soft deleted. For historical purposes, the tax should not be hard deleted |
description | String | A description for the tax | |
gst | Double | 0.0 | The percentage of the tax which should be considered GST, where applicable |
The Users
resource represents employees and system users.
Url | /users |
Version | V2 |
Access | Private |
{ "userId": 6, "firstname": "Steve", "lastname": "Stevens", "username": "the_steve", "cardId": null, "enabled": true, "email": "test@somewhere.com", "phone": "1234567890", "deleted": false, "empStartDate": "2010-00-00T00:00:00.00", "isSystemUser": false }
Name | Type | Default | Description |
---|---|---|---|
userId | Integer | {Generated} | The primary key for the record |
cardId | Integer | The card id for the user | |
deleted | Boolean | false | A flag indicating whether the user has been deleted |
String | The email address for the user | ||
empStartDate | DateTime | The date at which the user started employment | |
enabled | Boolean | true | A flag indicating whether the user is considered enabled |
firstname | String | The first name of the user | |
lastname | String | The last name of the user | |
isSystemUser | Boolean | false | A flag indicating whether the user is a system / application user, or a track employee |
password | String | The password for the user. Note that this field can be created and updated, but not read | |
phoneNumber | String | The phone number for the user | |
username | String | The username for the user. To be used with logins | |
webPassword | String | {User.password} | The password of the user to be used for logging in to a web portal, such as the admin panel or posting to /users/login . Will use User.password as a default, if not webPassword is not provided during a create. Note that this field can be created and updated, but not read |
CustomerDependents
are the records that store a customer's minors/dependents
Url | /CustomerDependents |
Version | V2 |
Access | Private |
{ "customerDependentId": 2, "custId": 1000001, "dependentCustId": 1000005 }
Name | Type | Default | Description |
---|---|---|---|
CustomerDependentId | Big Integer | {Generated} | The primary key for the record. |
CustId | String | The Id of the customer (parent). | |
dependentCustId | String | The Id of the dependent/minor customer. |
CustomerRelationships
are the records that store a customer's relationships
Url | /CustomerRelationships |
Version | V2 |
Access | Private |
{ "id": 7, "custId": 1000001, "RelativeCustID": 1000005, "RelationShip": "Father", }
Name | Type | Default | Description |
---|---|---|---|
id | Integer | id | |
CustId | String | The Id of the customer (parent). | |
RelativeCustID | String | ||
RelationShip | String |