Skip to content

← All API operations

Apply a location template to a location ​

Overwrites every captured field of the location from the named template's snapshot and links the location to it. The answer is the location's configuration document as it stands afterwards, with template naming the template just applied.

Behavior and permissions

The overwrite is total for the captured groups: the location's services, windows and operating hours become the template's, and a window the template does not capture is removed rather than left behind. A location already linked to another template is relinked; no detach is needed and none is a member of this body.

templateId is required. A body omitting it, or carrying it blank, is answered 400 with an errors entry naming templateId and code required. A templateId that is present but names no template of this tenant — another tenant's, a deleted one, or a value this surface could not have issued — is answered 404 template_not_found, one answer for all three.

The apply is refused 409 template_apply_blocked when it would drop a service that still holds a non-terminal ticket, with one blockers entry counting those tickets. Nothing is written when it is.

Requires a credential issued by a tenant administrator. The location's reach is checked before the body is read, so a location outside the credential's reach never reveals whether the named template exists.

Authorization · Example request · Parameters · Request body · Responses

POST/api/integration/v1/locations/{locationId}/configuration/apply-template

Authorization

  • apiKeyAuth — apiKey sent in the Authorization header

Use Authorization: Api-Key <secret>. Get a credential and check the scopes and issuer authority required for this operation.

Example request

Set QMS_BASE_URL to your workspace URL and QMS_API_KEY to your secret. Replace example identifiers with your own.

cURL
curl --request POST "$QMS_BASE_URL/api/integration/v1/locations/22222222-2222-4222-8222-222222222222/configuration/apply-template" \
  --header "Authorization: Api-Key $QMS_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "templateId": "99999999-9999-4999-8999-999999999999"
}'

Parameters

NameInRequiredSchema
locationIdpathyes{"type":"string"}

locationId: The location's opaque identifier.

Request body

Example body
{
  "templateId": "99999999-9999-4999-8999-999999999999"
}
Request schema

The apply-template body: the template to apply, and nothing else.

templateId · string · required

The template whose snapshot is written over the location's configuration. Required; absent or blank is answered 400 `validation_failed` naming this member, while a value naming no template of this tenant is answered 404 `template_not_found`.

Raw JSON Schema

application/json

{
  "type": "object",
  "description": "The apply-template body: the template to apply, and nothing else.",
  "properties": {
    "templateId": {
      "type": "string",
      "description": "The template whose snapshot is written over the location's configuration. Required; absent or blank is answered 400 `validation_failed` naming this member, while a value naming no template of this tenant is answered 404 `template_not_found`.",
      "example": "99999999-9999-4999-8999-999999999999"
    }
  },
  "required": [
    "templateId"
  ]
}

Responses

200 — The location's configuration, as the template left it.

200 · Example
{
  "template": {
    "id": "99999999-9999-4999-8999-999999999999",
    "name": "Branch standard"
  },
  "services": [
    {
      "id": "77777777-7777-4777-8777-777777777777",
      "defaultDurationMinutes": 30
    }
  ],
  "windows": [
    {
      "id": "A1",
      "floor": "Ground",
      "status": "ACTIVE"
    }
  ],
  "operatingHours": [
    {
      "day": "MON",
      "opensAt": "08:30",
      "closesAt": "17:30",
      "closed": false
    },
    {
      "day": "TUE",
      "opensAt": "08:30",
      "closesAt": "17:30",
      "closed": false
    },
    {
      "day": "WED",
      "opensAt": "08:30",
      "closesAt": "17:30",
      "closed": false
    },
    {
      "day": "THU",
      "opensAt": "08:30",
      "closesAt": "17:30",
      "closed": false
    },
    {
      "day": "FRI",
      "opensAt": "08:30",
      "closesAt": "17:30",
      "closed": false
    },
    {
      "day": "SAT",
      "opensAt": null,
      "closesAt": null,
      "closed": true
    },
    {
      "day": "SUN",
      "opensAt": null,
      "closesAt": null,
      "closed": true
    }
  ],
  "qrEntryMode": "SINGLE",
  "walkInNoShowGraceSeconds": 120,
  "appointmentNoShowGraceSeconds": 900,
  "operatorNameVisible": true
}
200 response schema

One location's queue configuration. Every member is always present; a member that does not apply is null rather than absent. The document holds no name for anything it references: a service is its catalogue identifier, and the service's name is read from the service catalogue. The only name here is the linked template's, because a template has no read of its own a location manager can reach.

template · one of · required

The template this location is provisioned from, or null when it is independent. Read-only on the configuration write: the link is moved by the apply-template operation and cut by that write's `detach`.

Show nested fields

The template this location is provisioned from, or null when it is independent. Read-only on the configuration write: the link is moved by the apply-template operation and cut by that write's `detach`.

Option 1 · object

The template a location is provisioned from, named so it can be shown without a second read.

id · string · required

name · string · required

Option 2 · null

services · array · required

The services this location offers, each with the duration in force here.

Show nested fields

One service this location offers.

id · string · required

The catalogue service's own identifier, as the service read publishes it.

defaultDurationMinutes · integer · required

How long one appointment for this service takes AT THIS LOCATION — the resolved value, which is the location's own override where it has one and the catalogue's default otherwise. Never null here.

windows · array · required

The location's service windows, active and inactive alike.

Show nested fields

One service window of the location.

id · string · required

The window's own short code, the one printed above the desk — 1 to 20 alphanumeric characters, unique within the location. It is the key this surface merges a window by, not a server-generated identifier.

floor · string | null · required

A free-text floor label of at most 20 characters, or null when none is set.

status · string · required

Whether the window is in service. A window is retired by moving it to `INACTIVE`, never by deleting it, so the code it published stays recognisable.

Allowed values: "ACTIVE", "INACTIVE"

operatingHours · array · required

The weekly schedule: exactly seven entries, one per day of the week, whether the location opens that day or not.

Show nested fields

One day of the weekly schedule.

day · string · required

A day of the week, as the three-letter code the schedule is keyed by.

Allowed values: "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"

