Club Speed API - Version 1.0.0

Getting Started.


We currently have our Rental Karting data exposed and documented below.

Caching

Currently, no requests are cached.

Rate Limiting

The API is not currently rate limited. Please use good judgment when designing your application.

Output Formats

We currently support JSON, JSONP & XML (plus iCal on Events).

Questions/Requests

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 billing

Private Access

This icon represents a private call. When making a private call, either the private api key or an administrator username and password is required.

Rental Karting.


Use these methods to retrieve rental karting data.

You will need a key to access the Karting API. Email us to obtain your own.

Racers

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.

  • Find racer_id by Nickname: /racers/search?query=Wes Ratcliff (JSON, JSONP, XML)
  • Find racer_id by Email: /racers/search?field=email&query=wes@nolamotor.com (JSON, JSONP, XML)
  • Find Racer by racer_id: /racers/1000002 (JSON, JSONP, XML)
  • Find Racer's Races: /racers/1000002/races (JSON, JSONP, XML)
  • Top RPM Ranking
    • Limit: /racers/toprpm?limit=5 (JSON, JSONP, XML)
    • Gender (m: Male, f: Female): /racers/toprpm?gender=m (JSON, JSONP, XML)
    • Most Improved RPM (range: (month or year); month; year): /racers/most_improved_rpm?range=month&month=6&year=2014&limit=5 (JSON, JSONP, XML)
    • Most Improved RPM (start; end): /racers/most_improved_rpm?start=2016-09-09&end=2016-10-02 (JSON, JSONP, XML)
  • Find by last updated: /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)

Races - Race Results

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.

  • Today's Races: /races/races (JSON, JSONP, XML)
  • Today's Upcoming Races: /races/upcoming (JSON, JSONP, XML)
  • Races on Date: /races/races.json?start=2014-01-01&end=2014-01-01 (JSON, JSONP, XML)
  • Get next race: (defaults to track 1, offset 0) /races/next (JSON, JSONP, XML)
  • Get previous race: (defaults to track 1, offset 0) /races/previous (JSON, JSONP, XML)
  • Get current race_id: (defaults to track 1) /races/current_race_id (JSON, JSONP, XML)
  • Details on race: /races/9829 (JSON, JSONP, XML)
  • Laps completed: /races/9829/number_of_laps (JSON, JSONP, XML)
  • Details on race (limiting by racer and only laps after a certain lap_id): /races/9829/laps.json?racer_id=1000002&lap_id=584079 (JSON, JSONP, XML)
  • Upcoming Heat Types (for Web): /races/upcoming_heat_types (JSON, JSONP, XML)

Races - Scoreboard

Get the scoreboard for a specific heat or track

Races - Stats

Find out some interesting info about the laps run during races

Races - After specific time

Get a list of completed heats after a specific date and time

  • Races after specific time: /races/since?&date=2014-04-01 09:00:00&limit=200
    (JSON, JSONP, XML)
    (Limit is an optional parameter. Defaults to 100 rows, maxes out at 500 rows.)

Races - Final positions

Find out the final positions for each racer in a finished heat

  • Final positions of heat: /races/final_positions?&race_id=1000 (JSON,JSONP,XML)

Races - Fastest Laps

Find the fastest laps. Results have many options for filtering and sorting. Supports a maximum of 100 per query.

  • By Time Period
    • Day: /races/fastest?range=day (JSON, JSONP, XML)
    • Week: /races/fastest?range=week
    • Month: /races/fastest?range=month
    • Year: /races/fastest?range=year
    • In a Date Range: /races/fastest?start=2012-01-01&end=2012-01-01
  • Filter Results By
    • Tracks (1: Rental, 2: Oval, 3: Race): /races/fastest?track=1
    • Speed Level (1: Adult Rental CCW; 2: Junior Rental CCW; 3-4 Not Used; 5: Event Track: 6; Adult Rental CW; 7: Junior Rental CW): /races/fastest?speed_level=1
    • Limt: /races/fastest?limit=5
    • Gender (m: Male, f: Female): /races/fastest?gender=m
    • Exclude Employees: /races/fastest?exclude_employees=1
    • Only Employees: /races/fastest?only_employees=1
    • Employees and Customers: /races/fastest?exclude_employees=0
    • Weight (light: 0-155lb, medium: 156-190lb, heavy: 191-220lb, sumo: 221+lb): /races/fastest?weight=light
    • Birth Date in Range: /races/fastest?start_birthdate=1982-01-01&end_birthdate=1982-12-31

