Write a location's queue configuration
A partial write: a member absent from the body is left alone, and a member present replaces what is stored. The answer is the whole configuration document as it stands after the write, exactly as the read returns it.
Behavior and permissions
The three collections are not written the same way. services REPLACES what the location holds — a service not named in the array is removed. operatingHours replaces the whole week and must name all seven days: an array that does not is refused as an errors entry naming operatingHours with code required, so no day is ever removed by omission. windows UPSERTS: an entry is merged onto the window carrying the same id, a id the location does not hold yet creates a window ACTIVE, and a window not named is left untouched rather than deleted. Retiring a window is therefore an entry naming it with status INACTIVE, never its absence.
Nothing is written on any refusal, whichever member caused it: the field rules, the two state guards and the template-link guard are all evaluated before the first group is written.
template is not a member of the body. A location's link is moved by the apply-template operation and cut by this operation's detach, never set here directly.
detach is admission and nothing else. On a location linked to a template, a body that writes any captured field without detach true is refused 409 location_linked_to_template; with it, the write proceeds and the link is cut as part of writing. A body carrying detach true AND no captured field writes nothing, so it answers 200 with the link still in place — detach alone does not unlink.
Requires a credential whose reach includes the location. Both a tenant administrator's and a location manager's credential reach this operation; a location outside the credential's reach is the 404, never a 403.
Authorization · Example request · Parameters · Request body · Responses
PATCH/api/integration/v1/locations/{locationId}/configuration
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 --request PATCH "$QMS_BASE_URL/api/integration/v1/locations/22222222-2222-4222-8222-222222222222/configuration" \
--header "Authorization: Api-Key $QMS_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"services": [
{
"id": "77777777-7777-4777-8777-777777777777",
"defaultDurationMinutes": 20
}
],
"windows": [
{
"id": "A1",
"floor": "Ground",
"status": "ACTIVE"
}
],
"walkInNoShowGraceSeconds": 180,
"detach": true
}'Parameters
| Name | In | Required | Schema |
|---|---|---|---|
locationId | path | yes | {"type":"string"} |
locationId: The location's opaque identifier.
Request body
{
"services": [
{
"id": "77777777-7777-4777-8777-777777777777",
"defaultDurationMinutes": 20
}
],
"windows": [
{
"id": "A1",
"floor": "Ground",
"status": "ACTIVE"
}
],
"walkInNoShowGraceSeconds": 180,
"detach": true
}Request schema
The configuration write body. Every member is optional; one left out is left alone, and one sent as JSON `null` is indistinguishable from an absent one, so no member can be cleared through this operation. `services` and `operatingHours` replace what the location holds. `windows` upserts by `id` and deletes nothing. `template` is not a member: see `detach`.
services · array · optional
The services the location is to offer, replacing the current set. A service the location holds today and this array does not name is removed — which is refused while it still holds open work.
Show nested fields
One entry of the `services` array.
id · string · required
The catalogue service to offer. It must name an ACTIVE service of this tenant's catalogue — one that does not is answered `not_in_catalogue`, an archived one `archived`, and the same id twice in the array `duplicate`.
defaultDurationMinutes · integer · optional
A per-location duration override for the service, 1 to 480 minutes. On the location configuration write it is this location's own duration; omitted, a service the location already offers keeps the duration it has, and a service being added takes the catalogue default. On a template's `configuration` the same member captures an override for every location the template is applied to; omitted, the template captures none, and each such location takes the catalogue default. This entry shape is shared by both bodies, which is why the two readings sit together here.
windows · array · optional
Windows to create or merge, by `id`. A window the location holds and this array does not name is left exactly as it is; retiring one is an entry naming it with `status` `INACTIVE`.
Show nested fields
One entry of the `windows` array, merged onto the window carrying the same `id`.
id · string · required
The window's short code, 1 to 20 alphanumeric characters, and the key the entry is merged by. A value of another shape is answered `invalid_format`; the same code twice in the array, `duplicate`.
floor · string · optional
A floor label of at most 20 characters. Omitted, an existing window's label is left as it is.
status · string · optional
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 · optional
The whole weekly schedule, replacing the current one. All seven days must be present when this member is sent; a missing day is answered as an `errors` entry naming `operatingHours` with code `required`.
Show nested fields
One entry of the `operatingHours` array. On a closed day `opensAt` and `closesAt` are not read and may be omitted.
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 · optional
24-hour `HH:MM`. Required on a day whose `closed` is false, and null or omitted on a day whose `closed` is true.
closesAt · string | null · optional
24-hour `HH:MM`, strictly after `opensAt`. Required on a day whose `closed` is false, and null or omitted on a day whose `closed` is true.
closed · boolean · optional
Whether the location is shut that day. Omitted, the day is treated as open.
qrEntryMode · string · optional
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 · optional
Between 30 and 600 seconds; outside that it is answered `out_of_range`.
appointmentNoShowGraceSeconds · integer · optional
Between 60 and 3600 seconds; outside that it is answered `out_of_range`.
operatorNameVisible · boolean · optional
detach · boolean · optional
The caller's acknowledgement that this write may break the location's template link. It admits the write and does nothing else: on a linked location a body writing any captured field without it is refused `location_linked_to_template`, and a body carrying it with no captured field writes nothing and leaves the link in place.
Raw JSON Schema
application/json
{
"type": "object",
"description": "The configuration write body. Every member is optional; one left out is left alone, and one sent as JSON `null` is indistinguishable from an absent one, so no member can be cleared through this operation.\n\n`services` and `operatingHours` replace what the location holds. `windows` upserts by `id` and deletes nothing. `template` is not a member: see `detach`.",
"properties": {
"services": {
"type": "array",
"description": "The services the location is to offer, replacing the current set. A service the location holds today and this array does not name is removed — which is refused while it still holds open work.",
"items": {
"type": "object",
"description": "One entry of the `services` array.",
"properties": {
"id": {
"type": "string",
"description": "The catalogue service to offer. It must name an ACTIVE service of this tenant's catalogue — one that does not is answered `not_in_catalogue`, an archived one `archived`, and the same id twice in the array `duplicate`.",
"example": "77777777-7777-4777-8777-777777777777"
},
"defaultDurationMinutes": {
"type": "integer",
"minimum": 1,
"maximum": 480,
"description": "A per-location duration override for the service, 1 to 480 minutes.\n\nOn the location configuration write it is this location's own duration; omitted, a service the location already offers keeps the duration it has, and a service being added takes the catalogue default. On a template's `configuration` the same member captures an override for every location the template is applied to; omitted, the template captures none, and each such location takes the catalogue default. This entry shape is shared by both bodies, which is why the two readings sit together here.",
"example": 20
}
},
"required": [
"id"
]
}
},
"windows": {
"type": "array",
"description": "Windows to create or merge, by `id`. A window the location holds and this array does not name is left exactly as it is; retiring one is an entry naming it with `status` `INACTIVE`.",
"items": {
"type": "object",
"description": "One entry of the `windows` array, merged onto the window carrying the same `id`.",
"properties": {
"id": {
"type": "string",
"pattern": "^[A-Za-z0-9]{1,20}$",
"description": "The window's short code, 1 to 20 alphanumeric characters, and the key the entry is merged by. A value of another shape is answered `invalid_format`; the same code twice in the array, `duplicate`.",
"example": "A1"
},
"floor": {
"type": "string",
"maxLength": 20,
"description": "A floor label of at most 20 characters. Omitted, an existing window's label is left as it is.",
"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"
]
}
},
"operatingHours": {
"type": "array",
"description": "The whole weekly schedule, replacing the current one. All seven days must be present when this member is sent; a missing day is answered as an `errors` entry naming `operatingHours` with code `required`.",
"items": {
"type": "object",
"description": "One entry of the `operatingHours` array. On a closed day `opensAt` and `closesAt` are not read and may be omitted.",
"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"
],
"pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
"description": "24-hour `HH:MM`. Required on a day whose `closed` is false, and null or omitted on a day whose `closed` is true.",
"example": "09:00"
},
"closesAt": {
"type": [
"string",
"null"
],
"pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
"description": "24-hour `HH:MM`, strictly after `opensAt`. Required on a day whose `closed` is false, and null or omitted on a day whose `closed` is true.",
"example": "18:00"
},
"closed": {
"type": "boolean",
"description": "Whether the location is shut that day. Omitted, the day is treated as open.",
"example": false
}
},
"required": [
"day"
]
}
},
"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",
"minimum": 30,
"maximum": 600,
"description": "Between 30 and 600 seconds; outside that it is answered `out_of_range`.",
"example": 180
},
"appointmentNoShowGraceSeconds": {
"type": "integer",
"minimum": 60,
"maximum": 3600,
"description": "Between 60 and 3600 seconds; outside that it is answered `out_of_range`.",
"example": 900
},
"operatorNameVisible": {
"type": "boolean",
"example": true
},
"detach": {
"type": "boolean",
"description": "The caller's acknowledgement that this write may break the location's template link. It admits the write and does nothing else: on a linked location a body writing any captured field without it is refused `location_linked_to_template`, and a body carrying it with no captured field writes nothing and leaves the link in place.",
"example": true
}
}
}Responses
200 — The location's queue configuration after the write.
{
"template": null,
"services": [
{
"id": "77777777-7777-4777-8777-777777777777",
"defaultDurationMinutes": 20
}
],
"windows": [
{
"id": "A1",
"floor": "Ground",
"status": "ACTIVE"
}
],
"operatingHours": [
{
"day": "MON",
"opensAt": "09:00",
"closesAt": "18:00",
"closed": false
},
{
"day": "TUE",
"opensAt": "09:00",
"closesAt": "18:00",
"closed": false
},
{
"day": "WED",
"opensAt": "09:00",
"closesAt": "18:00",
"closed": false
},
{
"day": "THU",
"opensAt": "09:00",
"closesAt": "18:00",
"closed": false
},
{
"day": "FRI",
"opensAt": "09:00",
"closesAt": "18:00",
"closed": false
},
{
"day": "SAT",
"opensAt": null,
"closesAt": null,
"closed": true
},
{
"day": "SUN",
"opensAt": null,
"closesAt": null,
"closed": true
}
],
"qrEntryMode": "SINGLE",
"walkInNoShowGraceSeconds": 180,
"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`.
{
"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.
{
"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 authenticated credential does not carry a scope that admits this operation. The scope check runs before every other admission check, so this refusal displaces `insufficient_authority` on an operation that requires both.
{
"type": "urn:qms:problem:insufficient_scope",
"title": "Insufficient Scope",
"status": 403,
"code": "insufficient_scope",
"detail": "The API credential 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 — No location was found for this identifier. Outside the credential's reach, in another tenant and nonexistent are one answer, so that the existence of another tenant's data cannot be probed.
{
"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 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 — The configuration write was refused, and nothing was written. Three codes share this status: `location_linked_to_template` when the location is still provisioned from a template and the body carried no `detach` `true`; `service_removal_blocked` when the write would drop a service that still holds a non-terminal ticket or a future appointment, with one `blockers` entry per non-zero category; and `window_deactivation_blocked` when it would set a window `INACTIVE` while operators are still assigned to it, with one `blockers` entry counting them. The two state guards are evaluated before the link guard, so a linked location whose body would also strand open work is told about the work. Branch on `code`.
{
"type": "urn:qms:problem:location_linked_to_template",
"title": "Location Linked To Template",
"status": 409,
"code": "location_linked_to_template",
"detail": "The location is provisioned from a template; send detach true to write its configuration directly."
}{
"type": "urn:qms:problem:service_removal_blocked",
"title": "Service Removal Blocked",
"status": 409,
"code": "service_removal_blocked",
"detail": "A service cannot be removed while something still depends on it.",
"blockers": [
{
"kind": "TICKET",
"count": 3
}
]
}{
"type": "urn:qms:problem:window_deactivation_blocked",
"title": "Window Deactivation Blocked",
"status": 409,
"code": "window_deactivation_blocked",
"detail": "A window cannot be deactivated while an operator is still assigned to it.",
"blockers": [
{
"kind": "OPERATOR",
"count": 2
}
]
}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.
{
"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
}