openapi: 3.1.0 info: title: Discourse API Documentation Admin Posts API x-logo: url: https://docs.discourse.org/logo.svg version: latest description: 'This page contains the documentation on how to use Discourse through API calls. > Note: For any endpoints not listed you can follow the [reverse engineer the Discourse API](https://meta.discourse.org/t/-/20576) guide to figure out how to use an API endpoint. ### Request Content-Type The Content-Type for POST and PUT requests can be set to `application/x-www-form-urlencoded`, `multipart/form-data`, or `application/json`. ### Endpoint Names and Response Content-Type Most API endpoints provide the same content as their HTML counterparts. For example the URL `/categories` serves a list of categories, the `/categories.json` API provides the same information in JSON format. Instead of sending API requests to `/categories.json` you may also send them to `/categories` and add an `Accept: application/json` header to the request to get the JSON response. Sending requests with the `Accept` header is necessary if you want to use URLs for related endpoints returned by the API, such as pagination URLs. These URLs are returned without the `.json` prefix so you need to add the header in order to get the correct response format. ### Authentication Some endpoints do not require any authentication, pretty much anything else will require you to be authenticated. To become authenticated you will need to create an API Key from the admin panel. Once you have your API Key you can pass it in along with your API Username as an HTTP header like this: ``` curl -X GET "http://127.0.0.1:3000/admin/users/list/active.json" \ -H "Api-Key: 714552c6148e1617aeab526d0606184b94a80ec048fc09894ff1a72b740c5f19" \ -H "Api-Username: system" ``` and this is how POST requests will look: ``` curl -X POST "http://127.0.0.1:3000/categories" \ -H "Content-Type: multipart/form-data;" \ -H "Api-Key: 714552c6148e1617aeab526d0606184b94a80ec048fc09894ff1a72b740c5f19" \ -H "Api-Username: system" \ -F "name=89853c20-4409-e91a-a8ea-f6cdff96aaaa" \ -F "color=49d9e9" \ -F "text_color=f0fcfd" ``` ### Boolean values If an endpoint accepts a boolean be sure to specify it as a lowercase `true` or `false` value unless noted otherwise. ' license: name: MIT url: https://docs.discourse.org/LICENSE.txt servers: - url: https://{defaultHost} variables: defaultHost: default: discourse.example.com tags: - name: Posts paths: /posts.json: get: summary: List latest posts across topics tags: - Posts operationId: listPosts parameters: - name: before in: query required: false description: Load posts with an id lower than this value. Useful for pagination. schema: type: integer responses: '200': description: latest posts content: application/json: schema: additionalProperties: false properties: latest_posts: type: array items: type: object additionalProperties: false properties: id: type: integer name: type: - string - 'null' username: type: string avatar_template: type: string created_at: type: string cooked: type: string post_number: type: integer post_type: type: integer posts_count: type: integer updated_at: type: string reply_count: type: integer reply_to_post_number: type: - string - 'null' quote_count: type: integer incoming_link_count: type: integer reads: type: integer readers_count: type: integer score: type: number yours: type: boolean topic_id: type: integer topic_slug: type: string topic_title: type: string topic_html_title: type: string category_id: type: integer display_username: type: - string - 'null' primary_group_name: type: - string - 'null' flair_name: type: - string - 'null' flair_url: type: - string - 'null' flair_bg_color: type: - string - 'null' flair_color: type: - string - 'null' flair_group_id: type: - string - 'null' badges_granted: type: array items: {} version: type: integer can_edit: type: boolean can_delete: type: boolean can_recover: type: boolean can_see_hidden_post: type: boolean can_wiki: type: boolean user_title: type: - string - 'null' bookmarked: type: boolean raw: type: string actions_summary: type: array items: type: object additionalProperties: false properties: id: type: integer can_act: type: boolean required: - id - can_act moderator: type: boolean admin: type: boolean staff: type: boolean user_id: type: integer hidden: type: boolean trust_level: type: integer deleted_at: type: - string - 'null' user_deleted: type: boolean edit_reason: type: - string - 'null' can_view_edit_history: type: boolean wiki: type: boolean excerpt: type: string truncated: type: boolean reviewable_id: type: - string - 'null' reviewable_score_count: type: integer reviewable_score_pending_count: type: integer post_url: type: string required: - id - name - username - avatar_template - created_at - cooked - post_number - post_type - posts_count - updated_at - reply_count - reply_to_post_number - quote_count - incoming_link_count - reads - readers_count - score - yours - topic_id - topic_slug - topic_title - topic_html_title - category_id - display_username - primary_group_name - flair_name - flair_url - flair_bg_color - flair_color - flair_group_id - badges_granted - version - can_edit - can_delete - can_recover - can_see_hidden_post - can_wiki - user_title - bookmarked - raw - actions_summary - moderator - admin - staff - user_id - hidden - trust_level - deleted_at - user_deleted - edit_reason - can_view_edit_history - wiki - excerpt - truncated - reviewable_id - reviewable_score_count - reviewable_score_pending_count - post_url required: - latest_posts post: summary: Creates a new topic, a new post, or a private message tags: - Posts operationId: createTopicPostPM parameters: [] responses: '200': description: post created content: application/json: schema: additionalProperties: false properties: id: type: integer name: type: - string - 'null' username: type: string avatar_template: type: string created_at: type: string raw: type: string cooked: type: string post_number: type: integer post_type: type: integer posts_count: type: integer updated_at: type: string reply_count: type: integer reply_to_post_number: type: - string - 'null' quote_count: type: integer incoming_link_count: type: integer reads: type: integer readers_count: type: integer score: type: number yours: type: boolean topic_id: type: integer topic_slug: type: string display_username: type: - string - 'null' primary_group_name: type: - string - 'null' flair_name: type: - string - 'null' flair_url: type: - string - 'null' flair_bg_color: type: - string - 'null' flair_color: type: - string - 'null' flair_group_id: type: - integer - 'null' badges_granted: type: array items: {} version: type: integer can_edit: type: boolean can_delete: type: boolean can_recover: type: boolean can_see_hidden_post: type: boolean can_wiki: type: boolean user_title: type: - string - 'null' bookmarked: type: boolean actions_summary: type: array items: type: object additionalProperties: false properties: id: type: integer can_act: type: boolean required: - id - can_act moderator: type: boolean admin: type: boolean staff: type: boolean user_id: type: integer draft_sequence: type: integer hidden: type: boolean trust_level: type: integer deleted_at: type: - string - 'null' user_deleted: type: boolean edit_reason: type: - string - 'null' can_view_edit_history: type: boolean wiki: type: boolean reviewable_id: type: - integer - 'null' reviewable_score_count: type: integer reviewable_score_pending_count: type: integer post_url: type: string post_localizations: type: array items: {} mentioned_users: type: array items: {} required: - id - name - username - avatar_template - created_at - cooked - post_number - post_type - posts_count - updated_at - reply_count - reply_to_post_number - quote_count - incoming_link_count - reads - readers_count - score - yours - topic_id - topic_slug - display_username - primary_group_name - flair_name - flair_url - flair_bg_color - flair_color - version - can_edit - can_delete - can_recover - can_wiki - user_title - bookmarked - actions_summary - moderator - admin - staff - user_id - draft_sequence - hidden - trust_level - deleted_at - user_deleted - edit_reason - can_view_edit_history - wiki - reviewable_id - reviewable_score_count - reviewable_score_pending_count - post_url requestBody: content: application/json: schema: additionalProperties: false properties: title: type: string description: Required if creating a new topic or new private message. raw: type: string topic_id: type: integer description: Required if creating a new post. category: type: integer description: 'Optional if creating a new topic, and ignored if creating a new post.' target_recipients: type: string description: Required for private message, comma separated. example: blake,sam target_usernames: type: string description: Deprecated. Use target_recipients instead. deprecated: true archetype: type: string description: Required for new private message. example: private_message created_at: type: string reply_to_post_number: type: integer description: Optional, the post number to reply to inside a topic. embed_url: type: string description: 'Provide a URL from a remote system to associate a forum topic with that URL, typically for using Discourse as a comments system for an external blog.' external_id: type: string description: 'Provide an external_id from a remote system to associate a forum topic with that id.' auto_track: type: boolean description: 'If false, the user will not track the topic. By default, the user will track the topic.' required: - raw /posts/{id}.json: get: summary: Retrieve a single post tags: - Posts operationId: getPost description: 'This endpoint can be used to get the number of likes on a post using the `actions_summary` property in the response. `actions_summary` responses with the id of `2` signify a `like`. If there are no `actions_summary` items with the id of `2`, that means there are 0 likes. Other ids likely refer to various different flag types. ' parameters: - name: id in: path schema: type: string required: true responses: '200': description: single reviewable post content: application/json: schema: additionalProperties: true properties: id: type: integer username: type: string avatar_template: type: string created_at: type: string cooked: type: string post_number: type: integer post_type: type: integer posts_count: type: integer updated_at: type: string reply_count: type: integer reply_to_post_number: type: - string - 'null' quote_count: type: integer incoming_link_count: type: integer reads: type: integer readers_count: type: integer score: type: number yours: type: boolean topic_id: type: integer topic_slug: type: string primary_group_name: type: - string - 'null' flair_name: type: - string - 'null' flair_url: type: - string - 'null' flair_bg_color: type: - string - 'null' flair_color: type: - string - 'null' flair_group_id: type: - integer - 'null' version: type: integer can_edit: type: boolean can_delete: type: boolean can_recover: type: boolean can_see_hidden_post: type: boolean can_wiki: type: boolean user_title: type: - string - 'null' bookmarked: type: boolean raw: type: string actions_summary: type: array items: type: object additionalProperties: false properties: id: type: integer description: '`2`: like, `3`, `4`, `6`, `7`, `8`: flag' count: type: integer acted: type: boolean can_undo: type: boolean can_act: type: boolean required: - id moderator: type: boolean admin: type: boolean staff: type: boolean user_id: type: integer hidden: type: boolean trust_level: type: integer deleted_at: type: - string - 'null' user_deleted: type: boolean edit_reason: type: - string - 'null' can_view_edit_history: type: boolean wiki: type: boolean reviewable_id: type: - integer - 'null' reviewable_score_count: type: integer reviewable_score_pending_count: type: integer post_url: type: string mentioned_users: type: array items: {} name: type: - string - 'null' display_username: type: - string - 'null' required: - id - username - avatar_template - created_at - cooked - post_number - post_type - posts_count - updated_at - reply_count - reply_to_post_number - quote_count - incoming_link_count - reads - readers_count - score - yours - topic_id - topic_slug - primary_group_name - flair_name - flair_url - flair_bg_color - flair_color - version - can_edit - can_delete - can_recover - can_wiki - user_title - bookmarked - raw - actions_summary - moderator - admin - staff - user_id - hidden - trust_level - deleted_at - user_deleted - edit_reason - can_view_edit_history - wiki - reviewable_id - reviewable_score_count - reviewable_score_pending_count - post_url put: summary: Update a single post tags: - Posts operationId: updatePost parameters: - name: id in: path schema: type: string required: true responses: '200': description: post updated content: application/json: schema: additionalProperties: false properties: post: type: object additionalProperties: false properties: id: type: integer username: type: string avatar_template: type: string created_at: type: string cooked: type: string post_number: type: integer post_type: type: integer posts_count: type: integer updated_at: type: string reply_count: type: integer reply_to_post_number: type: - string - 'null' quote_count: type: integer incoming_link_count: type: integer reads: type: integer readers_count: type: integer score: type: number yours: type: boolean topic_id: type: integer topic_slug: type: string primary_group_name: type: - string - 'null' flair_name: type: - string - 'null' flair_url: type: - string - 'null' flair_bg_color: type: - string - 'null' flair_color: type: - string - 'null' flair_group_id: type: - integer - 'null' badges_granted: type: array items: {} version: type: integer can_edit: type: boolean can_delete: type: boolean can_recover: type: boolean can_see_hidden_post: type: boolean can_wiki: type: boolean user_title: type: - string - 'null' bookmarked: type: boolean raw: type: string actions_summary: type: array items: type: object additionalProperties: false properties: id: type: integer can_act: type: boolean required: - id - can_act moderator: type: boolean admin: type: boolean staff: type: boolean user_id: type: integer draft_sequence: type: integer hidden: type: boolean trust_level: type: integer deleted_at: type: - string - 'null' user_deleted: type: boolean edit_reason: type: - string - 'null' can_view_edit_history: type: boolean wiki: type: boolean reviewable_id: type: - integer - 'null' reviewable_score_count: type: integer reviewable_score_pending_count: type: integer post_url: type: string post_localizations: type: array items: {} mentioned_users: type: array items: {} name: type: - string - 'null' display_username: type: - string - 'null' required: - id - username - avatar_template - created_at - cooked - post_number - post_type - posts_count - updated_at - reply_count - reply_to_post_number - quote_count - incoming_link_count - reads - readers_count - score - yours - topic_id - topic_slug - primary_group_name - flair_name - flair_url - flair_bg_color - flair_color - version - can_edit - can_delete - can_recover - can_wiki - user_title - bookmarked - raw - actions_summary - moderator - admin - staff - user_id - draft_sequence - hidden - trust_level - deleted_at - user_deleted - edit_reason - can_view_edit_history - wiki - reviewable_id - reviewable_score_count - reviewable_score_pending_count - post_url required: - post requestBody: content: application/json: schema: additionalProperties: false properties: post: type: object additionalProperties: false properties: raw: type: string edit_reason: type: string required: - raw bypass_bump: type: boolean description: 'Skip bumping the topic when updating the post. Requires staff or TL4 permissions.' delete: summary: delete a single post tags: - Posts operationId: deletePost parameters: - name: id in: path schema: type: integer required: true responses: '200': description: success response requestBody: content: application/json: schema: additionalProperties: false properties: force_destroy: type: boolean example: true description: 'The `SiteSetting.can_permanently_delete` needs to be enabled first before this param can be used. Also this endpoint needs to be called first without `force_destroy` and then followed up with a second call 5 minutes later with `force_destroy` to permanently delete.' /posts/{id}/replies.json: get: summary: List replies to a post tags: - Posts operationId: postReplies parameters: - name: id in: path schema: type: string required: true responses: '200': description: post replies content: application/json: schema: type: array uniqueItems: true items: type: object properties: id: type: integer name: type: - string - 'null' username: type: string avatar_template: type: string created_at: type: string cooked: type: string post_number: type: integer post_type: type: integer posts_count: type: integer updated_at: type: string reply_count: type: integer reply_to_post_number: type: integer quote_count: type: integer incoming_link_count: type: integer reads: type: integer readers_count: type: integer score: type: number yours: type: boolean topic_id: type: integer topic_slug: type: string display_username: type: - string - 'null' primary_group_name: type: - string - 'null' flair_name: type: - string - 'null' flair_url: type: - string - 'null' flair_bg_color: type: - string - 'null' flair_color: type: - string - 'null' flair_group_id: type: - integer - 'null' version: type: integer can_edit: type: boolean can_delete: type: boolean can_recover: type: boolean can_see_hidden_post: type: boolean can_wiki: type: boolean user_title: type: - string - 'null' reply_to_user: type: object additionalProperties: false properties: id: type: integer username: type: string name: type: string avatar_template: type: string required: - username - avatar_template bookmarked: type: boolean actions_summary: type: array items: type: object additionalProperties: false properties: id: type: integer can_act: type: boolean required: - id - can_act moderator: type: boolean admin: type: boolean staff: type: boolean user_id: type: integer hidden: type: boolean trust_level: type: integer deleted_at: type: - string - 'null' user_deleted: type: boolean edit_reason: type: - string - 'null' can_view_edit_history: type: boolean wiki: type: boolean reviewable_id: type: - integer - 'null' reviewable_score_count: type: integer reviewable_score_pending_count: type: integer post_url: type: string required: - id - name - username - avatar_template - created_at - cooked - post_number - post_type - posts_count - updated_at - reply_count - reply_to_post_number - quote_count - incoming_link_count - reads - readers_count - score - yours - topic_id - topic_slug - display_username - primary_group_name - flair_name - flair_url - flair_bg_color - flair_color - version - can_edit - can_delete - can_recover - can_see_hidden_post - can_wiki - user_title - reply_to_user - bookmarked - actions_summary - moderator - admin - staff - user_id - hidden - trust_level - deleted_at - user_deleted - edit_reason - can_view_edit_history - wiki - reviewable_id - reviewable_score_count - reviewable_score_pending_count - post_url /posts/{id}/locked.json: put: summary: Lock a post from being edited tags: - Posts operationId: lockPost parameters: - name: Api-Key in: header required: true schema: type: string - name: Api-Username in: header required: true schema: type: string - name: id in: path schema: type: string required: true responses: '200': description: post updated content: application/json: schema: type: object properties: locked: type: boolean description: Whether the post is locked required: - locked requestBody: content: application/json: schema: type: object properties: locked: type: string description: Whether to lock the post (true/false) required: - locked /post_actions.json: post: summary: Like a post and other actions tags: - Posts operationId: performPostAction parameters: - name: Api-Key in: header required: true schema: type: string - name: Api-Username in: header required: true schema: type: string responses: '200': description: post updated content: application/json: schema: additionalProperties: true properties: id: type: integer description: The ID of the post name: type: string description: The name of the post author username: type: string description: The username of the post author avatar_template: type: string description: Template for the author's avatar URL created_at: type: string description: When the post was created cooked: type: string description: The HTML content of the post post_number: type: integer description: The post number within the topic post_type: type: integer description: The type of post posts_count: type: integer description: Total posts count for the user updated_at: type: string description: When the post was last updated reply_count: type: integer description: Number of replies to this post reply_to_post_number: type: - string - 'null' description: Post number this post is replying to quote_count: type: integer description: Number of times this post has been quoted incoming_link_count: type: integer description: Number of incoming links to this post reads: type: integer description: Number of reads readers_count: type: integer description: Number of readers score: type: number description: Post score yours: type: boolean description: Whether this post belongs to the current user topic_id: type: integer description: ID of the topic this post belongs to topic_slug: type: string description: Slug of the topic this post belongs to display_username: type: string description: Display username of the post author primary_group_name: type: - string - 'null' description: Primary group name of the author flair_name: type: - string - 'null' description: Flair name of the author flair_url: type: - string - 'null' description: Flair URL of the author flair_bg_color: type: - string - 'null' description: Flair background color of the author flair_color: type: - string - 'null' description: Flair color of the author flair_group_id: type: - integer - 'null' description: Flair group ID of the author badges_granted: type: array description: Badges granted to the user version: type: integer description: Version number of the post can_edit: type: boolean description: Whether the current user can edit this post can_delete: type: boolean description: Whether the current user can delete this post can_recover: type: boolean description: Whether the current user can recover this post can_see_hidden_post: type: boolean description: Whether the current user can see hidden posts can_wiki: type: boolean description: Whether the current user can wiki this post user_title: type: - string - 'null' description: Title of the post author bookmarked: type: boolean description: Whether the post is bookmarked by the current user actions_summary: type: array description: Summary of actions performed on this post items: type: object additionalProperties: true properties: id: type: integer description: ID of the action type (e.g., 2 for like) count: type: integer description: Number of times this action has been performed acted: type: boolean description: 'Whether the current user has performed this action' can_undo: type: boolean description: Whether the current user can undo this action can_act: type: boolean description: Whether the current user can perform this action moderator: type: boolean description: Whether the post author is a moderator admin: type: boolean description: Whether the post author is an admin staff: type: boolean description: Whether the post author is staff user_id: type: integer description: ID of the post author hidden: type: boolean description: Whether the post is hidden trust_level: type: integer description: Trust level of the post author deleted_at: type: - string - 'null' description: When the post was deleted user_deleted: type: boolean description: Whether the post was deleted by the user edit_reason: type: - string - 'null' description: Reason for the last edit can_view_edit_history: type: boolean description: Whether the current user can view edit history wiki: type: boolean description: Whether this is a wiki post reviewable_id: type: - integer - 'null' description: ID of the reviewable if this post is under review reviewable_score_count: type: integer description: Number of reviewable scores reviewable_score_pending_count: type: integer description: Number of pending reviewable scores post_url: type: string description: URL of the post required: - id - name - username - avatar_template - created_at - cooked - post_number - post_type - posts_count - updated_at - reply_count - reply_to_post_number - quote_count - incoming_link_count - reads - readers_count - score - yours - topic_id - topic_slug - display_username - primary_group_name - flair_name - flair_url - flair_bg_color - flair_color - flair_group_id - badges_granted - version - can_edit - can_delete - can_recover - can_see_hidden_post - can_wiki - user_title - bookmarked - actions_summary - moderator - admin - staff - user_id - hidden - trust_level - deleted_at - user_deleted - edit_reason - can_view_edit_history - wiki - reviewable_id - reviewable_score_count - reviewable_score_pending_count - post_url requestBody: content: application/json: schema: additionalProperties: false properties: id: type: integer description: The ID of the post to perform the action on post_action_type_id: type: integer description: The ID of the post action type (e.g., 2 for like) flag_topic: type: boolean description: Whether to flag the entire topic required: - id - post_action_type_id