Tracks

Discover all tracks at a venue

Version

Get the current version of Club Speed

Channel

Get the configuration for a "Speed Screen" channel

  • Get Club Speed channel configuration: /channel/:channelId (JSON, JSONP, XML)

Users

Attempt to login a user

  • Login (returns true or false): /users/login (JSON, JSONP, XML)
  • Login Admin (returns true or false): /users/login (JSON, JSONP, XML)

Translations

Tie into Club Speed's translation database. Translations are grouped by "namespaces".

  • Retrieve by namespace: /translations/getNamespace (JSON, JSONP, XML)
  • Retrieve by language: /translations/getTranslations (JSON, JSONP, XML)
  • Translate by key(s). Keys may be String or Array: /translations/translate (JSON, JSONP, XML)

Settings

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 - Images

Retrieve images from Club Speed (requires private key). Settings are grouped by app.

Currently supported apps: kiosk

  • Retrieve images by app: /settings/getImages (JSON, JSONP, XML)

Authentication

Authentication Types

Usage

The ClubSpeed API requires one of three types of authentication:

  1. Public key authentication
  2. Private key authentication
  3. Basic 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://gllincoln.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.

RESTful

Routes

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

Status Codes

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!"
  }
}

Query Operations

Versioning

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.

Column Selection

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://gllincoln.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
  }
]

Record Filtering

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.


Available Comparison Operators

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

Available Logical Operators

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 )

Examples

 ?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
  )
)

Ordering

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.

Examples

 ?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 

Pagination / Limiting

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.

Examples

 ?limit=50 
 ?limit=50&skip=50 
 ?where={"amount":{"$gte":50}}&skip=50&take=10 
 ?limit=10&order=recordId DESC 

Response Types

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:

  1. Supply the Accept header
  2. Add .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>

Record Filtering (V1)

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

Available Comparators:

  • <
  • <=
  • >
  • >=
  • =
  • !=
  • <>
  • 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 )

Available Connectors

  • AND
  • OR

Examples

 ?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 (V1)

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):

Example

GET https://gllincoln.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
    }
  ]
}

Typical Usage

Online Booking

Usage

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.

  1. Create an Online Booking
    • The Online Booking is considered to be a container for available reservations for a selected race. Typically, this portion would already be created through the new ClubSpeed admin panel.
  2. Get a List of Available Online Bookings
    • If the Booking containers are already created, then the result from this call should be used to show customers which spaces are available for booking.
    • When collecting these, special consideration should be taken for the heatId in the response, as it will be needed when the customer checks out by using Process Payment.
  3. Customer Access and Authentication
  4. Create an Online Booking Reservation
    • A temporary booking reservation should be made at the point a customer adds a race to their cart. As the expectation is to have the cart maintained by the front-end, making a reservation will prevent accidental overbooking.
    • These temporary reservations can be upgraded to permanence after the final purchase is made, or deleted if the item is removed from the cart.
  5. Create a Virtual Check
    • This virtual check should be used to calculate Totals, Subtotals, and Taxes for the upcoming check and line items without creating the permanent check in the database.
  6. Create a Permanent Check
    • The permanent check should be created at the point the customer commits to purchasing all items in the cart.
  7. Load the Permanent Check data by CheckID
    • This should be done to ensure data integrity with the database, and to ensure all Check calculations have been made by the server logic.
  8. Process Payment
  9. Update each Reservation to be Permanent
    • Once the purchase has been made, any temporary reservations for the cart should be upgraded to be permanent.

