openapi: 3.1.0 info: title: Discourse API Documentation Admin 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: Admin paths: /admin/users/{id}.json: get: summary: Get a user by id tags: - Admin operationId: adminGetUser parameters: - name: id in: path required: true schema: type: integer responses: '200': description: response content: application/json: schema: additionalProperties: false properties: id: type: integer username: type: string name: type: - string - 'null' avatar_template: type: string active: type: boolean admin: type: boolean moderator: type: boolean last_seen_at: type: - string - 'null' last_emailed_at: type: - string - 'null' created_at: type: string last_seen_age: type: - number - 'null' last_emailed_age: type: - number - 'null' created_at_age: type: - number - 'null' trust_level: type: integer manual_locked_trust_level: type: - string - 'null' title: type: - string - 'null' time_read: type: integer staged: type: boolean days_visited: type: integer posts_read_count: type: integer topics_entered: type: integer post_count: type: integer associated_accounts: type: array items: {} can_send_activation_email: type: boolean can_activate: type: boolean can_deactivate: type: boolean can_change_trust_level: type: boolean ip_address: type: string registration_ip_address: type: - string - 'null' can_grant_admin: type: boolean can_revoke_admin: type: boolean can_grant_moderation: type: boolean can_revoke_moderation: type: boolean can_impersonate: type: boolean like_count: type: integer like_given_count: type: integer topic_count: type: integer flags_given_count: type: integer flags_received_count: type: integer private_topics_count: type: integer can_delete_all_posts: type: boolean can_be_deleted: type: boolean can_be_anonymized: type: boolean can_be_merged: type: boolean full_suspend_reason: type: - string - 'null' latest_export: type: - object - 'null' silence_reason: type: - string - 'null' post_edits_count: type: - integer - 'null' primary_group_id: type: - integer - 'null' badge_count: type: integer warnings_received_count: type: integer bounce_score: type: - integer - 'null' reset_bounce_score_after: type: - string - 'null' can_view_action_logs: type: boolean can_disable_second_factor: type: boolean can_delete_sso_record: type: boolean api_key_count: type: integer similar_users_count: type: integer single_sign_on_record: type: - string - 'null' approved_by: type: - object - 'null' additionalProperties: false properties: id: type: integer username: type: string name: type: string avatar_template: type: string required: - id - username - name - avatar_template suspended_by: type: - string - 'null' silenced_by: type: - string - 'null' penalty_counts: type: object additionalProperties: false properties: silenced: type: integer suspended: type: integer required: - silenced - suspended next_penalty: type: string tl3_requirements: type: object additionalProperties: false properties: time_period: type: integer requirements_met: type: boolean requirements_lost: type: boolean trust_level_locked: type: boolean on_grace_period: type: boolean days_visited: type: integer min_days_visited: type: integer num_topics_replied_to: type: integer min_topics_replied_to: type: integer topics_viewed: type: integer min_topics_viewed: type: integer posts_read: type: integer min_posts_read: type: integer topics_viewed_all_time: type: integer min_topics_viewed_all_time: type: integer posts_read_all_time: type: integer min_posts_read_all_time: type: integer num_flagged_posts: type: integer max_flagged_posts: type: integer num_flagged_by_users: type: integer max_flagged_by_users: type: integer num_likes_given: type: integer min_likes_given: type: integer num_likes_received: type: integer min_likes_received: type: integer num_likes_received_days: type: integer min_likes_received_days: type: integer num_likes_received_users: type: integer min_likes_received_users: type: integer penalty_counts: type: object additionalProperties: false properties: silenced: type: integer suspended: type: integer total: type: integer required: - silenced - suspended - total required: - time_period - requirements_met - requirements_lost - trust_level_locked - on_grace_period - days_visited - min_days_visited - num_topics_replied_to - min_topics_replied_to - topics_viewed - min_topics_viewed - posts_read - min_posts_read - topics_viewed_all_time - min_topics_viewed_all_time - posts_read_all_time - min_posts_read_all_time - num_flagged_posts - max_flagged_posts - num_flagged_by_users - max_flagged_by_users - num_likes_given - min_likes_given - num_likes_received - min_likes_received - num_likes_received_days - min_likes_received_days - num_likes_received_users - min_likes_received_users - penalty_counts groups: type: array items: type: object additionalProperties: false properties: id: type: integer automatic: type: boolean name: type: string display_name: type: string user_count: type: integer mentionable_level: type: integer messageable_level: type: integer visibility_level: type: integer primary_group: type: boolean title: type: - string - 'null' grant_trust_level: type: - string - 'null' incoming_email: type: - string - 'null' has_messages: type: boolean flair_url: type: - string - 'null' flair_bg_color: type: - string - 'null' flair_color: type: - string - 'null' flair_group_id: type: - integer - 'null' bio_raw: type: - string - 'null' bio_cooked: type: - string - 'null' bio_excerpt: type: - string - 'null' public_admission: type: boolean public_exit: type: boolean allow_membership_requests: type: boolean full_name: type: - string - 'null' default_notification_level: type: integer membership_request_template: type: - string - 'null' members_visibility_level: type: integer can_see_members: type: boolean can_admin_group: type: boolean publish_read_state: type: boolean required: - id - automatic - name - display_name - user_count - mentionable_level - messageable_level - visibility_level - primary_group - title - grant_trust_level - incoming_email - has_messages - flair_url - flair_bg_color - flair_color - bio_raw - bio_cooked - bio_excerpt - public_admission - public_exit - allow_membership_requests - full_name - default_notification_level - membership_request_template - members_visibility_level - can_see_members - can_admin_group - publish_read_state external_ids: type: object include_ip: type: boolean upcoming_changes_stats: type: array items: type: object additionalProperties: false properties: name: type: string humanized_name: type: string description: type: string enabled: type: boolean specific_groups: type: array items: type: string reason: type: string enum: - enabled_for_everyone - enabled_for_no_one - in_specific_groups - not_in_specific_groups required: - name - humanized_name - description - enabled - specific_groups - reason required: - id - username - name - avatar_template - active - admin - moderator - last_seen_at - last_emailed_at - created_at - last_seen_age - last_emailed_age - created_at_age - trust_level - manual_locked_trust_level - title - time_read - staged - days_visited - posts_read_count - topics_entered - post_count - can_send_activation_email - can_activate - can_deactivate - ip_address - registration_ip_address - can_grant_admin - can_revoke_admin - can_grant_moderation - can_revoke_moderation - can_impersonate - like_count - like_given_count - topic_count - flags_given_count - flags_received_count - private_topics_count - can_delete_all_posts - can_be_anonymized - can_be_merged - full_suspend_reason - primary_group_id - badge_count - warnings_received_count - bounce_score - reset_bounce_score_after - can_view_action_logs - can_disable_second_factor - can_delete_sso_record - api_key_count - single_sign_on_record - approved_by - suspended_by - silenced_by - groups - external_ids - include_ip delete: summary: Delete a user tags: - Admin operationId: deleteUser parameters: - name: id in: path required: true schema: type: integer responses: '200': description: response content: application/json: schema: additionalProperties: false properties: deleted: type: boolean required: - deleted requestBody: content: application/json: schema: additionalProperties: false properties: delete_posts: type: boolean block_email: type: boolean block_urls: type: boolean block_ip: type: boolean /admin/users/{id}/activate.json: put: summary: Activate a user tags: - Admin operationId: activateUser parameters: - name: id in: path required: true schema: type: integer responses: '200': description: response content: application/json: schema: additionalProperties: false properties: success: type: string example: OK required: - success /admin/users/{id}/deactivate.json: put: summary: Deactivate a user tags: - Admin operationId: deactivateUser parameters: - name: id in: path required: true schema: type: integer responses: '200': description: response content: application/json: schema: additionalProperties: false properties: success: type: string example: OK required: - success /admin/users/{id}/suspend.json: put: summary: Suspend a user tags: - Admin operationId: suspendUser parameters: - name: id in: path required: true schema: type: integer responses: '200': description: response content: application/json: schema: additionalProperties: false properties: suspension: type: object additionalProperties: false properties: suspend_reason: type: string full_suspend_reason: type: string suspended_till: type: string suspended_at: type: string suspended_by: type: object additionalProperties: false properties: id: type: integer username: type: string name: type: string avatar_template: type: string required: - id - username - name - avatar_template required: - suspend_reason - full_suspend_reason - suspended_till - suspended_at - suspended_by required: - suspension requestBody: content: application/json: schema: additionalProperties: false properties: suspend_until: type: string example: '2121-02-22' reason: type: string message: type: string description: Will send an email with this message when present post_action: type: string example: delete required: - suspend_until - reason /admin/users/{id}/silence.json: put: summary: Silence a user tags: - Admin operationId: silenceUser parameters: - name: id in: path required: true schema: type: integer responses: '200': description: response content: application/json: schema: additionalProperties: false properties: silence: type: object additionalProperties: false properties: silenced: type: boolean silence_reason: type: string silenced_till: type: string silenced_at: type: string silenced_by: type: object additionalProperties: false properties: id: type: integer username: type: string name: type: string avatar_template: type: string required: - id - username - name - avatar_template required: - silenced - silence_reason - silenced_till - silenced_at - silenced_by required: - silence requestBody: content: application/json: schema: additionalProperties: false properties: silenced_till: type: string example: '2022-06-01T08:00:00.000Z' reason: type: string message: type: string description: Will send an email with this message when present post_action: type: string example: delete required: - silenced_till - reason /admin/users/{id}/anonymize.json: put: summary: Anonymize a user tags: - Admin operationId: anonymizeUser parameters: - name: id in: path required: true schema: type: integer responses: '200': description: response content: application/json: schema: additionalProperties: false properties: success: type: string username: type: string required: - success - username /admin/users/{id}/log_out.json: post: summary: Log a user out tags: - Admin operationId: logOutUser parameters: - name: id in: path required: true schema: type: integer responses: '200': description: response content: application/json: schema: additionalProperties: false properties: success: type: string example: OK required: - success /user_avatar/{username}/refresh_gravatar.json: post: summary: Refresh gravatar tags: - Admin operationId: refreshGravatar parameters: - name: username in: path required: true schema: type: string responses: '200': description: response content: application/json: schema: additionalProperties: false properties: gravatar_upload_id: type: - integer - 'null' gravatar_avatar_template: type: - string - 'null' required: - gravatar_upload_id - gravatar_avatar_template /admin/users.json: get: summary: List users tags: - Admin operationId: adminListUsers parameters: - name: order in: query schema: type: string enum: - created - last_emailed - seen - username - email - trust_level - days_visited - posts_read - topics_viewed - posts - read_time - name: asc in: query schema: type: string enum: - 'true' - name: page in: query schema: type: integer - name: show_emails in: query description: 'Include user email addresses in response. These requests will be logged in the staff action logs.' schema: type: boolean - name: stats in: query description: Include user stats information schema: type: boolean - name: email in: query description: Filter to the user with this email address schema: type: string - name: ip in: query description: Filter to users with this IP address schema: type: string responses: '200': description: users response content: application/json: schema: type: array minItems: 1 uniqueItems: true items: type: object properties: id: type: integer username: type: string name: type: - string - 'null' avatar_template: type: string email: type: string secondary_emails: type: array items: {} active: type: boolean admin: type: boolean moderator: type: boolean last_seen_at: type: - string - 'null' last_emailed_at: type: - string - 'null' created_at: type: string last_seen_age: type: - number - 'null' last_emailed_age: type: - number - 'null' created_at_age: type: - number - 'null' trust_level: type: integer manual_locked_trust_level: type: - string - 'null' title: type: - string - 'null' time_read: type: integer staged: type: boolean days_visited: type: integer posts_read_count: type: integer topics_entered: type: integer post_count: type: integer required: - id - username - name - avatar_template - active - admin - moderator - last_seen_at - last_emailed_at - created_at - last_seen_age - last_emailed_age - created_at_age - trust_level - manual_locked_trust_level - title - time_read - staged - days_visited - posts_read_count - topics_entered - post_count /admin/users/list/{flag}.json: get: summary: List users by flag tags: - Admin operationId: adminListUsersFlag parameters: - name: flag in: path schema: type: string enum: - active - new - staff - suspended - blocked - suspect required: true - name: order in: query schema: type: string enum: - created - last_emailed - seen - username - email - trust_level - days_visited - posts_read - topics_viewed - posts - read_time - name: asc in: query schema: type: string enum: - 'true' - name: page in: query schema: type: integer - name: show_emails in: query description: 'Include user email addresses in response. These requests will be logged in the staff action logs.' schema: type: boolean - name: stats in: query description: Include user stats information schema: type: boolean - name: email in: query description: Filter to the user with this email address schema: type: string - name: ip in: query description: Filter to users with this IP address schema: type: string responses: '200': description: response content: application/json: schema: type: array minItems: 1 uniqueItems: true items: type: object properties: id: type: integer username: type: string name: type: - string - 'null' avatar_template: type: string email: type: string secondary_emails: type: array items: {} active: type: boolean admin: type: boolean moderator: type: boolean last_seen_at: type: - string - 'null' last_emailed_at: type: - string - 'null' created_at: type: string last_seen_age: type: - number - 'null' last_emailed_age: type: - number - 'null' created_at_age: type: - number - 'null' trust_level: type: integer manual_locked_trust_level: type: - string - 'null' title: type: - string - 'null' time_read: type: integer staged: type: boolean days_visited: type: integer posts_read_count: type: integer topics_entered: type: integer post_count: type: integer required: - id - username - name - avatar_template - active - admin - moderator - last_seen_at - last_emailed_at - created_at - last_seen_age - last_emailed_age - created_at_age - trust_level - manual_locked_trust_level - title - time_read - staged - days_visited - posts_read_count - topics_entered - post_count