opensAt · string | null · required

When the location opens that day, as 24-hour `HH:MM`. Null on a day whose `closed` is true.

closesAt · string | null · required

When it closes, as 24-hour `HH:MM`, and strictly after `opensAt`. Null on a day whose `closed` is true.

closed · boolean · required

Whether the location is shut that day.

qrEntryMode · string · required

How the location hands out its QR entry points: `SINGLE` is one code for the whole branch and the customer picks a service after scanning, `PER_SERVICE` is one code per service the location offers. This surface stores and applies the mode; it serves no QR artefact.

Allowed values: "SINGLE", "PER_SERVICE"

walkInNoShowGraceSeconds · integer · required

How long a called walk-in ticket is held before it may be marked a no-show. The EFFECTIVE value: a location storing no override publishes the platform default rather than null. Between 30 and 600 seconds on a write.

appointmentNoShowGraceSeconds · integer · required

The same, for a ticket issued from an appointment. Between 60 and 3600 seconds on a write.

operatorNameVisible · boolean · required

Whether the operator's name is shown to the customer at this location.

Raw JSON Schema

application/json

{
  "type": "object",
  "description": "One location's queue configuration. Every member is always present; a member that does not apply is null rather than absent.\n\nThe document holds no name for anything it references: a service is its catalogue identifier, and the service's name is read from the service catalogue. The only name here is the linked template's, because a template has no read of its own a location manager can reach.",
  "properties": {
    "template": {
      "description": "The template this location is provisioned from, or null when it is independent. Read-only on the configuration write: the link is moved by the apply-template operation and cut by that write's `detach`.",
      "oneOf": [
        {
          "type": "object",
          "description": "The template a location is provisioned from, named so it can be shown without a second read.",
          "properties": {
            "id": {
              "type": "string",
              "example": "99999999-9999-4999-8999-999999999999"
            },
            "name": {
              "type": "string",
              "example": "Branch standard"
            }
          },
          "required": [
            "id",
            "name"
          ]
        },
        {
          "type": "null"
        }
      ]
    },
    "services": {
      "type": "array",
      "description": "The services this location offers, each with the duration in force here.",
      "items": {
        "type": "object",
        "description": "One service this location offers.",
        "properties": {
          "id": {
            "type": "string",
            "description": "The catalogue service's own identifier, as the service read publishes it.",
            "example": "77777777-7777-4777-8777-777777777777"
          },
          "defaultDurationMinutes": {
            "type": "integer",
            "description": "How long one appointment for this service takes AT THIS LOCATION — the resolved value, which is the location's own override where it has one and the catalogue's default otherwise. Never null here.",
            "example": 15
          }
        },
        "required": [
          "id",
          "defaultDurationMinutes"
        ]
      }
    },
    "windows": {
      "type": "array",
      "description": "The location's service windows, active and inactive alike.",
      "items": {
        "type": "object",
        "description": "One service window of the location.",
        "properties": {
          "id": {
            "type": "string",
            "description": "The window's own short code, the one printed above the desk — 1 to 20 alphanumeric characters, unique within the location. It is the key this surface merges a window by, not a server-generated identifier.",
            "example": "A1"
          },
          "floor": {
            "type": [
              "string",
              "null"
            ],
            "description": "A free-text floor label of at most 20 characters, or null when none is set.",
            "example": "Ground"
          },
          "status": {
            "type": "string",
            "description": "Whether the window is in service. A window is retired by moving it to `INACTIVE`, never by deleting it, so the code it published stays recognisable.",
            "enum": [
              "ACTIVE",
              "INACTIVE"
            ],
            "example": "ACTIVE"
          }
        },
        "required": [
          "id",
          "floor",
          "status"
        ]
      }
    },
    "operatingHours": {
      "type": "array",
      "description": "The weekly schedule: exactly seven entries, one per day of the week, whether the location opens that day or not.",
      "items": {
        "type": "object",
        "description": "One day of the weekly schedule.",
        "properties": {
          "day": {
            "type": "string",
            "description": "A day of the week, as the three-letter code the schedule is keyed by.",
            "enum": [
              "MON",
              "TUE",
              "WED",
              "THU",
              "FRI",
              "SAT",
              "SUN"
            ],
            "example": "MON"
          },
          "opensAt": {
            "type": [
              "string",
              "null"
            ],
            "description": "When the location opens that day, as 24-hour `HH:MM`. Null on a day whose `closed` is true.",
            "example": "09:00"
          },
          "closesAt": {
            "type": [
              "string",
              "null"
            ],
            "description": "When it closes, as 24-hour `HH:MM`, and strictly after `opensAt`. Null on a day whose `closed` is true.",
            "example": "18:00"
          },
          "closed": {
            "type": "boolean",
            "description": "Whether the location is shut that day.",
            "example": false
          }
        },
        "required": [
          "day",
          "opensAt",
          "closesAt",
          "closed"
        ]
      }
    },
    "qrEntryMode": {
      "type": "string",
      "description": "How the location hands out its QR entry points: `SINGLE` is one code for the whole branch and the customer picks a service after scanning, `PER_SERVICE` is one code per service the location offers. This surface stores and applies the mode; it serves no QR artefact.",
      "enum": [
        "SINGLE",
        "PER_SERVICE"
      ],
      "example": "SINGLE"
    },
    "walkInNoShowGraceSeconds": {
      "type": "integer",
      "description": "How long a called walk-in ticket is held before it may be marked a no-show. The EFFECTIVE value: a location storing no override publishes the platform default rather than null. Between 30 and 600 seconds on a write.",
      "example": 120
    },
    "appointmentNoShowGraceSeconds": {
      "type": "integer",
      "description": "The same, for a ticket issued from an appointment. Between 60 and 3600 seconds on a write.",
      "example": 900
    },
    "operatorNameVisible": {
      "type": "boolean",
      "description": "Whether the operator's name is shown to the customer at this location.",
      "example": true
    }
  },
  "required": [
    "template",
    "services",
    "windows",
    "operatingHours",
    "qrEntryMode",
    "walkInNoShowGraceSeconds",
    "appointmentNoShowGraceSeconds",
    "operatorNameVisible"
  ]
}