Booking

Info

Description

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.

Endpoint

Url /booking
Version V1
Access Private

Example JSON

{
  "bookings": [
    {
      "onlineBookingsId": 4,
      "heatId": 4344,
      "productsId": 5,
      "isPublic": true,
      "quantityTotal": 5
    }
  ]
}

Fields

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

Booking Availability

Info

Description

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.

Endpoint

Url /bookingAvailability
Version V1
Access Private

Example JSON

{
  "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"
        }
      ]
    }
  ]
}

Fields

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.

Check Details

Info

Description

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.

stuff

Endpoint

Url /checkDetails
Version V1
Access Private

Example JSON

{
  "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
    }
  ]
}

Fields

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
  1. New
  2. Voided
  3. Permanent
Note that when creating a new check detail, this will always be set to 1.
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
  1. Regular
  2. Point
  3. Food
  4. Reservation
  5. GameCard
  6. Membership
  7. Gift Card
  8. Entitle
unitPrice Double The unitPrice of the product, which corresponds to Product.price1
voidNotes String Any notes which were added while voiding the check detail

Checks

Info

Description

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.

Endpoint

Url /checks
Version V1
Access Private

Example JSON

{
  "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
    }
  ]
}

Fields

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
  1. Regular
  2. Event
status Integer 0 The status of the check
  1. Open
  2. Closed
Note that when creating a new Check record, this will always be set to 0
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

Void

Information

Url /checks/:id/void
Verb POST
Access Private

Usage

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.

Finalize

Information

Url /checks/:id/finalize
Verb POST
Access Private

Usage

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://gllincoln.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://gllincoln.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://gllincoln.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"
        }
    ]
}

Check Totals

Info

Endpoint

Url /checkTotals
Version V1
Access Private

Fields

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

Create

Information

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

Usage

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.

Example

POST https://gllincoln.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
}

Virtual

Information

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

Usage

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.

Example

POST https://gllincoln.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
        }
      ]
    }
  ]
}

Customers

Info

Description

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.

Endpoint

Url /customers
Version V2
Access Private

Example JSON

{
  "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",
}

Fields

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
email 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
  1. Other / Unspecified
  2. Male
  3. Female
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

Info

Description

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.

Endpoint

Url /discountType
Version V2
Access Private

Example JSON

{
    "discountId": 1,
    "description": "$1 Race Discount",
    "calculateType": 1,
    "amount": 1,
    "enabled": false,
    "needApproved": false,
    "productClassId": 1,
    "deleted": true
}

Fields

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 amount is to be considered and used for calculations

  1. Amount
  2. Percentage
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

Event Heat Details

Info

Description

An EventHeatDetails record is a reference to a Customer who has been placed in a queue for a specific Event.

Endpoint

Url /eventHeatDetails
Version V2
Access Private

Example JSON

{
  "eventId": 3,
  "customerId": 1000007,
  "proskill": 1200,
  "added": "2013-05-29T11:35:33.23",
  "roundLoseNum": 0,
  "totalRaces": 1
}

Fields

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
proskill Integer The proskill for the customer
totalRacesInEvent Integer The total number of races in the event

Event Heat Types

Info

Description

Event Heat Types contains information grouped by Event Type designed to be a lookup for creating Event Rounds when creating an Event.

Endpoint

Url /eventHeatTypes
Version V2
Access Private

Example JSON

{
    "eventHeatTypeId": 1,
    "cadetsPerHeat": 0,
    "description": "5 Minute Qualifying",
    "eventTypeId": 1,
    "heatsPerRacer": 1,
    "heatTypeId": 17,
    "racersPerHeat": 22,
    "roundNumber": 1
}

