> ## Documentation Index
> Fetch the complete documentation index at: https://developer.meetergo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDKs & Code Examples

> Ready-to-use code snippets in multiple languages

Copy-paste code examples to get started quickly with the meetergo API.

## Quick Reference

<CodeGroup>
  ```javascript JavaScript theme={null}
  const MEETERGO_API = 'https://api.meetergo.com/v4';
  const API_KEY = process.env.MEETERGO_API_KEY;

  const headers = {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json'
  };

  // Add user ID header for most requests
  function withUser(userId) {
    return { ...headers, 'x-meetergo-api-user-id': userId };
  }
  ```

  ```python Python theme={null}
  import os
  import requests

  MEETERGO_API = 'https://api.meetergo.com/v4'
  API_KEY = os.environ['MEETERGO_API_KEY']

  headers = {
      'Authorization': f'Bearer {API_KEY}',
      'Content-Type': 'application/json'
  }

  def with_user(user_id):
      return {**headers, 'x-meetergo-api-user-id': user_id}
  ```

  ```php PHP theme={null}
  <?php
  $MEETERGO_API = 'https://api.meetergo.com/v4';
  $API_KEY = getenv('MEETERGO_API_KEY');

  $headers = [
      'Authorization: Bearer ' . $API_KEY,
      'Content-Type: application/json'
  ];

  function withUser($userId) {
      global $headers;
      return array_merge($headers, ['x-meetergo-api-user-id: ' . $userId]);
  }
  ```

  ```go Go theme={null}
  package main

  import (
      "net/http"
      "os"
  )

  const meetergoAPI = "https://api.meetergo.com/v4"

  var apiKey = os.Getenv("MEETERGO_API_KEY")

  func newRequest(method, path string) *http.Request {
      req, _ := http.NewRequest(method, meetergoAPI+path, nil)
      req.Header.Set("Authorization", "Bearer "+apiKey)
      req.Header.Set("Content-Type", "application/json")
      return req
  }
  ```
</CodeGroup>

## Authentication

### Verify API Key

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function verifyApiKey() {
    const response = await fetch(`${MEETERGO_API}/user/me`, { headers });

    if (!response.ok) {
      throw new Error(`API key invalid: ${response.status}`);
    }

    return response.json();
  }

  // Usage
  const user = await verifyApiKey();
  console.log('Authenticated as:', user.email);
  ```

  ```python Python theme={null}
  def verify_api_key():
      response = requests.get(f'{MEETERGO_API}/user/me', headers=headers)
      response.raise_for_status()
      return response.json()

  # Usage
  user = verify_api_key()
  print(f'Authenticated as: {user["email"]}')
  ```

  ```php PHP theme={null}
  function verifyApiKey() {
      global $MEETERGO_API, $headers;

      $ch = curl_init("$MEETERGO_API/user/me");
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

      $response = curl_exec($ch);
      $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
      curl_close($ch);

      if ($httpCode !== 200) {
          throw new Exception("API key invalid: $httpCode");
      }

      return json_decode($response, true);
  }
  ```
</CodeGroup>

## Users

### Create User

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function createUser({ email, firstName, lastName, timezone = 'Europe/Berlin' }) {
    const response = await fetch(`${MEETERGO_API}/user`, {
      method: 'POST',
      headers,
      body: JSON.stringify({
        email,
        givenName: firstName,
        familyName: lastName,
        timezone
      })
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`Failed to create user: ${error.message}`);
    }

    return response.json();
  }

  // Usage
  const user = await createUser({
    email: 'john@example.com',
    firstName: 'John',
    lastName: 'Doe'
  });
  console.log('Created user:', user.userId);
  console.log('Booking URL:', user.bookingUrl);
  ```

  ```python Python theme={null}
  def create_user(email, first_name, last_name, timezone='Europe/Berlin'):
      response = requests.post(
          f'{MEETERGO_API}/user',
          headers=headers,
          json={
              'email': email,
              'givenName': first_name,
              'familyName': last_name,
              'timezone': timezone
          }
      )
      response.raise_for_status()
      return response.json()

  # Usage
  user = create_user('john@example.com', 'John', 'Doe')
  print(f'Created user: {user["userId"]}')
  print(f'Booking URL: {user["bookingUrl"]}')
  ```

  ```php PHP theme={null}
  function createUser($email, $firstName, $lastName, $timezone = 'Europe/Berlin') {
      global $MEETERGO_API, $headers;

      $data = json_encode([
          'email' => $email,
          'givenName' => $firstName,
          'familyName' => $lastName,
          'timezone' => $timezone
      ]);

      $ch = curl_init("$MEETERGO_API/user");
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

      $response = curl_exec($ch);
      curl_close($ch);

      return json_decode($response, true);
  }
  ```
