Get price level by ID

GET /api/configuration/price-levels/{priceLevelId}

Success: 200 OK

Overview

Returns a single price level, together with the site- and activity-specific alternative descriptions configured against it.

A price level is the operator-defined pricing band a person is charged under — adult, junior, concession, staff and so on. It holds no money. Prices are held separately, keyed on product, time band and price level together, so a price level is one axis of a price lookup rather than a price in its own right. Nothing in this response is an amount. What a price level does carry is eligibility (membersAllowed, nonMembersAllowed, webNonMembersAllowed), an age band, and pointers to two other price levels — nextPriceLevel for automatic progression such as a junior ageing into adult pricing, and infringementPriceLevel for the band a member is moved onto when they breach terms. A member record carries a price level id, and that is what ties a person to the prices they are charged.

Get the id from Get all price levels. Ids are operator-defined and not comparable across tenants, so never hardcode one. This call gives you two things the list does not: the alternativeDescriptions block, and a translations array that is actually populated.

A price level id that does not exist returns 404, not 400. The body is the plain-text message Unable to locate price level with id of {priceLevelId} — not JSON, and not a problem-details object.

One thing this response cannot tell you: a price level has an inactive flag which is neither filtered on nor returned. A price level the operator has retired still comes back as a normal 200, indistinguishable from a live one.

Endpoint

GET {base_url}/api/configuration/price-levels/{priceLevelId}

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

Path parameters

NameTypeRequiredDescription
priceLevelIdstringYesThe id of the price level to read, maximum 15 characters. Take it from the id field of Get all price levels rather than constructing it. Ids are uppercase with spaces stripped, because that is how the create endpoint normalises them, so send the value exactly as the platform returned it. No inactive filtering is applied — a retired price level is still returned.

Sample request

cURL
curl -X GET '{base_url}/api/configuration/price-levels/{priceLevelId}' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true'

Response fields

