This page lists every webhook event MeetOne can deliver, with a full example payload for each.

Event summary

Room events

Event Fired when
room.created A room is created (admin UI or public API).
room.reopened A closed room is reopened from the admin UI.
room.closed A room is closed (billing is calculated at the same time).
room.billing_calculated Billing for a room is calculated or recalculated.
room.deleted A room is deleted. Also fires once per room in a bulk delete.
room.participant_joined A host or guest joins the video call.
room.participant_left A host or guest leaves the video call (explicit leave, tab close, navigation, or connection drop).

Appointment events

Event Fired when
appointment.created An appointment is created (admin, API, doctor, patient booking, or onboarding).
appointment.cancel An appointment is cancelled.
appointment.complete An appointment is completed, with or without a prescription.
appointment.schedule An unscheduled appointment request is scheduled by a doctor.
appointment.reschedule A confirmed appointment is rescheduled to a new time.
appointment.reopen A completed appointment is reopened.
appointment.prescription_complete A prescription has been signed and the signed PDF is available.

Appointment events are only available on full-platform MeetOne instances. Rooms-only instances can only configure and receive room.* events.

Each endpoint only receives events it explicitly subscribes to — a newly released event is never automatically added to existing endpoints.

Envelope

Every delivery wraps its payload in the same envelope:

{
  "event": "room.created",
  "payload": { ... }
}

Payload shapes below are stable but may gain additional fields over time — your integration should ignore unknown fields rather than fail on them. Timestamps are ISO 8601 strings with a UTC offset, e.g. 2026-04-16T14:30:00+02:00.

Privacy model for room events

room.created and room.reopened include the raw call-entry credentials for the room — access_token, guest_token, the join URLs, and any additional participant tokens. Anyone holding these values can join the call as that participant.

Every other room event (room.closed, room.billing_calculated, room.participant_joined, room.participant_left) never includes raw tokens. Instead, participants are identified by a participant_hash: a deterministic, non-reversible 16-character SHA-256 prefix of the participant's access token. It cannot be used to join a call, but it is stable across every webhook event for the same participant in the same room, so you can use it to correlate a participant across join, leave, and billing events.

Treat the receiver of room.created / room.reopened payloads with the same care as your signing secret — a leak exposes working call credentials, not just a hash.

room.created, room.reopened

{
  "event": "room.created",
  "payload": {
    "token": "4402b290c75ec165",
    "name": "Consultation with Dr. Doe",
    "status": "active",
    "access_token": "a1b2c3d4e5f6...",
    "guest_token": "g1h2i3j4k5l6...",
    "expected_guest_count": 1,
    "meeting_duration": 15,
    "enable_chat": true,
    "enable_screenshare": true,
    "enable_invites": true,
    "scheduled_at": "2026-04-16T14:30:00+02:00",
    "created_at": "2026-04-11T12:00:00+02:00",
    "host_join_url": "https://your-tenant.meetone.io/r/a1b2c3d4e5f6...",
    "guest_join_url": "https://your-tenant.meetone.io/r/g1h2i3j4k5l6...",
    "additional_access_tokens": [
      {
        "id": 7,
        "token": "x1y2z3...",
        "join_url": "https://your-tenant.meetone.io/r/x1y2z3..."
      }
    ]
  }
}

additional_access_tokens is only present when your instance has additional room participants enabled. room.reopened carries the same shape plus an updated_at field.

room.closed

{
  "event": "room.closed",
  "payload": {
    "token": "4402b290c75ec165",
    "name": "Consultation with Dr. Doe",
    "status": "closed",
    "scheduled_at": "2026-04-16T14:30:00+02:00",
    "started_at": "2026-04-16T14:31:12+02:00",
    "ended_at": "2026-04-16T14:45:58+02:00",
    "closed_at": "2026-04-16T14:46:00+02:00",
    "billing": {
      "total_billable_minutes": 15,
      "is_billable": true,
      "participants": [
        {
          "participant_hash": "9c4f0bef83a14a90",
          "type": "host",
          "first_seen_at": 1744813872,
          "last_seen_at": 1744814758,
          "overlap_start": 1744813872,
          "overlap_end": 1744814758,
          "overlap_seconds": 886,
          "raw_minutes": 14.77,
          "billable_minutes": 15
        }
      ]
    }
  }
}

