Improving Discourse API documentation for building fully custom frontend community

Hi everyone :waving_hand:

I’ve been building a custom frontend using Discourse as a headless backend (Next.js-based architecture), and I’d like to share some practical gaps I’ve encountered in the current API design from a real-world integration perspective.

This is not a critique of Discourse itself (it’s powerful and flexible), but rather feedback to improve DX for modern frontend + API-driven architectures..


1. Pagination & Topic Posts Structure

Current issue:

  • Pagination is not always consistent across endpoints

  • Topic posts (/t/{id}.json) mixes:

    • original post

    • replies

    • internal metadata

  • This makes it harder to build clean infinite scroll / normalized state (Redux/Zustand/React Query)

Suggestion:

  • Provide clearer separation or optional query flags like:

    • ?include_first_post=true|false

    • ?posts_only=replies

    • Cursor-based pagination support (instead of page-based only)


2. Replies vs Topic Structure

Right now:

  • Replies are embedded inside topic response

  • No clear separation between:

    • “topic metadata”

    • “post stream”

This causes:

  • extra parsing logic in frontend

  • duplication when normalizing state

Suggestion:

  • Offer dedicated endpoints like:

    • /t/{id}/posts

    • /t/{id}/replies

    • or support filtering inside /t/{id}.json


3. Lack of Field-Level Documentation in API Response

For example in topic response:

  • created_at

  • bumped_at

  • last_posted_at

  • updated_at

These are not always clearly differentiated.

Problem:

  • Developers often misinterpret:

    • bumped_at vs updated_at

    • what triggers “topic activity”

Suggestion:

  • Add inline schema documentation or OpenAPI-style metadata:

    • meaning of each field

    • lifecycle explanation


4. Statistics & Caching Inconsistencies

Issues:

  • posts_count, reply_count, participants_count sometimes lag behind real-time data

  • heavy reliance on cached counters

Impact:

  • inaccurate UI (especially for dashboards / analytics pages)

  • requires extra API calls to validate state

Suggestion:

  • Add “real-time vs cached” indicator or endpoint variant

  • Or provide webhook/event-driven updates for counts


5. Sitemap + SEO + Framework Integration Gaps

When integrating with modern frameworks (Next.js, Nuxt, etc.):

Problems:

  • No unified API for:

    • updated topics for sitemap generation

    • category-level last change tracking

    • full post indexation support

Developers end up doing:

  • multiple API calls per category

  • manual diffing for updated_at

  • pagination crawling to detect updates

Suggestion:

  • Add dedicated endpoints:

    • /categories/updated

    • /topics/changes?since=timestamp

    • /sitemap.json (API-driven sitemap feed)


6. User Metrics & Aggregations Missing

Common needed data:

  • total likes received per user

  • total likes given

  • reaction breakdown per post/user

  • engagement stats per category

Current issue:

  • requires multiple endpoints + aggregation on frontend

Suggestion:

  • Add aggregated endpoints like:

    • /users/{id}/stats

    • /topics/{id}/stats


7. User Avatars Flexibility

Current limitation:

  • avatars are tightly coupled with Discourse upload system

Request:

  • allow external avatar URLs (S3 / CDN / external auth providers)

  • support:

    • external_avatar_url

This would help with:

  • SSO systems

  • headless identity providers


8. API Keys: Admin vs User Keys

Clarification needed in docs:

Difference between:

  • admin API key

  • user API key (created via /admin/api/keys or user API endpoints)

Questions:

  • lifecycle & expiration rules

  • revocation rules per user vs global

  • security scope limitations per type

This is critical when building production-grade integrations.


Final Thoughts

Discourse API is already powerful, but it feels optimized for “server-rendered forum usage” more than “headless / frontend-driven architecture”.

Modern frameworks (Next.js, Remix, etc.) benefit a lot from:

  • fewer round trips

  • clearer data boundaries

  • predictable caching rules

  • better aggregation endpoints

Would love feedback from maintainers or others building headless Discourse setups.

Thanks :folded_hands:

Something else I noticed that annoys me is some endpoints are “protected” using formencoding instead of JSON maybe to deter people from messing with the API? The best example of this is the link click track API, which I guess makes sense as protection but anybody can still misuse it if they really want so at the end of the day it’s just more difficult for developers to do stuff with.