JSON API (LMS v1)
HMAC-signed REST for custom backends. Moodle plugins should use the LMS wire API instead.
Base URL
https://{slug}.2meet.ir/lms/v1/
Authentication (HMAC)
| Header | Value |
|---|---|
X-2meet-Timestamp | Unix seconds (UTC); skew ≤ 5 minutes |
X-2meet-Signature | Hex HMAC-SHA256 (lowercase) of payload below |
X-2meet-Reseller-Slug | Optional if slug is already in the hostname |
payload = "{timestamp}\n{METHOD}\n{path}\n{body}"
signature = hex(HMAC-SHA256(integration_secret, payload))
For GET requests, body is the empty string. path is the URL path only (no host, no query).
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /meetings | Create (JSON) — logo + cover via URL fields |
| GET | /meetings | List (paginated) |
| GET | /meetings/{id} | Detail (internal UUID) |
| PATCH | /meetings/{id} | Update name / logout / cover_url / org |
| DELETE | /meetings/{id} | End meeting |
| GET | /meetings/{id}/report | Attendance report (see below) |
| POST | /meetings/{id}/join-links | Fresh join URLs with per-user identity |
Create meeting
POST /meetings — pure JSON. For LMS, send image links (cover_url + org.logo_url). No file upload required.
{
"name": "کلاس ریاضی — هفته ۳",
"external_id": "course-42-week-3",
"max_participants": 80,
"session_mode": "lecture",
"duration_minutes": 90,
"logout_url": "https://lms.example/course/view.php?id=5",
"cover_url": "https://lms.example/media/class-cover.jpg",
"org": {
"org_display_name": "آکادمی نمونه",
"logo_url": "https://lms.example/media/school-logo.png"
}
}
| Field | Required | Description |
|---|---|---|
name | Yes | Session title |
external_id | Recommended | Stable LMS id (attendance report aggregates by this) |
max_participants | No | Default 80 |
session_mode | No | lecture (default) or interactive |
duration_minutes | No | Hard time cap; omit → 10 min demo default |
logout_url | No | Return URL after leave/end |
cover_url | No | Absolute http(s) URL of stage cover image (applied when class goes live) |
org | No | School branding object (see below) |
org.logo_url | No | Absolute http(s) URL of school/class logo in the desktop header |
org.org_display_name | No | School/academy short name (tab title + chrome) |
org.org_name | No | Optional legal/internal name |
features | No | Per-session feature toggles |
School / class logo (org)
On create (or PATCH), snapshot branding into the meeting:
org.logo_urlset → logo on the left of the desktop header- No logo → centered 2Meet wordmark on desktop (hidden on phone)
"org": {
"org_display_name": "آکادمی نمونه",
"logo_url": "https://lms.example/media/school-logo.png"
}
Wire create: meta_org_logo_url, meta_org_display_name, meta_org_name.
Session cover (cover_url)
Static image on the video stage when the host camera is off or before start.
Primary (LMS): pass a link on create / PATCH — no binary upload:
{ "cover_url": "https://lms.example/media/class-cover.jpg" }
Wire: meta_cover_url=https://…. Applied when the class goes live. Clients then load GET /api/v1/portal/sessions/{sessionId}/cover.
Advanced only: multipart file field cover on create, or POST /meetings/{id}/cover — not needed when you already have a public image URL.
Join identity (per user)
Create returns generic join URLs. Before sending a user into the room, call POST /meetings/{id}/join-links. Always send user_id for attendance.
POST /meetings/{meeting_id}/join-links
{
"display_name": "Alice Teacher",
"avatar_url": "https://lms.example/avatars/alice.jpg",
"user_id": "42",
"role": "moderator",
"logout_url": "https://lms.example/mod/bigbluebuttonbn/view.php?id=9"
}
Attendance report
Pull-only grading / attendance (HMAC):
GET /meetings/{id}/report
{id} | Behavior |
|---|---|
Your external_id | Aggregates all occurrences (presence, joins, voice/video, class wall-clock). Includes occurrence_count. |
| Internal meeting UUID | Single occurrence only |
{
"meeting_id": "course-42-week-3",
"occurrence_count": 4,
"participant_count": 12,
"total_duration_seconds": 13828,
"participants": [
{
"user_id": "42",
"display_name": "Alice Teacher",
"joined": true,
"total_duration_seconds": 12040,
"join_count": 8,
"voice_minutes": 164,
"video_minutes": 132
}
]
}