For the backend dev mapping MEC customization onto the theme and content endpoints: real screens broken into small chunks, each paired with the JSON that would produce it.
What this guide is. The theme endpoint contract and content endpoint contract define the shape of the two APIs a MEC-customized screen depends on. This guide shows what that shape looks like filled in with real content, one visual chunk at a time, using screens that are already fully documented and screenshot-verified in the page-composition docs. It is a companion, not a replacement — always check the two contract docs for the authoritative field list; this guide shows worked instances of that shape.
Why chunked, not full-page. A full-page screenshot next to a full-page JSON payload is hard to cross-reference. Each chunk below is one visually distinct section — matching the numbered rows already used in the page-composition slot tables — paired with just the JSON that drives that section.
Every MEC-customized screen is built from exactly two upstream sources — never hardcoded per-airline in client code:
| Source | Endpoint | Drives |
|---|---|---|
| Theme | GET /api/theme/{mecId} | Colors, fonts, spacing, corner radii — the 45-token map documented in theme-endpoint-contract.html. Resolved values only, never semantic references. |
| Content | MobileContent API | Navigation tiles (MenuItem) and content cards (DocumentItem) — documented in content-endpoint-contract.html. Not every component on a MEC screen is MobileContent-driven — see the Representatives chunk below for a real counter-example. |
Some components aren't documented yet. The content contract's component↔type mapping (§4) covers card-sm, ButtonCard, TextCard, card-lg/HeroCard, and Carousels. It does not yet cover every component visible on a real MEC screen — e.g. the "listy card generic" Representatives block. Where a chunk below uses an undocumented component, this guide says so explicitly rather than inventing a schema. Treat those as open items, not gaps in this guide.
Everything below is real traffic captured off a live, authenticated UAL pilot session (production gateway, 2026-07-15) using MauiDevFlow's network monitor and its native ILogger log stream (maui-devflow MAUI network / MAUI logs) — not reconstructed from screenshots. Names/emails/phones shown are published MEC/LEC officer directory info, the same category of data already documented for DAL's Council 44 representatives elsewhere in this doc set. Auth tokens and session identifiers are excluded.
Correction to this guide's earlier framing. The Representatives, Events, and Committees content on the current, live MEC section is not MobileContent-driven at all — confirmed by capture, not inferred. The client-side entry points are IMECQueries.GetMECLECRepsAsync(scope) and GetMECLECEventsAsync(scope) (scope = MEC or LEC — confirmed via ALPADocs.Services.RestService log lines [GetMECLECRepsAsync] Scope:MEC / Scope:LEC), which call a separate, previously-undocumented carrier/* HTTP API:
GET /api/carrier/getmecreps — MEC-level representative roster (GetMECLECRepsAsync("MEC"))GET /api/carrier/getlecreps — LEC-level representative roster (GetMECLECRepsAsync("LEC"))GET /api/carrier/getmecevents — MEC-wide events feed, Exchange/Outlook-calendar backed (GetMECLECEventsAsync("MEC"))GET /api/carrier/getlecevents — LEC-scoped events feed (GetMECLECEventsAsync("LEC"))GET /api/carrier/GetCommittees — committee + volunteer directory (GetMECCommitteesAsync)This is the legacy native page's actual live data source (MyPilotGroupPageViewModel), not a hypothetical. The content contract's MenuItem/DocumentItem model remains the target shape for the new Blazor MEC pages this doc set otherwise describes — but until those pages are wired up, carrier/* is the ground truth for this content category. A backend dev extending MEC customization should decide whether the new pages call these same endpoints directly or go through a MobileContent migration — that decision isn't made in this repo yet.
Unlike Representatives/Events/Committees, the "MEC Documents" section of the same live page is genuinely DocumentItem-backed — confirmed via a real Shell navigation log line, not a guess:
This is a real 3-parameter query — Scope, Category, and Grouping — matching DataManager.GetDocumentsForScopeCategoryGroupingAsync(scope, category, grouping), one level more specific than the 2-parameter Scope+Category selection described in the content contract §5. Navigating this route rendered one real document:
| Title | Date |
|---|---|
| MEC Roster | 06/03/2026 |
The raw JSON for this specific document wasn't captured this session — the underlying bulk document fetch (GetDocumentListAsync → GET /api/doc/getdocuments) happens once and is cached in a local LiteDB store (_documentDatabase); it had already fired and been persisted before this capture window started, so no matching network request appeared in the live monitor. The route, the real category structure (Contract / Did You Know? / Roster / Policy Manual / Treasurer Reports, each with its own document count), and the rendered title+date are confirmed; the exact field-level JSON for this document is not.
Note the office_level/mec_cd/lec_cd discriminator — this exact shape is reused for LEC-level reps below, just with office_level: "LEC" and a populated lec_cd. Brian Noyes is the same real MEC Chair whose name appears in the confirmed UAL Media Hub screenshot's "Master Chair Messages" video card — independent cross-confirmation this is real production data, not a stub.
This session's LEC is 012, not CLE172 — the shape is identical to what CLE172's Representatives block (chunk 3 below) renders; only the specific roster differs per LEC.
36 events returned MEC-wide. Two of them are the exact same real events already documented from the CLE172 Figma screenshot (chunk 2 below) — confirming that screenshot's content is live, current data, not placeholder:
This is a materially different shape than the DocumentItem guess this guide originally made for CLE172's events chunk. The real event record is calendar/Exchange-backed (title/startDate/endDate/startTime/endTime/a raw HTML description body/an Exchange item id) — not a DocumentItem's Scope/Category/publishDate/image shape at all. The client strips the HTML down to the "SAVE THE DATE" / title / date display seen in the screenshot. Chunk 2 below is corrected accordingly.
This LEC (012) currently has zero LEC-scoped events — a genuine empty array, not an error. Useful as the real "no events" reference rather than guessing what an empty state should look like.
This is the full UAL committee tree (national + per-LEC committees) in one call, not paginated or scoped by category — the client presumably filters client-side for whatever subset a given screen needs. Volunteers nest one level deep per committee.
Read this before the chunks below. CLE172 is a Figma mockup for a per-LEC detail screen that does not exist in the live app yet — the live app's actual MEC section (MyPilotGroupPage, confirmed via live capture — see Live Data Samples) is a flatter, non-per-LEC list (MEC Communications, MEC Documents, MEC Committee Updates, MEC Committees, MEC Events, MEC Reps, MEC Hotels). The screenshots below are real design captures; the specific field values in chunks 1 and 4 (item ids, exact path strings) were reconstructed to match the confirmed general MenuItem shape, not independently captured for these exact items — no "CLE 172 Roster" or "Meeting Minutes Archive" MenuItem was found in any live capture this session. Chunks 2 and 3 (Events, Representatives) are independently confirmed real, since the same underlying carrier/* data drives both this mockup and the live app regardless of which screen renders it.
Chosen because it is the richest content example captured from Figma: a fully-resolved theme (no open design questions), and comms content for every slot. Full slot table: ual-mec-page-compositions.html#lec-detail.
CLE172 (20826:1699), top slice
Corrected 2026-07-15. An earlier version of this guide labeled the JSON below "confirmed live production shape ... captured off gateway.alpa.org" — that overstated it. What's actually confirmed live is the general MenuItem field shape (from unrelated top-level items — see Live Data Samples); this specific "CLE 172 Roster" item was never observed in any capture. Worse, the userFilterType: "MEC" / userFilterValue: "UAL" values below were a guess about how MEC-scoping works — the one real MEC-related item actually captured (top-level "My Pilot Group") has both fields empty, contradicting that guess. Treat the shape below as illustrative only, not a confirmed contract.
More useful real finding: a live-navigated capture found the actual app has a "MEC Documents → Roster" category containing one real document titled "MEC Roster" (dated 06/03/2026) — i.e. in the live app, "Roster" is DocumentItem content, not a MenuItem route at all. This is a real, independently-confirmed alternative to the guess below — worth checking with design/backend before assuming the new Blazor CLE172 page's Roster button should behave like this speculative MenuItem.
Fixed userFilterType/userFilterValue to empty strings to match the one real example on file, rather than the unverified "MEC"/"UAL" guess. How MenuItem-level MEC-scoping actually works (if it exists at all, distinct from the carrier/* mec_cd/lec_cd pattern) remains an open question — do not build against this field until it's confirmed.
CLE172, Upcoming Events slice
Corrected 2026-07-15 — this is not a DocumentItem feed. A live capture confirmed these two exact events come from GET /api/carrier/getmecevents (see Live Data Samples above), a calendar/Exchange-backed feed, not MobileContent. An earlier version of this guide modeled it as DocumentItem — that was an unverified guess made before this endpoint was known; the shape below is the real captured record.
Real captured record for the "GUARDIANS VS PIRATES" card (client renders the HTML description down to the "SAVE THE DATE" / date line shown in the screenshot):
The "CLEVELAND AIRSHOW" card is the same shape — real title "Family Awareness – CLE – Airshow", startDate: "9/7/2026". Both were confirmed present in the live 36-event MEC-wide feed, matching the Figma screenshot exactly.
CLE172, Representatives slice
Endpoint confirmed 2026-07-15 (this guide originally flagged this as undocumented — it no longer is). The three rows (Ed Higgins, Josh Burke, Mark Wapenaar) come from GET /api/carrier/getlecreps, keyed by LEC code (CLE172 = lec_cd: "012"... except CLE172's real code wasn't captured this session — see note below). Same shape as the real UAL LEC-012 capture in Live Data Samples above: office_level, mec_cd, lec_cd, name, status, office, termenddate, phone, email, sortorder, block.
This is not a MenuItem or DocumentItem — do not force it into that shape. The captured session's test pilot belongs to LEC-012, not CLE172, so the exact rep names in the live sample above (Phil Anderson, Tom Cross, Shanon Jamison) differ from CLE172's own roster (Ed Higgins, Josh Burke, Mark Wapenaar) — but the endpoint and field shape are confirmed identical regardless of which LEC is queried.
CLE172, bottom slice
Corrected 2026-07-15 — same issue as chunk 1. This "Meeting Minutes Archive" item was never observed in any live capture; it's a plausible reconstruction of the confirmed general MenuItem shape, not confirmed data. userFilterType/userFilterValue corrected to empty strings to match the one real example on file (see chunk 1's note).
Same shape as chunk 1, but an external link — path is a full URL rather than a client route:
If confirmed a MenuItem, an external path (starts with http) is expected to open in the in-app web view rather than the Shell router, per the general external-link pattern elsewhere in the app — not independently verified for this specific item.
DAL's theme is not shown here — DQ-15 (which surface gets which of the two candidate navy tones) is still open, and fabricating a resolved token map would misrepresent an unresolved design decision. What DAL's Home screen usefully demonstrates instead is the mock/placeholder convention already live on real screens — several feeds here are not yet populated with real content, and they render with an explicit, consistent stub shape rather than being empty. Full slot table: dal-mec-page-compositions.html#home-dal.
DAL Home, top slice
Same caveat as the CLE172 chunks above. This session's live capture was a UAL pilot session — nothing DAL-specific was independently captured. The JSON below is a plausible reconstruction matching the confirmed general MenuItem field shape, not confirmed data; userFilterType/userFilterValue are left empty to match the one real example on file (see Live Data Samples) rather than guessing "MEC"/"DAL".
The Welcome banner reads from IAuthentication/UserInfo, not MobileContent (see content contract §4, "Welcome / Pilot Card" row) — no JSON needed for that part. The Council 44 row below it, if it's a MenuItem, would plausibly look like this:
DAL Home, Publications slice
This is the same DocumentItem feed shape as CLE172's Events — this is literally what "not populated" looks like at the JSON level, not just visually. Every not-yet-content-team-populated feed across every MEC screen documented so far (DAL Publications, DAL Council Updates, DAL Notepads) uses this exact stub pattern:
If you're authoring mock data for an unbuilt MEC section, matching this exact stub shape (title: "SUBJECT LINE", lorem-ipsum description, a real but generic publishDate, image: null) is the established convention — it's what every other in-flight MEC screen already does, and it reads clearly as "structure confirmed, content pending" rather than looking like a bug.
DAL Home, Contract 2026 slice
Partial confidence, not fully captured. The card title/subtitle text ("CONTRACT COMPARISON" / "View the Contract Comparison Guide") is genuinely confirmed — it's real, screenshot-verified text from dal-mec-page-compositions.html#contract-2026, matching this session's UAL finding that not-yet-populated feeds use a distinct "SUBJECT LINE" stub pattern (chunk 3) — this one clearly isn't that. But the surrounding JSON shape (id, exact scope/category strings, path) was not independently captured this session; it's a plausible reconstruction, not confirmed data. Do not treat the field values below as confirmed — only the card's displayed text.
Same DocumentItem shape as chunk 3, illustrating the "populated" contrast against the stub pattern above:
DAL Home, Navigate + Tools slice
Same caveat as chunk 1. "PILOT DASHBOARD" is real, screenshot-confirmed tile text, but the JSON below was not independently captured this session — plausible reconstruction only, userFilterType/userFilterValue left empty to match the one real example on file rather than guessing.
"NAVIGATE" is a 3-up card-btn row — same MenuItem shape again, this time with a glyph (icon tiles use the app's icon system, not an image):
The "TOOLS" feed below it ("SCHEDULING TICKETING SYSTEM", "DART") has real, screenshot-confirmed title/description text — same caveat as chunk 4 applies to its exact JSON shape.
One complete, literal starting point: the resolved UAL theme (fully confirmed, from theme-endpoint-contract.html §4) plus the content items from the CLE172 chunks above, combined as a backend dev would actually receive/author them across the two endpoints.
Trimmed to the fields that vary per item for readability — every field from the chunk examples above is present in the real payload; this isn't a smaller schema, just a smaller listing. Events (chunk 2) and Representatives (chunk 3) are intentionally absent from this payload — both are confirmed sourced from carrier/*, not MobileContent; see Live Data Samples for their real captured shape.
DocumentItem ids; it resolves to whatever currently matches its configured Scope/Category (optionally Grouping), in the order the API returns them (content contract §5).Visible is true; ShowOnHomeScreen additionally gates home-screen tiles; SortOrder is the display order (content contract §5).userFilterType/userFilterValue scopes a MenuItem to one MEC. Set userFilterType: "MEC", userFilterValue: "UAL" (or "DAL", "FDX") to make an item MEC-specific; omit/blank for an item shared across all MECs."Surface/Brand") appear in the dynamic feed, not in the theme response.carrier/* endpoints and shapes.title: "SUBJECT LINE", lorem-ipsum description, a real publishDate, image: null. This is what every other in-progress MEC feed already does.