Lists booking discount usage records with optional filtering and pagination

GET /api/configuration/booking-discount-usage

Success: 200 OK

Overview

Returns a history of booking discounts that have actually been taken: one record per discounted booking line, with the promotion code used, the price before and after the discount, and the member and booking it applied to. Use it to audit promotion use or to show a member why a booking cost what it cost. It reports past use only — to find out which discounts are available, call List booking discounts for an activity and date.

At least one filter is required. Calling with no parameters at all fails with 400; there is no way to page through every record. Filters combine with AND, and every id you filter on must exist — filtering on a member, booking, activity or promotion code that does not exist is a 400, not an empty result.

This endpoint is gated behind the BOOKINGDISCOUNTS feature. Without it, every call returns 403.

Results are paged with a continuation token rather than an offset. Follow links.next until it is null; do not construct the token yourself. Because a token is emitted whenever a page comes back full, the last page of an exact multiple of limit will hand you a link that returns an empty data array — that is the normal way the sequence ends, not an error.

Endpoint

GET {base_url}/api/configuration/booking-discount-usage

{base_url} is the environment URL issued to your integration. See Authenticating with Gladstone APIs.

Query parameters

NameTypeRequiredDescription
MemberIDinteger (int32)NoRestricts results to discounts taken on bookings this member is on. The member must exist or the call fails with 400 and Member with ID '{MemberID}' does not exist. — an existing member with no discounted bookings returns 200 with an empty data array instead. Note the capitalised parameter name.
BookingIDinteger (int32)NoRestricts results to one booking. The booking must exist or the call fails with 400 and Booking with ID '{BookingID}' does not exist. Combines with the other filters using AND, so a booking that does not also match them returns nothing.
ActivityIDstringNoRestricts results to bookings of one activity, matched exactly against the booking's activity id — no partial or case-insensitive matching. The activity must exist or the call fails with 400 and Activity with ID '{ActivityID}' does not exist.
PromotionCodestringNoRestricts results to one promotion code, matched exactly against the code string rather than an id. The code must exist or the call fails with 400 and Promotion code '{PromotionCode}' does not exist.
DateFromstring (date-time)NoKeeps only records whose booking start date is on or after this date. Only the date part is used, so a time component has no effect and the boundary day is always included. May be used without DateTo, in which case there is no upper bound.
DateTostring (date-time)NoKeeps only records whose booking end date is on or before this date — note it tests the end of the booking, while DateFrom tests the start, so a booking spanning midnight can fall outside a single-day range. Only the date part is used. If both are supplied and DateTo is earlier than DateFrom, the call fails with 400 and DateTo cannot be before DateFrom. Please enter a valid date.
continuation-tokenstringNoTake this from links.next of the previous response rather than building it. Its form is discount-usage-id:{id} and the next page starts strictly after that record id. Omit it for the first page. It is parsed before anything else is validated, so a malformed value fails with 400 — Invalid continuation token format when it is not two colon-separated parts, Invalid continuation token key when the part before the colon is not discount-usage-id, and Invalid continuation token value when the part after it is not an integer. Repeat the same filters alongside it; changing them mid-sequence silently changes what you are paging through.
limitinteger (int32)NoMaximum records in data. Defaults to 50 when omitted. It is not validated: limit=0 fails with 500, because an empty page is mistaken for a full one. There is no documented upper bound, so a very large value is not capped.

Sample request

cURL
curl -X GET '{base_url}/api/configuration/booking-discount-usage' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true'

Response fields

FieldTypeDescription
dataarray of objectThe page of usage records, ordered by id ascending. Empty rather than null when nothing matches. Its length is at most limit; a length equal to limit is what causes links.next to be issued.
data[].idinteger (int32)Identifies the discount-usage record, and doubles as the pagination cursor — the last one on a page becomes the continuation token. It is not unique within the response: a single usage record spanning more than one sales invoice or booking member produces one entry per combination. Because the next page starts strictly after the last entry's id, a group of entries sharing an id that straddles a page boundary loses its remainder; use a limit comfortably larger than any such group.
data[].promotionCodestringThe promotion code string that was applied, not its id. It is the same value the PromotionCode filter matches on.
data[].priceLevelCombostringThe price-level combination that qualified for the discount, returned as a single raw string — at most 200 characters, in a bracketed, comma-separated form. Beware: the identically named field on List booking discounts is an array of strings parsed from this same value, so the two endpoints report the same data in different shapes. Parse it yourself if you need the individual price levels.
data[].originalPricenumber (double)The combined price the booking would have cost without the discount, held to 2 decimal places. Compare with discountedPrice to derive the saving — the saving itself is not returned.
data[].discountedPricenumber (double)The combined price actually charged after the discount, held to 2 decimal places. This is the whole combination's price, not a per-person figure.
data[].discountSalesInvoiceIdinteger (int32)The sales invoice line recording the discount itself.
data[].memberIdinteger (int32)The member on the booking this entry relates to. Where a discounted booking covers several members, each produces its own entry against the same usage id, so summing prices across entries double-counts.
data[].bookingIdinteger (int32)The booking the discount was applied to — the same identifier the BookingID filter takes.
data[].bookingRefinteger (int32)The booking's reference number as held against the member's place on it. Nullable, so expect null on older records.
data[].bookingStartDateTimestring (date-time)When the booking starts. This is the value DateFrom filters on. Nullable — a booking with no start recorded is still returned, and is excluded by any DateFrom filter.
data[].bookingEndDateTimestring (date-time)When the booking ends. This is the value DateTo filters on. Nullable, with the same consequence as for the start.
linksobjectPagination links. Always present, even on the last page.
links.nextstringThe absolute URL of the next page: this endpoint's public URL with your filters re-applied, plus continuation-token and limit. Follow it as-is. It is null when the page came back shorter than limit, which is the only reliable end-of-sequence signal — a page that is exactly full always yields a link, even when no records remain.

Sample response

200 OK
{
  "data": [
    {
      "id": 12345,
      "promotionCode": "string",
      "priceLevelCombo": "string",
      "originalPrice": 10.5,
      "discountedPrice": 10.5,
      "discountSalesInvoiceId": 12345,
      "memberId": 12345,
      "bookingId": 12345,
      "bookingRef": 1,
      "bookingStartDateTime": "2026-08-14T19:00:00Z",
      "bookingEndDateTime": "2026-08-14T19:00:00Z"
    }
  ],
  "links": {
    "next": "string"
  }
}

Errors

StatusMeaningWhen
400Bad requestOne of: no filter at all — At least one of the following query parameters must be provided: MemberID, BookingID, ActivityID, PromotionCode, DateFrom, DateTo.; DateTo before DateFrom; a malformed continuation-token; or a MemberID, BookingID, ActivityID or PromotionCode that does not exist, each with its own message naming the value. The body is the plain message string, not JSON.
403ForbiddenYour token does not carry the BOOKINGDISCOUNTS feature. The body is the plain string The requested operation requires Module BOOKINGDISCOUNTS to be enabled. Contact Gladstone Support to have the feature enabled for your integration.
500Internal server errorAny unexpected server-side failure, with an empty body. Two causes are reachable from the request itself: limit=0, and a request that does not come through the gateway, which leaves the endpoint unable to build links.next.

This page as markdown · All pages · llms.txt