400 — The request body or query parameters failed field validation. `errors` carries one entry per offending field, naming the member as this document spells it and the reason as a published slug. The member is absent when no single field can be named. On the service edit this status is shared with `service_code_immutable` — see that response. Branch on `code`.

400 · Example
{
  "type": "urn:qms:problem:validation_failed",
  "title": "Validation Failed",
  "status": 400,
  "code": "validation_failed",
  "detail": "The request body failed field validation.",
  "errors": [
    {
      "field": "country",
      "code": "invalid_country"
    },
    {
      "field": "name",
      "code": "required"
    }
  ]
}
400 response schema

An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.

type · string · required

A URN identifying the problem kind, one per `code`.

title · string · required

A fixed English summary of the problem kind.

status · integer · required

The HTTP status code, repeated in the body.

code · string · required

The published slug this surface's error vocabulary uses.

detail · string · required

An English explanation of this occurrence.

errors · array · optional

One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.

Show nested fields

One offending field of a 400 field-validation refusal.

field · string · required

The member as THIS document spells it, which is not always what the same field is called inside the system.

code · string · required

The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`. Three of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.

blockers · array · optional

One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.

Show nested fields

One non-zero blocking category of a 409 refusal, and how many things it counted.

kind · string · required

What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.

Allowed values: "LOCATION", "TICKET", "APPOINTMENT", "TEMPLATE", "OPERATOR"

count · integer · required

How many of them there are. Always greater than zero.

checkCode · string · optional

The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.

planLimit · object · optional

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

Show nested fields

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

currentPlan · object · required

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

activeLocations · integer · required

The number of ACTIVE locations the tenant holds.

nextPlan · object · optional

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

enterpriseOffer · object · optional

The published Enterprise offer, named when no active plan covers the tenant's active location count.

Show nested fields

The published Enterprise offer, named when no active plan covers the tenant's active location count.

minLocations · integer · required

The smallest number of locations the offer covers.

fromMonthlyPriceCents · integer · int64 · required

The monthly price from which the offer starts, in euro cents.

extraLocationPriceCents · integer · int64 · required

The monthly price of each location beyond `minLocations`, in euro cents.

contactEmail · string · optional

The address to write to about a larger plan or an individual contract.

Raw JSON Schema

application/problem+json

{
  "type": "object",
  "description": "An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.",
  "properties": {
    "type": {
      "type": "string",
      "description": "A URN identifying the problem kind, one per `code`.",
      "example": "urn:qms:problem:location_not_found"
    },
    "title": {
      "type": "string",
      "description": "A fixed English summary of the problem kind.",
      "example": "Location Not Found"
    },
    "status": {
      "type": "integer",
      "description": "The HTTP status code, repeated in the body.",
      "example": 404
    },
    "code": {
      "type": "string",
      "description": "The published slug this surface's error vocabulary uses.",
      "example": "location_not_found"
    },
    "detail": {
      "type": "string",
      "description": "An English explanation of this occurrence.",
      "example": "No location was found for this identifier."
    },
    "errors": {
      "type": "array",
      "description": "One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.",
      "items": {
        "type": "object",
        "description": "One offending field of a 400 field-validation refusal.",
        "properties": {
          "field": {
            "type": "string",
            "description": "The member as THIS document spells it, which is not always what the same field is called inside the system.",
            "example": "defaultLocale"
          },
          "code": {
            "type": "string",
            "description": "The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`.\n\nThree of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.",
            "example": "invalid_locale"
          }
        },
        "required": [
          "field",
          "code"
        ]
      }
    },
    "blockers": {
      "type": "array",
      "description": "One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.",
      "items": {
        "type": "object",
        "description": "One non-zero blocking category of a 409 refusal, and how many things it counted.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.",
            "enum": [
              "LOCATION",
              "TICKET",
              "APPOINTMENT",
              "TEMPLATE",
              "OPERATOR"
            ],
            "example": "TICKET"
          },
          "count": {
            "type": "integer",
            "description": "How many of them there are. Always greater than zero.",
            "example": 3
          }
        },
        "required": [
          "kind",
          "count"
        ]
      }
    },
    "checkCode": {
      "type": "string",
      "description": "The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.",
      "example": "unreachable"
    },
    "planLimit": {
      "type": "object",
      "description": "What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.",
      "properties": {
        "currentPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "activeLocations": {
          "type": "integer",
          "description": "The number of ACTIVE locations the tenant holds.",
          "example": 3
        },
        "nextPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "enterpriseOffer": {
          "type": "object",
          "description": "The published Enterprise offer, named when no active plan covers the tenant's active location count.",
          "properties": {
            "minLocations": {
              "type": "integer",
              "description": "The smallest number of locations the offer covers.",
              "example": 8
            },
            "fromMonthlyPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price from which the offer starts, in euro cents.",
              "example": 27900
            },
            "extraLocationPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price of each location beyond `minLocations`, in euro cents.",
              "example": 2900
            }
          },
          "required": [
            "minLocations",
            "fromMonthlyPriceCents",
            "extraLocationPriceCents"
          ]
        },
        "contactEmail": {
          "type": "string",
          "description": "The address to write to about a larger plan or an individual contract.",
          "example": "sales@example.com"
        }
      },
      "required": [
        "currentPlan",
        "activeLocations"
      ]
    }
  },
  "required": [
    "type",
    "title",
    "status",
    "code",
    "detail"
  ],
  "additionalProperties": false
}

401 — No valid API credential was presented. Every refusal cause — absent, malformed, unknown, expired, revoked, or belonging to another tenant — answers with this one document, and no `WWW-Authenticate` header is returned.

401 · Example
{
  "type": "urn:qms:problem:unauthenticated",
  "title": "Unauthenticated",
  "status": 401,
  "code": "unauthenticated",
  "detail": "The request presented no valid API credential."
}
401 response schema

An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.

type · string · required

