Create site

POST /api/configuration/sites

Success: 201 Created

Overview

Creates a site — a physical centre, branch or venue. A site is the fundamental scoping unit of the platform: activities, prices, memberships, bookings, bank accounts and system configuration all hang off a site id, so this is usually one of the first calls you make when setting up an account.

The site id is a string of up to 15 characters and you normally choose it yourself by sending id. Leave id out and the platform allocates the next one in the SITE sequence — the highest existing id beginning with SITE, incremented, zero-padded to 15 characters, giving values such as SITE00000000001.

The response has no body. On success you get a bare 201 Created with no payload and no Location header, so a call that omitted id gives you no way to learn the id that was allocated — you have to follow up with Retrieve all sites and look for it. If you need to know the id, send your own.

Retrying is safe in the sense that it will not silently duplicate: site ids are unique, so a second call carrying the same id returns 409 Conflict with Site ID: {id} already exists. A retry that omits id is a different matter — it allocates a fresh sequence value and creates a second site.

Creating a site also sets up its system configuration, which is why a new site is immediately usable rather than blank:

Endpoint

POST {base_url}/api/configuration/sites

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

Request body

address, location and contact are required objects, but every field inside them is optional — send {} if you have nothing to put in one. Everything else is optional.

FieldTypeRequiredDescription
idstringNoThe site id, and the value you will pass as siteId to almost every other endpoint. Maximum 15 characters, or the call fails with The site cannot be more than 15 characters. It is upper-cased before being stored, so send MYSITE rather than mysite and use the upper-case form everywhere afterwards. Must not already be in use — a clash returns 409. Watch out for spaces: the duplicate check strips them before comparing but the value is stored with them intact, so MY SITE can be accepted alongside an existing MYSITE and then never match it. Omit the field (or send an empty string) to have an id allocated from the SITE sequence instead, at the cost of not being told what it was.
namestringNoThe site's public-facing name, and what Retrieve all sites returns as name. Maximum 255 characters. An empty string is rejected with Site name cannot be empty, but the field carries no required check, so omitting it altogether is accepted and creates a site with no name — send one.
legalNamestringNoThe registered legal entity operating the site, where that differs from the trading name — for invoices and statutory documents. Maximum 255 characters. Omitting it leaves it null; nothing falls back to name.
vatIdstringNoThe site's VAT registration number, as free text. Maximum 20 characters. Not validated for format or checked against any tax authority.
descriptionstringNoA longer description of the site, separate from name. Maximum 255 characters. Returned as description by the site GET endpoints.
addressobjectYesThe site's postal address. The object itself must be present — omit it and the call fails with Address section is required — but all seven members inside it are optional, so "address": {} is valid.
address.addressLine1stringNoFirst line of the postal address. Maximum 100 characters. No lines are mandatory and none are validated against a postal address file.
address.addressLine2stringNoSecond line of the postal address. Maximum 100 characters.
address.addressLine3stringNoThird line of the postal address. Maximum 100 characters.
address.townCitystringNoTown or city. Maximum 100 characters.
address.regionstringNoCounty, state or region. Maximum 100 characters.
address.postalCodestringNoPostcode or ZIP code. Maximum 25 characters. Kept exactly as sent — not normalised, spaced or upper-cased.
address.countrystringNoCountry, as free text. Maximum 100 characters. Not an ISO country code and not validated against a list.
locationobjectYesThe site's map coordinates, used for distance-based site searches. The object must be present — omit it and the call fails with Location section is required — but both members are optional, so "location": {} is valid.
location.latitudestringNoLatitude in decimal degrees, sent as a string, for example "51.4816". Maximum 40 characters. Not parsed or range-checked on the way in, so a malformed value is accepted here and only causes trouble later, wherever the coordinate is used.
location.longitudestringNoLongitude in decimal degrees, sent as a string, for example "-3.1791". Maximum 40 characters, and subject to the same lack of validation as latitude.
contactobjectYesThe site's public contact details. The object must be present — omit it and the call fails with Contact section is required — but both members are optional, so "contact": {} is valid.
contact.telephonestringNoPublic telephone number as free text. Maximum 100 characters. No format validation, so send it in whatever form you want displayed.
contact.emailstringNoPublic contact email address for the site. Maximum 255 characters. Length is the only check — the value is not validated as an email address.
websiteUrlstringNoThe site's own web page. Maximum 255 characters. Stored and returned verbatim; not fetched or validated, so include the scheme yourself.
logoUrlstringNoAbsolute URL of the site's logo image. Maximum 255 characters. Nothing is uploaded or resized by this call — host the image yourself and pass the link.
termsConditionsUrlstringNoLink to the terms and conditions that apply at this site. Maximum 255 characters.
privacyPolicyUrlstringNoLink to the privacy policy that applies at this site. Maximum 255 characters.
openActiveTaxModestringNoStored verbatim against the site and returned by the site GET endpoints. Maximum 100 characters, or the call fails with Open active tax mode cannot be more than 100 characters.
isActivebooleanNoWhether the site is in service. Defaults to true when omitted — unlike most flags on this API — so a site you create is live unless you explicitly send false. Send false to stage a site before opening it, then switch it on with Update site. The field is not nullable: sending null is rejected as malformed JSON with a 400.
isWebVisiblebooleanNoWhether the site is shown in consumer-facing web and app channels. Independent of isActive — a site can be active for staff yet hidden from the public. Defaults to false when omitted or sent as null, so a new site is invisible online until you set it to true.
openingDatestring (date-time)NoThe date the site opens to the public. Only the date part is kept; the time is discarded. Must be today or later — a past date is rejected with Site opening date cannot be in the past., which also means you cannot backdate a historical site through this endpoint. Omit it to leave the site with no opening date, which is accepted.
amenitiesarray of objectNoThe amenities available at the site — showers, parking and so on. Omit the array or send [] for none. Every id must exist and no id may appear twice; either fault rejects the whole request and no site is created.
amenities[].idinteger (int32)NoAn amenity identifier from Retrieve all site amenities. Amenities are reference data and are not created for you here.
facilitiesarray of objectNoThe facilities the site has — pool, sports hall and so on. Omit the array or send [] for none. As with amenities, an unknown or repeated id rejects the whole request.
facilities[].idinteger (int32)NoA facility identifier from Retrieve all site facilities.
organisationsarray of objectNoThe organisations that run this site, linking it into your operator hierarchy for reporting. Omit the array or send [] for none. An unknown or repeated id rejects the whole request.
organisations[].idinteger (int32)NoAn organisation identifier from Retrieve all organisations. Create the organisation first if it does not exist.