Fields

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

Event Reservations

Info

Description

An EventReservation is paired to an Event as a way of storing and indicating specific reservation values for an Event.

Endpoint

Url /eventReservations
Version V2
Access Private

Example JSON

{
  "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
}

Fields

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

Update Event Status

Information

Url /eventReservations/:id
Verb PUT
Access Private

Usage

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://gllincoln.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://gllincoln.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

Info

Description

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.

Endpoint

Url /eventReservationTypes
Version V2
Access Private

Example JSON

[
  {
    "eventReservationTypeId": 1,
    "description": "Indoor Track"
  },
  {
    "eventReservationTypeId": 2,
    "description": "Outdoor Track"
  },
  {
    "eventReservationTypeId": 3,
    "description": "Party Room 1"
  }
]

Fields

Name Type Default Description
eventReservationTypeId Integer {Generated} The primary key for the record
description String The description of the event reservation type

Event Rounds

Info

Description

An Event Round is the link between Events and their corresponding rounds in the Heat Main, through HeatMain.eventRound.

Endpoint

Url /eventRounds
Version V2
Access Private

Example JSON

{
    "eventRoundId": 31,
    "cadetsPerHeat": 0,
    "eventId": 15,
    "heatDescription": "10 Minute Qualifying",
    "heatsPerRacer": 1,
    "heatTypeId": 1,
    "racersPerHeat": 22,
    "roundNumber": 1
}

Fields

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

Events

Info

Description

An Event is the parent record for all event specific information.

Endpoint

Url /events
Version V2
Access Private

Example JSON

{
  "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
}

Fields

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

Event Statuses

Info

Description

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.

Endpoint

Url /eventStatuses
Version V2
Access Private

Example JSON

{
  "eventStatusId": 1,
  "colorId": -16711936,
  "seq": 1,
  "status": "Unconfirmed"
}

Fields

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.

Event Tasks

Info

Description

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.

Endpoint

Url /eventTasks
Version V2
Access Private

Example JSON

{
    "eventTaskId": 128,
    "eventReservationId": 28,
    "completedBy": 1,
    "completedAt": "2016-01-01T00:00:00.00",
    "eventTaskTypeId": 4
}

Fields

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

Info

Description

Event task types is a container of task types to be tracked for completion, where the tracking information is stored with the EventTasks.

Endpoint

Url /eventTaskTypes
Version V2
Access Private

Example JSON

{
    "eventTaskTypeId": 1,
    "deleted": false,
    "seq": 2,
    "description": "",
    "name": "Confirmation Email Sent"
}

Fields

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

Event Types

Info

Endpoint

Url /eventTypes
Version V2
Access Private

Example JSON

{
  "eventTypeId": 1,
  "deleted": false,
  "description": "Sprint Race",
  "displayAtRegistration": true,
  "enabled": true,
  "eventTypeName": "Sprint Race",
  "eventTypeTheme": -20304,
  "memberOnly": false,
  "onlineProductId": 0,
  "ptsPerReservation": 1,
  "trackId": 1
}

Fields

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

Gift Card History

Info

Description

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.

Endpoint

Url /giftCardHistory
Version V2
Access Private

Example JSON

{
    "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"
}

Fields

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
  1. Sold gift card
  2. Transferred gift card in
  3. Void sold gift card
  4. Paid with gift card
  5. Void paid with gift card
  6. Refunded to gift card
  7. Sold gift card external
  8. Void sold gift card external
  9. Paid with gift card external
  10. Void paid with gift card external
  11. Refunded to gift card external
  12. Invoice paid
userId Integer The id of the user which recorded the transaction

Heat Details

Info

Description

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.

Endpoint

Url /heatDetails
Version V2
Access Private

Example JSON

{
  "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,
}

Fields

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

Heat Main

Info

Description

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.

Endpoint

Url /heatMain
Version V2
Access Private