A URN identifying the problem kind, one per `code`.

title · string · required

A fixed English summary of the problem kind.

status · integer · required

The HTTP status code, repeated in the body.

code · string · required

The published slug this surface's error vocabulary uses.

detail · string · required

An English explanation of this occurrence.

errors · array · optional

One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.

Show nested fields

One offending field of a 400 field-validation refusal.

field · string · required

The member as THIS document spells it, which is not always what the same field is called inside the system.

code · string · required

The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`. Three of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.

blockers · array · optional

One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.

Show nested fields

One non-zero blocking category of a 409 refusal, and how many things it counted.

kind · string · required

What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.

Allowed values: "LOCATION", "TICKET", "APPOINTMENT", "TEMPLATE", "OPERATOR"

count · integer · required

How many of them there are. Always greater than zero.

checkCode · string · optional

The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.

planLimit · object · optional

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

Show nested fields

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

currentPlan · object · required

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

activeLocations · integer · required

The number of ACTIVE locations the tenant holds.

nextPlan · object · optional

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

enterpriseOffer · object · optional

The published Enterprise offer, named when no active plan covers the tenant's active location count.

Show nested fields

The published Enterprise offer, named when no active plan covers the tenant's active location count.

minLocations · integer · required

The smallest number of locations the offer covers.

fromMonthlyPriceCents · integer · int64 · required

The monthly price from which the offer starts, in euro cents.

extraLocationPriceCents · integer · int64 · required

The monthly price of each location beyond `minLocations`, in euro cents.

contactEmail · string · optional

The address to write to about a larger plan or an individual contract.

Raw JSON Schema

application/problem+json

{
  "type": "object",
  "description": "An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.",
  "properties": {
    "type": {
      "type": "string",
      "description": "A URN identifying the problem kind, one per `code`.",
      "example": "urn:qms:problem:location_not_found"
    },
    "title": {
      "type": "string",
      "description": "A fixed English summary of the problem kind.",
      "example": "Location Not Found"
    },
    "status": {
      "type": "integer",
      "description": "The HTTP status code, repeated in the body.",
      "example": 404
    },
    "code": {
      "type": "string",
      "description": "The published slug this surface's error vocabulary uses.",
      "example": "location_not_found"
    },
    "detail": {
      "type": "string",
      "description": "An English explanation of this occurrence.",
      "example": "No location was found for this identifier."
    },
    "errors": {
      "type": "array",
      "description": "One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.",
      "items": {
        "type": "object",
        "description": "One offending field of a 400 field-validation refusal.",
        "properties": {
          "field": {
            "type": "string",
            "description": "The member as THIS document spells it, which is not always what the same field is called inside the system.",
            "example": "defaultLocale"
          },
          "code": {
            "type": "string",
            "description": "The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`.\n\nThree of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.",
            "example": "invalid_locale"
          }
        },
        "required": [
          "field",
          "code"
        ]
      }
    },
    "blockers": {
      "type": "array",
      "description": "One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.",
      "items": {
        "type": "object",
        "description": "One non-zero blocking category of a 409 refusal, and how many things it counted.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.",
            "enum": [
              "LOCATION",
              "TICKET",
              "APPOINTMENT",
              "TEMPLATE",
              "OPERATOR"
            ],
            "example": "TICKET"
          },
          "count": {
            "type": "integer",
            "description": "How many of them there are. Always greater than zero.",
            "example": 3
          }
        },
        "required": [
          "kind",
          "count"
        ]
      }
    },
    "checkCode": {
      "type": "string",
      "description": "The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.",
      "example": "unreachable"
    },
    "planLimit": {
      "type": "object",
      "description": "What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.",
      "properties": {
        "currentPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "activeLocations": {
          "type": "integer",
          "description": "The number of ACTIVE locations the tenant holds.",
          "example": 3
        },
        "nextPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "enterpriseOffer": {
          "type": "object",
          "description": "The published Enterprise offer, named when no active plan covers the tenant's active location count.",
          "properties": {
            "minLocations": {
              "type": "integer",
              "description": "The smallest number of locations the offer covers.",
              "example": 8
            },
            "fromMonthlyPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price from which the offer starts, in euro cents.",
              "example": 27900
            },
            "extraLocationPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price of each location beyond `minLocations`, in euro cents.",
              "example": 2900
            }
          },
          "required": [
            "minLocations",
            "fromMonthlyPriceCents",
            "extraLocationPriceCents"
          ]
        },
        "contactEmail": {
          "type": "string",
          "description": "The address to write to about a larger plan or an individual contract.",
          "example": "sales@example.com"
        }
      },
      "required": [
        "currentPlan",
        "activeLocations"
      ]
    }
  },
  "required": [
    "type",
    "title",
    "status",
    "code",
    "detail"
  ],
  "additionalProperties": false
}

403 — The operation was refused before anything was read or written. Two codes share this status: `insufficient_scope` when the credential's scope set does not admit the operation at all, and `insufficient_authority` when the scope set admits it but the user who issued the credential is a location manager and the operation requires a tenant administrator. The scope check runs first, so it displaces the authority refusal whenever both apply, and widening the scopes never lifts the authority refusal. Branch on `code`, never on the status alone.

403 · insufficientScope
{
  "type": "urn:qms:problem:insufficient_scope",
  "title": "Insufficient Scope",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "The API credential does not reach this operation."
}
403 · insufficientAuthority
{
  "type": "urn:qms:problem:insufficient_authority",
  "title": "Insufficient Authority",
  "status": 403,
  "code": "insufficient_authority",
  "detail": "The API credential's role does not reach this operation."
}
403 response schema

An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.

type · string · required

A URN identifying the problem kind, one per `code`.

title · string · required

A fixed English summary of the problem kind.

status · integer · required

The HTTP status code, repeated in the body.

code · string · required

The published slug this surface's error vocabulary uses.

detail · string · required

An English explanation of this occurrence.

errors · array · optional

One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.

Show nested fields

One offending field of a 400 field-validation refusal.

field · string · required

