Bridge APISync bookings

Sync bookings

Copy Bridge bookings into your CRM, database or spreadsheet, and keep them up to date as people book, reschedule and cancel.

This guide shows how to keep a copy of your workspace's bookings in another system. You load every booking once, then check for changes every few minutes.

You need an API key with Read access. See Authentication.

How it works

Every booking has an updated_at time. It changes when the booking is created, rescheduled, cancelled or given a different host. To find what changed since your last sync, ask for bookings updated after that time:

curl -G https://api.meetonbridge.com/v1/bookings \
  -H "Authorization: Bearer $BRIDGE_API_KEY" \
  --data-urlencode "after_updated_at=2026-10-28T09:00:00Z" \
  -d sort_by=updated_at \
  -d order=asc \
  -d take=100

Cancelled bookings are included, so you see cancellations as well as new bookings.

Set up the sync

Load every booking once

Request GET /bookings with sort_by=updated_at, order=asc and take=100, with no after_updated_at. Increase skip by 100 until pagination.has_more is false. See Pagination.

Save each booking by its id

Use the booking id as the key in your system. If a booking with that id exists, replace it. If not, add it. Getting the same booking twice is then harmless.

Save a checkpoint

Before each run starts, note the current time. When the run finishes, save that time minus 5 minutes as your checkpoint. The 5 minutes covers bookings that change while the run is in progress, and small clock differences.

Check for changes on a schedule

Every few minutes, run the same request with after_updated_at set to your checkpoint. Save each booking by id, then save the new checkpoint.

Here is a complete sync in JavaScript. Run it on a schedule, such as every 5 minutes:

const API = "https://api.meetonbridge.com/v1";
const headers = { Authorization: `Bearer ${process.env.BRIDGE_API_KEY}` };

async function syncBookings(checkpoint) {
  const runStartedAt = new Date();
  let skip = 0;
  let hasMore = true;

  while (hasMore) {
    const params = new URLSearchParams({ sort_by: "updated_at", order: "asc", take: "100", skip: String(skip) });
    if (checkpoint) params.set("after_updated_at", checkpoint);

    const response = await fetch(`${API}/bookings?${params}`, { headers });
    if (response.status === 429) {
      const wait = Number(response.headers.get("RateLimit-Reset") ?? 60);
      await new Promise((resolve) => setTimeout(resolve, wait * 1000));
      continue;
    }
    const body = await response.json();
    if (body.status !== "success") throw new Error(body.error.message);

    for (const booking of body.data) {
      await saveBooking(booking);
    }
    hasMore = body.pagination.has_more;
    skip += 100;
  }

  return new Date(runStartedAt.getTime() - 5 * 60 * 1000).toISOString();
}

saveBooking is your own function that adds or replaces the booking in your system. Store the value syncBookings returns and pass it in on the next run. Pass nothing on the first run.

What changes look like

ChangeWhat you see
New bookingA booking you haven't seen before, with status set to confirmed.
RescheduledThe same id with a new start and end. rescheduled_at shows when it moved.
CancelledThe same id with status set to cancelled. cancellation shows when, who cancelled (invitee, host or calendar) and the reason.
New hostThe same id with a different hosts list.

Fields worth syncing

FieldWhat it holds
attendeeThe person who booked: name, first_name, last_name, email, timezone and phone.
guestsEmail addresses of anyone else the attendee invited.
responsesAnswers to the booking page's questions. Each item has the question as it was worded when the person booked, its type and the answer.
sms_consentWhether the attendee agreed to text messages, and when. null when no phone number was given.
locationtype (bridge, in_person or none), the address and maps_url for in-person meetings, and the meeting_url for Bridge meetings.
utmUTM tags from the booking link, such as utm_source and utm_campaign.
booking_pageThe id and name of the page the booking came from.

Questions keep the wording they had when the person booked. If you later rename a question on the booking page, older bookings still show the old wording.

Tips

  • To sync one booking page only, add booking_page_id to the request.
  • To skip cancelled bookings during the first load, add status=confirmed. Keep cancelled bookings in the scheduled check so you see cancellations.
  • Checking every 5 minutes uses a few requests. Each key can make 120 requests per minute. See Rate limits.