</CodeGroup>

## Availability

### Get Available Slots

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function getAvailableSlots(meetingTypeId, startDate, endDate, userId) {
    const params = new URLSearchParams({
      meetingTypeId,
      start: startDate,
      end: endDate
    });

    const response = await fetch(
      `${MEETERGO_API}/booking-availability?${params}`,
      { headers: withUser(userId) }
    );

    const data = await response.json();
    return data.dates?.flatMap(d => d.spots) || [];
  }

  // Usage
  const slots = await getAvailableSlots(
    'meeting-type-id',
    '2024-01-15',
    '2024-01-22',
    'user-id'
  );

  slots.forEach(slot => {
    console.log(`Available: ${new Date(slot.startTime).toLocaleString()}`);
  });
  ```

  ```python Python theme={null}
  def get_available_slots(meeting_type_id, start_date, end_date, user_id):
      response = requests.get(
          f'{MEETERGO_API}/booking-availability',
          headers=with_user(user_id),
          params={
              'meetingTypeId': meeting_type_id,
              'start': start_date,
              'end': end_date
          }
      )
      response.raise_for_status()
      data = response.json()
      dates = data.get('dates', [])
      return [spot for d in dates for spot in d.get('spots', [])]

  # Usage
  from datetime import datetime, timedelta

  today = datetime.now().strftime('%Y-%m-%d')
  next_week = (datetime.now() + timedelta(days=7)).strftime('%Y-%m-%d')

  slots = get_available_slots('meeting-type-id', today, next_week, 'user-id')
  for slot in slots:
      print(f'Available: {slot["startTime"]}')
  ```

  ```php PHP theme={null}
  function getAvailableSlots($meetingTypeId, $startDate, $endDate, $userId) {
      global $MEETERGO_API;

      $params = http_build_query([
          'meetingTypeId' => $meetingTypeId,
          'start' => $startDate,
          'end' => $endDate
      ]);

      $ch = curl_init("$MEETERGO_API/booking-availability?$params");
      curl_setopt($ch, CURLOPT_HTTPHEADER, withUser($userId));
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

      $response = curl_exec($ch);
      curl_close($ch);

      $data = json_decode($response, true);
      $spots = [];
      foreach ($data['dates'] ?? [] as $date) {
          $spots = array_merge($spots, $date['spots'] ?? []);
      }
      return $spots;
  }
  ```
</CodeGroup>

## Bookings

### Create Booking

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function createBooking({
    meetingTypeId,
    start,
    attendee,
    userId
  }) {
    const response = await fetch(`${MEETERGO_API}/booking`, {
      method: 'POST',
      headers: withUser(userId),
      body: JSON.stringify({
        meetingTypeId,
        start,
        attendee: {
          email: attendee.email,
          fullname: attendee.name,
          phone: attendee.phone
        }
      })
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`Booking failed: ${error.message}`);
    }

    return response.json();
  }

  // Usage
  const booking = await createBooking({
    meetingTypeId: 'meeting-type-id',
    start: '2024-01-16T10:00:00Z',
    attendee: {
      email: 'client@example.com',
      name: 'Jane Client',
      phone: '+1234567890'
    },
    userId: 'user-id'
  });

  console.log('Booking confirmed:', booking.id);
  console.log('Meeting link:', booking.meetingLink);
  ```

  ```python Python theme={null}
  def create_booking(meeting_type_id, start, attendee, user_id):
      response = requests.post(
          f'{MEETERGO_API}/booking',
          headers=with_user(user_id),
          json={
              'meetingTypeId': meeting_type_id,
              'start': start,
              'attendee': {
                  'email': attendee['email'],
                  'fullname': attendee['name'],
                  'phone': attendee.get('phone')
              }
          }
      )
      response.raise_for_status()
      return response.json()

  # Usage
  booking = create_booking(
      meeting_type_id='meeting-type-id',
      start='2024-01-16T10:00:00Z',
      attendee={
          'email': 'client@example.com',
          'name': 'Jane Client',
          'phone': '+1234567890'
      },
      user_id='user-id'
  )
  print(f'Booking confirmed: {booking["id"]}')
  ```

  ```php PHP theme={null}
  function createBooking($meetingTypeId, $start, $attendee, $userId) {
      global $MEETERGO_API;

      $data = json_encode([
          'meetingTypeId' => $meetingTypeId,
          'start' => $start,
          'attendee' => [
              'email' => $attendee['email'],
              'fullname' => $attendee['name'],
              'phone' => $attendee['phone'] ?? null
          ]
      ]);

      $ch = curl_init("$MEETERGO_API/booking");
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_HTTPHEADER, withUser($userId));
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

      $response = curl_exec($ch);
      curl_close($ch);

      return json_decode($response, true);
  }
  ```