The member as THIS document spells it, which is not always what the same field is called inside the system.

code · string · required

The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`. Three of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.

blockers · array · optional

One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.

Show nested fields

One non-zero blocking category of a 409 refusal, and how many things it counted.

kind · string · required

What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.

Allowed values: "LOCATION", "TICKET", "APPOINTMENT", "TEMPLATE", "OPERATOR"

count · integer · required

How many of them there are. Always greater than zero.

checkCode · string · optional

The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.

planLimit · object · optional

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

Show nested fields

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

currentPlan · object · required

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

activeLocations · integer · required

The number of ACTIVE locations the tenant holds.

nextPlan · object · optional

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

enterpriseOffer · object · optional

The published Enterprise offer, named when no active plan covers the tenant's active location count.

Show nested fields

The published Enterprise offer, named when no active plan covers the tenant's active location count.

minLocations · integer · required

The smallest number of locations the offer covers.

fromMonthlyPriceCents · integer · int64 · required

The monthly price from which the offer starts, in euro cents.

extraLocationPriceCents · integer · int64 · required

The monthly price of each location beyond `minLocations`, in euro cents.

contactEmail · string · optional

The address to write to about a larger plan or an individual contract.

Raw JSON Schema

application/problem+json

{
  "type": "object",
  "description": "An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.",
  "properties": {
    "type": {
      "type": "string",
      "description": "A URN identifying the problem kind, one per `code`.",
      "example": "urn:qms:problem:location_not_found"
    },
    "title": {
      "type": "string",
      "description": "A fixed English summary of the problem kind.",
      "example": "Location Not Found"
    },
    "status": {
      "type": "integer",
      "description": "The HTTP status code, repeated in the body.",
      "example": 404
    },
    "code": {
      "type": "string",
      "description": "The published slug this surface's error vocabulary uses.",
      "example": "location_not_found"
    },
    "detail": {
      "type": "string",
      "description": "An English explanation of this occurrence.",
      "example": "No location was found for this identifier."
    },
    "errors": {
      "type": "array",
      "description": "One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.",
      "items": {
        "type": "object",
        "description": "One offending field of a 400 field-validation refusal.",
        "properties": {
          "field": {
            "type": "string",
            "description": "The member as THIS document spells it, which is not always what the same field is called inside the system.",
            "example": "defaultLocale"
          },
          "code": {
            "type": "string",
            "description": "The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`.\n\nThree of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.",
            "example": "invalid_locale"
          }
        },
        "required": [
          "field",
          "code"
        ]
      }
    },
    "blockers": {
      "type": "array",
      "description": "One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.",
      "items": {
        "type": "object",
        "description": "One non-zero blocking category of a 409 refusal, and how many things it counted.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.",
            "enum": [
              "LOCATION",
              "TICKET",
              "APPOINTMENT",
              "TEMPLATE",
              "OPERATOR"
            ],
            "example": "TICKET"
          },
          "count": {
            "type": "integer",
            "description": "How many of them there are. Always greater than zero.",
            "example": 3
          }
        },
        "required": [
          "kind",
          "count"
        ]
      }
    },
    "checkCode": {
      "type": "string",
      "description": "The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.",
      "example": "unreachable"
    },
    "planLimit": {
      "type": "object",
      "description": "What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.",
      "properties": {
        "currentPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "activeLocations": {
          "type": "integer",
          "description": "The number of ACTIVE locations the tenant holds.",
          "example": 3
        },
        "nextPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "enterpriseOffer": {
          "type": "object",
          "description": "The published Enterprise offer, named when no active plan covers the tenant's active location count.",
          "properties": {
            "minLocations": {
              "type": "integer",
              "description": "The smallest number of locations the offer covers.",
              "example": 8
            },
            "fromMonthlyPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price from which the offer starts, in euro cents.",
              "example": 27900
            },
            "extraLocationPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price of each location beyond `minLocations`, in euro cents.",
              "example": 2900
            }
          },
          "required": [
            "minLocations",
            "fromMonthlyPriceCents",
            "extraLocationPriceCents"
          ]
        },
        "contactEmail": {
          "type": "string",
          "description": "The address to write to about a larger plan or an individual contract.",
          "example": "sales@example.com"
        }
      },
      "required": [
        "currentPlan",
        "activeLocations"
      ]
    }
  },
  "required": [
    "type",
    "title",
    "status",
    "code",
    "detail"
  ],
  "additionalProperties": false
}

404 — The apply named something this credential cannot see. Two codes share this status: `location_not_found` for the path's location, and `template_not_found` for the body's `templateId`. The location is resolved first, so a location outside the credential's reach never reveals whether the named template exists. Branch on `code`.

404 · locationNotFound
{
  "type": "urn:qms:problem:location_not_found",
  "title": "Location Not Found",
  "status": 404,
  "code": "location_not_found",
  "detail": "No location was found for this identifier."
}
404 · templateNotFound
{
  "type": "urn:qms:problem:template_not_found",
  "title": "Template Not Found",
  "status": 404,
  "code": "template_not_found",
  "detail": "No location template was found for this identifier."
}
404 response schema

An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.

type · string · required

A URN identifying the problem kind, one per `code`.

title · string · required

A fixed English summary of the problem kind.

status · integer · required

The HTTP status code, repeated in the body.

code · string · required

The published slug this surface's error vocabulary uses.

detail · string · required

An English explanation of this occurrence.

errors · array · optional

One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.

Show nested fields

One offending field of a 400 field-validation refusal.

field · string · required

The member as THIS document spells it, which is not always what the same field is called inside the system.

code · string · required

