Skip to content

Latest commit

 

History

History
196 lines (140 loc) · 6.59 KB

File metadata and controls

196 lines (140 loc) · 6.59 KB

The m-anage / VMX programme API

Technical reference, reconstructed on 2026-08-03 from the public "Programme at a Glance" (PAG) page of a congress. Scope: the public area before any login. Every endpoint documented here is one the PAG page itself calls while nobody is signed in.


How the page is built

The PAG page is a thin Vue single-page-application shell (~5 KB of HTML served from a CDN) that bootstraps a <manage-pag> web component. The URL path segments are the configuration:

https://pag.virtual-meeting.org/<INSTANCE>/<EVENTSHORT>/<LANGUAGE>/pag
                                 MCON      kkj2026      de-DE

The application bundle is public and contains the complete instance→host configuration in cleartext:

https://vmx-components.m-anage.com/m-anage.com.pag-standalone/m-anage.com.component.pag-standalone-feature-solr.dev.js

Two backends

Backend Host Auth Role
m-anage Core per instance, e.g. api.congress.mcon-mannheim.de none event metadata, discovery, translations
VMX / Solr api-lb.virtual-meeting.net static Basic auth programme data: sessions, talks, rooms

Authentication on the programme API

Authorization: Basic bS1ldmVudHM6a2ltcw==     # base64("m-events:kims")

These are not user credentials. They appear as a literal in the platform's publicly served JavaScript (Authorization:"Basic "+btoa("m-events:kims")), where they serve anonymous reading of the public programme. They open nothing behind the login. Without the header the API answers 401 {"error":"Unauthorized: "}.

Recovering the credential

If the API starts answering 401, the platform has rotated this value. To recover it:

  1. Open the PAG page of any congress on the platform.
  2. Open the application bundle URL above (or find it in the page source).
  3. Search the file for btoa( — the credential is the string literal passed to it.
  4. Update SOLR_AUTH in pag-extract.mjs.

A pull request with the new value is very welcome.


Discovery — the entry point

Resolves both internal ids from the event shortname. Without this step the ids would have to be hardcoded; with it, access is generic across every congress.

GET https://api.congress.mcon-mannheim.de/api/Core/GetVMXHeader?shortname=kkj2026&language=de-DE
Field Example Meaning
EventId 872 m-anage internal event id
VMEventId 969 VMX/Solr event id — required for all programme data
EventName Kongress für Kinder- und Jugendmedizin display name
EventFrom / EventTo 2026-11-18 / 2026-11-21 congress span
EventLanguages ["de-DE"] available languages

Never hardcode VMEventId. Always resolve it through GetVMXHeader.


Programme endpoints

Base: https://api-lb.virtual-meeting.net

Congress days

GET /v1/events/{VMEventId}/dates.json?use_cache=1

Returns an array of { date, contentsessions_count, first_contentsession_starts_at, last_contentsession_ends_at }.

Sessions of one day, grouped by room

GET /v1/rooms.json
    ?event_id={VMEventId}
    &starts_at_from=YYYY-MM-DD
    &per_page=100
    &include_contentsessions=1
    &include_contentsessiontags=1
    &from_body=1
    &page=1
    &include_sponsor=1

Returns an array of rooms, each carrying contentsessions[].

Despite its name, starts_at_from filters to exactly that day — verified: no sessions leak into later days, and no session appears in two day queries.

Session fields (a selection of 60+): id, title, subtitle, starts_at_local, ends_at_local, room.title, contentsessiontype, contentsessiontopic, contentsessiontags[], chairs[], description, cme_points, is_poster, sponsor.

Person objects (chairs[], authors[]) carry academic_title, firstname, surname, city, country. Contact fields (email, street, zip) are null on the public endpoints.

The include_sponsor parameter

=1 additionally returns industry / sponsored sessions; =0 returns the scientific programme only. For the reference congress: 144 vs 119 sessions.

Note that the platform's own per-day counts in dates.json (120 in total) match neither figure exactly — the two counters apply different filters. =1 is what the live page sends and is the tool's default.

Individual talks (paginated)

GET /v1/media_items.json
    ?event_ids={VMEventId}
    &from_body=1
    &hide_on_pag_search=-1
    &per_page=100
    &page=N

Pagination is driven by response headers: X-Total, X-Total-Pages, X-Page, X-Per-Page. For the reference congress: 666 talks.

The payload sits under .body: title, starts_at_local, contentsession.{id,title} (the link back to its session), main_author, authors[], topic, keywords[], ref, external_abstract_url.

Filter taxonomy

GET /v1/media_items/filters.json
    ?event_ids={VMEventId}&from_body=1&per_page=1
    &filters=contentsessiontype_ids,contentsessiontrack_ids,contentsessiontopic_ids,...

Other observed endpoints (m-anage Core, no auth)

GET /api/Modules/PAGData/?eventid={EventId}      # compressed layout/config blob
GET /api/Modules/PAGRooms?eventid={EventId}
GET /api/modules/GetResources?eventshort=X&setname={PAG|VMX|general|config_json|PAGTheme|AppTranslations}&language=de-DE
GET /api/Core/ServerTime

Adding a new organisation

Each organisation ("instance") has its own m-anage Core host. The known map lives in API_HOSTS in pag-extract.mjs. To add one:

  1. Open the PAG page of that congress.
  2. Open the application bundle (see top of this document).
  3. Search for the instance name followed by apiBaseUrl: — e.g. mcon:{oauth2:{...},apiBaseUrl:"https://api.congress.mcon-mannheim.de".
  4. Add instance: "https://…" to API_HOSTS and open a pull request.

Alternatively, open the browser developer tools on the Network tab and read the host of the GetVMXHeader request.


Stability risks

  1. The static Basic credential is hardcoded in the vendor bundle and can change on any platform release. See Recovering the credential.
  2. The bundle filename carries dev yet is the production artefact. It may be renamed.
  3. VMEventId must always be resolved, never hardcoded.
  4. The instance→host map grows as organisations join the platform.

Courtesy

The endpoints above are read-only and unthrottled as far as observed. A full programme extraction is a handful of requests. Please keep it that way: cache results locally, do not poll, and do not run this on a schedule tighter than the data actually changes.