Skip to main content
Documentation

Calendar

calendar.day_capacity

Check how many events each day holds against the shop's caps
Read-onlyRead budget

REST

Shipping
POST /api/v1/calendar/day_capacity

MCP tool

Live
calendar.day_capacity

Exposed 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

FieldTypeDescription
fromrequiredstring

The first day, YYYY-MM-DD in the shop's own timezone.

daysinteger1–60

How many days from `from` to measure, 1-60. Defaults to 7.

Default: 7

Output

FieldTypeDescription
timezonestring

capsobject

caps.max_jobs_per_daynumber

caps.max_booked_hours_per_daynumber

caps.has_capsboolean

daysobject[]

days[].datestring

days[].closedboolean

days[].jobsnumber

days[].booked_hoursnumber

days[].fullboolean

days[].overbookedboolean

days[].messagestring

Examples

Built from this capability's own schema — required fields and the ones carrying a default, and nothing invented. Paste one and it validates.

curl
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}'

TypeScript (fetch)
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;

Python (requests)
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"]

MCP tools/call — https://www.servicevin.com/api/mcp
{
  "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.

StatusCodeWhen
404not_foundThe id is unknown, or the feature is not enabled for this account. Deliberately the same answer for both.
403forbiddenThis login does not hold jobs.access.
422validation_errorAn argument was wrong. The message names the field.
429rate_limitedToo many read calls. Back off and retry.
500internal_errorSomething failed on our side. Nothing was changed.