The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`. Three of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.

blockers · array · optional

One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.

Show nested fields

One non-zero blocking category of a 409 refusal, and how many things it counted.

kind · string · required

What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.

Allowed values: "LOCATION", "TICKET", "APPOINTMENT", "TEMPLATE", "OPERATOR"

count · integer · required

How many of them there are. Always greater than zero.

checkCode · string · optional

The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.

planLimit · object · optional

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

Show nested fields

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

currentPlan · object · required

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

activeLocations · integer · required

The number of ACTIVE locations the tenant holds.

nextPlan · object · optional

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

enterpriseOffer · object · optional

The published Enterprise offer, named when no active plan covers the tenant's active location count.

Show nested fields

The published Enterprise offer, named when no active plan covers the tenant's active location count.

minLocations · integer · required

The smallest number of locations the offer covers.

fromMonthlyPriceCents · integer · int64 · required

The monthly price from which the offer starts, in euro cents.

extraLocationPriceCents · integer · int64 · required

The monthly price of each location beyond `minLocations`, in euro cents.

contactEmail · string · optional

The address to write to about a larger plan or an individual contract.

Raw JSON Schema

application/problem+json

{
  "type": "object",
  "description": "An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.",
  "properties": {
    "type": {
      "type": "string",
      "description": "A URN identifying the problem kind, one per `code`.",
      "example": "urn:qms:problem:location_not_found"
    },
    "title": {
      "type": "string",
      "description": "A fixed English summary of the problem kind.",
      "example": "Location Not Found"
    },
    "status": {
      "type": "integer",
      "description": "The HTTP status code, repeated in the body.",
      "example": 404
    },
    "code": {
      "type": "string",
      "description": "The published slug this surface's error vocabulary uses.",
      "example": "location_not_found"
    },
    "detail": {
      "type": "string",
      "description": "An English explanation of this occurrence.",
      "example": "No location was found for this identifier."
    },
    "errors": {
      "type": "array",
      "description": "One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.",
      "items": {
        "type": "object",
        "description": "One offending field of a 400 field-validation refusal.",
        "properties": {
          "field": {
            "type": "string",
            "description": "The member as THIS document spells it, which is not always what the same field is called inside the system.",
            "example": "defaultLocale"
          },
          "code": {
            "type": "string",
            "description": "The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`.\n\nThree of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.",
            "example": "invalid_locale"
          }
        },
        "required": [
          "field",
          "code"
        ]
      }
    },
    "blockers": {
      "type": "array",
      "description": "One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.",
      "items": {
        "type": "object",
        "description": "One non-zero blocking category of a 409 refusal, and how many things it counted.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.",
            "enum": [
              "LOCATION",
              "TICKET",
              "APPOINTMENT",
              "TEMPLATE",
              "OPERATOR"
            ],
            "example": "TICKET"
          },
          "count": {
            "type": "integer",
            "description": "How many of them there are. Always greater than zero.",
            "example": 3
          }
        },
        "required": [
          "kind",
          "count"
        ]
      }
    },
    "checkCode": {
      "type": "string",
      "description": "The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.",
      "example": "unreachable"
    },
    "planLimit": {
      "type": "object",
      "description": "What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.",
      "properties": {
        "currentPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "activeLocations": {
          "type": "integer",
          "description": "The number of ACTIVE locations the tenant holds.",
          "example": 3
        },
        "nextPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "enterpriseOffer": {
          "type": "object",
          "description": "The published Enterprise offer, named when no active plan covers the tenant's active location count.",
          "properties": {
            "minLocations": {
              "type": "integer",
              "description": "The smallest number of locations the offer covers.",
              "example": 8
            },
            "fromMonthlyPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price from which the offer starts, in euro cents.",
              "example": 27900
            },
            "extraLocationPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price of each location beyond `minLocations`, in euro cents.",
              "example": 2900
            }
          },
          "required": [
            "minLocations",
            "fromMonthlyPriceCents",
            "extraLocationPriceCents"
          ]
        },
        "contactEmail": {
          "type": "string",
          "description": "The address to write to about a larger plan or an individual contract.",
          "example": "sales@example.com"
        }
      },
      "required": [
        "currentPlan",
        "activeLocations"
      ]
    }
  },
  "required": [
    "type",
    "title",
    "status",
    "code",
    "detail"
  ],
  "additionalProperties": false
}

409 — A template apply refused because the overwrite would drop a service that still holds a non-terminal ticket, with one `blockers` entry counting those tickets. Nothing is written. The only code at this status on the apply.

409 · Example
{
  "type": "urn:qms:problem:template_apply_blocked",
  "title": "Template Apply Blocked",
  "status": 409,
  "code": "template_apply_blocked",
  "detail": "The template cannot be applied while something still depends on the service it would drop.",
  "blockers": [
    {
      "kind": "TICKET",
      "count": 3
    }
  ]
}
409 response schema

An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.

type · string · required

A URN identifying the problem kind, one per `code`.

title · string · required

A fixed English summary of the problem kind.

status · integer · required

The HTTP status code, repeated in the body.

code · string · required

The published slug this surface's error vocabulary uses.

detail · string · required

An English explanation of this occurrence.

errors · array · optional

One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.

Show nested fields

One offending field of a 400 field-validation refusal.

field · string · required

The member as THIS document spells it, which is not always what the same field is called inside the system.

code · string · required

