Content Module API & Integration Guide
Admin and public contracts for IT Mart CMS page-section payloads.
Content Module - API & Integration Guide
Quick Metadata
- Module:
Content - Admin base:
/api/admin/content/pages - Public base:
/api/content/pages - Mobile mirror:
/api/mobile/content/pages - Swagger tags:
Content Pages (Admin),Content Pages - Response envelope:
ResponseDto<T>
Admin routes use JwtAuthGuard + RoleGuard + @Permissions(...). Public and mobile reads are public.
Read Caching and Purge Behavior
Content page reads use Redis cache-aside:
| Route | Cache key prefix |
|---|---|
GET /api/content/pages/:pageKey | content:page:public: |
GET /api/mobile/content/pages/:pageKey | content:page:public: |
GET /api/admin/content/pages/:pageKey | content:page:admin: |
TTL envs:
CONTENT_PAGE_PUBLIC_CACHE_TTL_SECONDSCONTENT_PAGE_ADMIN_CACHE_TTL_SECONDS
Successful admin writes purge both projections for the changed page:
PATCH /:pageKey/metaPUT /:pageKey/sections/:sectionKeyDELETE /:pageKey/sections/:sectionKey
The service invalidates Redis patterns for both content:page:admin:pageKey:<pageKey>* and content:page:public:pageKey:<pageKey>*, then triggers frontend revalidation tags through CacheInvalidationService. Redis or revalidation failures are fail-open and logged; the content write still returns if the database write succeeded.
Page Keys
| Page key | Frontend route | Status |
|---|---|---|
about | /about | Live |
faq | /faq | Live |
privacy_policy | /privacy-policy | Live |
terms_of_service | /terms-of-service | Live |
home | / | Target CMS schema |
global_footer | site-wide footer | Target CMS schema |
digital_products | /digitalproducts | Target CMS schema |
repair | /repair | Target CMS schema |
itmartcare | /itmartcare | Target CMS schema |
itmartcare_claim | /itmartcare/claim | Target CMS schema |
itmartcare_detail | /itmartcare/[slug] | Target CMS schema |
categories | /categories | Target CMS schema |
brands | /brands | Target CMS schema |
articles | /articles | Target CMS schema |
Retired copied page keys such as products_thangkas, products_singing_bowls, products_statues, and products_jewellery are no longer valid API params.
Page-to-Section Matrix
| Page key | Allowed sections |
|---|---|
home | new_arrivals, trending, popular_picks, categories, itmart_care, brands, trusted_partner, repair_process, customer_reviews, tech_articles |
about | hero, quote, story_blocks, why_choose, faq_intro, blogs |
faq | faq_intro |
privacy_policy | document |
terms_of_service | document |
global_footer | brand_blurb, quick_links, legal_links, copyright |
digital_products | hero, product_listing |
repair | hero, steps, upsell_promo |
itmartcare | hero |
itmartcare_claim | claim_steps |
itmartcare_detail | before_you_continue, fallback_description |
categories | hero |
brands | hero |
articles | hero |
Payload validation is page-aware. The same sectionKey, especially hero, can have a different shape on different pages.
Admin Endpoints
| Method | Path | Permission | Behavior |
|---|---|---|---|
GET | /api/admin/content/pages/:pageKey | Content_READ | Auto-creates page if missing and returns all sections |
PATCH | /api/admin/content/pages/:pageKey/meta | Content_UPDATE | Updates title and/or seoId |
PUT | /api/admin/content/pages/:pageKey/sections/:sectionKey | Content_UPDATE | Validates and upserts one section |
DELETE | /api/admin/content/pages/:pageKey/sections/:sectionKey | Content_DELETE | Deletes one existing section |
PUT body:
{
"payloadJson": {
"heading": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [{ "type": "text", "text": "New Arrivals" }]
}
]
},
"description": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Latest products for IT Mart customers." }
]
}
]
},
"ctaLabel": "Shop now"
},
"position": 0,
"isEnabled": true
}position and isEnabled are optional. Section rows upsert by unique (pageId, sectionKey).
Public and Mobile Endpoints
| Method | Path | Behavior |
|---|---|---|
GET | /api/content/pages/:pageKey | Returns enabled sections only |
GET | /api/mobile/content/pages/:pageKey | Same response as public route under mobile composition |
Public reads do not auto-create pages. Missing pages return 404 CONTENT_NOT_FOUND.
Payload Field Rules
- Tiptap fields must be JSON docs with
type: "doc"and non-emptycontent[]. - Plain text fields are strings.
- URL fields allow absolute HTTP(S) URLs or site-relative paths beginning with
/. - All payloads are strict: unknown fields are rejected.
privacy_policy.document,terms_of_service.document, andfaq.faq_introremain compatible with the existing live pages.
Section Payload Schemas
home
Sections new_arrivals, trending, popular_picks, categories, brands, customer_reviews, and tech_articles:
{
"heading": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "New Arrivals" }] }] },
"description": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Latest products for IT Mart customers." }] }] },
"ctaLabel": "Shop now"
}itmart_care:
{
"badge": "IT Mart Care",
"description": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Protection and service support for your devices." }] }] },
"ctaLabel": "Explore plans",
"logo": { "src": "/images/itmart-care-logo.svg", "alt": "IT Mart Care" },
"benefits": [
{ "icon": "shield", "title": "Coverage", "description": "Flexible protection for eligible products." }
]
}trusted_partner:
{
"heading": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Your Trusted Tech Partner" }] }] },
"description": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Reliable devices, service, and support." }] }] },
"ctaLabel": "Learn more",
"image": { "src": "/images/trusted-partner.webp", "alt": "IT Mart support team" }
}repair_process:
{
"heading": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Repair Made Simple" }] }] },
"description": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Book, diagnose, repair, and collect." }] }] },
"ctaLabel": "Start repair",
"steps": [
{ "id": "book", "image": "/images/repair/book.svg", "step": "Step 1", "title": "Book a repair" }
]
}about
hero:
{
"label": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "About IT Mart" }] }] },
"heading": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Technology for Everyday Nepal" }] }] },
"subtitle": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Devices, service, and care in one place." }] }] },
"description": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "IT Mart connects customers with reliable tech products and support." }] }] },
"images": { "main": { "src": "/images/about-main.webp", "alt": "IT Mart store" } }
}quote, story_blocks, why_choose, and faq_intro follow the fields in the IT Mart CMS spec. blogs is an enabled/disabled toggle section and uses an empty payload {}.
Legal and FAQ
faq.faq_intro:
{
"label": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "FAQ" }] }] },
"heading": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Questions Answered" }] }] },
"description": { "type": "doc", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Everything you need to know before shopping." }] }] }
}privacy_policy.document and terms_of_service.document:
{
"eyebrow": "Privacy",
"title": "Privacy Policy",
"summary": "We respect your privacy and protect your personal information.",
"lastUpdated": "Last updated: April 1, 2026",
"sections": [
{
"id": "information-we-collect",
"title": "1. Information We Collect",
"paragraphs": ["We collect account and order details needed to process purchases."],
"bullets": ["Name and email", "Shipping details"]
}
]
}Other Pages
| Page.section | Payload |
|---|---|
digital_products.hero, repair.hero, categories.hero, brands.hero | heading Tiptap, description Tiptap |
digital_products.product_listing | heading text |
repair.steps | steps[] with { id, image, step, title } |
repair.upsell_promo | title Tiptap, ctaLabel text, href URL |
itmartcare.hero | logo, description Tiptap, shieldImage |
itmartcare_claim.claim_steps | pickupDropSteps[] and inStoreSteps[], each { id, image, step, title } |
itmartcare_detail.before_you_continue | heading text, steps[] with { text } Tiptap |
itmartcare_detail.fallback_description | text Tiptap |
articles.hero | heading Tiptap |
global_footer.brand_blurb | logo, heading Tiptap, description Tiptap, contacts[] with `icon: "phone" |
global_footer.quick_links | columnHeading text, columns[] with nested links[] |
global_footer.legal_links | links[] with { label, href } |
global_footer.copyright | text string or Tiptap |
Listing data for products, categories, brands, care packages, reviews, FAQs, and articles stays owned by their existing feature APIs. CMS only owns editorial copy listed here.
Error Code Mapping
| errorCode | HTTP | Cause |
|---|---|---|
CONTENT_NOT_FOUND | 404 | Missing page or missing section on delete |
CONTENT_SECTION_KEY_INVALID | 400 | Section is not allowed for selected page |
CONTENT_SECTION_PAYLOAD_INVALID | 400 | Payload does not match page-specific schema |
CONTENT_SEO_NOT_FOUND | 400 | Non-null seoId does not exist |
RATE_LIMIT_EXCEEDED | 429 | Admin throttling exceeded |
Integration Checklist
- Client page keys match backend enums exactly.
- Admin panel sends Tiptap JSON for fields marked Tiptap.
- Admin panel sends plain strings for fields marked text.
- Frontend keeps backend-driven listing data outside CMS payloads.
- Manual purge/revalidation uses the new IT Mart tags and content Redis patterns.
Manual content purge example:
{
"tags": ["content:page:home", "page:home"],
"targetScope": "content",
"redisScope": "content",
"redisPatterns": [
"content:page:public:pageKey:home*",
"content:page:admin:pageKey:home*"
],
"reason": "admin.manual_purge",
"entityType": "content_page",
"entityId": "home"
}