room.billing_calculated

{
  "event": "room.billing_calculated",
  "payload": {
    "token": "4402b290c75ec165",
    "name": "Consultation with Dr. Doe",
    "total_billable_minutes": 15,
    "billing_calculated_at": "2026-04-16T14:46:00+02:00",
    "is_billable": true,
    "participants": [
      {
        "participant_hash": "9c4f0bef83a14a90",
        "type": "host",
        "first_seen_at": 1744813872,
        "last_seen_at": 1744814758,
        "overlap_start": 1744813872,
        "overlap_end": 1744814758,
        "overlap_seconds": 886,
        "raw_minutes": 14.77,
        "billable_minutes": 15
      }
    ]
  }
}

This event fires whenever billing for a room is calculated or recalculated — typically right after room.closed, but also whenever billing data is recomputed afterward.

room.deleted

{
  "event": "room.deleted",
  "payload": {
    "token": "4402b290c75ec165",
    "name": "Consultation with Dr. Doe",
    "status": "active"
  }
}

Fires once per room. A bulk delete of several rooms produces one room.deleted delivery per room.

room.participant_joined, room.participant_left

{
  "event": "room.participant_joined",
  "payload": {
    "token": "4402b290c75ec165",
    "name": "Consultation with Dr. Doe",
    "status": "started",
    "participant_hash": "9c4f0bef83a14a90",
    "participant_type": "host"
  }
}

participant_type is "host" or "guest". These events are debounced against MeetOne's live participant tracker, so a brief reconnect or tab navigation does not generate spurious join/leave pairs — room.participant_left only fires once a participant has genuinely gone offline.

appointment.created

{
  "event": "appointment.created",
  "payload": {
    "access_token": "22a17439daa281a36cb34ba1b6888505",
    "external_identifier": "",
    "duration": 30,
    "status": "confirmed",
    "scheduled_at": "2026-04-16T14:30:00+02:00",
    "created_at": "2026-04-11T12:00:00+02:00",
    "doctor": {
      "id": 42,
      "full_name": "Dr. Jane Doe",
      "address_place": "Berlin",
      "address_zipcode": "10243",
      "address_country": "Germany"
    }
  }
}

appointment.cancel, appointment.complete, appointment.schedule, appointment.reschedule, appointment.reopen

These five events all carry the full appointment record — the same representation used elsewhere in the platform — rather than a slimmed-down event-specific body. Top-level keys include:

id, external_identifier, access_token, duration, scheduled_at,
confirmed_at, completed_at, cancelled_at, created_at, updated_at,
confirmation_reminder_sent_at, reminder_sent_at,
completed_status, cancelled_reason, message_to_doctor, message_to_patient,
doctor_personal_notes, medical_history, patient { ... }, doctor { ... },
room { ... }, completed_by { ... }, cancelled_by { ... }

patient, doctor, room, completed_by, and cancelled_by are nested objects with their own fields.

This payload includes patient personal data (name, contact details, address, and medical history where present). Handle and store it according to the data protection requirements that apply to your integration.

To see the exact shape for your instance, inspect a real delivery in the admin under Webhook Events, or trigger the event against a test appointment — see Testing webhooks locally.

appointment.prescription_complete

{
  "event": "appointment.prescription_complete",
  "payload": {
    "access_token": "22a17439daa281a36cb34ba1b6888505",
    "external_identifier": "",
    "prescription_pdf_url": "https://your-tenant.meetone.io/path/to/.../signed.pdf",
    "prescription_pdf_signed_at": "2026-04-11T12:00:00+02:00",
    "prescription_pdf_created_at": "2026-04-11T11:55:00+02:00"
  }
}

prescription_pdf_url is a pre-signed URL that streams the signed PDF directly. It expires, so download the file soon after receiving the event.

Questions? Contact us at support@meetone.io.