Skip to main content
Build scheduling capabilities into your platform so your users can offer appointment booking to their clients. Perfect for marketplaces, directories, and SaaS platforms.

Use Cases

  • Professional directories (e.g., anwalt.de, doctors, consultants) - Let listed professionals accept bookings
  • Marketplaces - Enable service providers to manage appointments
  • SaaS platforms - Add scheduling as a feature for your customers
  • Agency tools - Manage booking for multiple client accounts

Architecture Overview

Implementation Steps

1. Platform Setup

First, get your API credentials and set up the admin user:
const MEETERGO_API_KEY = process.env.MEETERGO_API_KEY;
const headers = {
  'Authorization': `Bearer ${MEETERGO_API_KEY}`,
  'Content-Type': 'application/json'
};

2. Create Users for Your Platform Members

When a user signs up on your platform, create a corresponding meetergo user:
async function createPlatformUser(platformUser) {
  const response = await fetch('https://api.meetergo.com/v4/user', {
    method: 'POST',
    headers,
    body: JSON.stringify({
      email: platformUser.email,
      givenName: platformUser.firstName,
      familyName: platformUser.lastName,
      timezone: platformUser.timezone || 'Europe/Berlin',
      // Custom availability for professionals
      availability: {
        name: 'Business Hours',
        timezone: platformUser.timezone || 'Europe/Berlin',
        schedule: [
          { dayOfWeek: 'monday', intervals: [{ from: '09:00', to: '18:00' }] },
          { dayOfWeek: 'tuesday', intervals: [{ from: '09:00', to: '18:00' }] },
          { dayOfWeek: 'wednesday', intervals: [{ from: '09:00', to: '18:00' }] },
          { dayOfWeek: 'thursday', intervals: [{ from: '09:00', to: '18:00' }] },
          { dayOfWeek: 'friday', intervals: [{ from: '09:00', to: '17:00' }] }
        ]
      },
      // Default meeting type
      meetingType: {
        name: 'Consultation',
        duration: 30,
        slug: `${platformUser.slug}-consultation`
      }
    })
  });

  const data = await response.json();

  // Store the mapping in your database
  await db.users.update({
    where: { id: platformUser.id },
    data: {
      meetergoUserId: data.userId,
      meetergoMeetingTypeId: data.meetingTypeId,
      bookingUrl: data.bookingUrl
    }
  });

  return data;
}

3. Embed Booking on Profile Pages

Option A: Embed the booking widget
<!-- On the professional's public profile page -->
<iframe
  src="https://cal.meetergo.com/embed/{companySlug}/{userSlug}/{meetingTypeSlug}"
  width="100%"
  height="700"
  frameborder="0"
></iframe>
Option B: Build custom UI with API
// Fetch available slots
async function getAvailableSlots(meetingTypeId, startDate, endDate) {
  const params = new URLSearchParams({
    meetingTypeId,
    start: startDate,
    end: endDate
  });

  const response = await fetch(
    `https://api.meetergo.com/v4/booking-availability?${params}`,
    { headers }
  );

  return response.json();
}

// Display in your UI
const slots = await getAvailableSlots(meetingTypeId, '2024-01-15', '2024-01-22');

// Render custom calendar component
slots.availableSlots.forEach(slot => {
  // Your custom rendering logic
});

4. Handle Bookings

async function createBooking(meetingTypeId, slot, clientInfo) {
  const response = await fetch('https://api.meetergo.com/v4/booking', {
    method: 'POST',
    headers,
    body: JSON.stringify({
      meetingTypeId,
      start: slot.start,
      attendee: {
        email: clientInfo.email,
        fullname: clientInfo.name,
        phone: clientInfo.phone
      }
    })
  });

  const booking = await response.json();

  // Track in your platform's analytics
  await trackBooking(booking);

  return booking;
}

Multi-Tenant Management

List All Platform Users

async function getPlatformUsers() {
  const response = await fetch('https://api.meetergo.com/v4/user', {
    headers
  });

  return response.json();
}

Update User Settings

async function updateUserMeetingType(userId, meetingTypeId, updates) {
  const response = await fetch(
    `https://api.meetergo.com/v4/meeting-type/${meetingTypeId}`,
    {
      method: 'PATCH',
      headers: {
        ...headers,
        'x-meetergo-api-user-id': userId
      },
      body: JSON.stringify(updates)
    }
  );

  return response.json();
}

// Example: Update duration and buffer time
await updateUserMeetingType(userId, meetingTypeId, {
  duration: 45,
  bufferTimeBefore: 15,
  bufferTimeAfter: 10
});

Bulk Operations

// Create multiple users at once
async function onboardPlatformUsers(users) {
  const results = await Promise.allSettled(
    users.map(user => createPlatformUser(user))
  );

  const successful = results.filter(r => r.status === 'fulfilled');
  const failed = results.filter(r => r.status === 'rejected');

  console.log(`Created ${successful.length} users, ${failed.length} failed`);

  return { successful, failed };
}

