Shop It Docs
Developer ResourcesBlog

Blog Module API & Integration Guide

Admin and public blog API contracts, payload rules, and integration behavior.

Audience: Frontend and integration developers Scope: Blog admin CRUD + public blog consumption

Blog Module - API & Integration Guide

1. Quick Metadata

  • Module: Blog
  • Admin base URLs:
    • /api/admin/blog/posts
    • /api/admin/blog/categories
  • Public base URL: /api/blogs
  • Mobile-composed public base URL: /api/mobile/blogs
  • Response envelope: ResponseDto<T>

2. High-Level API Split

  • Admin surface:
    • full CRUD for posts/categories
    • publish/unpublish actions
    • relation payload updates (products/faqs/cta/videos)
  • Public surface:
    • paginated published posts
    • published categories with counts
    • slug detail with history fallback

3. Route Summary

3.1 Admin Posts

MethodPathPermission
GET/api/admin/blog/postsBlog_READ
GET/api/admin/blog/posts/:idBlog_READ
POST/api/admin/blog/postsBlog_CREATE
PUT/api/admin/blog/posts/:idBlog_UPDATE
DELETE/api/admin/blog/posts/:idBlog_DELETE
POST/api/admin/blog/posts/:id/publishBlog_UPDATE
POST/api/admin/blog/posts/:id/unpublishBlog_UPDATE

3.2 Admin Categories

MethodPathPermission
GET/api/admin/blog/categoriesBlog_READ
GET/api/admin/blog/categories/:idBlog_READ
POST/api/admin/blog/categoriesBlog_CREATE
PUT/api/admin/blog/categories/:idBlog_UPDATE
DELETE/api/admin/blog/categories/:idBlog_DELETE

3.3 Public Blog

MethodPathAuth
GET/api/blogsPublic
GET/api/blogs/categoriesPublic
GET/api/blogs/:slugPublic

Mobile-composed equivalents:

  • GET /api/mobile/blogs
  • GET /api/mobile/blogs/categories
  • GET /api/mobile/blogs/:slug

4. Query Parameters

4.1 Public list (GET /api/blogs)

ParamTypeDefault
paginationbooleantrue
pagenumber1
sizenumber20
sortpublishedAt | displayDate | createdAt | updatedAt | titlepublishedAt
orderasc | descdesc
searchstring (min 2 chars)optional
categoryIdnumberoptional

4.2 Admin list (GET /api/admin/blog/posts)

ParamTypeDefault
paginationbooleantrue
pagenumber1
sizenumber20 (max 100)
sorttitle | slug | status | displayDate | publishedAt | createdAt | updatedAtupdatedAt
orderasc | descdesc
searchstring (min 2 chars)optional
statusdraft | publishedoptional
categoryIdnumberoptional

5. Request Payload Contracts

5.1 Admin create post (POST /api/admin/blog/posts)

{
  "title": "How to Read a Green Tara Thangka",
  "slug": "how-to-read-green-tara-thangka",
  "excerpt": "Symbolism and visual grammar explained",
  "heroIntro": "Green Tara iconography decoded",
  "body": "<p>...</p>",
  "featuredImageUrl": "https://cdn.example.com/blog/green-tara.jpg",
  "featuredImageAlt": "Green Tara detail",
  "displayDate": "2026-05-01T00:00:00.000Z",
  "categoryId": 1,
  "seoId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "draft",
  "productIds": [8, 3, 12],
  "faqs": [
    {
      "question": "Is Green Tara always shown with one leg extended?",
      "answer": "Often yes, representing readiness to act.",
      "position": 0
    }
  ],
  "cta": {
    "ctaTitle": "Explore Green Tara Thangkas",
    "ctaButtonLabel": "Browse",
    "ctaButtonLink": "https://nepathangka.com/products",
    "position": 0
  },
  "videos": [
    {
      "title": "Green Tara Ritual Walkthrough",
      "videoUrl": "https://cdn.example.com/videos/green-tara-ritual.mp4",
      "seoId": "018f3c98-8dcf-7b1c-a8b9-c32b3f6de101",
      "description": "Step-by-step visual guide",
      "thumbnailUrl": "https://cdn.example.com/videos/green-tara-cover.jpg",
      "position": 0
    }
  ]
}

5.2 Admin update post (PUT /api/admin/blog/posts/:id)

  • Supports partial fields.
  • productIds: replace full linked-product set.
  • faqs: replace full FAQ set ([] clears all FAQs).
  • cta: object replaces CTA; null removes CTA.
  • videos: replace full video set ([] clears all videos).