The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`. Three of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.

blockers · array · optional

One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.

Show nested fields

One non-zero blocking category of a 409 refusal, and how many things it counted.

kind · string · required

What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.

Allowed values: "LOCATION", "TICKET", "APPOINTMENT", "TEMPLATE", "OPERATOR"

count · integer · required

How many of them there are. Always greater than zero.

checkCode · string · optional

The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.

planLimit · object · optional

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

Show nested fields

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

currentPlan · object · required

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

activeLocations · integer · required

The number of ACTIVE locations the tenant holds.

nextPlan · object · optional

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

enterpriseOffer · object · optional

The published Enterprise offer, named when no active plan covers the tenant's active location count.

Show nested fields

The published Enterprise offer, named when no active plan covers the tenant's active location count.

minLocations · integer · required

The smallest number of locations the offer covers.

fromMonthlyPriceCents · integer · int64 · required

The monthly price from which the offer starts, in euro cents.

extraLocationPriceCents · integer · int64 · required

The monthly price of each location beyond `minLocations`, in euro cents.

contactEmail · string · optional

The address to write to about a larger plan or an individual contract.

Raw JSON Schema

application/problem+json

{
  "type": "object",
  "description": "An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.",
  "properties": {
    "type": {
      "type": "string",
      "description": "A URN identifying the problem kind, one per `code`.",
      "example": "urn:qms:problem:location_not_found"
    },
    "title": {
      "type": "string",
      "description": "A fixed English summary of the problem kind.",
      "example": "Location Not Found"
    },
    "status": {
      "type": "integer",
      "description": "The HTTP status code, repeated in the body.",
      "example": 404
    },
    "code": {
      "type": "string",
      "description": "The published slug this surface's error vocabulary uses.",
      "example": "location_not_found"
    },
    "detail": {
      "type": "string",
      "description": "An English explanation of this occurrence.",
      "example": "No location was found for this identifier."
    },
    "errors": {
      "type": "array",
      "description": "One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.",
      "items": {
        "type": "object",
        "description": "One offending field of a 400 field-validation refusal.",
        "properties": {
          "field": {
            "type": "string",
            "description": "The member as THIS document spells it, which is not always what the same field is called inside the system.",
            "example": "defaultLocale"
          },
          "code": {
            "type": "string",
            "description": "The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`.\n\nThree of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.",
            "example": "invalid_locale"
          }
        },
        "required": [
          "field",
          "code"
        ]
      }
    },
    "blockers": {
      "type": "array",
      "description": "One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.",
      "items": {
        "type": "object",
        "description": "One non-zero blocking category of a 409 refusal, and how many things it counted.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.",
            "enum": [
              "LOCATION",
              "TICKET",
              "APPOINTMENT",
              "TEMPLATE",
              "OPERATOR"
            ],
            "example": "TICKET"
          },
          "count": {
            "type": "integer",
            "description": "How many of them there are. Always greater than zero.",
            "example": 3
          }
        },
        "required": [
          "kind",
          "count"
        ]
      }
    },
    "checkCode": {
      "type": "string",
      "description": "The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.",
      "example": "unreachable"
    },
    "planLimit": {
      "type": "object",
      "description": "What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.",
      "properties": {
        "currentPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "activeLocations": {
          "type": "integer",
          "description": "The number of ACTIVE locations the tenant holds.",
          "example": 3
        },
        "nextPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "enterpriseOffer": {
          "type": "object",
          "description": "The published Enterprise offer, named when no active plan covers the tenant's active location count.",
          "properties": {
            "minLocations": {
              "type": "integer",
              "description": "The smallest number of locations the offer covers.",
              "example": 8
            },
            "fromMonthlyPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price from which the offer starts, in euro cents.",
              "example": 27900
            },
            "extraLocationPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price of each location beyond `minLocations`, in euro cents.",
              "example": 2900
            }
          },
          "required": [
            "minLocations",
            "fromMonthlyPriceCents",
            "extraLocationPriceCents"
          ]
        },
        "contactEmail": {
          "type": "string",
          "description": "The address to write to about a larger plan or an individual contract.",
          "example": "sales@example.com"
        }
      },
      "required": [
        "currentPlan",
        "activeLocations"
      ]
    }
  },
  "required": [
    "type",
    "title",
    "status",
    "code",
    "detail"
  ],
  "additionalProperties": false
}

500 — The request could not be processed. The body names no internal detail. A retry is safe on every read described here; on a create, an edit or a lifecycle transition a retry may or may not repeat a change that already committed, so read the resource back before retrying one of those.

500 · Example
{
  "type": "urn:qms:problem:internal_error",
  "title": "Internal Server Error",
  "status": 500,
  "code": "internal_error",
  "detail": "The request could not be processed."
}
500 response schema

An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.

type · string · required

A URN identifying the problem kind, one per `code`.

title · string · required

A fixed English summary of the problem kind.

status · integer · required

The HTTP status code, repeated in the body.

code · string · required

The published slug this surface's error vocabulary uses.

detail · string · required

An English explanation of this occurrence.

errors · array · optional

One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.

Show nested fields

One offending field of a 400 field-validation refusal.

field · string · required

The member as THIS document spells it, which is not always what the same field is called inside the system.

code · string · required