Example JSON

{
  "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
}

Fields

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
  1. Minutes
  2. Laps
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
  1. Open
  2. Racing
  3. Finished
  4. Aborted
  5. Closed
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
  1. Best Time
  2. Finish Position

Heat Types

Info

Description

A HeatType is treated as a default template

Endpoint

Url /heatTypes
Version V2
Access Private

Example JSON

{
  "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
}

Fields

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
  1. Minutes
  2. Laps
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
  1. Best Time
  2. Finish Position

Memberships

Info

Description

A Membership is a pairing of Customer and MembershipType, representing a membership which the customer either has or had up until the expiration date.

Endpoint

Url /memberships
Version V2
Access Private

Example JSON

{
  "customerId": 1000001,
  "membershipTypeId": 105,
  "byUserId": 1
  "changed": "2014-06-17T00:00:00.00",
  "expiration": "2015-06-17T00:00:00.00",
  "notes": "",
}

Fields

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

Membership Types

Info

Description

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.

Endpoint

Url /membershipTypes
Version V2
Access Private

Example JSON

{
  "membershipTypeId": 1,
  "description": "Annual Membership",
  "enabled": true,
  "expirationType": 365,
  "expires": true,
  "priceLevel": 1
  "seq": 1,
}

Fields

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

Omnipay

List Vendors

Information

Url /omnipay
Verb GET
Access Private

Usage

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.

  • The name will be the name of the payment processor to be used when accepting a payment.
  • The 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.
  • The 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.

Example

GET https://gllincoln.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"
    ]
  }
]

Accept Payment

Information

Url /omnipay/purchase
Verb POST
Access Private

Usage

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.

  • The name will indicate which payment processor to use.
  • The 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.
  • The amount is the monetary amount for which you wish to accept a payment.
  • The 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.
  • The 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.
  • The 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.
  • The 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.

Example

POST https://gllincoln.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",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    "",
    ""
  ]
}

Complete Payment

Information

Url /omnipay/complete
Verb POST
Access Private

Usage

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:

  1. Initiate payment through API's /omnipay/purchase
  2. Receive redirect response from API
  3. Using your website and the API response, redirect customer to offsite payment portal
  4. Customer submits personal / credit card information into offsite payment portal
  5. Offsite payment redirects customer back to your website
  6. Your website collects response information from offsite payment portal (most likely from the query string)
  7. Encode and post this data in a request body to API's /omnipay/complete
  8. API returns response stating whether payment was successfully accepted

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.

Passwords

Generate Reset Token

Information

Url /passwords
Verb POST
Access Private

Usage

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.

Example

POST https://gllincoln.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

Consume Reset Token

Information

Url /passwords
Verb PUT
Access Private

Usage

The call detailed below will consume a password reset token and update the customer's password using a lookup based on the token.

Example

PUT https://gllincoln.clubspeedtiming.com/api/index.php/passwords HTTP/1.1
{
    "token": "81f6fde27692402fb2139f971b8accb29b1b20c6",
    "password": "some_new_password"
}
HTTP/1.1 200 OK

Payments

Info

Endpoint

Url /payments
Version V2
Access Private

Example JSON

{
  "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
}

Fields

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
  1. Paid
  2. Void
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

  1. Cash
  2. Credit
  3. External / Third Party Processor
  4. Gift Card
  5. Voucher
  6. Complementary
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

Process Payment

Info

Endpoint

Url /processPayment
Version V1
Access Private

Fields

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.

Process

Information

Url /processPayment
Verb POST
Access Private
Required
name
options
check
check.checkId
Available
card

Usage

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.

Example

POST https://gllincoln.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

Process Payment - SimplePay

Info

Description

To make a payment using Simple Pay processor.

