For the complete documentation index, see llms.txt.

How do I build a Calendly alternative?

Building a Calendly alternative requires three primitives: a shareable booking page, an availability API to show open slots, and a booking API to confirm appointments. Vennio provides all three as composable API endpoints — you own the frontend, Vennio handles the scheduling logic, calendar sync, and confirmations.

The answer

A Calendly-style product has three moving parts:

  1. A booking page with a URL someone can share (Venn Links)
  2. An availability grid showing open slots (Availability API)
  3. A booking form that confirms the appointment (Bookings API)

With Vennio you can have a working end-to-end flow in under an hour. Use the hosted Venn Link if you don't want to build a UI, or build a fully custom frontend with the API and @vennio/react widget.

Architecture overview

User visits booking URL
  └── GET /v1/venn-links/:shortcode        ← public, no auth needed

User selects duration / date
  └── GET /v1/venn-links/:shortcode/availability  ← public, returns open slots

User fills in name + email, clicks confirm
  └── POST /v1/venn-links/:shortcode/book        ← creates booking

Vennio side effects (automatic):
  ├── Calendar event created
  ├── Confirmation emails to host + guest
  └── booking.created webhook fired

Create a booking page

A Venn Link is a shareable booking page with a short code. Create one per meeting type.

curl -X POST https://api.vennio.app/v1/venn-links \
  -H "Authorization: Bearer vennio_sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "30-minute intro call",
    "duration_minutes": 30,
    "business_id": "YOUR_BUSINESS_ID"
  }'
{
  "venn_link": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "short_code": "abc123",
    "title": "30-minute intro call",
    "duration_minutes": 30,
    "url": "https://book.vennio.app/abc123",
    "business_id": "YOUR_BUSINESS_ID"
  }
}

Share the url field. Vennio hosts the default booking page at that URL. To build a custom UI, use the short code to fetch availability and accept bookings yourself (see below).

Show availability

Fetch open slots for the Venn Link. This endpoint is public — no API key required.

# Public endpoint — no auth required
curl "https://api.vennio.app/v1/venn-links/abc123/availability?timezone=America%2FNew_York"
{
  "slots": [
    { "start": "2026-04-01T09:00:00-05:00", "end": "2026-04-01T09:30:00-05:00" },
    { "start": "2026-04-01T10:00:00-05:00", "end": "2026-04-01T10:30:00-05:00" },
    { "start": "2026-04-01T14:00:00-05:00", "end": "2026-04-01T14:30:00-05:00" }
  ]
}

Accept bookings

When the user submits the booking form, call the book endpoint. Also public — no API key needed on the frontend.

// This runs in the browser — no API key needed
const res = await fetch('https://api.vennio.app/v1/venn-links/abc123/book', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    customer_email: 'customer@example.com',
    customer_name: 'Jane Doe',
    start_time: '2026-04-01T09:00:00-05:00',
    end_time: '2026-04-01T09:30:00-05:00',
  }),
})

const { booking } = await res.json()
console.log('Confirmed:', booking.id)

Embed a booking widget

For a faster build, drop the pre-built React widget into your app instead of building a booking UI from scratch.

npm install @vennio/react
import { VennioWidget } from '@vennio/react'

export default function BookingPage() {
  return (
    <VennioWidget
      vennLinkId="abc123"
      publishableKey="vennio_pk_live_YOUR_KEY"
      onBooked={(booking) => {
        console.log('Booked:', booking.id)
      }}
    />
  )
}
Paid bookings

Add Stripe Connect to charge for appointments. Set price_amount and price_currency on the Venn Link. Vennio returns a checkout_url for payment before confirming the booking. See Paid Bookings.

Next steps