The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`. Three of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.

blockers · array · optional

One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.

Show nested fields

One non-zero blocking category of a 409 refusal, and how many things it counted.

kind · string · required

What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.

Allowed values: "LOCATION", "TICKET", "APPOINTMENT", "TEMPLATE", "OPERATOR"

count · integer · required

How many of them there are. Always greater than zero.

checkCode · string · optional

The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.

planLimit · object · optional

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

Show nested fields

What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.

currentPlan · object · required

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

activeLocations · integer · required

The number of ACTIVE locations the tenant holds.

nextPlan · object · optional

A plan named by a `plan_location_limit_reached` refusal.

Show nested fields

A plan named by a `plan_location_limit_reached` refusal.

planId · string · required

The plan's stable identifier.

displayName · string · required

The plan's name, not translated.

maxLocations · integer · required

The most ACTIVE locations the plan covers.

enterpriseOffer · object · optional

The published Enterprise offer, named when no active plan covers the tenant's active location count.

Show nested fields

The published Enterprise offer, named when no active plan covers the tenant's active location count.

minLocations · integer · required

The smallest number of locations the offer covers.

fromMonthlyPriceCents · integer · int64 · required

The monthly price from which the offer starts, in euro cents.

extraLocationPriceCents · integer · int64 · required

The monthly price of each location beyond `minLocations`, in euro cents.

contactEmail · string · optional

The address to write to about a larger plan or an individual contract.

Raw JSON Schema

application/problem+json

{
  "type": "object",
  "description": "An RFC 9457 problem document: `type`, `title`, `status`, `code` and `detail`, every one of those five always present. `errors`, `blockers`, `checkCode` and `planLimit` are the exceptions — each is scoped to one family of refusal and is ABSENT on every other document, which is why none is required below. `code` is the stable, machine-readable member; branch on it rather than on `title` or `detail`, which are English prose meant for a developer reading a log.",
  "properties": {
    "type": {
      "type": "string",
      "description": "A URN identifying the problem kind, one per `code`.",
      "example": "urn:qms:problem:location_not_found"
    },
    "title": {
      "type": "string",
      "description": "A fixed English summary of the problem kind.",
      "example": "Location Not Found"
    },
    "status": {
      "type": "integer",
      "description": "The HTTP status code, repeated in the body.",
      "example": 404
    },
    "code": {
      "type": "string",
      "description": "The published slug this surface's error vocabulary uses.",
      "example": "location_not_found"
    },
    "detail": {
      "type": "string",
      "description": "An English explanation of this occurrence.",
      "example": "No location was found for this identifier."
    },
    "errors": {
      "type": "array",
      "description": "One entry per offending field of a 400 field-validation refusal. Present on those alone, and ABSENT — not null, not an empty array — on every other problem document, including a field-validation refusal that can name no single field. Sorted by `field`, so two refusals over the same body produce the same document.",
      "items": {
        "type": "object",
        "description": "One offending field of a 400 field-validation refusal.",
        "properties": {
          "field": {
            "type": "string",
            "description": "The member as THIS document spells it, which is not always what the same field is called inside the system.",
            "example": "defaultLocale"
          },
          "code": {
            "type": "string",
            "description": "The published reason slug. Typed as a plain string rather than an enumeration, because the set is not closed — an integrity backstop can report a slug outside the published list. The values in use today are `required`, `too_long`, `invalid_format`, `invalid_timezone`, `invalid_locale`, `invalid_country`, `name_taken`, `code_taken`, `display_prefix_taken`, `out_of_range`, `not_in_catalogue`, `archived`, `duplicate`, `not_found`, `not_linked_to_location`, `inactive`, `language_not_in_catalogue`, `not_writable`, `password_too_short` and `password_breached`.\n\nThree of them are worth a sentence. `invalid_format` covers a value whose SHAPE is wrong — a window code that is not alphanumeric, a time that is not `HH:MM` — and, on the operating hours, the one fault that is a relation rather than a shape: a `closesAt` that is not after its `opensAt`, where both values are well formed and it is their ORDER that is refused. It also covers a member whose JSON type cannot be read — a string where a boolean belongs — reported under its path, e.g. `operatingHours[0].closed`. `not_found` means the member names something this tenant does not hold; it is the same word as the document-level `code` that answers an unserved path, at a different level and never with that status. `not_writable` is the operator invite, the operator profile edit and the visit-reason replace's own: a body member the request type declares no slot for, refused by NAME whether or not its value would have changed anything. `password_too_short` and `password_breached` are the operator create's own, under `initialPassword`.",
            "example": "invalid_locale"
          }
        },
        "required": [
          "field",
          "code"
        ]
      }
    },
    "blockers": {
      "type": "array",
      "description": "One entry per non-zero blocking category of a 409 refusal that names what blocks it. Present on those alone, and ABSENT on every other problem document. A category with nothing to report is absent rather than present with a count of 0.",
      "items": {
        "type": "object",
        "description": "One non-zero blocking category of a 409 refusal, and how many things it counted.",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What kind of thing still depends on the entry — or, on a configuration refusal, on what the write would take away.",
            "enum": [
              "LOCATION",
              "TICKET",
              "APPOINTMENT",
              "TEMPLATE",
              "OPERATOR"
            ],
            "example": "TICKET"
          },
          "count": {
            "type": "integer",
            "description": "How many of them there are. Always greater than zero.",
            "example": 3
          }
        },
        "required": [
          "kind",
          "count"
        ]
      }
    },
    "checkCode": {
      "type": "string",
      "description": "The discovery-failure code of a `connection_check_failed` refusal: `unreachable`, `timeout`, `not_https`, `private_address`, `issuer_mismatch`, `missing_endpoint` or `invalid_document`. Present on that refusal alone, and ABSENT on every other problem document.",
      "example": "unreachable"
    },
    "planLimit": {
      "type": "object",
      "description": "What a `plan_location_limit_reached` refusal reports. Present on that refusal alone, and ABSENT on every other problem document. Exactly one of `nextPlan` and `enterpriseOffer` is present: `nextPlan` when an active plan above the active location count exists, `enterpriseOffer` when none does. `contactEmail` is absent when no contact address is configured.",
      "properties": {
        "currentPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "activeLocations": {
          "type": "integer",
          "description": "The number of ACTIVE locations the tenant holds.",
          "example": 3
        },
        "nextPlan": {
          "type": "object",
          "description": "A plan named by a `plan_location_limit_reached` refusal.",
          "properties": {
            "planId": {
              "type": "string",
              "description": "The plan's stable identifier.",
              "example": "business"
            },
            "displayName": {
              "type": "string",
              "description": "The plan's name, not translated.",
              "example": "Business"
            },
            "maxLocations": {
              "type": "integer",
              "description": "The most ACTIVE locations the plan covers.",
              "example": 5
            }
          },
          "required": [
            "planId",
            "displayName",
            "maxLocations"
          ]
        },
        "enterpriseOffer": {
          "type": "object",
          "description": "The published Enterprise offer, named when no active plan covers the tenant's active location count.",
          "properties": {
            "minLocations": {
              "type": "integer",
              "description": "The smallest number of locations the offer covers.",
              "example": 8
            },
            "fromMonthlyPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price from which the offer starts, in euro cents.",
              "example": 27900
            },
            "extraLocationPriceCents": {
              "type": "integer",
              "format": "int64",
              "description": "The monthly price of each location beyond `minLocations`, in euro cents.",
              "example": 2900
            }
          },
          "required": [
            "minLocations",
            "fromMonthlyPriceCents",
            "extraLocationPriceCents"
          ]
        },
        "contactEmail": {
          "type": "string",
          "description": "The address to write to about a larger plan or an individual contract.",
          "example": "sales@example.com"
        }
      },
      "required": [
        "currentPlan",
        "activeLocations"
      ]
    }
  },
  "required": [
    "type",
    "title",
    "status",
    "code",
    "detail"
  ],
  "additionalProperties": false
}