There are three steps required to complete the payment process:

  1. Prepare the checkout: Make a POST request to Prepare Payment endpoint with the required data.
  2. Create the payment form: You can use the Payment Form Template as a reference.
  3. Complete the payment process: Once the payment has been processed, the customer is redirected to your shopperResultUrl. Make a POST request to Complete Payment endpoint with the required data.

For more detail please see the Simple Pay documentation.

Endpoint

Url /processPayment/preparesimplepay & /processPayment/completesimplepay
Version V1
Access Private

Fields

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

Prepare Payment

Information

Url /processPayment/preparesimplepay & /processPayment/completesimplepay/preparesimplepay
Verb POST
Access Private

Usage

The request body accepts the following items: name, options, and check.

  • The name has to be set to SimplePay
  • The options 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.
  • The 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:

  • Add the value of scriptUrl from prepare payment call to src attribute of script.
  • The 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.
    Important: The shopperResultUrl must end in a "/", e.g. "https://test.simplepays.com/".

Payment Form Template

<!doctype html>
<html>
  <head>
    <script src="{scriptUrl}"></script>
  </head>
  <body>
    <form action="{shopperResultUrl}" class="paymentWidgets" data-brands="VISA MASTER AMEX"></form>
  </body>
</html>

Example

POST https://gllincoln.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"
}

Complete Payment

Information

Url /processPayment/preparesimplepay & /processPayment/completesimplepay/completesimplepay
Verb POST
Access Private

Usage

In the shopperResultUrl page, make a complete payment call.

In the request body, add id value received from prepare payment.

Example

POST https://gllincoln.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"
}

Product Classes

Info

Description

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.

Endpoint

Url /productClasses
Version V2
Access Private

Example JSON

{
  "productClassId": 16,
  "description": "Karting",
  "deleted": false,
  "exportName": "kartexport_123"
}

Fields

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

Products

Info

Endpoint

Url /products
Version V1
Access Private

Example JSON

{
  "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,
    }
  ]
}

Fields

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
  1. Regular
  2. Point
  3. Food
  4. Reservation
  5. GameCard
  6. Membership
  7. Gift Card
  8. Entitle
r_Points Double The amount of reservation points provided when this product is purchased
taxId Integer The ID of the tax for the product

Racers

Create Customer

Information

Url /racers/create
Verb POST
Access Private
Required
racername
email
password
donotemail
firstname
lastname
birthdate
gender
mobilephone
Address
Address2
City
Country
howdidyouhearaboutus
State
Zip

Usage

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.

Example

POST https://gllincoln.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"
}

Login

Information

Url /racers/login
Verb POST
Access Private
Required
username
password

Example

POST https://gllincoln.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"
}

Facebook Login

Information

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

Usage

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.

Example

POST https://gllincoln.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"
}

Reservations

Info

Description

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.

Endpoint

Url /reservations
Version V2
Access Private

Example JSON

{
  "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
    }
  ]
}

Fields

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

  1. Temporary
  2. Permanent
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

Sources

Info

Description

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.

Endpoint

Url /sources
Version V2
Access Private

Example JSON

{
  "sourceId": 1,
  "deleted": false,
  "enabled": true,
  "locationId": 1
  "name": "Radio Advertisement",
  "seq": 9,
}

Fields

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

Taxes

Info

Description

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.

Endpoint

Url /taxes
Version V1
Access Private

Example JSON

{
  "taxes": [
    {
      "taxId": 2,
      "description": "Sales Taxes",
      "amount": 6.25,
      "deleted": false,
      "gst": 0
    }
  ]
}

Fields

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

Users

Info

Description

The Users resource represents employees and system users.

Endpoint

Url /users
Version V2
Access Private

Example JSON

{
    "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
}

Fields

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
email 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

Info

Description

CustomerDependents are the records that store a customer's minors/dependents

Endpoint

Url /CustomerDependents
Version V2
Access Private

Example JSON

{
    "customerDependentId": 2,
    "custId": 1000001,
    "dependentCustId": 1000005
}

Fields

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.