Northwind Tutoring Nebulm Meet integration demo
Demo · Built on Nebulm Meet

Live lessons, right inside your own site.

Northwind Tutoring is a made-up tutoring marketplace. Every lesson is a Nebulm Meet meeting in an iframe: no accounts for students, no app to install, and the call speaks to the page around it.

Checking the connection…
How it works

Three steps, one API key, zero video code.

Your server talks to the Nebulm Meet API. Your page shows an iframe. Nebulm runs the call.

1

Your server mints a join link

Create a meeting for the lesson, then a signed join link for each person. The link fixes their name and role, so nobody signs up and nobody can rename themselves.

  • The API key stays on your server: Authorization: Bearer …
  • Roles: host, participant, viewer
  • externalUserId comes back in attendance and webhooks
  • Links skip the waiting room and expire (1 min – 30 days)
server.js · Node
// The API key never leaves your server.
const NEBULM = 'https://meet.nebulm.com/api/v1';
const headers = {
  Authorization: `Bearer ${process.env.NEBULM_API_KEY}`,
  'Content-Type': 'application/json',
};

// 1. One meeting per lesson
const { meeting } = await fetch(`${NEBULM}/meetings`, {
  method: 'POST', headers,
  body: JSON.stringify({ title: 'Algebra with Ms. Rivera', externalId: lesson.id }),
}).then((r) => r.json());

// 2. A join link per person: name and role fixed by it
const { joinLink } = await fetch(`${NEBULM}/meetings/${meeting.id}/join-links`, {
  method: 'POST', headers,
  body: JSON.stringify({
    displayName: student.name, role: 'participant',
    externalUserId: student.id, expiresInSec: 7200,
  }),
}).then((r) => r.json());

res.json({ joinUrl: joinLink.url }); // https://meet.nebulm.com/embed/…#t=…
2

Your page shows it in an iframe

Put the link’s url in an iframe. It opens on a camera check (or straight into the call with ?prejoin=0), branded with your organization.

  • Add your site under Settings → Developers → Sites that can embed meetings, or browsers refuse the frame
  • allow= lets the call use the camera, mic and screen share
  • Options: ?prejoin=0, ?mic=0, ?cam=0 (before the #)
lesson.html
<iframe
  src="{joinUrl}"
  allow="camera; microphone; display-capture; fullscreen; autoplay; clipboard-write; screen-wake-lock"
  allowfullscreen
  style="width:100%; height:640px; border:0; border-radius:16px">
</iframe>
3

The call tells your page what happened

The embedded meeting posts events to the parent page, but only to the origins you allowed. React to them: show a summary when the lesson ends, a “rejoin” hint when someone leaves.

  • Check event.origin and source: 'nebulm-meet'
  • For server-side truth, add a webhook: participant.joined, meeting.ended, recording.ready…
lesson.js
window.addEventListener('message', (event) => {
  if (event.origin !== 'https://meet.nebulm.com') return;
  const msg = event.data;
  if (!msg || msg.source !== 'nebulm-meet') return;

  // msg.type: ready · joined · left · ended · removed · visit-ended · error
  if (msg.type === 'ended') showLessonSummary(msg.meetingId);
  if (msg.type === 'error') showHelp(msg.code); // e.g. link_expired
});
The events

What the iframe sends

Every message is { source: 'nebulm-meet', type, meetingId }, plus code on errors. The live demo shows them as they arrive.

ready

The link was checked and the meeting page loaded. The person sees the camera check next.

joined

They went into the call (from the camera check, or straight away with ?prejoin=0).

left

They left the call. The frame offers “Rejoin”.

ended

The meeting is over: a host ended it for everyone, or it had already ended.

removed

A host removed them. Their link stops working until a host lets them back in.

visit-ended

A host wrapped up this person’s visit (rooms). They can’t come back until a host lets them.

error

The link couldn’t be used. code says why: link_expired, link_revoked, meeting_locked, meeting_full…

Setup

What this demo needed

Three things in the Nebulm Meet dashboard of the organization that owns the meetings.

An API key

Settings → Developers → API keys, with the scopes meetings:read and meetings:write. It lives in this server’s environment, never in the browser.

An embed origin

Add this site’s origin to Sites that can embed meetings. Only those origins can frame meetings and receive the iframe’s events.

Optional: a webhook

Add an endpoint for participant.joined, meeting.ended or recording.ready to keep your own records in step, signed and retried.

See it working

Start a lesson, then open the invite link on your phone to join as a student.

Start a lesson