Documentation
Booking
booking.locations
REST
ShippingPOST /api/v1/booking/locationsMCP tool
Livebooking.locationsExposed on: REST API · Shop MCP server · Claude connector · Dash (in-app copilot) · Zapier. Part of the Booking domain.
Operating contract
The other shops under the same business, with where each one is and whether it is taking bookings.
READ THIS BEFORE TELLING ANYBODY THE SHOP IS FULL. A customer who cannot be fitted in this week at one branch can often be fitted in at another twenty minutes away, and every other capability in this domain answers for ONE shop only.
bookable: false MEANS DO NOT SEND ANYONE THERE. That branch has online booking switched off or is not currently taking work, and offering it is sending a customer at a page that will not take them.
current: true marks the branch this call is about. Everything else in this registry — availability, services, deposits, the act of booking — answers for that one.
ONE ROW MEANS ONE LOCATION and there is nothing to choose between. Do not present a single branch as a choice.
TAKING A BOOKING AT ANOTHER BRANCH IS NOT POSSIBLE FROM HERE. Each branch is its own shop with its own calendar, catalog and prices; the customer goes to that branch's own booking page, or phones it.
Every branch is returned, so nothing is truncated.
Who may call it
- Permission
- NoneThe location picker on the public storefront at /book/<slug>. Every field returned is already printed on that branch's own public booking page.
- Plan
- Every planNo plan gate. Available on every Service VIN plan.
- Retries
naturalNaturally idempotent — running it twice leaves the same world as running it once. A retrying integration needs no key.- Rate class
readCounted against the read budget — the widest of the four.
Input
This capability takes no arguments.
Output
| Field | Type | Description |
|---|---|---|
| items | object[] | — |
| items[].slug | string | — |
| items[].name | string | — |
| items[].locality | string | null | — |
| items[].bookable | boolean | — |
| items[].current | boolean | — |
| total | number | — |
| multi_location | boolean | — |
Examples
Built from this capability's own schema — required fields and the ones carrying a default, and nothing invented. Paste one and it validates.
export SERVICEVIN_API_KEY=svk_live_…
curl -X POST https://www.servicevin.com/api/v1/booking/locations \
-H "Authorization: Bearer $SERVICEVIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'const res = await fetch("https://www.servicevin.com/api/v1/booking/locations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SERVICEVIN_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
// Success and failure are both envelopes. Switch on error.code, never
// on error.message — the codes are stable, the messages are for people.
const payload = await res.json();
if (!res.ok) throw new Error(payload.error.code);
const data = payload.data;import os, requests
res = requests.post(
"https://www.servicevin.com/api/v1/booking/locations",
headers={"Authorization": f"Bearer {os.environ['SERVICEVIN_API_KEY']}"},
json={},
timeout=30,
)
payload = res.json()
if not res.ok:
raise RuntimeError(payload["error"]["code"])
data = payload["data"]{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "booking.locations",
"arguments": {}
}
}Refusals
The four gates run in this order on every surface, and the order is not arbitrary — see Authentication.
| Status | Code | When |
|---|---|---|
| 404 | not_found | The id is unknown, or the feature is not enabled for this account. Deliberately the same answer for both. |
| 422 | validation_error | An argument was wrong. The message names the field. |
| 429 | rate_limited | Too many read calls. Back off and retry. |
| 500 | internal_error | Something failed on our side. Nothing was changed. |