Webhook Integration

Get notified of all bookings across your platform:
// Register a webhook for all booking events
const webhook = await fetch('https://api.meetergo.com/webhooks', {
  method: 'POST',
  headers,
  body: JSON.stringify({
    endpoint: 'https://your-platform.com/webhooks/meetergo',
    description: 'Platform booking notifications',
    eventTypes: ['booking_created', 'booking_cancelled', 'booking_rescheduled']
  })
});
Handle webhooks to update your platform:
app.post('/webhooks/meetergo', async (req, res) => {
  res.status(200).send('OK');

  const { event, data } = req.body;
  const hostUserId = data.hosts[0]?.id;

  // Find the platform user
  const platformUser = await db.users.findFirst({
    where: { meetergoUserId: hostUserId }
  });

  switch (event) {
    case 'booking_created':
      // Update platform analytics
      await db.bookings.create({
        data: {
          platformUserId: platformUser.id,
          clientEmail: data.attendees[0].email,
          scheduledAt: data.start,
          meetergoBookingId: data.id
        }
      });

      // Send platform-specific notification
      await sendPlatformNotification(platformUser, 'new_booking', data);
      break;

    case 'booking_cancelled':
      await db.bookings.update({
        where: { meetergoBookingId: data.id },
        data: { status: 'cancelled' }
      });
      break;
  }
});

Customization Options

Custom Branding per User

// Update personal page branding
await fetch(`https://api.meetergo.com/v4/personal-page`, {
  method: 'PATCH',
  headers: {
    ...headers,
    'x-meetergo-api-user-id': userId
  },
  body: JSON.stringify({
    headerTitle: 'Book a consultation',
    headerSubtitle: 'Select a time that works for you',
    primaryColor: '#0066cc'
  })
});

Meeting Type Templates

Create templates that all platform users can use:
// Create a template
const template = await fetch('https://api.meetergo.com/v4/meeting-type-template/create', {
  method: 'POST',
  headers,
  body: JSON.stringify({
    name: 'Initial Consultation',
    duration: 30,
    description: 'Free initial consultation to discuss your needs'
  })
});

// Assign template to a user (creates a meeting type from template)
await fetch(`https://api.meetergo.com/v4/meeting-type-template/assign/${templateId}`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    userId: platformUserId
  })
});

Best Practices

Store user mappings - Keep meetergo user IDs in your database for easy lookup
Use webhooks - Don’t poll for booking changes, use webhooks instead
Handle errors gracefully - API calls can fail; implement retry logic
Respect rate limits - Batch operations where possible
Secure your webhook endpoint - Validate incoming webhook requests
API key security - Never expose your API key in client-side code. All API calls should go through your backend.

Example: Professional Directory

Complete example for a lawyer directory:
// lawyer-directory.js

class LawyerDirectory {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.headers = {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    };
  }

  // When a lawyer joins the directory
  async onboardLawyer(lawyer) {
    // Create meetergo user
    const meetergoUser = await this.createMeetergoUser({
      email: lawyer.email,
      firstName: lawyer.firstName,
      lastName: lawyer.lastName,
      specialty: lawyer.specialty
    });

    // Create specialized meeting types
    await this.createMeetingTypes(meetergoUser.userId, lawyer.specialty);

    return meetergoUser;
  }

  async createMeetergoUser(lawyer) {
    const response = await fetch('https://api.meetergo.com/v4/user', {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({
        email: lawyer.email,
        givenName: lawyer.firstName,
        familyName: lawyer.lastName,
        timezone: 'Europe/Berlin',
        meetingType: {
          name: 'Erstberatung',
          duration: 30,
          slug: `${lawyer.firstName.toLowerCase()}-${lawyer.lastName.toLowerCase()}-erstberatung`
        }
      })
    });

    return response.json();
  }

  async createMeetingTypes(userId, specialty) {
    const meetingTypes = [
      { name: 'Telefonische Beratung', duration: 15 },
      { name: 'Ausführliche Beratung', duration: 60 },
      { name: 'Mandatsgespräch', duration: 45 }
    ];

    for (const mt of meetingTypes) {
      await fetch('https://api.meetergo.com/v4/meeting-type', {
        method: 'POST',
        headers: {
          ...this.headers,
          'x-meetergo-api-user-id': userId
        },
        body: JSON.stringify(mt)
      });
    }
  }

  // Render booking widget on lawyer profile
  getEmbedCode(lawyer) {
    return `
      <iframe
        src="${lawyer.bookingUrl}?embed=true"
        width="100%"
        height="700"
        frameborder="0"
        title="Termin buchen bei ${lawyer.firstName} ${lawyer.lastName}"
      ></iframe>
    `;
  }
}

Next Steps