For the complete documentation index, see llms.txt.

Multi-Host Accounts

One account can manage many hosts — each an independently-bookable principal with its own calendar, availability, and bookings. Use this when you run a roster of people on shared infrastructure: an L&D org with many coaches, an agency booking on behalf of its clients, a marketplace of practitioners.

Each host has its own principal_id. You query that host's availability and book against it; the booking is attributed to that host and written to their calendar. Your account's API key carries delegated authority over every host it manages — a few keys cover hundreds of hosts.

Teams vs hosts. Team Scheduling finds a slot where several people are all free (one meeting, many attendees) — supply-side coordination. Multi-host is the opposite: many independent bookable people under one account, each booked separately — demand-side delegation. Reach for teams to coordinate a group; reach for hosts to operate a roster.

Endpoints

Method Path Purpose
POST /v1/hosts Provision a host principal
GET /v1/hosts List managed hosts (with calendar status)
POST /v1/hosts/:id/connect-link Get a calendar-connect URL for a host
DELETE /v1/hosts/:id Unlink a host (revokes delegated authority)
POST /v1/calendars/google/connect-guest-link Get a single-use calendar-connect URL for a customer

Availability and booking use the existing endpoints with the host's principal_id:

Method Path Purpose
GET /v1/availability/slots?principal_id=… A single host's free/busy
GET /v1/availability/mutual?principal_ids=… Free time shared by a host and your customers
POST /v1/bookings (principal_id) Book against a specific host
GET /v1/bookings?principal_id=… List one host's bookings

The flow

1. Provision a host

curl -X POST https://api.vennio.app/v1/hosts \
  -H "Authorization: Bearer $VENNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "display_name": "Coach Alice" }'
// Response
{
  "host": {
    "principal_id": "903f701d-…",
    "display_name": "Coach Alice",
    "status": "active",
    "calendar_connected": false,
    "created_at": "2026-06-24T10:30:54Z"
  }
}

2. Send the host a calendar-connect link

The host connects their own calendar — you never handle their credentials.

curl -X POST https://api.vennio.app/v1/hosts/903f701d-…/connect-link \
  -H "Authorization: Bearer $VENNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "redirect_url": "https://app.example.com/connected" }'
// Response — send connect_url to the host (single-use, expires in 5 min)
{
  "principal_id": "903f701d-…",
  "connect_url": "https://api.vennio.app/v1/calendars/google/connect?token=…",
  "expires_in": 300
}

Email or message connect_url to the host. When they complete it, calendar_connected flips to true in GET /v1/hosts.

3. Query that host's availability

curl -G "https://api.vennio.app/v1/availability/slots" \
  -H "Authorization: Bearer $VENNIO_API_KEY" \
  --data-urlencode "principal_id=903f701d-…" \
  --data-urlencode "duration_minutes=30" \
  --data-urlencode "from=2026-07-01T09:00:00Z" \
  --data-urlencode "to=2026-07-04T17:00:00Z" \
  --data-urlencode "timezone=Europe/London"

Each host returns its own free/busy — no merging across the roster.

To find time that suits both a host and a customer, pass both to /v1/availability/mutual:

curl -G "https://api.vennio.app/v1/availability/mutual" \
  -H "Authorization: Bearer $VENNIO_API_KEY" \
  --data-urlencode "principal_ids=903f701d-…,5b2e9c14-…" \
  --data-urlencode "duration_minutes=30" \
  --data-urlencode "from=2026-07-01T09:00:00Z" \
  --data-urlencode "to=2026-07-04T17:00:00Z"

Hosts your account manages need no consent. Every other principal in the list must be connected to your account or have granted it consent. Consent belongs to the account, not to a host: a customer who connects once can be queried alongside any of your hosts.

Connect a customer

To query a customer without a Vennio account, have them connect their Google Calendar to your account. Mint a single-use connect link from your server with your secret key:

curl -X POST https://api.vennio.app/v1/calendars/google/connect-guest-link \
  -H "Authorization: Bearer $VENNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "redirect_url": "https://yourapp.com/connected",
    "reference": "trip_8812"
  }'
{
  "connect_url": "https://api.vennio.app/v1/calendars/google/connect?token=…",
  "expires_in": 300
}

Mint on click, redirect immediately. Call this when the customer clicks "Connect calendar", then redirect their browser to connect_url. The link works once and expires after 5 minutes, so don't email it or put it in a page.

When the customer finishes Google sign-in:

4. Book against the host

curl -X POST https://api.vennio.app/v1/bookings \
  -H "Authorization: Bearer $VENNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "principal_id": "903f701d-…",
    "customer_email": "jane@example.com",
    "customer_name": "Jane Doe",
    "start_time": "2026-07-01T13:00:00Z",
    "end_time": "2026-07-01T13:30:00Z"
  }'

The booking's business_id (and principal_id) is the host — attribution is automatic, and the calendar event lands on the host's calendar.

With the SDK

import { Vennio } from '@vennio/sdk';

const vennio = new Vennio(process.env.VENNIO_API_KEY!);

const host = await vennio.hosts.create({ display_name: 'Coach Alice' });
const link = await vennio.hosts.createConnectLink(host.principal_id);
// → email link.connect_url to the coach

const result = await vennio.bookings.create({
  principal_id: host.principal_id,
  customer_email: 'jane@example.com',
  customer_name: 'Jane Doe',
  start_time: '2026-07-01T13:00:00Z',
  end_time: '2026-07-01T13:30:00Z',
});

AI agents can do the same over MCP with the provision_host, list_hosts, create_host_connect_link, and create_booking (with principal_id) tools.

Gotchas