FieldTypeDescription
alternativeDescriptionsarray of objectLabels that replace description for particular sites or activities — an operator running the same band under a different name at one site, for example. Empty array when none are configured, which is the common case. Each entry is one distinct label text, with the activities and sites it applies at collected under it, so a label used at three sites appears once with three entries in sites. This block is exclusive to this endpoint; the list endpoint does not return it. Overrides scoped to an activity group rather than an individual activity are deliberately excluded and will not appear here.
alternativeDescriptions[].alternativeDescriptionstringThe replacement label itself, at most 25 characters — noticeably shorter than description, so expect an abbreviation rather than a full phrase.
alternativeDescriptions[].activitiesarray of objectThe activities this label applies to. Empty when the override is scoped only to sites. When both activities and sites are populated, they were configured as separate overrides sharing the same label text, not as an activity-and-site intersection.
alternativeDescriptions[].activities[].idstringThe activity's id, maximum 15 characters, matching the activity ids used elsewhere in the Configuration API.
alternativeDescriptions[].activities[].namestringThe activity's own description, included so you do not have to look the activity up separately for display.
alternativeDescriptions[].sitesarray of objectThe sites this label applies to. Empty when the override is scoped only to activities.
alternativeDescriptions[].sites[].siteIdstringThe site's id, maximum 15 characters and uppercase.
alternativeDescriptions[].sites[].namestringThe site's own description, for display.
alternativeDescriptions[].translationsarray of objectLocalised versions of alternativeDescription. Duplicates are removed before the array is built, so each culture appears once even when several overrides share the label. Empty array when no translations are configured. Note this is a different set of translations from the top-level translations field, which localises description.
alternativeDescriptions[].translations[].typestringThe property the text replaces.
alternativeDescriptions[].translations[].culturestringThe culture the text applies to, at most 20 characters. Must be a code the platform knows about — unknown cultures are rejected when translations are written — so you will only see recognised codes here.
alternativeDescriptions[].translations[].textstringThe translated label for that culture. No culture filtering happens server-side: you receive every configured culture and pick the one you want.
idstringThe price level's own identifier, maximum 15 characters and unique within the tenant. This is the value you pass back as priceLevelId, and the value that appears as a member's price level elsewhere in the API. Treat it as opaque — a value such as ADULT at one operator says nothing about another.
descriptionstringThe operator's own label for the band, intended for display. Maximum 255 characters and never blank: an empty description is rejected when the price level is written. Localise it using translations where you have a non-default culture.
ageRangeStartinteger (int32)Lower bound in years of the age band this price level covers. Always present, and 0 means "no meaningful lower bound" rather than "applies from birth". Must be less than or equal to ageRangeEnd; writes reject the reverse with The starting age range is greater than the ending age range, so you will not see it violated here.
ageRangeEndinteger (int32)Upper bound in years of the age band. Always present. Read it together with ageRangeStart, and with nextPriceLevel where the operator uses age progression — this is the boundary at which a member moves on.
backColourHexstringBackground colour the operator has assigned for showing this price level on staff-facing screens, as #RRGGBB. It is converted from a legacy integer colour value, so an unset colour comes back as an empty string, not null. Purely cosmetic; nothing behavioural depends on it. The create endpoint substitutes #E0E0E0 when no colour is sent, so recently created levels are rarely blank.
textColourHexstringForeground colour for the same display, as #RRGGBB, with the same empty-string-when-unset behaviour as backColourHex; the create endpoint defaults it to #000000. It is meant to be legible against backColourHex, but the platform does not check that it is.
membersAllowedbooleanWhether members may be charged at this price level. Derived from a legacy numeric indicator where only the value 1 counts as true, so false means "not enabled" and cannot be distinguished from "never configured". This is what filter=Member selects on in Get all price levels.
nonMembersAllowedbooleanWhether non-members — casual, pay-as-you-go visitors — may be charged at this price level. Derived the same way as membersAllowed, with the same "unset becomes false" behaviour. Independent of webNonMembersAllowed: a level can allow non-members at the counter without allowing them online.
infringementPriceLevelstringThe id of the price level a member is moved onto when they breach the terms of their membership — falling into debt or missing payments, for example. null when the operator has configured none, in which case no automatic move happens. The value is validated against existing price levels when it is set, so it always resolves. Do not confuse it with nextPriceLevel; the two exist for entirely different reasons.
nextPriceLevelstringThe id of the price level a member progresses to automatically, typically on ageing out of the band defined by ageRangeStart/ageRangeEnd. null when no progression is configured, meaning the member stays on this level indefinitely. Also validated to exist when set.
webNonMembersAllowedbooleanWhether non-members may be charged at this level through online channels specifically. Never null and defaults to false, so it is always present. Treat it as a narrowing of nonMembersAllowed rather than a substitute for it — it is the flag the webNonMembers=true query parameter filters on in Get all price levels.
translationsarray of objectLocalised alternatives to description, and the main reason to call this endpoint rather than the list. Only the description is translated — no other field on the price level has translations — and the array is empty when the operator has configured none.
translations[].typestringThe property the translated text replaces. Always description here, because that is the only property this endpoint returns translations for.
translations[].culturestringThe culture the text applies to, at most 20 characters and drawn from the platform's configured culture list. Every configured culture is returned; there is no way to ask for one.
translations[].textstringThe translated description for that culture.

Sample response

200 OK
{
  "alternativeDescriptions": [
    {
      "alternativeDescription": "string",
      "activities": [
        {
          "id": "string",
          "name": "string"
        }
      ],
      "sites": [
        {
          "siteId": "string",
          "name": "string"
        }
      ],
      "translations": [
        {
          "type": "string",
          "culture": "string",
          "text": "string"
        }
      ]
    }
  ],
  "id": "string",
  "description": "string",
  "ageRangeStart": 1,
  "ageRangeEnd": 1,
  "backColourHex": "string",
  "textColourHex": "string",
  "membersAllowed": true,
  "nonMembersAllowed": true,
  "infringementPriceLevel": "string",
  "nextPriceLevel": "string",
  "webNonMembersAllowed": true,
  "translations": [
    {
      "type": "string",
      "culture": "string",
      "text": "string"
    }
  ]
}

Errors

StatusMeaningWhen
400Bad requestNot returned by this endpoint: the only lookup failure is the not-found case below. Do not treat 400 as your missing-price-level signal — see the 404 row.
404Not foundNo price level exists with that id. The body is the plain-text message Unable to locate price level with id of {priceLevelId}, echoing the id exactly as you sent it.
500Internal server errorAn unexpected server-side failure while reading the price level, its alternative descriptions or their translations. The body is empty and carries no diagnostic detail.

This page as markdown · All pages · llms.txt