</CodeGroup>

### Cancel Booking

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function cancelBooking(appointmentId, userId, reason = null) {
    const response = await fetch(`${MEETERGO_API}/appointment/${appointmentId}/cancel`, {
      method: 'POST',
      headers: { ...withUser(userId), 'Content-Type': 'application/json' },
      body: reason ? JSON.stringify({ reason }) : undefined
    });

    if (!response.ok) {
      throw new Error(`Cancel failed: ${response.status}`);
    }

    return true;
  }

  // Usage
  await cancelBooking('appointment-id', 'user-id', 'Customer requested');
  ```

  ```python Python theme={null}
  def cancel_booking(appointment_id, user_id, reason=None):
      data = None
      if reason:
          data = {'reason': reason}

      response = requests.post(
          f'{MEETERGO_API}/appointment/{appointment_id}/cancel',
          headers=with_user(user_id),
          json=data
      )
      response.raise_for_status()
      return True

  # Usage
  cancel_booking('appointment-id', 'user-id', 'Customer requested')
  ```
</CodeGroup>

## Webhooks

### Webhook Handler (Express.js)

```javascript theme={null}
const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhooks/meetergo', async (req, res) => {
  // Respond immediately
  res.status(200).send('OK');

  const payload = req.body;

  try {
    switch (payload.webhookType) {
      case 'booking_created':
        console.log('New booking:', payload.id);
        // Add to CRM, send notifications, etc.
        break;

      case 'booking_cancelled':
        console.log('Booking cancelled:', payload.id);
        // Update records, process refunds, etc.
        break;

      case 'booking_rescheduled':
        console.log('Booking rescheduled:', payload.rescheduledAppointment.id);
        // Update calendar, notify team, etc.
        break;
    }
  } catch (error) {
    console.error('Webhook processing failed:', error);
  }
});

app.listen(3000);
```

### Webhook Handler (Python/Flask)

```python theme={null}
from flask import Flask, request, jsonify
import threading

app = Flask(__name__)

def process_webhook(payload):
    webhook_type = payload.get('webhookType')
    if webhook_type == 'booking_created':
        print(f'New booking: {payload["id"]}')
    elif webhook_type == 'booking_cancelled':
        print(f'Booking cancelled: {payload["id"]}')
    elif webhook_type == 'booking_rescheduled':
        print(f'Booking rescheduled: {payload["rescheduledAppointment"]["id"]}')

@app.route('/webhooks/meetergo', methods=['POST'])
def webhook():
    payload = request.json

    # Process in background thread
    thread = threading.Thread(target=process_webhook, args=(payload,))
    thread.start()

    return jsonify({'status': 'ok'}), 200

if __name__ == '__main__':
    app.run(port=3000)
