You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1337 lines
38 KiB
YAML

openapi: 3.0.0
info:
title: NodeBB Write API
description: >-
# Overview
The following document outlines every route exposed by the NodeBB Write API. As of NodeBB v1.15.0, NodeBB will use these routes to make changes to the database (e.g. creating new posts, editing user profiles, etc.)
We invite you to build external integrations with NodeBB using this document as a guide.
# History
Up until v1.15.0, NodeBB utilised the [WebSocket](https://en.wikipedia.org/wiki/WebSocket) protocol to communicate with the backend. However, it was decided in early 2020 that this usage of WebSocket – while functional – led to occasional wheel reinvention and disregarded an otherwise fully-featured technology (that is, REST).
Years prior to this determination, many users of NodeBB had asked for a RESTful API to call against NodeBB, which led to the creation of [`nodebb-plugin-write-api`](https://github.com/NodeBB/nodebb-plugin-write-api). In tandem with the above decision, the Write API was merged into NodeBB core in late 2020.
v3 of the Write API (this document) achieves rough feature parity with v2 of the Write API plugin.
version: 1.15.0
contact:
email: support@nodebb.org
license:
name: GPL-3.0
servers:
- url: /api/v1
tags:
- name: users
description: 'Account related calls (create, modify, delete, etc.)'
- name: categories
description: Administrative calls to manage categories
paths:
/users/:
post:
tags:
- users
summary: create a user
description: This operation creates a new user account
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
description: 'If the username is taken, a number will be appended'
password:
type: string
email:
type: string
required:
- username
example:
username: Dragon Fruit
password: s3cre7password
email: dragonfruit@example.org
responses:
'200':
description: user successfully created
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
$ref: '#/components/schemas/UserObj'
'400':
$ref: '#/components/responses/400'
'401':
$ref: '#/components/responses/401'
'403':
$ref: '#/components/responses/403'
'426':
$ref: '#/components/responses/426'
'500':
$ref: '#/components/responses/500'
delete:
tags:
- users
summary: delete one or more users
description: This operation deletes one or many user accounts, including their contributions (posts, topics, etc.)
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
uids:
type: array
description: A collection of uids
items:
type: number
example:
uids:
- 1
- 2
- 3
responses:
'200':
description: user account(s) deleted
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
'/users/{uid}':
delete:
tags:
- users
summary: delete a single user account
parameters:
- in: path
name: uid
schema:
type: integer
required: true
description: uid of the user to delete
responses:
'200':
description: user account deleted
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
put:
tags:
- users
summary: update a user account
parameters:
- in: path
name: uid
schema:
type: integer
required: true
description: uid of the user to update
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserRequest'
responses:
'200':
description: user profile updated
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
$ref: '#/components/schemas/UserObj'
'401':
$ref: '#/components/responses/401'
'403':
$ref: '#/components/responses/403'
'426':
$ref: '#/components/responses/426'
'500':
$ref: '#/components/responses/500'
'/users/{uid}/password':
put:
tags:
- users
summary: change a user's password
parameters:
- in: path
name: uid
schema:
type: integer
required: true
description: uid of the user to update
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
currentPassword:
type: string
description: test
example: oldp455word
newPassword:
type: string
example: s3cre7password
required:
- newPassword
responses:
'200':
description: user profile updated
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
'/users/{uid}/follow':
post:
tags:
- users
summary: follow a user
parameters:
- in: path
name: uid
schema:
type: integer
required: true
description: uid of the user to follow
responses:
'200':
description: successfully followed user
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
delete:
tags:
- users
summary: unfollows a user
parameters:
- in: path
name: uid
schema:
type: integer
required: true
description: uid of the user to unfollow
responses:
'200':
description: successfully unfollowed user
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
'/users/{uid}/ban':
put:
tags:
- users
summary: ban a user
parameters:
- in: path
name: uid
schema:
type: integer
required: true
description: uid of the user to ban
requestBody:
content:
application/json:
schema:
type: object
properties:
until:
type: number
description: UNIX timestamp of the ban expiry
example: 1585775608076
reason:
type: string
example: the reason for the ban
responses:
'200':
description: successfully banned user
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
delete:
tags:
- users
summary: unbans a user
parameters:
- in: path
name: uid
schema:
type: integer
required: true
description: uid of the user to unban
responses:
'200':
description: successfully unbanned user
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
'/users/{uid}/tokens':
post:
tags:
- users
summary: generate a user token
description: This route can only be used to generate tokens for the same user. In other words, you cannot use this route to generate a token for a different user than the one you are authenticated as.
responses:
'200':
description: successfully generated a user token
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
delete:
tags:
- users
summary: delete user token
parameters:
- in: path
name: token
schema:
type: string
required: true
description: a valid API token
responses:
'200':
description: successfully deleted user token
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
/categories/:
post:
tags:
- categories
summary: create a category
description: This operation creates a new category
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description:
type: string
parentCid:
type: number
cloneFromCid:
type: number
icon:
type: string
description: A ForkAwesome icon without the `fa-` prefix
bgColor:
type: string
color:
type: string
link:
type: string
class:
type: string
backgroundImage:
type: string
required:
- name
example:
name: My New Category
description: Lorem ipsum, dolor sit amet
parentCid: 0
cloneFromCid: 0
icon: bullhorn
bgColor: '#ffffff'
color: '#000000'
link: 'https://example.org'
class: 'col-md-3 col-xs-6'
backgroundImage: '/assets/relative/path/to/image'
responses:
'200':
description: category successfully created
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
$ref: '#/components/schemas/CategoryObj'
/groups/:
post:
tags:
- groups
summary: create a new group
description: This operation creates a new group
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
timestamp:
type: number
disableJoinRequests:
type: number
enum: [0, 1]
disableLeave:
type: number
enum: [0, 1]
hidden:
type: number
enum: [0, 1]
ownerUid:
type: number
private:
type: number
enum: [0, 1]
description:
type: string
userTitleEnabled:
type: number
enum: [0, 1]
createtime:
type: number
required:
- name
example:
name: 'My Test Group'
hidden: 1
responses:
'200':
description: group successfully created
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
$ref: components/schemas/GroupObject.yaml#/GroupDataObject
delete:
tags:
- groups
summary: Delete an existing group
description: This operation deletes an existing group, all members within this group will cease to be members after the group is deleted.
responses:
'200':
description: group successfully deleted
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/groups/{slug}/membership/{uid}:
put:
tags:
- groups
summary: join a group
description: This operation joins an existing group, or causes another user to join a group. If the group is private and you are not an administrator, this method will cause that user to request membership, instead. For user _invitations_, you'll want to call `PUT /groups/{slug}/invites/{uid}`.
responses:
'200':
description: group successfully joined, or membership requested
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/topics:
post:
tags:
- topics
summary: create a new topic
description: This operation creates a new topic with a post. Topic creation without a post is not allowed via the Write API as it is an internal-only method.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
cid:
type: number
title:
type: string
content:
type: string
tags:
type: array
items:
type: string
required:
- cid
- title
- content
example:
cid: 1
title: Test topic
content: This is the test topic's content
responses:
'200':
description: topic successfully created
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
$ref: components/schemas/TopicObject.yaml#/TopicObject
/topics/{tid}:
post:
tags:
- topics
summary: peply to a topic
description: This operation creates a new reply to an existing topic.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
content:
type: string
timestamp:
type: number
toPid:
type: number
required:
- content
example:
content: This is a test reply
responses:
'200':
description: post successfully created
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
$ref: components/schemas/PostsObject.yaml#/PostsObject
delete:
tags:
- topics
summary: delete a topic
description: This operation purges a topic and all of its posts (careful, there is no confirmation!)
responses:
'200':
description: Topic successfully purged
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/topics/{tid}/state:
delete:
tags:
- topics
summary: delete a topic
description: This operation deletes an existing topic.
responses:
'200':
description: Topic successfully deleted
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
put:
tags:
- topics
summary: restore a topic
description: This operation restores a topic.
responses:
'200':
description: Topic successfully restored
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/topics/{tid}/lock:
put:
tags:
- topics
summary: lock a topic
description: This operation locks an existing topic.
responses:
'200':
description: Topic successfully locked
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
delete:
tags:
- topics
summary: unlock a topic
description: This operation unlocks a topic.
responses:
'200':
description: Topic successfully unlocked
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/topics/{tid}/pin:
put:
tags:
- topics
summary: pin a topic
description: This operation pins an existing topic.
responses:
'200':
description: Topic successfully pinned
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
delete:
tags:
- topics
summary: unpin a topic
description: This operation unpins a topic.
responses:
'200':
description: Topic successfully unpinned
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/topics/{tid}/follow:
put:
tags:
- topics
summary: follow a topic
description: This operation follows (or watches) a topic.
responses:
'200':
description: Topic successfully followed
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
delete:
tags:
- topics
summary: unfollow a topic
description: This operation unfollows (or unwatches) a topic.
responses:
'200':
description: Topic successfully unwatched
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/topics/{tid}/ignore:
put:
tags:
- topics
summary: ignore a topic
description: This operation ignores (or watches) a topic.
responses:
'200':
description: Topic successfully ignored
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
delete:
tags:
- topics
summary: unignore a topic
description: This operation unignores (or unfollows/unwatches) a topic. It is functionally identical to `DEL /topics/{tid}/follow`.
responses:
'200':
description: Topic successfully unignored/unwatched
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/topics/{tid}/tags:
put:
tags:
- topics
summary: adds tags to a topic
description: This operation adds tags to a topic
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
tags:
type: array
description: 'An array of tags'
items:
type: string
example:
tags:
- test
- foobar
responses:
'200':
description: Topic tags successfully added
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
delete:
tags:
- topics
summary: Removes all tags from a topic
description: This operation removed all tags associated with a topic.
responses:
'200':
description: Topic tags successfully removed.
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/posts/{pid}:
put:
tags:
- posts
summary: edit a post
description: This operation edits a post
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
content:
type: string
description: New post content
title:
type: string
description: Topic title, only accepted for main posts
required:
- content
example:
content: 'New post content'
title: 'New title'
responses:
'200':
description: Post successfully edited
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
$ref: components/schemas/PostsObject.yaml#/PostsObject
delete:
tags:
- posts
summary: purge a post
description: This operation purges a post.
responses:
'200':
description: Post successfully purged
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/posts/{pid}/state:
put:
tags:
- posts
summary: restore a post
description: This operation restores a post.
responses:
'200':
description: Topic successfully restored
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
delete:
tags:
- posts
summary: deletes a post
description: This operation soft deletes a post.
responses:
'200':
description: Post successfully deleted
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/posts/{pid}/vote:
put:
tags:
- posts
summary: vote on a post
description: This operation casts a vote on a post.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
delta:
type: number
description: Positive integer for upvote, negative integer for downvote (0 to unvote.)
example:
delta: 1
responses:
'200':
description: Post successfully upvoted
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
delete:
tags:
- posts
summary: unvote a post
description: This operation removes a pre-cast vote on a post.
responses:
'200':
description: Post successfully unvoted
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/posts/{pid}/bookmark:
put:
tags:
- posts
summary: bookmark a post
description: This operation bookmarks a post.
responses:
'200':
description: Post successfully bookmarked
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
delete:
tags:
- posts
summary: unbookmark a post
description: This operation unbookmarks a post.
responses:
'200':
description: Post successfully unbookmarked
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
/admin/settings/{setting}:
put:
tags:
- admin
summary: update configuration setting
description: This operation updates a configuration setting in the backend. The calling user must have the `admin:settings` privilege (or be a superadmin) in order for this call to proceed.
parameters:
- in: path
name: setting
schema:
type: string
required: true
description: backend id of the setting to update
responses:
'200':
description: Admin setting updated
content:
application/json:
schema:
type: object
properties:
status:
$ref: '#/components/schemas/Status'
response:
type: object
properties: {}
components:
schemas:
Status:
type: object
properties:
code:
type: string
example: ok
message:
type: string
example: OK
Error:
type: object
properties:
status:
type: object
properties:
code:
type: string
message:
type: string
response:
type: object
UserObj:
properties:
uid:
type: number
example: 1
username:
type: string
example: Dragon Fruit
userslug:
type: string
example: dragon-fruit
email:
type: string
example: dragonfruit@example.org
'email:confirmed':
type: number
example: 1
joindate:
type: number
example: 1585337827953
lastonline:
type: number
example: 1585337827953
picture:
type: string
example: 'https://images.unsplash.com/photo-1560070094-e1f2ddec4337?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=256&h=256&q=80'
fullname:
type: string
example: Mr. Dragon Fruit Jr.
location:
type: string
example: 'Toronto, Canada'
birthday:
type: string
description: A birthdate given in an ISO format parseable by the Date object
example: 03/27/2020
website:
type: string
example: 'https://example.org'
aboutme:
type: string
example: |
This is a paragraph all about how my life got twist-turned upside-down
and I'd like to take a minute and sit right here,
to tell you all about how I because the administrator of NodeBB
signature:
type: string
example: |
This is an example signature
It can span multiple lines.
uploadedpicture:
type: string
example: /assets/profile/1-profileimg.png
description: 'In almost all cases, defer to "picture" instead. Use this if you need to specifically reference the picture uploaded to the forum.'
profileviews:
type: number
example: 1000
reputation:
type: number
example: 100
postcount:
type: number
example: 1000
topiccount:
type: number
example: 50
lastposttime:
type: number
example: 1585337827953
banned:
type: number
example: 0
'banned:expire':
type: number
example: 1585337827953
status:
type: string
example: online
flags:
type: number
example: 0
followercount:
type: number
example: 2
followingcount:
type: number
example: 5
'cover:url':
type: string
example: /assets/profile/1-cover.png
'cover:position':
type: string
example: 50.0301% 19.2464%
groupTitle:
type: string
example: '["administrators","Staff"]'
groupTitleArray:
type: array
example:
- administrators
- Staff
'icon:text':
type: string
example: D
'icon:bgColor':
type: string
example: '#9c27b0'
joindateISO:
type: string
example: '2020-03-27T20:30:36.590Z'
lastonlineISO:
type: string
example: '2020-03-27T20:30:36.590Z'
banned_until:
type: number
example: 0
banned_until_readable:
type: string
example: Not Banned
UserRequest:
properties:
username:
type: string
example: Dragon Fruit
email:
type: string
example: dragonfruit@example.org
fullname:
type: string
example: Mr. Dragon Fruit Jr.
website:
type: string
example: 'https://example.org'
location:
type: string
example: 'Toronto, Canada'
groupTitle:
type: string
example: '["administrators","Staff"]'
birthday:
type: string
description: A birthdate given in an ISO format parseable by the Date object
example: 03/27/2020
signature:
type: string
example: |
This is an example signature
It can span multiple lines.
aboutme:
type: string
example: |
This is a paragraph all about how my life got twist-turned upside-down
and I'd like to take a minute and sit right here,
to tell you all about how I because the administrator of NodeBB
CategoryObj:
properties:
cid:
type: number
example: 1
name:
type: string
example: My New Category
description:
type: string
example: Lorem ipsum, dolor sit amet
descriptionParsed:
type: string
example: Lorem ipsum, dolor sit amet
icon:
type: string
example: bullhorn
bgColor:
type: string
example: '#ffffff'
color:
type: string
example: '#000000'
slug:
type: string
example: 1/my-new-category
parentCid:
type: number
example: 0
topic_count:
type: number
example: 0
post_count:
type: number
example: 0
disabled:
type: number
example: 0
order:
type: number
example: 5
link:
type: number
example: 'https://example.org'
numRecentReplies:
type: number
example: 1
class:
type: string
example: col-md-3 col-xs-6
imageClass:
type: string
example: cover
isSection:
type: number
example: 0
totalPostCount:
type: number
example: 0
totalTopicCount:
type: number
example: 0
tagWhitelist:
type: array
example:
- some-tag
- another-tag
unread-class:
type: string
backgroundImage:
type: string
example: '/assets/images/covers/Circuit1.png'
responses:
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
description: Not Authorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'426':
description: Upgrade Required
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'