Skip to main content
This guide walks you through the end-to-end flow for programmatically booking an event via the Zeeg API.
The availability and booking endpoints require a paid Zeeg subscription. Requests on free plans will be rejected.
Always verify availability before creating an event. Attempting to book a slot that is no longer available will result in an error. Check available time slots immediately before creating the event to avoid race conditions.

End-to-end booking flow

1
Get your scheduling page details
2
Retrieve the scheduling page (event type) you want to book against. You need its slug, the owner’s slug, any custom invitee questions, and whether a phone number is required.
3
List all your scheduling pages:
4
GET /event-types
5
Or fetch a specific one by UUID:
6
GET /event-types/{uuid}
7
Example response (key fields highlighted):
8
{
  "resource": {
    "uri": "https://api.zeeg.me/v2/event-types/80f46bf5-eb01-4c07-960e-a9a3e18aae5e",
    "uuid": "80f46bf5-eb01-4c07-960e-a9a3e18aae5e",
    "title": "30-Minute Discovery Call",
    "type": "ONE_ON_ONE",
    "slug": "30min-discovery-call",
    "schedulingUrl": "https://zeeg.me/lena-meier/30min-discovery-call",
    "isActive": true,
    "duration": 30,
    "profile": {
      "type": "User",
      "firstName": "Lena",
      "lastName": "Meier",
      "slug": "lena-meier",
      "email": "lena.meier@horizondigital.de"
    },
    "inviteePhoneNumber": false,
    "inviteeQuestions": [
      {
        "id": 1,
        "order": 1,
        "question": "What would you like to discuss?",
        "isActive": true,
        "isRequired": true,
        "type": "TEXT_INPUT",
        "options": null
      }
    ]
  }
}
9
Take note of:
10
  • slug — identifies the event type in subsequent requests (e.g., 30min-discovery-call).
  • profile.slug — the owner’s slug, used as ownerSlug (e.g., lena-meier).
  • inviteeQuestions — custom questions with their numeric ids. You will pass answers in step 3 using question_id.
  • inviteePhoneNumbertrue if a phone number is required, false otherwise.
  • 11
    Check available time slots
    12
    Query the availability endpoint to find open slots for the scheduling page.
    13
    cURL
    curl -X GET "https://api.zeeg.me/v2/availability/lena-meier/event-types/30min-discovery-call?startDate=2026-04-01&endDate=2026-04-14&timeZone=Europe/Berlin" \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -H "Accept: application/json"
    
    JavaScript
    const response = await fetch(
      "https://api.zeeg.me/v2/availability/lena-meier/event-types/30min-discovery-call?" +
        new URLSearchParams({
          startDate: "2026-04-01",
          endDate: "2026-04-14",
          timeZone: "Europe/Berlin",
        }),
      {
        headers: {
          Authorization: "Bearer YOUR_TOKEN",
          Accept: "application/json",
        },
      }
    );
    
    const data = await response.json();
    
    Python
    import requests
    
    response = requests.get(
        "https://api.zeeg.me/v2/availability/lena-meier/event-types/30min-discovery-call",
        params={
            "startDate": "2026-04-01",
            "endDate": "2026-04-14",
            "timeZone": "Europe/Berlin",
        },
        headers={
            "Authorization": "Bearer YOUR_TOKEN",
            "Accept": "application/json",
        },
    )
    
    data = response.json()
    
    14
    Example response:
    15
    {
      "ownerSlug": "lena-meier",
      "eventTypeSlug": "30min-discovery-call",
      "schedulingUrl": "https://zeeg.me/lena-meier/30min-discovery-call",
      "duration": 30,
      "firstAvailableDate": "2026-04-01",
      "lastAvailableDate": "2026-04-14",
      "timeZone": "Europe/Berlin",
      "timeZoneOffset": "+02:00",
      "isNotAvailable": false,
      "availability": [
        {
          "date": "2026-04-01",
          "slots": ["09:00", "09:30", "10:00", "10:30", "14:00", "14:30", "15:00"]
        },
        {
          "date": "2026-04-02",
          "slots": ["09:00", "09:30", "10:00", "11:00", "14:00", "15:00"]
        },
        {
          "date": "2026-04-03",
          "slots": []
        }
      ],
      "currentTime": "2026-03-20T12:00:00+00:00"
    }
    
    16
    This endpoint requires the admin:full or timetable scope.
    17
    Shared event types (Round Robin, Flexi, Collective):
    18
  • Use shared as the ownerSlug instead of a specific user’s slug.
  • For Round Robin events, add withHostsCount=1 to the query to see how many hosts are available per slot.
  • 19
    Additional query parameters:
    20
  • Add duration=45 to override the default meeting duration (useful when the scheduling page supports multiple durations).
  • Add seats=3 to check availability for group event types that support multiple attendees.
  • 21
    Shared links: If you have a shared scheduling link, you can use the alternative endpoint:
    22
    GET /availability-by-shared-link/{sharedLink}?startDate=2026-04-01&endDate=2026-04-14&timeZone=Europe/Berlin
    
    23
    Create the event
    24
    Book a slot by sending a POST request to /event with the slot details and invitee information.
    25
    cURL
    curl -X POST "https://api.zeeg.me/v2/event" \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -H "Content-Type: application/json" \
      -H "Accept: application/json" \
      -d '{
        "ownerSlug": "lena-meier",
        "eventTypeSlug": "30min-discovery-call",
        "date": "2026-04-15",
        "start": "09:00",
        "duration": 30,
        "name": "Sophie Laurent",
        "email": "sophie.laurent@northwind.io",
        "timeZone": "Europe/Paris",
        "guests": ["alex.chen@northwind.io"],
        "location": "GOOGLE_MEET",
        "question_answers": [
          { "question_id": 1, "answer": "Product demo and pricing options" }
        ]
      }'
    
    JavaScript
    const response = await fetch("https://api.zeeg.me/v2/event", {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_TOKEN",
        "Content-Type": "application/json",
        Accept: "application/json",
      },
      body: JSON.stringify({
        ownerSlug: "lena-meier",
        eventTypeSlug: "30min-discovery-call",
        date: "2026-04-15",
        start: "09:00",
        duration: 30,
        name: "Sophie Laurent",
        email: "sophie.laurent@northwind.io",
        timeZone: "Europe/Paris",
        guests: ["alex.chen@northwind.io"],
        location: "GOOGLE_MEET",
        question_answers: [
          { question_id: 1, answer: "Product demo and pricing options" },
        ],
      }),
    });
    
    const event = await response.json();
    
    Python
    import requests
    
    response = requests.post(
        "https://api.zeeg.me/v2/event",
        headers={
            "Authorization": "Bearer YOUR_TOKEN",
            "Content-Type": "application/json",
            "Accept": "application/json",
        },
        json={
            "ownerSlug": "lena-meier",
            "eventTypeSlug": "30min-discovery-call",
            "date": "2026-04-15",
            "start": "09:00",
            "duration": 30,
            "name": "Sophie Laurent",
            "email": "sophie.laurent@northwind.io",
            "timeZone": "Europe/Paris",
            "guests": ["alex.chen@northwind.io"],
            "location": "GOOGLE_MEET",
            "question_answers": [
                {"question_id": 1, "answer": "Product demo and pricing options"},
            ],
        },
    )
    
    event = response.json()
    
    26
    This endpoint requires the admin:full or booking scope.
    27
    Required fields:
    28
    FieldDescriptionownerSlugThe scheduling page owner’s slug (from profile.slug in step 1)eventTypeSlugThe scheduling page slug (from step 1)dateThe date of the slot (from step 2), e.g. 2026-04-01startThe start time of the slot (from step 2), e.g. 09:00durationDuration in minutes (must match the event type duration)nameInvitee’s full nameemailInvitee’s email addresstimeZoneInvitee’s time zone, e.g. Europe/Berlin
    29
    Optional fields:
    30
    FieldDescriptionphoneInvitee’s phone number (required if inviteePhoneNumber is true on the scheduling page)question_answersArray of { question_id, answer } objects matching the inviteeQuestions from step 1guestsArray of additional guest email addresseslocationLocation type: GOOGLE_MEET, ZOOM, MICROSOFT_TEAMS, IN_PERSON, PHONE_CALLlocationOptionsAdditional location details (see below)utmUTM tracking object with keys: utm_campaign, utm_source, utm_medium, utm_content, utm_termcustomQueryParamsCustom URL query parameters to attach to the event. Keys must start with c__ (max 10 fields)sharedLinkRequired for shared event types (Round Robin, Flexi, Collective)
    31
    Location options:
    32
    For IN_PERSON locations, include locationOptions with the meeting address:
    33
    {
      "location": "IN_PERSON",
      "locationOptions": {
        "address": "123 Main St, Berlin, Germany",
        "details": "3rd floor, room 301"
      }
    }
    
    34
    For PHONE_CALL locations, include locationOptions with the call type and a phone number:
    35
    {
      "location": "PHONE_CALL",
      "locationOptions": {
        "callType": "I_WILL_CALL"
      },
      "phone": "+49 170 1234567"
    }
    
    36
    Verify the booking
    37
    The response from step 3 contains the created event with all its details.
    38
    Example response:
    39
    {
      "uri": "https://api.zeeg.me/v2/scheduled-events/zg-O69bac566950c6",
      "uuid": "zg-O69bac566950c6",
      "title": "30-Minute Discovery Call",
      "type": "ONE_ON_ONE",
      "startTime": "2026-04-15T07:00:00.000000Z",
      "endTime": "2026-04-15T07:30:00.000000Z",
      "duration": 30,
      "status": "confirmed",
      "eventTypeUri": "https://api.zeeg.me/v2/event-types/80f46bf5-eb01-4c07-960e-a9a3e18aae5e",
      "location": {
        "type": "Google Meet",
        "joinUrl": "https://meet.google.com/abc-defg-hij"
      },
      "invitees": [
        {
          "uuid": "zg-O69bad4047abf0",
          "fullName": "Sophie Laurent",
          "email": "sophie.laurent@northwind.io",
          "timeZone": "Europe/Paris",
          "guests": ["alex.chen@northwind.io"]
        }
      ],
      "hosts": [
        {
          "firstName": "Lena",
          "lastName": "Meier",
          "email": "lena.meier@horizondigital.de",
          "slug": "lena-meier"
        }
      ]
    }
    
    40
    To verify the booking at any later point, fetch it by UUID:
    41
    cURL
    curl -X GET "https://api.zeeg.me/v2/scheduled-events/zg-O69bac566950c6" \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -H "Accept: application/json"
    
    JavaScript
    const response = await fetch(
      "https://api.zeeg.me/v2/scheduled-events/zg-O69bac566950c6",
      {
        headers: {
          Authorization: "Bearer YOUR_TOKEN",
          Accept: "application/json",
        },
      }
    );
    
    const event = await response.json();
    
    Python
    import requests
    
    response = requests.get(
        "https://api.zeeg.me/v2/scheduled-events/zg-O69bac566950c6",
        headers={
            "Authorization": "Bearer YOUR_TOKEN",
            "Accept": "application/json",
        },
    )
    
    event = response.json()
    
    Last modified on April 4, 2026