```

## Complete Example: Booking Flow

Full example of checking availability and creating a booking:

<CodeGroup>
  ```javascript JavaScript theme={null}
  class MeetergoClient {
    constructor(apiKey) {
      this.apiKey = apiKey;
      this.baseUrl = 'https://api.meetergo.com/v4';
    }

    async request(method, path, userId = null, body = null) {
      const headers = {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json'
      };

      if (userId) {
        headers['x-meetergo-api-user-id'] = userId;
      }

      const response = await fetch(`${this.baseUrl}${path}`, {
        method,
        headers,
        body: body ? JSON.stringify(body) : undefined
      });

      if (!response.ok) {
        const error = await response.json().catch(() => ({}));
        throw new Error(error.message || `HTTP ${response.status}`);
      }

      return response.json();
    }

    async getAvailability(meetingTypeId, startDate, endDate, userId) {
      const params = new URLSearchParams({
        meetingTypeId,
        start: startDate,
        end: endDate
      });
      return this.request('GET', `/booking-availability?${params}`, userId);
    }

    async createBooking(meetingTypeId, start, attendee, userId) {
      return this.request('POST', '/booking', userId, {
        meetingTypeId,
        start,
        attendee
      });
    }
  }

  // Usage
  async function bookAppointment() {
    const client = new MeetergoClient(process.env.MEETERGO_API_KEY);

    const meetingTypeId = 'your-meeting-type-id';
    const userId = 'your-user-id';

    // 1. Get available slots
    const today = new Date().toISOString().split('T')[0];
    const nextWeek = new Date(Date.now() + 7 * 86400000).toISOString().split('T')[0];

    const availability = await client.getAvailability(
      meetingTypeId,
      today,
      nextWeek,
      userId
    );

    const allSlots = availability.dates?.flatMap(d => d.spots) || [];
    if (!allSlots.length) {
      throw new Error('No available slots');
    }

    // 2. Book the first available slot
    const slot = allSlots[0];
    const booking = await client.createBooking(
      meetingTypeId,
      slot.startTime,
      {
        email: 'client@example.com',
        fullname: 'Client Name',
        phone: '+1234567890'
      },
      userId
    );

    console.log('Booked!', booking);
    return booking;
  }

  bookAppointment().catch(console.error);
  ```

  ```python Python theme={null}
  import os
  import requests
  from datetime import datetime, timedelta

  class MeetergoClient:
      def __init__(self, api_key):
          self.api_key = api_key
          self.base_url = 'https://api.meetergo.com/v4'

      def request(self, method, path, user_id=None, json=None, params=None):
          headers = {
              'Authorization': f'Bearer {self.api_key}',
              'Content-Type': 'application/json'
          }

          if user_id:
              headers['x-meetergo-api-user-id'] = user_id

          response = requests.request(
              method,
              f'{self.base_url}{path}',
              headers=headers,
              json=json,
              params=params
          )
          response.raise_for_status()
          return response.json()

      def get_availability(self, meeting_type_id, start_date, end_date, user_id):
          return self.request('GET', '/booking-availability', user_id, params={
              'meetingTypeId': meeting_type_id,
              'start': start_date,
              'end': end_date
          })

      def create_booking(self, meeting_type_id, start, attendee, user_id):
          return self.request('POST', '/booking', user_id, json={
              'meetingTypeId': meeting_type_id,
              'start': start,
              'attendee': attendee
          })


  def book_appointment():
      client = MeetergoClient(os.environ['MEETERGO_API_KEY'])

      meeting_type_id = 'your-meeting-type-id'
      user_id = 'your-user-id'

      # 1. Get available slots
      today = datetime.now().strftime('%Y-%m-%d')
      next_week = (datetime.now() + timedelta(days=7)).strftime('%Y-%m-%d')

      availability = client.get_availability(
          meeting_type_id,
          today,
          next_week,
          user_id
      )

      dates = availability.get('dates', [])
      all_slots = [spot for d in dates for spot in d.get('spots', [])]
      if not all_slots:
          raise Exception('No available slots')

      # 2. Book the first available slot
      slot = all_slots[0]
      booking = client.create_booking(
          meeting_type_id,
          slot['startTime'],
          {
              'email': 'client@example.com',
              'fullname': 'Client Name',
              'phone': '+1234567890'
          },
          user_id
      )

      print('Booked!', booking)
      return booking


  if __name__ == '__main__':
      book_appointment()
  ```
</CodeGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="book" href="https://api.meetergo.com/spec/v2">
    Full API documentation
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/developer-docs/troubleshooting">
    Common issues and solutions
  </Card>
</CardGroup>
