WP_REST_Comments_Controller
Core controller used to access comments via the REST API.
Class Synopsis
class WP_REST_Comments_Controller extends WP_REST_Controller {
protected $meta;
public function __construct();
public function register_routes();
// Permission Checks
public function get_items_permissions_check( $request );
public function get_item_permissions_check( $request );
public function create_item_permissions_check( $request );
public function update_item_permissions_check( $request );
public function delete_item_permissions_check( $request );
// CRUD Operations
public function get_items( $request );
public function get_item( $request );
public function create_item( $request );
public function update_item( $request );
public function delete_item( $request );
// Data Preparation
protected function prepare_item_for_database( $request );
public function prepare_item_for_response( $item, $request );
protected function prepare_links( $comment );
// Schema & Parameters
public function get_item_schema();
public function get_collection_params();
// Utilities
protected function get_comment( $id );
protected function normalize_query_param( $query_param );
protected function prepare_status_response( $comment_approved );
protected function handle_status_param( $new_status, $comment_id );
protected function check_read_permission( $comment, $request );
protected function check_read_post_permission( $post, $request );
protected function check_edit_permission( $comment );
protected function check_is_comment_content_allowed( $prepared_comment );
protected function check_post_type_supports_notes( $post_type );
public function check_comment_author_email( $value, $request, $param );
}
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /wp/v2/comments |
List comments |
| POST | /wp/v2/comments |
Create a comment |
| GET | /wp/v2/comments/{id} |
Get a single comment |
| POST/PUT/PATCH | /wp/v2/comments/{id} |
Update a comment |
| DELETE | /wp/v2/comments/{id} |
Delete a comment |
Constructor
public function __construct()
Sets namespace to 'wp/v2', rest_base to 'comments', and creates WP_REST_Comment_Meta_Fields instance.
Collection Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
context |
string | ‘view’ | Scope under which request is made |
page |
integer | 1 | Current page |
per_page |
integer | 10 | Items per page (max 100) |
search |
string | – | Search string |
after |
date-time | – | Comments after date |
before |
date-time | – | Comments before date |
author |
array | – | Filter by author IDs |
author_exclude |
array | – | Exclude author IDs |
author_email |
string | – | Filter by author email |
exclude |
array | [] | Exclude specific IDs |
include |
array | [] | Include specific IDs |
offset |
integer | – | Offset for pagination |
order |
string | ‘desc’ | Sort order (asc/desc) |
orderby |
string | ‘date_gmt’ | Sort field |
parent |
array | – | Filter by parent IDs |
parent_exclude |
array | – | Exclude parent IDs |
post |
array | – | Filter by post IDs |
status |
string | ‘approve’ | Comment status |
type |
string | ‘comment’ | Comment type |
password |
string | – | Post password (for protected posts) |
Orderby Options
date– Comment date (local)date_gmt– Comment date (GMT)id– Comment IDinclude– Order by include parameterpost– Post IDparent– Parent comment IDtype– Comment type
Status Values
approve/approved– Approved commentshold– Pending/unapproved commentsspam– Spam commentstrash– Trashed commentsall– All comments (requires capability)
Schema Properties
| Property | Type | Context | Description |
|---|---|---|---|
id |
integer | view, edit, embed | Comment ID (readonly) |
author |
integer | view, edit, embed | Author user ID (0 if guest) |
author_email |
string (email) | edit | Author email |
author_ip |
string (ip) | edit | Author IP address |
author_name |
string | view, edit, embed | Author display name |
author_url |
string (uri) | view, edit, embed | Author URL |
author_user_agent |
string | edit | Author user agent |
content |
object | view, edit, embed | Comment content (raw/rendered) |
date |
string (date-time) | view, edit, embed | Date (site timezone) |
date_gmt |
string (date-time) | view, edit | Date (GMT) |
link |
string (uri) | view, edit, embed | Comment permalink (readonly) |
parent |
integer | view, edit, embed | Parent comment ID (default: 0) |
post |
integer | view, edit | Associated post ID (default: 0) |
status |
string | view, edit | Comment status |
type |
string | view, edit, embed | Comment type (readonly) |
author_avatar_urls |
object | view, edit, embed | Avatar URLs (readonly) |
meta |
object | view, edit | Comment meta |
Permission Checks
get_items_permissions_check()
- Validates read permission for specified posts
- Requires
moderate_commentsfor comments without posts - Requires
edit_postsfor protected parameters:author,author_exclude,author_emailtype(when not ‘comment’)status(when not ‘approve’)
- Special handling for
notetype comments
get_item_permissions_check()
- Validates comment exists
- Requires
moderate_commentsforeditcontext (oredit_commentfor notes) - Calls
check_read_permission()andcheck_read_post_permission()
create_item_permissions_check()
- Requires login if
comment_registrationis enabled - Notes always require login
- Anonymous comments require
rest_allow_anonymous_commentsfilter - Validates
author,author_ip,statussettings require appropriate capabilities - Validates post exists and is not draft/trash
- Validates comments are open for the post
update_item_permissions_check()
- Requires
edit_commentcapability (viacheck_edit_permission())
delete_item_permissions_check()
- Requires
edit_commentcapability
Comment Types
The controller supports two comment types:
Regular Comments (comment)
- Standard user comments on posts
- Subject to comment moderation, flood control, and duplicate checking
- Anonymous submission possible if allowed
Notes (note)
- Internal editorial notes (since WordPress 6.x)
- Requires authentication
- Not subject to moderation/flood control
- Requires post type support (
'note'comment type)
Key Methods
get_comment()
protected function get_comment( int $id ): WP_Comment|WP_Error
Gets the comment if ID is valid. Also validates the associated post exists.
check_read_permission()
protected function check_read_permission( WP_Comment $comment, WP_REST_Request $request ): bool
Checks if a comment can be read. Validates comment status and post visibility.
check_edit_permission()
protected function check_edit_permission( WP_Comment $comment ): bool
Checks if the user can edit a comment. Uses edit_comment capability.
check_is_comment_content_allowed()
protected function check_is_comment_content_allowed( array $prepared_comment ): bool
Validates that the comment content meets requirements (not empty for regular comments, may include note status for notes).
prepare_status_response()
protected function prepare_status_response( string $comment_approved ): string
Converts database status values to API status strings:
'hold'/'0'→'hold''approve'/'1'→'approved''spam'→'spam''trash'→'trash'
handle_status_param()
protected function handle_status_param( string $new_status, int $comment_id ): bool
Updates comment status using wp_set_comment_status().
normalize_query_param()
protected function normalize_query_param( string $query_param ): string
Maps API parameter names to WP_Comment_Query parameter names.
Response Links
| Relation | Description |
|---|---|
self |
Link to this comment |
collection |
Link to comments collection |
author |
Link to author user (embeddable, if logged in) |
up |
Link to parent post (embeddable) |
in-reply-to |
Link to parent comment (embeddable) |
children |
Link to child comments (embeddable) |
Deletion Behavior
DELETE /wp/v2/comments/{id}
Parameters:
force– Iftrue, permanently delete. Iffalse, move to trash.password– Post password if the parent post is protected
Trash Support:
Controlled by EMPTY_TRASH_DAYS constant and rest_comment_trashable filter.
Response:
// With force=true
{
"deleted": true,
"previous": { ... }
}
// With force=false (trashed)
{
"id": 123,
"status": "trash",
...
}
Avatar URLs
If avatars are enabled, includes avatar URLs at multiple sizes:
{
"author_avatar_urls": {
"24": "https://secure.gravatar.com/avatar/...?s=24",
"48": "https://secure.gravatar.com/avatar/...?s=48",
"96": "https://secure.gravatar.com/avatar/...?s=96"
}
}
Usage Example
// Get comments for a specific post
$request = new WP_REST_Request( 'GET', '/wp/v2/comments' );
$request->set_param( 'post', 123 );
$request->set_param( 'per_page', 20 );
$request->set_param( 'orderby', 'date' );
$request->set_param( 'order', 'asc' );
$controller = new WP_REST_Comments_Controller();
$response = $controller->get_items( $request );
// Create a comment
$request = new WP_REST_Request( 'POST', '/wp/v2/comments' );
$request->set_param( 'post', 123 );
$request->set_param( 'content', 'Great article!' );
$request->set_param( 'author_name', 'John Doe' );
$request->set_param( 'author_email', '[email protected]' );
$response = $controller->create_item( $request );
// Reply to a comment
$request = new WP_REST_Request( 'POST', '/wp/v2/comments' );
$request->set_param( 'post', 123 );
$request->set_param( 'parent', 456 ); // Parent comment ID
$request->set_param( 'content', 'I agree!' );
$response = $controller->create_item( $request );
// Update comment status (moderate)
$request = new WP_REST_Request( 'POST', '/wp/v2/comments/123' );
$request->set_param( 'status', 'approved' );
$response = $controller->update_item( $request );
Anonymous Comments
By default, anonymous comment creation via REST API is disabled. Enable with:
add_filter( 'rest_allow_anonymous_comments', function( $allow, $request ) {
return true;
}, 10, 2 );
Source
wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
Since
WordPress 4.7.0
Changelog
| Version | Description |
|---|---|
| 4.7.0 | Introduced |
| 4.8.0 | rest_pre_insert_comment can return WP_Error |
| 5.0.0 | Added rest_after_insert_comment action |