Documentation
Calendar
calendar.day_capacity
REST
ShippingPOST /api/v1/calendar/day_capacityMCP tool
Livecalendar.day_capacityExposed on: REST API · Shop MCP server · Claude connector · Dash (in-app copilot) · Zapier. Part of the Calendar domain.
Operating contract
How loaded the shop's days are, one row per day: how many jobs hold a bay inside opening hours, how many bay-hours are committed, and whether that is at or past the ceilings the owner set.
full: true means the shop will take no more that day — either it is closed, or it has hit a cap. overbooked: true means staff have already pushed PAST a cap, which is not blocked and is worth mentioning rather than alarming about: a shop is always allowed to squeeze one more car in.
message is the sentence to say — 'Tue Aug 4: 6 jobs / 41h booked — your cap is 4 / 32h' — and it quotes only the dimensions this shop actually measures itself on. An empty message means the shop has set no daily ceilings at all, and then full only ever means closed.
THIS IS NOT AVAILABILITY. A day that is not full may still have no bookable time in it, because a slot also needs a capable bay, a certified installer and the shop's minimum notice. Use booking.availability for anything you are going to say to a customer.
closed: true days are the shop's non-working weekdays. They carry no load and no cap.
This walks every day in the range you ask for and returns them all, so nothing is truncated; the range itself is capped at 60 days.
Who may call it
- Permission
jobs.accessThe caller must hold Jobs at the ACT level. A read-only dashboard grant on the same section is refused.- 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
| Field | Type | Description |
|---|---|---|
| fromrequired | string | The first day, YYYY-MM-DD in the shop's own timezone. |
| days | integer1–60 | How many days from `from` to measure, 1-60. Defaults to 7. Default:7 |
Output
| Field | Type | Description |
|---|---|---|
| timezone | string | — |
| caps | object | — |
| caps.max_jobs_per_day | number | — |
| caps.max_booked_hours_per_day | number | — |
| caps.has_caps | boolean | — |
| days | object[] | — |
| days[].date | string | — |
| days[].closed | boolean | — |
| days[].jobs | number | — |
| days[].booked_hours | number | — |
| days[].full | boolean | — |
| days[].overbooked | boolean | — |
| days[].message | string | — |
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/calendar/day_capacity \
-H "Authorization: Bearer $SERVICEVIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{"from":"…","days":7}'const res = await fetch("https://www.servicevin.com/api/v1/calendar/day_capacity", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SERVICEVIN_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"from": "…",
"days": 7
}),
});
// 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/calendar/day_capacity",
headers={"Authorization": f"Bearer {os.environ['SERVICEVIN_API_KEY']}"},
json={
"from": "…",
"days": 7
},
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": "calendar.day_capacity",
"arguments": {
"from": "…",
"days": 7
}
}
}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. |
| 403 | forbidden | This login does not hold jobs.access. |
| 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. |