commentify/api/v1 (configurable via api.prefix). Middleware is api.middleware plus ResolveCommentifyGuard. Writes also use EnsureCommentifyWritable (read-only → 423).
Rate limiters: commentify-api-read (default 300/min) and commentify-api-write (default 60/min), keyed by user id or IP.
{type} is a commentable alias, never a class name. Unknown aliases 404 with “Unknown commentable type.”
Endpoints
Named routes use the
commentify-pro.* prefix (commentify-pro.comments.index, …).
GET ui
Keeps frontends honest. Labels come from trans('commentify::commentify.comments'). Feature flags mirror config so turning off sorting or reporting affects every stack. Also reports whether the visitor may comment (read-only, bans, guests).
List comments
GET /commentify/api/v1/articles/1/comments
Query:
sort—newest(default from config),oldest,most_liked,most_repliedpage,per_page(max 50)cursor— cursor pagination when sort isnewestoroldest
api.replies_per_parent (default 3) children. Pinned parents sort first (pinnedFirst()). Unapproved comments are omitted except the current user’s own.
Standard Laravel pagination JSON (data, links, meta). Cursor paginator when cursor is present.
Create
POST /commentify/api/v1/articles/1/comments → 201
is_approved is true unless require_approval is on or the spam pipeline returns review. Pipeline deny aborts the save (save() returns false) → spam_rejected.
Update / delete
PATCH body: { "body": "…" } (max 10000). Spam pipeline runs again on body edits.
DELETE returns 204.
Like
POST .../like toggles. Response:
user_id. Guests key on IP + user agent when api.guest_likes is true.
Report
reason must be in core.report_reasons. Details (max 500) are appended as reason: details in storage, matching Livewire. Duplicate reports → already_reported (409). 201 { "reported": true }. Disabled reporting → 404.
Pin
POST / DELETE .../pin. Only parent comments. One pin per thread (pinning another clears the previous). Disabled pins → 404. Non-moderators → 403.
Markdown preview
{ "data": { "html": "…" } } using CommentPresenter::preview() — same CommonMark + mention linking as published comments. Empty body → empty HTML.
User search
GET users?q=may — authenticated only. q 1–50 chars. % and _ are escaped. Max 5 rows. { "data": [ { "id", "name", "avatar" } ] }.
Media
POST media as multipart/form-data field file. See Image uploads. 201 { "url", "thumbnail_url" }. Disabled → 404.
Comment resource
user.id is null, name from guest_name, avatar from Gravatar when configured.
Error codes
JSON:
Validation failures are ordinary Laravel
422 with errors. File too large → 413. Upload rate limit → 429.
Inherited from core: sort, pagination, approval, CommentPolicy, read-only, bans. See Authorization.
