For AI agents

BusyBoard is built to be read and acted on by agents, not just humans — a hosted MCP server, scoped API keys, and share links that answer JSON when asked.

30-second start

  1. Create an API key in Settings → API. New keys default to read-only scopes, which are free.
  2. Or skip keys entirely: any BusyBoard share link answers JSON when asked for it — no signup, no auth beyond the link itself.
curl https://busyboard.app/a/{slug}/{token} \
  -H "Accept: application/json"

Same URL a human would open in a browser — the Acceptheader is what routes it to structured data instead of the HTML page. Can't set headers? Appending ?format=json to the link does the same thing. Default window is the next 14 days; pass startDate/endDate ISO query params for a specific range (max 5 weeks). The response includes the resolved timezone, working-hours window, and — when the sharer has booking enabled — a links.book URL plus the constraints (durations, min notice, horizon, slot alignment) needed to propose a valid time on the first try.

Hosted MCP (zero install)

The fastest way to give an agent full BusyBoard access: a Streamable HTTP MCP endpoint, stateless, authenticated with the same API key as the REST API. No local process to run or npm package to install.

{
  "mcpServers": {
    "busyboard": {
      "url": "https://busyboard.app/api/mcp",
      "headers": {
        "Authorization": "Bearer bb_live_your_key_here"
      }
    }
  }
}

This is the config shape Claude's custom connectors and most Streamable-HTTP MCP clients expect — paste the endpoint URL and key wherever your client asks for a remote MCP server.

ToolDoes
get_my_scheduleYour schedule for a day
get_my_availabilityYour busy blocks for a date range
get_person_availabilityCheck someone's availability
list_my_peopleEveryone you can schedule with
find_mutual_timeFind slots when everyone is free
propose_bookingPropose a meeting time — creates an approval request (or books instantly on auto-accept shares)

Use BusyBoard from the Claude API

Calling Claude directly via the Messages API? Point it at the same hosted MCP endpoint with the mcp_servers parameter — no separate client needed.

"mcp_servers": [
  {
    "type": "url",
    "url": "https://busyboard.app/api/mcp",
    "name": "busyboard",
    "authorization_token": "YOUR_BB_LIVE_KEY"
  }
]

Requires the beta header anthropic-beta: mcp-client-2025-11-20 on the request. Same key, same scopes, same rate limits as everywhere else on this page.

Local stdio alternative

Prefer a local process (Claude Desktop, Cursor, or any stdio MCP client)? The same five read tools plus propose_booking ship as @busyboard/mcp.

npm install -g @busyboard/mcp
{
  "mcpServers": {
    "busyboard": {
      "command": "busyboard-mcp",
      "env": {
        "BUSYBOARD_API_KEY": "bb_live_your_key_here"
      }
    }
  }
}

Goes in claude_desktop_config.json (Claude Desktop) or .cursor/mcp.json (Cursor). Both transports authenticate with the same API keys and hit the same scopes and rate limits — pick whichever fits your client.

Worked examples

Find mutual time

curl "https://busyboard.app/api/v1/find-time?userIds=<user-id>&durationMinutes=30&startDate=2026-08-17&endDate=2026-08-21" \
  -H "Authorization: Bearer bb_live_your_key_here"

Requires read:freebusy. Pass externalConnectionIds instead of/alongside userIds to include people outside your org (from /people connections[].connectionId).

Propose a booking (with approval)

curl -X POST https://busyboard.app/api/v1/booking-proposals \
  -H "Authorization: Bearer bb_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "shareToken": "the-token-from-their-share-url",
    "startTime": "2026-08-18T15:00:00-04:00",
    "durationMinutes": 30,
    "note": "Quick sync on the roadmap",
    "idempotencyKey": "propose-2026-08-18-1500-quick-sync"
  }'

Requires propose:booking (Pro). Provide exactly one of shareToken or connectionId. idempotencyKey is required — retry the exact same request on timeout and you get the original outcome back with an X-Idempotency-Replayed: true header, never a duplicate. The response is status: "pending"(lands in the recipient's notification bell for approval) or status: "confirmed" (the share has auto-accept on) — there is no API scope that confirms a booking directly; that stays a human action.

Read a share link as JSON

curl https://busyboard.app/a/jane-doe/AbCdEfGhIjKl \
  -H "Accept: application/json"

No API key needed — the token in the URL is the credential, with exactly the trust of a human holding the same link. Works for any active share link.

Scopes & limits

ScopePlanCovers
read:freebusyFree/availability, /availability/summary, /find-time, /calendars, /working-hours
read:peopleFree/people, /groups
propose:bookingPro/booking-proposals
manage:preferencesPro (reserved)Not a live feature yet

GET /api/v1/me needs no scope — any valid key can call it. New keys default to read-only.

SurfaceLimit
REST API reads100 / min per key
POST /booking-proposals10 / min per user
Share-link JSON (Accept: application/json)60 / min per IP
Hosted MCP endpoint60 / min per key (transport-level; per-tool calls into the API above)

Every rate-limited response carries a Retry-After header. Missing a required scope returns 403 with code: "insufficient_scope"; a write scope on a free-plan key returns code: "plan_required".

Privacy

Every surface here — share links, the REST API, and MCP — follows the same structural rule as the product: agents (and the humans directing them) only ever see free/busytime for anyone other than the API key's owner. Event titles, descriptions, attendees, and locations are never returned, never stored for sharing, and no scope can widen that — scopes only narrow capability further. This isn't a setting an agent can request around; it's enforced structurally, independent of what any endpoint is asked to return.

Reference