Update price level
PUT /api/configuration/price-levels/{priceLevelId}
- Products: Operator (
FOH) - Features: Front of House Generic Access (
FOHGENERIC)
Overview
Rewrites a price level — the banding a member or visitor is placed in, which determines which prices apply to them. This call sets the price level's name, its age band, its colours, who may be assigned it, the price levels it transitions to, its translations and its per-site or per-activity alternative names. It does not set any actual prices; those are held against products and activities.
This is a full replacement, and one of the more dangerous updates in this API. Everything below is written on every call, and three things are worth knowing before you use it:
- Fields you omit are cleared. Every field is written unconditionally, so an
omitted
description,infringementPriceLevelornextPriceLevelis written as null, and an omitted boolean is written asfalse. Read the price level first withGET /api/configuration/price-levelsand send every field back. - Settings this endpoint does not expose are reset. Every update resets several settings the
request cannot carry: the Connect non-members, force booking payment, force payment
via Connect and kiosk non-members indicators are all set to
0, the loyalty point threshold is set to0, and the smart card reference is set to an empty string. If your estate uses any of those, updating a price level through this endpoint silently turns them off. backColourHexandtextColourHexmust be present. An empty string is understood as "no colour", butnull— including the null you get by omitting the field — fails with500.
translations and alternativeDescriptions are also full-set replacements: the existing translations
are deleted and rebuilt, and alternative descriptions for any site or activity missing from your
request are deleted.
Validation of the whole request happens before anything is written. The write itself is not atomic: the price level record and its translations are saved first, then the alternative descriptions in separate steps, so a failure part-way through can leave the two inconsistent.
On success the response is 204 No Content and the change is visible on the next read.
Endpoint
PUT {base_url}/api/configuration/price-levels/{priceLevelId}
{base_url} is the environment URL issued to your integration. See Authenticating with Gladstone APIs.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
priceLevelId | string | Yes | Identifier of the price level to rewrite, up to 15 characters, as listed by GET /api/configuration/price-levels. It is converted to upper case before the record is looked up. If no price level matches, the request fails with 404 and the body Record cannot be found. The identifier is not writable. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
description | string | No | The price level's name, as shown wherever price levels are listed. Maximum 255 characters (The price level description cannot be more than 255 characters); an empty string is rejected (A blank description is not allowed), but null is accepted and clears the name. Written on every call. |
ageRangeStart | integer (int32) | No | Youngest age this price level applies to. Used when a member's date of birth is checked against the price level they are being given, and by age-based transitions. Range 0 to 32767 (AgeRangeStart has to be greater or equal to 0). Must not be greater than ageRangeEnd, or the request fails with The starting age range is greater than the ending age range. Omitting it writes 0. |
ageRangeEnd | integer (int32) | No | Oldest age this price level applies to, on the same 0–32767 range (AgeRangeEnd has to be greater or equal to 0). Omitting it writes 0 — which, with any non-zero ageRangeStart, then fails the start-versus-end check. Always send both ages together. |
backColourHex | string | Yes | Background colour used when the price level is displayed, as #RRGGBB — the same form GET /api/configuration/price-levels returns. The value you read back is a normalised hex string rather than exactly what you sent. Send an empty string to store no colour. Do not omit it and do not send null: the request fails with 500. |
textColourHex | string | Yes | Foreground colour used for the price level's text, in the same #RRGGBB form and with the same normalisation and the same null trap as backColourHex. Empty string means no colour. |
membersAllowed | boolean | No | Whether this price level may be used for members. Used to filter price levels — the member-only listing returns just those with this set. Omitting it or sending null writes false, removing the price level from member selection. |
nonMembersAllowed | boolean | No | Whether this price level may be used for non-members — casual visitors rather than members. Used the same way for the non-member listing. Omitting it writes false. |
webNonMembersAllowed | boolean | No | Whether non-members may be given this price level through the public web channel, as opposed to only at the counter. Listings can filter on it in combination with membersAllowed. Omitting it writes false and quietly withdraws the price level from online journeys. |
infringementPriceLevel | string | No | The price level a member is moved to when they breach terms — for example debt or missed payments. Give the identifier of another price level, up to 15 characters; it must already exist or the request fails with 400 PriceLevel {id} does not exist. Empty and null are accepted and clear the setting, so omitting it removes the infringement route. Do not confuse it with nextPriceLevel. |
nextPriceLevel | string | No | The price level this one automatically transitions to, used for progressions such as a junior band becoming an adult band once the age range is exceeded. Give the identifier of another price level, up to 15 characters; it must already exist or the request fails with 400 PriceLevel {id} does not exist. Cleared when omitted or null. |
translations | array of object | No | The complete set of localised text for this price level. The existing translations are deleted and rebuilt from this array on every call, so omitting it removes every translation; there is no way to amend a single one. No validation is applied to the entries. |
translations[].type | string | No | Which piece of text this entry localises. Not validated. |
translations[].culture | string | No | The culture the text is written in, as a language-REGION culture code such as cy-GB. Not validated, so an unrecognised culture is accepted rather than rejected and the text simply never surfaces. |
translations[].text | string | No | The translated text itself, for the type and culture in the same entry. Not length-validated here, unlike description. |
alternativeDescriptions | array of object | No | Overrides for the price level's name at particular sites or on particular activities — for example the same band shown under a local name at one centre. This is a full-set replacement: overrides for any site or activity not named in your request are deleted, and omitting the array or sending it empty deletes them all. Each entry must supply alternativeDescription and at least one of siteIds or activityIds, and the names must be unique within the array, compared case-insensitively and trimmed. |
alternativeDescriptions[].alternativeDescription | string | No | The alternative name to show. Mandatory within an entry — an entry without one fails with 400 One or more alternative descriptions does not have a description. Maximum 25 characters (AlternativeDescriptions cannot be more than 25 characters), much shorter than description. Two entries with the same name, ignoring case and surrounding spaces, are rejected. |
alternativeDescriptions[].activityIds | array of string | No | Activities this alternative name applies to. Each identifier must exist or the request fails with 400 Some or all of the activities supplied are not valid, and no activity may appear twice across the whole array (Duplicate Activity IDs are not allowed across alternative descriptions) — one activity cannot have two alternative names. Ids are converted to upper case. Each activity gets its own override, independently of siteIds: the two lists are not combined into site-and-activity pairs. |
alternativeDescriptions[].siteIds | array of string | No | Sites this alternative name applies to. Each identifier must exist or the request fails with 400 Some or all of the sites supplied are not valid, and no site may appear twice across the whole array (Duplicate Site IDs are not allowed across alternative descriptions). Ids are converted to upper case, and each site gets its own override. An entry needs at least one site or activity, or the request fails with One or more alternative descriptions does not have a activity ID or site ID defined. |
Sample request
curl -X PUT '{base_url}/api/configuration/price-levels/{priceLevelId}' \
-H 'Authorization: Bearer {accessToken}' \
-H 'X-Use-SSO: true' \
-H 'Content-Type: application/json' \
-d '{
"description": "string",
"ageRangeStart": 1,
"ageRangeEnd": 1,
"backColourHex": "string",
"textColourHex": "string",
"membersAllowed": true,
"nonMembersAllowed": true,
"webNonMembersAllowed": true,
"infringementPriceLevel": "string",
"nextPriceLevel": "string",
"translations": [
{
"type": "string",
"culture": "string",
"text": "string"
}
],
"alternativeDescriptions": [
{
"alternativeDescription": "string",
"activityIds": [
"string"
],
"siteIds": [
"string"
]
}
]
}'Errors
| Status | Meaning | When |
|---|---|---|
400 | Bad request | Validation failed: description blank or over 255 characters, an age outside 0–32767, or an alternativeDescription over 25 characters. The body is a validation error object keyed by field name. |
400 | Bad request | ageRangeStart is greater than ageRangeEnd — The starting age range is greater than the ending age range. |
400 | Bad request | nextPriceLevel or infringementPriceLevel names a price level that does not exist — PriceLevel {id} does not exist. |
400 | Bad request | An alternative description entry has no name — One or more alternative descriptions does not have a description. |
400 | Bad request | An alternative description entry names neither a site nor an activity — One or more alternative descriptions does not have a activity ID or site ID defined. |
400 | Bad request | Two alternative descriptions share a name — Duplicate alternateDescriptions within the same PriceLevel is not allowed. Please ensure each alternateDescription is unique. |
400 | Bad request | A site or activity appears in more than one alternative description — Duplicate Site IDs are not allowed across alternative descriptions or Duplicate Activity IDs are not allowed across alternative descriptions. |
400 | Bad request | A site or activity does not exist — Some or all of the sites supplied are not valid or Some or all of the activities supplied are not valid. |
404 | Not found | No price level matches the path identifier — body is the string Record cannot be found. |
409 | Conflict | The update conflicts with an existing record — The record updating contains a key already in use. |
500 | Internal server error | backColourHex or textColourHex was null or omitted. Also any other unexpected server-side failure. No detail is returned. |