Discourse Admin API
The Admin API from Discourse — 10 operation(s) for admin.
The Admin API from Discourse — 10 operation(s) for admin.
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:
# --- truncated at 32 KB (38 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/discourse/refs/heads/main/openapi/discourse-admin-api-openapi.yml