Skip to content
Documentation / MemehCMS Public API Guide
MemehCMS Documentation

MemehCMS Public API Guide

Developer reference for building public websites, mobile apps, portals, dashboards, and Web Engine templates on top of MemehCMS.

MemehCMS Public API Guide

MemehCMS is headless-first. Public websites, portals, mobile apps, and Web Engine templates should read published content through the public API instead of scraping admin pages.

The API is tenant-scoped. Always send the institution tenant ID when building a public website.

Base URL

Use the MemehCMS application URL plus /api.

Example:

https://memehcms.com/api

For local development:

http://127.0.0.1:8000/api

Tenant Scope

Most public endpoints accept:

?tenant_id=<institution-uuid>

Example:

GET /api/articles?tenant_id=55c10ff5-fa35-4058-acfc-0e6f14df2b32

Do not hardcode another institution's tenant ID into a website. Each website should use the tenant ID from its own configuration.

Authentication

Public website endpoints do not require authentication for published content.

Authenticated users who belong to a tenant may preview drafts through selected endpoints when the request is made in an authenticated context. Public websites should normally request published content only.

Rate Limits

Public API endpoints are protected by the platform public API rate limit.

Developers should:

  1. Cache public responses where appropriate.
  2. Avoid polling too frequently.
  3. Use pagination.
  4. Avoid loading every module on every page.
  5. Handle HTTP 429 gracefully.

Standard Query Parameters

Common parameters:

Parameter Purpose
tenant_id Institution UUID. Strongly recommended for all public websites.
page Pagination page number.
per_page Items per page. Capped by the API.
status Usually published; draft preview is allowed only for authorized tenant users.
include Comma-separated related resources allowed by the endpoint.
sort_field Sort field where supported.
sort_dir asc or desc where supported.

Standard Pagination Shape

List endpoints usually return:

{
  "data": [],
  "meta": {
    "current_page": 1,
    "per_page": 20,
    "total": 0,
    "last_page": 1
  },
  "links": {
    "next": null,
    "prev": null
  }
}

Articles

Use articles for news, posts, speeches, press releases, and public updates.

List:

GET /api/articles?tenant_id=<uuid>&per_page=10&sort_field=published_at&sort_dir=desc

Show:

GET /api/articles/{id-or-slug}?tenant_id=<uuid>

Useful includes:

include=category,tags,featureImage,tenant

Example:

const url = `${API_BASE}/articles?tenant_id=${TENANT_ID}&include=category,featureImage&per_page=6`;
const res = await fetch(url);
if (!res.ok) throw new Error(`Articles failed: ${res.status}`);
const payload = await res.json();

Production note: the article API is used by live public websites. Do not assume draft content is available unless the viewer is authenticated and allowed to preview that tenant.

Categories

Use categories to group articles.

GET /api/categories?tenant_id=<uuid>

Category slugs are tenant-safe in the admin system so two institutions can both use names such as News or Press Releases.

Pages

Use pages for static public website pages.

List:

GET /api/pages?tenant_id=<uuid>

Show:

GET /api/pages/{id-or-slug}?tenant_id=<uuid>

Pages may include page-builder data, metadata, feature media, and body content depending on how the page was created.

Services And Products

Use services for public services, products, fees, application flows, and portal CTAs.

List:

GET /api/services?tenant_id=<uuid>&per_page=20

Show:

GET /api/services/{id-or-slug}?tenant_id=<uuid>

Service payloads may include title, slug, summary, body, fee, CTA label, CTA URL, department, and status.

Website rule: if a service has a CTA, render it as a clear button such as Apply, Pay, Book Appointment, Contact Office, or Learn More.

Departments

Use departments for organizational units, divisions, commands, directorates, and public structure.

GET /api/departments?tenant_id=<uuid>

Departments can power menu mega-dropdowns, directory pages, service filters, and staff pages.

Locations

Use locations for offices, stations, headquarters, regional branches, and service points.

List:

GET /api/locations?tenant_id=<uuid>

Show:

GET /api/locations/{id-or-slug}?tenant_id=<uuid>

Leadership

Use leadership for profiles and organogram-driven public pages.

List:

GET /api/leadership?tenant_id=<uuid>

Show:

GET /api/leadership/{id-or-slug}?tenant_id=<uuid>

Leadership photos should come from managed media where available.

Sliders

Use sliders for homepage or section hero slides.

List:

GET /api/sliders?tenant_id=<uuid>&include=image

Show:

GET /api/sliders/{id-or-slug}?tenant_id=<uuid>&include=image

Render only published slides on public websites. Respect sort order.

Media

Use media to retrieve managed files attached to content.

GET /api/media?tenant_id=<uuid>