Sample request

cURL
curl -X POST '{base_url}/api/configuration/sites' \
  -H 'Authorization: Bearer {accessToken}' \
  -H 'X-Use-SSO: true' \
  -H 'Content-Type: application/json' \
  -d '{
  "id": "CARDIFF",
  "name": "Cardiff Leisure Centre",
  "legalName": "Cardiff Leisure Trust Ltd",
  "vatId": "GB123456789",
  "description": "Eight-lane pool, gym and sports hall",
  "address": {
    "addressLine1": "12 Wood Street",
    "addressLine2": "",
    "addressLine3": "",
    "townCity": "Cardiff",
    "region": "South Glamorgan",
    "postalCode": "CF10 1EX",
    "country": "United Kingdom"
  },
  "location": {
    "latitude": "51.4763",
    "longitude": "-3.1795"
  },
  "contact": {
    "telephone": "029 2000 0000",
    "email": "cardiff@example.com"
  },
  "websiteUrl": "https://example.com/cardiff",
  "logoUrl": "https://example.com/cardiff/logo.png",
  "termsConditionsUrl": "https://example.com/terms",
  "privacyPolicyUrl": "https://example.com/privacy",
  "isActive": true,
  "isWebVisible": true,
  "openingDate": "2026-09-01T00:00:00Z",
  "amenities": [
    {
      "id": 3
    }
  ],
  "facilities": [
    {
      "id": 7
    }
  ],
  "organisations": [
    {
      "id": 1
    }
  ]
}'

Response fields

This endpoint returns no response body. A successful call is a bare 201 Created with an empty payload and no Location header.

The two fields in the table below appear against this endpoint in the published schema, but they are the shape of Retrieve site defaults (GET /api/configuration/sites/{siteId}/defaults), not of this call. Do not write code that reads them from this response.

FieldTypeDescription
timebandIdstringNever returned by this endpoint. It belongs to Retrieve site defaults, where it is the site's DefaultTimeBand setting — set to STAND when the site is created.
membershipTypeGroupIdstringNever returned by this endpoint. It belongs to Retrieve site defaults, where it is the site's DefaultSubTypeGroup setting — set to MISC when the site is created.

Sample response

201 Created
(no response body)

Errors

Validation is all-or-nothing: whichever check fails, no site is created and no configuration is saved.

StatusMeaningWhen
400Required section missingAddress section is required, Location section is required or Contact section is required. These are returned as a validation problem document (application/problem+json) with an errors map keyed by field name, listing every offending field at once.
400Field too longThe length-limit message for the field, for example The site cannot be more than 15 characters, Site name cannot be more than 255 characters, PostalCode cannot be more than 25 characters or Open active tax mode cannot be more than 100 characters. Also returned as a validation problem document.
400Empty site nameSite name cannot be empty — name was sent as an empty string. Omitting the field entirely passes validation instead.
400Opening date in the pastSite opening date cannot be in the past. — openingDate is earlier than today in UTC.
400Unknown amenity, facility or organisationUnable to create a site with Amenities as the Amenity ID(s) {ids} do not exist, or the equivalent …with Facilities as the Facility ID(s) {ids} do not exist and …with Organisations as the Organisation ID(s) {ids} do not exist. The message lists every id that could not be matched.
400Duplicate ids in a listUnable to create site as Amenities with ID {ids} are duplicated, or the equivalent for Facilities and Organisations. Repeating the same id within one array is rejected rather than de-duplicated.
400Malformed JSONisActive is not nullable and openingDate must be a date — sending null for isActive, or an unparseable date, is rejected as malformed JSON before validation runs. Omit a field rather than nulling it.
409Site id already in useSite ID: {id} already exists. Also returned as This entry already exists in the database if the clash is caught at the moment the site is saved rather than by the initial check. Sites are never overwritten by this endpoint — use Update site.
403ForbiddenThe access token does not satisfy this endpoint's requirements — the FOH product and the FOHGENERIC feature — or its scope is neither api nor partner.
500Internal server errorAn unexpected server-side failure while saving the site or its configuration. The body is empty.

This page as markdown · All pages · llms.txt