Portal developers integrate via the MobileContent.ApiClient.Admin NuGet package (IAdminApiClient). The Admin API provides full CRUD for sites, pages (including containers and items), and themes. All write operations target draft state. Separate workflow actions (publish, schedule, revert, archive) control the content lifecycle. A config endpoint provides enum values for all dropdown fields so nothing is hardcoded client-side.
Auth: All Admin endpoints are currently [AllowAnonymous] for development. Tighten to [Authorize] before production.
NuGet Setup
// Program.cs
services.AddHttpClient<IAdminApiClient, AdminApiClient>(client =>
{
client.BaseAddress = new Uri("https://gatewayapi.alpa.org");
// Add auth headers as needed
});
Sites
Sites are the top-level container. A site has a unique lowercase key (semantic identifier), a description, and an optional active theme. Deleting a site performs a soft delete (IsActive = false); it can be restored.
Endpoints
GET /api/mobilecontent/admin/site → IEnumerable<SiteDto>
GET /api/mobilecontent/admin/site/{siteKey} → SiteDto
GET /api/mobilecontent/admin/site/{siteKey}/pages/inactive → IEnumerable<PageDto> (soft-deleted pages only)
POST /api/mobilecontent/admin/site → SiteDto (201 Created)
PUT /api/mobilecontent/admin/site/{siteKey} → SiteDto
PATCH /api/mobilecontent/admin/site/{siteKey} → SiteDto (partial update)
DELETE /api/mobilecontent/admin/site/{siteKey} → 204 No Content (soft delete)
POST /api/mobilecontent/admin/site/{siteKey}/restore → 204 No Content
GET query parameters
Parameter
Type
Default
Description
includeInactive
bool
false
When true, includes soft-deleted sites in the results. Active pages within each site are still filtered to active-only.
The GET {siteKey} and GET (list) endpoints only include active pages in the pages collection. To see soft-deleted pages for a site use GET {siteKey}/pages/inactive.
AdminSiteRequest (POST / PUT body)
Field
Type
Required
Notes
siteKey
string
Yes
Unique lowercase identifier. Normalized on save.
description
string
Yes
Human-readable label for the site.
activeTheme
string?
No
Key of the theme (from DynamicThemes). Resolved to a GUID on save. Sets the default theme for all pages in this site.
AdminSitePatchRequest (PATCH body)
Send only the fields you want to change. Omitted fields are left unchanged.
Field
Type
Notes
description
string?
Updates the human-readable label. Omit to leave unchanged.
activeTheme
string?
Sets a new active theme by key (e.g. brand-dark). Omit to leave unchanged.
clearActiveTheme
bool
When true, removes the active theme assignment regardless of activeTheme.
SiteDto (response)
Field
Type
Notes
id
guid
Database PK.
key
string
Unique lowercase identifier.
description
string
Human-readable label for the site.
activeThemeId
guid?
GUID of the active theme, if assigned.
activeThemeKey
string?
Key of the active theme, if assigned.
pages
PageDto[]
Active pages only, ordered by sortOrder. Use /pages/inactive to retrieve soft-deleted pages.
Pages
A page belongs to a site and carries its own workflow state, sort order, and optional theme override. The page shell (key, title, sort order, theme) is managed via CRUD endpoints. Containers and items are managed via sub-resource endpoints on the same page controller. Content is editable only in Draft state.
Page Shell Endpoints
GET /api/mobilecontent/admin/site/{siteKey}/page/{pageKey} → PageDto
GET /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}?includeInactive=true
POST /api/mobilecontent/admin/site/{siteKey}/page → PageDto (201 Created)
PUT /api/mobilecontent/admin/site/{siteKey}/page/{pageKey} → PageDto
PATCH /api/mobilecontent/admin/site/{siteKey}/page/{pageKey} → PageDto (partial update)
DELETE /api/mobilecontent/admin/site/{siteKey}/page/{pageKey} → 204 No Content (soft delete)
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/reactivate → 204 No Content
PageDto (response)
Field
Type
Notes
id
guid
Database PK.
key
string
Unique slug within the site.
title
string?
Display title.
sortOrder
int
Position within the site's page list.
parentPageId
guid?
GUID of the parent page for nested hierarchies. Null for root-level pages.
langFallbackPageKey
string?
Key of the fallback page to serve when no locale-specific content exists.
activeThemeId
guid?
GUID of the per-page theme override. When null, the site-level theme applies.
activeThemeKey
string?
Key of the per-page theme override.
workflowState
string
Draft / Published / Unpublished / Archived.
activeSnapshotId
guid?
GUID of the currently published snapshot. Null if never published.
previewMessage
string
Non-empty when the response is a draft preview rather than a published snapshot.
isLocked
bool
True while another admin user has the page open for editing.
lockedByUser
string?
Identity of the user holding the edit lock. Null when not locked.
hasDraftChanges
bool
True when the draft content has been modified since the last publish. Use to display an “unpublished changes” badge. Cleared automatically on publish.
createdAt
DateTime
UTC timestamp when the page record was first created.
updatedAt
DateTime
UTC timestamp of the most recent change to the page record.
containers
ContainerDto[]
Ordered by sortOrder.
AdminPageRequest (POST / PUT body)
The site is identified via the route ({siteKey}) and must not be repeated in the request body.
Field
Type
Required
Notes
pageKey
string
No
Optional. When omitted the server slugifies title and resolves collisions by appending -1, -2, etc. When supplied it is used as-is; a 409 is returned if it already exists within the site.
title
string?
No
Display title shown in the admin UI.
sortOrder
int
No
Ordering hint within the site. Default 0.
activeTheme
string?
No
Key of the theme to override the site-level theme for this page (e.g. brand-dark). Resolved to a GUID on save.
scheduledPublishDate
DateTime?
No
UTC. Sets an auto-publish schedule at creation/update time.
AdminPagePatchRequest (PATCH body)
Send only the fields you want to change. Omitted fields are left unchanged.
Field
Type
Notes
title
string?
Updates the display title. Omit to leave unchanged.
sortOrder
int?
Updates the position within the site's page list. Omit to leave unchanged.
activeTheme
string?
Sets a per-page theme override by key (e.g. brand-dark). Omit to leave unchanged.
clearActiveTheme
bool
When true, removes the page-level theme override so the site theme applies.
Container Endpoints
Containers are ordered layout blocks on a page. pageKey is included in container routes for clarity, but only containerId (a GUID) is used for get/update/delete.
GET /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/container/{containerId} → ContainerDto (includes items, sortOrder)
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/container → ContainerDto
PUT /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/container/{containerId} → ContainerDto
DELETE /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/container/{containerId} → 204 No Content
AdminContainerRequest (POST / PUT body)
Field
Type
Required
Notes
containerType
string
Yes
Must match an active entry in the DynamicContainerTypes table. See Config endpoint.
title
string?
No
Optional display title shown above the container.
viewAllText
string?
No
Label for the "view all" action link.
viewAllLink
string?
No
URL or deep-link for the "view all" action.
columns
int?
No
Column count hint for grid layouts.
backgroundToken
string?
No
Any string token identifier for the container background. Passed through to the mobile client as-is.
cornerRadiusToken
string?
No
Any string token identifier for the container corner radius.
paddingToken
string?
No
Any string token identifier for the container padding.
titleToken
string?
No
Theme token path applied to the container title text color/style.
viewAllLinkToken
string?
No
Theme token path applied to the “view all” link element.
isSortable
bool
No
Whether the mobile app should allow item drag-reorder. Default true.
sortOrder
int
No
Display order of this container within the page.
Item Endpoints
Items are atomic content elements nested inside a container.
GET /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/container/{containerId}/item/{itemId} → ItemDto
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/container/{containerId}/item → ItemDto
PUT /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/container/{containerId}/item/{itemId} → ItemDto
DELETE /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/container/{containerId}/item/{itemId} → 204 No Content
AdminItemRequest (POST / PUT body)
Field
Type
Required
Notes
itemType
string
Yes
Must match an active entry in the DynamicItemTypes table. See Config.
tokenOverrides
string?
No
JSON object of theme token overrides scoped to this item (e.g., {"Surface/Brand":"#ff0000"}). Stored as-is; applied by the mobile client on top of the active theme.
isSortable
bool
No
Default true.
sortOrder
int
No
Display order within the container.
title
string?
No
Primary title / heading text.
headerText
string?
No
Secondary header text.
description
string?
No
Body text (up to 2000 chars).
eyebrow
string?
No
Small label above the title.
label
string?
No
Supplemental label text.
image
string?
No
Image URL or asset path.
link
string?
No
Primary navigation URL or deep-link.
linkText
string?
No
Display text for the primary link.
ctaText
string?
No
Call-to-action button label.
ctaLink
string?
No
Call-to-action destination URL.
backgroundToken
string?
No
Any string token identifier for the item background. Passed through to the mobile client as-is.
eyebrowToken
string?
No
Theme token path applied to the eyebrow text color/style.
titleToken
string?
No
Theme token path applied to the title text color/style.
descriptionToken
string?
No
Theme token path applied to the description text color/style.
headerTextToken
string?
No
Theme token path applied to the header text color/style.
identityToken
string?
No
Theme token path used to resolve user/member identity styling.
contractLinkToken
string?
No
Theme token path applied to the contract link element.
ctaTextToken
string?
No
Theme token path applied to the call-to-action button text.
rosterTitleToken
string?
No
Theme token path applied to the roster section title.
rosterNameToken
string?
No
Theme token path applied to roster member name text.
rosterEmailToken
string?
No
Theme token path applied to roster member email text.
rosterTelToken
string?
No
Theme token path applied to roster member telephone text.
viewAllLinkToken
string?
No
Theme token path applied to the “view all” link within an item.
iconSizeToken
string?
No
Theme token path controlling the size of an icon element within the item.
iconColorToken
string?
No
Theme token path controlling the color of an icon element within the item.
template
string?
No
Free-form JSON string carrying item-type-specific layout or data payload.
Page Workflow
Every page has a WorkflowState. The workflow endpoints transition pages between states and manage scheduling. All workflow actions accept a callerUser identity from the bearer token and stamp it on the snapshot.
State Transitions
From
Action
To
Endpoint
Draft
Publish immediately
Published
POST …/{pageKey}/publish (no future date)
Draft
Schedule publish
Draft (pending)
POST …/{pageKey}/publish with future scheduledPublishDate
Published
Unpublish immediately
Unpublished
POST …/{pageKey}/unpublish (no future date)
Published
Schedule unpublish
Published (pending)
POST …/{pageKey}/unpublish with future scheduledUnpublishDate
Unpublished
Re-publish from existing snapshot
Published
POST …/{pageKey}/republish
Any
Archive (retire)
Archived
POST …/{pageKey}/archive
Archived
Restore to draft
Draft
POST …/{pageKey}/restore
Draft
Rollback draft to past snapshot
Draft
POST …/{pageKey}/revert
Workflow Endpoints
GET /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/workflow → PageWorkflowDto
GET /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/versions → IEnumerable<PageVersionSummaryDto>
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/publish → { pageKey, versionNumber, message }
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/unpublish → { pageKey, message }
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/republish → { pageKey, message }
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/revert → { pageKey, message }
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/archive → { pageKey, message }
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/restore → { pageKey, message }
DELETE /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/schedule/publish → { pageKey, message }
DELETE /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/schedule/unpublish → { pageKey, message }
PUT /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/preview-users → { pageKey, previewUsers }
POST /api/mobilecontent/admin/site/{siteKey}/page/{pageKey}/lock → { pageKey, lockedBy }
POST /api/mobilecontent/admin/page/{pageKey}/unlock → { pageKey, message }
POST /api/mobilecontent/admin/page/{pageKey}/force-unlock → { pageKey, message }
AdminPublishPageRequest (POST /publish body)
Field
Type
Notes
notes
string?
Optional human-readable note stored with the snapshot (e.g., "Holiday campaign v2").
scheduledPublishDate
DateTime?
UTC. When set to a future time the page is NOT published immediately — the background scheduler fires the publish when the time is reached. When null or in the past, publishes immediately.
scheduledUnpublishDate
DateTime?
UTC. Optional auto-expiry. When set, the scheduler automatically unpublishes the page after it goes live. Can be combined with scheduledPublishDate to configure the full lifecycle in one call.
AdminUnpublishPageRequest (POST /unpublish body)
Field
Type
Notes
scheduledUnpublishDate
DateTime?
UTC. When set to a future time, unpublish is deferred to that time instead of firing immediately.
AdminRevertPageRequest (POST /revert body)
Field
Type
Notes
versionNumber
int
The snapshot version to restore as the new draft. Must exist in the page's snapshot history.
PageWorkflowDto (GET /workflow response)
Field
Type
Description
pageKey
string
workflowState
int
0=Draft, 1=Published, 2=Unpublished, 3=Archived
activeVersionNumber
int?
Version number of the currently active snapshot. Null if never published.
lastPublishedDateTime
DateTime?
UTC timestamp of the most recent publish action.
lastPublishedByUser
string?
Identity of who last published.
totalVersions
int
Number of snapshots in history.
previewUsers
string[]
User/group IDs that can preview the draft on mobile.
scheduledPublishDate
DateTime?
Non-null when an auto-publish is pending.
scheduledUnpublishDate
DateTime?
Non-null when an auto-unpublish is pending.
PageVersionSummaryDto (GET /versions list item)
Field
Type
Description
versionNumber
int
Monotonically increasing per page.
publishedByUser
string
Identity of the publisher.
publishedDateTime
DateTime
UTC publish timestamp.
notes
string?
Optional notes from the publish request.
Preview Users
stored in DynamicPagePreviewUsers
PUT /api/mobilecontent/admin/page/{pageKey}/preview-users accepts a List<string> body and fully replaces the current list.
Page Locking
The lock system prevents two portal users from overwriting each other's edits. The portal should lock a page when a user opens it for editing, and unlock it when they save or cancel. If a user closes their browser without unlocking, an admin can use force-unlock to clear the stale lock.
Endpoint
Who calls it
Behaviour
POST …/{pageKey}/lock
Editing user
Sets isLocked = true and records lockedByUser. Returns 409 Conflict if the page is already locked by a different user. Re-locking by the same user is idempotent.
POST …/{pageKey}/unlock
Editing user (on save or cancel)
Clears isLocked and lockedByUser. Always succeeds for any caller (no ownership check — the portal should only show this button to the lock owner).
POST …/{pageKey}/force-unlock
Admin
Clears the lock regardless of who set it. Use when a user forgot to unlock/save a draft they were editing.
The isLocked, lockedByUser, hasDraftChanges, createdAt, and updatedAt fields are returned on every PageDto response (including inside SiteDto.pages), so the portal can show lock badges, “unpublished changes” indicators, and timestamps without a separate API call.
Scheduling & Background Scheduler
The PageSchedulerService runs as a hosted background service. It polls periodically and fires pending scheduled publishes and unpublishes. When ScheduledPublishDate is reached, the page is published exactly as if the publish endpoint was called manually. When ScheduledUnpublishDate is reached, the page is unpublished. Use DELETE …/schedule/publish or DELETE …/schedule/unpublish to cancel a pending schedule before it fires.
Themes
Themes are named sets of design tokens. Creating a theme registers the shell (key, title, and optional description). When key is omitted on create, the server slugifies title to produce one. Tokens are managed separately via the token endpoints. Publishing a theme creates a JSON snapshot of all current tokens.
Theme CRUD Endpoints
GET /api/mobilecontent/admin/theme → IEnumerable<ThemeDto> (draft / live token values)
GET /api/mobilecontent/admin/theme/{key} → ThemeDto (draft / live token values)
GET /api/mobilecontent/admin/theme/{key}/published → ThemeDto (last published snapshot, immutable)
POST /api/mobilecontent/admin/theme → ThemeDto (201 Created)
PUT /api/mobilecontent/admin/theme/{key} → ThemeDto
PATCH /api/mobilecontent/admin/theme/{key} → ThemeDto (partial update)
DELETE /api/mobilecontent/admin/theme/{key} → 204 No Content (soft delete)
POST /api/mobilecontent/admin/theme/{key}/reactivate → 204 No Content
AdminThemeRequest (POST / PUT body)
Field
Type
Required
Notes
key
string
No
Unique semantic identifier. Lowercase normalized. When omitted, the server slugifies title.
title
string?
No
Human-readable display name. Used as the slug source when key is omitted.
description
string?
No
Additional notes or description for the theme.
AdminThemePatchRequest (PATCH body)
Send only the fields you want to change. Omitted fields are left unchanged.
Field
Type
Notes
title
string?
Updates the display name. Omit to leave unchanged.
description
string?
Updates the description. Omit to leave unchanged.
ThemeDto (response)
Field
Type
Notes
id
guid
Database PK.
key
string
Unique lowercase identifier.
title
string?
Human-readable display name.
description
string?
Additional notes or description.
tokens
Dictionary<string, string>
Current token values (draft read) or snapshot values (published read).
workflowState
int
0=Draft, 1=Published, 2=Unpublished, 3=Archived.
activeSnapshotId
guid?
GUID of the last published snapshot. Null if never published.
typography
Dictionary<string, TypographyStyle>
Named typography bundles. Empty when none have been set.
hasDraftChanges
bool
True when the live token rows have been modified since the last publish. Acts as a “pending changes” badge. Always false on a published-snapshot read (GET {key}/published).
previewMessage
string
Non-empty when this response is a draft preview rather than a published snapshot.
isLocked
bool
True while an admin user has this theme open for editing. Check this before rendering edit controls.
lockedByUser
string?
Identity of the user currently holding the lock. Null when the theme is not locked.
createdAt
DateTime
UTC timestamp when the theme record was first created.
updatedAt
DateTime
UTC timestamp of the most recent change to the theme record.
Theme Preview Users
Preview users allow specific portal users or groups to preview a theme in draft state on the mobile app before it is published. The current preview user list is returned in ThemeWorkflowDto.previewUsers.
PUT /api/mobilecontent/admin/theme/{key}/preview-users → 200 { key, previewUsers[] }
Supply the full desired list — the endpoint performs a full replace. Send an empty array to clear all preview users.
PUT /api/mobilecontent/admin/theme/{key}/preview-users
[
"user-id-123",
"PreviewUsers"
]
ThemeWorkflowDto (response)
Field
Type
Notes
key
string
Theme key.
workflowState
WorkflowState
Current state enum value.
activeVersionNumber
int?
Version number of the active snapshot. Null if never published.
lastPublishedDateTime
DateTime?
UTC timestamp of the last publish.
lastPublishedByUser
string?
User who last published.
totalVersions
int
Total number of snapshots created for this theme.
previewUsers
string[]
User IDs or group names that can preview this theme in draft state.
Theme Locking
The locking model mirrors page locking. Lock a theme before editing its tokens to prevent concurrent overwrites; unlock on save or cancel. Admins can force-unlock a theme left locked by another user.
Endpoint
Caller
Behaviour
POST …/{key}/lock
Editing user (on open)
Sets isLocked = true and records lockedByUser. Returns 409 Conflict if the theme is already locked by a different user. Re-locking by the same user is idempotent.
POST …/{key}/unlock
Editing user (on save or cancel)
Clears isLocked and lockedByUser. Always succeeds for any caller (the portal should only show this button to the lock owner).
POST …/{key}/force-unlock
Admin
Clears the lock regardless of who set it. Use when a user forgot to unlock/save a theme they were editing.
The isLocked and lockedByUser fields are returned on every ThemeDto response, so the portal can show a lock badge and disable token-editing controls without a separate API call.
Token Endpoints
Known paths and their metadata (display names, validation rules, defaults, categories) are defined in the MobDynThemeTokenRegistry table — 95 tokens across 15 categories: Surface, Text, Border, Icon, Action, Navigation, Status, Typography, Font Size, Font Weight, Text Transform, Letter Spacing, Spacing, Border Radius, and Icon Size.
GET /api/mobilecontent/admin/theme/{key}/tokens → Dictionary<string, string>
PUT /api/mobilecontent/admin/theme/{key}/tokens → 204 No Content (full replace)
PATCH /api/mobilecontent/admin/theme/{key}/tokens → 204 No Content (merge patch)
GET /api/mobilecontent/admin/theme/token-metadata → grouped token metadata (for UI)
POST /api/mobilecontent/admin/theme/validate-tokens → 200 OK or 400 with errors
PUT /tokens — full replace
Replaces all existing tokens for the theme. Any paths not included in the request are removed. Use this when loading a complete theme definition or copying tokens from another theme.
The example above updates Surface/Brand, removes Text/Secondary, and leaves every other token unchanged. Supplied (non-null) values are validated the same way as PUT; a 400 is returned if any value is invalid. Both PUT and PATCH set hasDraftChanges = true on a previously-published theme.
Token Metadata & Validation
GET /token-metadata returns grouped metadata for every known token (display name, validation rules, default values, etc.) so the admin UI can build a structured token editor without hardcoding anything. Use POST /validate-tokens to validate a token dictionary before committing it — returns a Dictionary<string, string> of path → error message on 400, or 200 OK if all tokens are valid.
Typography Endpoints
Typography entries are named bundles of font style properties (font family, size, weight, style, line height, transform, letter spacing, color) stored as JSON objects in DynamicThemeTypography.
GET /api/mobilecontent/admin/theme/{key}/typography → Dictionary<string, TypographyStyle>
PUT /api/mobilecontent/admin/theme/{key}/typography → 204 No Content (full replace)
CSS font-style value (e.g. italic, normal). Null = inherit.
lineHeight
string?
CSS line-height (e.g. 1.5, 24px). Null = inherit.
textTransform
string?
CSS text-transform value (e.g. uppercase). Null = inherit.
letterSpacing
string?
CSS letter-spacing (e.g. .05em). Null = inherit.
color
string?
Hex or rgba color value. Null = inherit from theme tokens.
Theme Workflow Endpoints
Theme workflow follows the same state machine as pages, without scheduling.
GET /api/mobilecontent/admin/theme/{key}/workflow → ThemeWorkflowDto
GET /api/mobilecontent/admin/theme/{key}/versions → IEnumerable<ThemeVersionSummaryDto>
POST /api/mobilecontent/admin/theme/{key}/publish → { key, versionNumber }
POST /api/mobilecontent/admin/theme/{key}/unpublish → 204 No Content
POST /api/mobilecontent/admin/theme/{key}/republish → 204 No Content
POST /api/mobilecontent/admin/theme/{key}/archive → 204 No Content
POST /api/mobilecontent/admin/theme/{key}/restore → 204 No Content
AdminPublishThemeRequest (POST /publish body)
Field
Type
Notes
notes
string?
Optional note stored with the snapshot.
ThemeWorkflowDto (GET /workflow response)
Field
Type
Description
key
string
workflowState
int
0=Draft, 1=Published, 2=Unpublished, 3=Archived
activeVersionNumber
int?
Active snapshot version. Null if never published.
lastPublishedDateTime
DateTime?
UTC.
lastPublishedByUser
string?
totalVersions
int
Config / Type Endpoints
These endpoints return the valid string values for all constrained fields. containerTypes and itemTypes are sourced from the DynamicContainerTypes and DynamicItemTypes database tables (managed by administrators), while token lists are derived from server-side enums. Call them once on Admin Portal load to populate dropdowns without hardcoding values in the client. All are anonymous and return plain arrays or a combined object.
GET /api/mobilecontent/admin/config → all enum sets in one object
GET /api/mobilecontent/admin/config/container-types → string[]
GET /api/mobilecontent/admin/config/item-types → string[]
GET /api/mobilecontent/admin/config/background-tokens → string[]
GET /api/mobilecontent/admin/config/padding-tokens → string[]
GET /api/mobilecontent/admin/config/corner-radius-tokens → string[]
Recommended pattern: Call GET /config once at admin portal initialization and cache the result in state. Use the returned arrays to populate every container type, item type, and token dropdown throughout the UI.
Complete Admin Endpoint Reference
Sites
GET /api/mobilecontent/admin/site
GET /api/mobilecontent/admin/site/{siteKey}
POST /api/mobilecontent/admin/site
PUT /api/mobilecontent/admin/site/{siteKey}
DELETE /api/mobilecontent/admin/site/{siteKey}
POST /api/mobilecontent/admin/site/{siteKey}/restore
Pages
GET /api/mobilecontent/admin/page/{pageKey}
POST /api/mobilecontent/admin/page
PUT /api/mobilecontent/admin/page/{pageKey}
DELETE /api/mobilecontent/admin/page/{pageKey}
POST /api/mobilecontent/admin/page/{pageKey}/reactivate
Containers
GET /api/mobilecontent/admin/page/{pageKey}/container/{containerId}
POST /api/mobilecontent/admin/page/{pageKey}/container
PUT /api/mobilecontent/admin/page/{pageKey}/container/{containerId}
DELETE /api/mobilecontent/admin/page/{pageKey}/container/{containerId}
Items
GET /api/mobilecontent/admin/page/{pageKey}/container/{containerId}/item/{itemId}
POST /api/mobilecontent/admin/page/{pageKey}/container/{containerId}/item
PUT /api/mobilecontent/admin/page/{pageKey}/container/{containerId}/item/{itemId}
DELETE /api/mobilecontent/admin/page/{pageKey}/container/{containerId}/item/{itemId}
Page Workflow
GET /api/mobilecontent/admin/page/{pageKey}/workflow
GET /api/mobilecontent/admin/page/{pageKey}/versions
POST /api/mobilecontent/admin/page/{pageKey}/publish
POST /api/mobilecontent/admin/page/{pageKey}/unpublish
POST /api/mobilecontent/admin/page/{pageKey}/republish
POST /api/mobilecontent/admin/page/{pageKey}/revert
POST /api/mobilecontent/admin/page/{pageKey}/archive
POST /api/mobilecontent/admin/page/{pageKey}/restore
DELETE /api/mobilecontent/admin/page/{pageKey}/schedule/publish
DELETE /api/mobilecontent/admin/page/{pageKey}/schedule/unpublish
PUT /api/mobilecontent/admin/page/{pageKey}/preview-users
Themes
GET /api/mobilecontent/admin/theme
GET /api/mobilecontent/admin/theme/{key}
POST /api/mobilecontent/admin/theme
PUT /api/mobilecontent/admin/theme/{key}
DELETE /api/mobilecontent/admin/theme/{key}
POST /api/mobilecontent/admin/theme/{key}/reactivate
GET /api/mobilecontent/admin/theme/{key}/tokens
PUT /api/mobilecontent/admin/theme/{key}/tokens
GET /api/mobilecontent/admin/theme/{key}/typography
PUT /api/mobilecontent/admin/theme/{key}/typography
GET /api/mobilecontent/admin/theme/{key}/workflow
GET /api/mobilecontent/admin/theme/{key}/versions
POST /api/mobilecontent/admin/theme/{key}/publish
POST /api/mobilecontent/admin/theme/{key}/unpublish
POST /api/mobilecontent/admin/theme/{key}/republish
POST /api/mobilecontent/admin/theme/{key}/archive
POST /api/mobilecontent/admin/theme/{key}/restore
PUT /api/mobilecontent/admin/theme/{key}/preview-users
POST /api/mobilecontent/admin/theme/{key}/lock
POST /api/mobilecontent/admin/theme/{key}/unlock
POST /api/mobilecontent/admin/theme/{key}/force-unlock
GET /api/mobilecontent/admin/theme/token-metadata
POST /api/mobilecontent/admin/theme/validate-tokens
Config
GET /api/mobilecontent/admin/config
GET /api/mobilecontent/admin/config/container-types
GET /api/mobilecontent/admin/config/item-types
GET /api/mobilecontent/admin/config/background-tokens
GET /api/mobilecontent/admin/config/padding-tokens
GET /api/mobilecontent/admin/config/corner-radius-tokens