Media payloads include URLs where possible. Do not expose private admin storage paths directly in a public website.

Publications

Use publications for official reports and PDF libraries.

GET /api/publications?tenant_id=<uuid>

Publications should link to managed media files when available.

Records, Laws, Policies, And Forms

Use library items for laws, policies, forms, manuals, templates, guidelines, circulars, and public records.

List:

GET /api/library-items?tenant_id=<uuid>

Show:

GET /api/library-items/{id-or-slug}?tenant_id=<uuid>

Public Notices

Use notices for formal notices and public advisories that are not standard articles.

GET /api/notices?tenant_id=<uuid>

Emergency Alerts

Use alerts for urgent public safety information.

List:

GET /api/emergency-alerts?tenant_id=<uuid>

Show:

GET /api/emergency-alerts/{id-or-slug}?tenant_id=<uuid>

Public websites should make active urgent alerts visible without requiring users to search.

FAQs

Use FAQs for help-centre content.

List:

GET /api/faqs?tenant_id=<uuid>

Show:

GET /api/faqs/{id-or-slug}?tenant_id=<uuid>

Jobs

Use jobs for recruitment notices.

GET /api/jobs?tenant_id=<uuid>

Render closing dates clearly.

Events

Use events for calendars, programmes, workshops, ceremonies, and public deadlines.

GET /api/events?tenant_id=<uuid>

Menus

Use menus to build website navigation.

Menu list:

GET /api/menus?tenant_id=<uuid>

Menu items:

GET /api/menus/{menuId}/items?tenant_id=<uuid>

Menus with items:

GET /api/menus-with-items?tenant_id=<uuid>

Menu locations:

GET /api/menu-locations?tenant_id=<uuid>

Menu by location:

GET /api/menus/by-location/{key}?tenant_id=<uuid>

Common locations include header, footer, services, publications, and other website-defined locations.

Accessibility Settings

Use accessibility settings to configure public website controls.

GET /api/accessibility-settings?tenant_id=<uuid>

Public websites should use these settings for language readiness, skip links, statement URLs, and related controls.

PHP Example

<?php

$apiBase = 'https://memehcms.com/api';
$tenantId = '55c10ff5-fa35-4058-acfc-0e6f14df2b32';

$url = $apiBase.'/articles?'.http_build_query([
    'tenant_id' => $tenantId,
    'include' => 'category,featureImage',
    'per_page' => 6,
]);

$json = file_get_contents($url);
$payload = json_decode($json, true);

$articles = $payload['data'] ?? [];

JavaScript Example

async function apiGet(path, params = {}) {
  const url = new URL(`https://memehcms.com/api/${path}`);
  url.searchParams.set('tenant_id', '55c10ff5-fa35-4058-acfc-0e6f14df2b32');

  for (const [key, value] of Object.entries(params)) {
    if (value !== undefined && value !== null && value !== '') {
      url.searchParams.set(key, value);
    }
  }

  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`MemehCMS API failed with ${response.status}`);
  }

  return response.json();
}

const articles = await apiGet('articles', {
  include: 'category,featureImage',
  per_page: 6,
});

Website Builder And Web Engine

The Web Engine starter kit stores API configuration in one place. Do not scatter tenant IDs across templates.

Recommended configuration:

MEMEH_API_BASE=https://memehcms.com/api
MEMEH_TENANT_ID=<institution-uuid>

Use service classes or ViewModels to normalize API payloads before rendering HTML.

Error Handling

Developers should handle:

  1. 200: success.
  2. 404: content not found, wrong slug, missing tenant, unpublished record, or invalid preview access.
  3. 403: authenticated user lacks access where auth is used.
  4. 422: invalid request data where applicable.
  5. 429: rate limit.
  6. 500: server error, log and show a graceful fallback.

Public websites should never display raw exception messages.

Security Rules For Developers

  1. Keep admin credentials out of public websites.
  2. Store tenant ID and API base in config.
  3. Escape rendered text.
  4. Sanitize or trust only server-sanitized HTML fields.
  5. Do not render scripts from imported WordPress content.
  6. Cache public API responses responsibly.
  7. Use HTTPS.
  8. Keep contact forms rate-limited and CSRF-protected.
  9. Do not expose private case or admin data.

Release Checklist For Public Websites

Before launch:

  1. Confirm the tenant ID.
  2. Confirm menus load.
  3. Confirm articles load.
  4. Confirm pages load.
  5. Confirm services and CTAs work.
  6. Confirm publications and media files open.
  7. Confirm mobile navigation.
  8. Confirm alerts display correctly.
  9. Confirm empty states do not break layout.
  10. Confirm HTTPS and security headers.