5.3 Admin create/update category

{
  "name": "Thangka Art Guides",
  "description": "Educational writing on thangka iconography"
}

6. Response Shape Examples

6.1 Public list success

{
  "message": "Blog posts fetched successfully",
  "data": [
    {
      "id": 1,
      "title": "How to Read a Green Tara Thangka",
      "slug": "how-to-read-green-tara-thangka",
      "excerpt": "Symbolism and visual grammar explained",
      "featuredImageUrl": "https://cdn.example.com/blog/green-tara.jpg",
      "featuredImageAlt": "Green Tara detail",
      "displayDate": "2026-05-01T00:00:00.000Z",
      "publishedAt": "2026-05-02T10:30:00.000Z",
      "categoryName": "Thangka Art Guides",
      "categorySlug": "thangka-art-guides"
    }
  ],
  "count": 42,
  "currentPage": 1,
  "totalPage": 3
}

6.2 Public detail success

{
  "message": "Blog post fetched successfully",
  "data": {
    "id": 1,
    "title": "How to Read a Green Tara Thangka",
    "slug": "how-to-read-green-tara-thangka",
    "excerpt": "...",
    "heroIntro": "...",
    "body": "<p>...</p>",
    "featuredImageUrl": "https://cdn.example.com/blog/green-tara.jpg",
    "featuredImageAlt": "Green Tara detail",
    "displayDate": "2026-05-01T00:00:00.000Z",
    "publishedAt": "2026-05-02T10:30:00.000Z",
    "categoryName": "Thangka Art Guides",
    "categorySlug": "thangka-art-guides",
    "authorName": "Admin User",
    "linkedProducts": [
      {
        "id": 8,
        "title": "Sterling Silver Dorje Pendant",
        "slug": "sterling-silver-dorje-pendant",
        "mrp": 5400,
        "sp": 4900,
        "thumbnailUrl": "https://...",
        "position": 0
      }
    ],
    "faqs": [
      {
        "question": "Is Green Tara always shown with one leg extended?",
        "answer": "...",
        "position": 0
      }
    ],
    "cta": {
      "ctaTitle": "Explore Green Tara Thangkas",
      "ctaButtonLabel": "Browse",
      "ctaButtonLink": "https://nepathangka.com/products",
      "position": 0
    },
    "videos": [
      {
        "id": 1,
        "title": "Green Tara Ritual Walkthrough",
        "videoUrl": "https://cdn.example.com/videos/green-tara-ritual.mp4",
        "seoId": "018f3c98-8dcf-7b1c-a8b9-c32b3f6de101",
        "description": "Step-by-step visual guide",
        "thumbnailUrl": "https://cdn.example.com/videos/green-tara-cover.jpg",
        "position": 0
      }
    ],
    "structuredData": {
      "article": { "@type": "Article" },
      "faq": { "@type": "FAQPage" },
      "breadcrumb": { "@type": "BreadcrumbList" }
    }
  }
}

6.3 Slug fallback behavior

If request is GET /api/blogs/old-slug-name and old slug exists in blog_slug_history for a published post:

  • returns 200 with current post data
  • response data.slug is current canonical slug
  • no redirect status/code is returned

7. Validation and Constraints

  • search requires at least 2 chars where defined.
  • size is globally capped at 100.
  • productIds deduped server-side and validated as published products.
  • videos is capped at 20 entries.
  • Every video requires a valid seoId and each seoId must be unique within payload.
  • Video seoId cannot already be linked to another blog post video.
  • Category delete returns conflict when category is not empty.

8. Error Reference

errorCodeHTTPMeaning
BLOG_POST_NOT_FOUND404Post does not exist or not visible in current surface
BLOG_CATEGORY_NOT_FOUND404Category not found
BLOG_CATEGORY_NOT_EMPTY409Category has linked posts
BLOG_CATEGORY_SLUG_ALREADY_EXISTS409Slug collision on category create/update
BLOG_POST_INVALID_STATUS_TRANSITION400Publish/unpublish transition invalid
PRODUCT_NOT_FOUND400One or more linked product IDs invalid/unpublished

9. Integration Notes

  • For public detail pages, frontend should consume structuredData and render JSON-LD tags.
  • For historical links, frontend should not expect redirects; use returned canonical slug if URL normalization is needed.
  • Public endpoints are available identically under /api/mobile/blogs*.
  • After admin mutation success, frontend can safely refetch; cache invalidation happens server-side.

See Also