This repository has been archived on 2020-04-21. You can view files and clone it, but cannot push or open issues or pull requests.
lemmy/docs/src/contributing_websocket_http_api.md
Dessalines 8b88a8e75b Squashed commit of the following:
commit f5b75f342b
Merge: bd1fc2b 69389f6
Author: Dessalines <happydooby@gmail.com>
Date:   Thu Jan 23 19:17:42 2020 -0500

    Done merging http-api and private_message

commit bd1fc2b80b
Author: Dessalines <happydooby@gmail.com>
Date:   Thu Jan 23 16:46:07 2020 -0500

    Remove danger from private-message.tsx

commit 69389f61c9
Author: Dessalines <happydooby@gmail.com>
Date:   Thu Jan 23 11:21:21 2020 -0500

    Fixing http curl POST docs.

commit 7fdcae4f07
Merge: dbe9ad0 752318f
Author: Dessalines <happydooby@gmail.com>
Date:   Thu Jan 23 11:01:06 2020 -0500

    Merge remote-tracking branch 'nutomic/http-api' into dessalines-http-api

commit 752318fdf3
Author: Felix <me@nutomic.com>
Date:   Thu Jan 23 15:22:17 2020 +0100

    api fixes

commit 9ccff18f23
Author: Dessalines <happydooby@gmail.com>
Date:   Wed Jan 22 22:29:11 2020 -0500

    Adding a toaster to replace alerts. Fixes #457

commit 5197407dd2
Merge: bacb9ac 58f673a
Author: Dessalines <happydooby@gmail.com>
Date:   Wed Jan 22 21:20:38 2020 -0500

    Merge branch 'private_messaging' into dev

commit 58f673ab78
Author: Dessalines <happydooby@gmail.com>
Date:   Wed Jan 22 21:09:17 2020 -0500

    Adding message to comment node actions.

commit bacb9ac59e
Merge: 10c6505 7d3adda
Author: Dessalines <happydooby@gmail.com>
Date:   Wed Jan 22 20:37:08 2020 -0500

    Merge branch 'private_messaging' into dev

commit 10c6505968
Author: Dessalines <happydooby@gmail.com>
Date:   Wed Jan 22 20:35:20 2020 -0500

    Adding correct hello_name to mail.

commit 7d3adda0cd
Author: Dessalines <happydooby@gmail.com>
Date:   Wed Jan 22 16:35:29 2020 -0500

    Adding private messaging, and matrix user ids.

    - Fixes #244

commit dbe9ad0998
Author: Dessalines <happydooby@gmail.com>
Date:   Mon Jan 20 18:49:54 2020 -0500

    Fixing last.

commit 20c9c54806
Author: Dessalines <happydooby@gmail.com>
Date:   Sun Jan 19 13:31:37 2020 -0500

    Updating API docs.

commit dc84ccaac9
Merge: 6c61dd2 3edd75e
Author: Dessalines <happydooby@gmail.com>
Date:   Sun Jan 19 10:06:25 2020 -0500

    Merge branch 'master' into dessalines-http-api

commit 6c61dd266b
Merge: c5eecd0 e518954
Author: Dessalines <happydooby@gmail.com>
Date:   Sun Jan 19 09:09:00 2020 -0500

    Merge remote-tracking branch 'nutomic/websocket-generics' into dessalines-http-api

commit e518954bca
Author: Felix <me@nutomic.com>
Date:   Sun Jan 19 14:25:50 2020 +0100

    Use generics to reduce code duplication in websocket

commit c5eecd055e
Author: Dessalines <happydooby@gmail.com>
Date:   Sun Jan 19 00:38:45 2020 -0500

    Strongly typing WebsocketJsonResponse. Forgot comment-form.tsx

commit 0c5eb47135
Author: Dessalines <happydooby@gmail.com>
Date:   Sat Jan 18 23:54:10 2020 -0500

    First pass at fixing UI to work with new websocketresponses.

commit baf77bb6be
Author: Felix <me@nutomic.com>
Date:   Sat Jan 18 17:25:45 2020 +0100

    simplify json serialization code

commit 047ec97e18
Author: Felix <me@nutomic.com>
Date:   Sat Jan 18 14:22:25 2020 +0100

    rewrite api endpoint urls

commit 2fb4900b0c
Author: Felix <me@nutomic.com>
Date:   Thu Jan 16 17:04:37 2020 +0100

    fix typo

commit cba8081579
Author: Felix <me@nutomic.com>
Date:   Thu Jan 16 16:47:38 2020 +0100

    fix formatting

commit d7285d8c25
Author: Felix <me@nutomic.com>
Date:   Thu Jan 16 16:09:01 2020 +0100

    small fix

commit 415040a1e9
Author: Felix <me@nutomic.com>
Date:   Thu Jan 16 15:39:08 2020 +0100

    working!

commit 7a97c981a0
Author: Felix <me@nutomic.com>
Date:   Wed Jan 15 16:48:21 2020 +0100

    try to simplify code with higher order functions

commit c41082f98f
Author: Felix <me@nutomic.com>
Date:   Wed Jan 15 16:37:25 2020 +0100

    Implement HTTP API using generics (fixes #380)
2020-01-23 19:39:59 -05:00

21 KiB
Vendored

Lemmy API

Note: this may lag behind the actual API endpoints here.

Data types

  • i16, i32 and i64 are respectively 16-bit, 32-bit and 64-bit integers.
  • Option<SomeType> designates an option which may be omitted in requests and not be present in responses. It will be of type SomeType.
  • Vec<SomeType> is a list which contains objects of type SomeType.
  • chrono::NaiveDateTime is a timestamp string in ISO 8601 format. Timestamps will be UTC.
  • Other data types are listed here.

Basic usage

Request and response strings are in JSON format.

WebSocket

Connect to ws://host/api/v1/ws to get started.

If the host supports secure connections, you can use wss://host/api/v1/ws.

Testing with Websocat

Websocat link

websocat ws://127.0.0.1:8536/api/v1/ws -nt

A simple test command: {"op": "ListCategories"}

Testing with the WebSocket JavaScript API

WebSocket JavaScript API

var ws = new WebSocket("ws://" + host + "/api/v1/ws");
ws.onopen = function () {
  console.log("Connection succeed!");
  ws.send(JSON.stringify({
    op: "ListCategories"
  }));
};

HTTP

Endpoints are at http://host/api/v1/endpoint. They'll be listed below for each action.

Testing with Curl

Get Example
curl /community/list?sort=Hot
Post Example
curl -i -H \
"Content-Type: application/json" \
-X POST \
-d '{
  "comment_id": X,
  "post_id": X,
  "score": X,
  "auth": "..."
}' \
/comment/like

Rate limits

  • 1 per hour for signups and community creation.
  • 1 per 10 minutes for post creation.
  • 30 actions per minute for post voting and comment creation.
  • Everything else is not rate-limited.

Errors

{
  op: String,
  message: String,
}

API documentation

Sort Types

These go wherever there is a sort field. The available sort types are:

  • Hot - the hottest posts/communities, depending on votes, views, comments and publish date
  • New - the newest posts/communities
  • TopDay - the most upvoted posts/communities of the current day.
  • TopWeek - the most upvoted posts/communities of the current week.
  • TopMonth - the most upvoted posts/communities of the current month.
  • TopYear - the most upvoted posts/communities of the current year.
  • TopAll - the most upvoted posts/communities on the current instance.

Websocket vs HTTP

  • Below are the websocket JSON requests / responses. For HTTP, ignore all fields except those inside data.
  • For example, an http login will be a POST {username_or_email: X, password: X}

User / Authentication / Admin actions

Login

The jwt string should be stored and used anywhere auth is called for.

Request
{
  op: "Login",
  data: {
    username_or_email: String,
    password: String
  }
}
Response
{
  op: "Login",
  data: {
    jwt: String,
  }
}
HTTP

POST /user/login

Register

Only the first user will be able to be the admin.

Request
{
  op: "Register",
  data: {
    username: String,
    email: Option<String>,
    password: String,
    password_verify: String,
    admin: bool
  }
}
Response
{
  op: "Register",
  data: {
    jwt: String,
  }
}
HTTP

POST /user/register

Get User Details

Request
{
  op: "GetUserDetails",
  data: {
    user_id: Option<i32>,
    username: Option<String>,
    sort: String,
    page: Option<i64>,
    limit: Option<i64>,
    community_id: Option<i32>,
    saved_only: bool,
    auth: Option<String>,
  }
}
Response
{
  op: "GetUserDetails",
  data: {
    user: UserView,
    follows: Vec<CommunityFollowerView>,
    moderates: Vec<CommunityModeratorView>,
    comments: Vec<CommentView>,
    posts: Vec<PostView>,
  }
}
HTTP

GET /user

Save User Settings

Request
{
  op: "SaveUserSettings",
  data: {
    show_nsfw: bool,
    theme: String, // Default 'darkly'
    default_sort_type: i16, // The Sort types from above, zero indexed as a number
    default_listing_type: i16, // Post listing types are `All, Subscribed, Community`
    auth: String
  }
}
Response
{
  op: "SaveUserSettings",
  data: {
    jwt: String
  }
}
HTTP

PUT /save_user_settings

Get Replies / Inbox

Request
{
  op: "GetReplies",
  data: {
    sort: String,
    page: Option<i64>,
    limit: Option<i64>,
    unread_only: bool,
    auth: String
  }
}
Response
{
  op: "GetReplies",
  data: {
    replies: Vec<ReplyView>,
  }
}
HTTP

GET /user/replies

Get User Mentions

Request
{
  op: "GetUserMentions",
  data: {
    sort: String,
    page: Option<i64>,
    limit: Option<i64>,
    unread_only: bool,
    auth: String,
  }
}
Response
{
  op: "GetUserMentions",
  data: {
    mentions: Vec<UserMentionView>,
  }
}
HTTP

GET /user/mentions

Edit User Mention

Request
{
  op: "EditUserMention",
  data: {
    user_mention_id: i32,
    read: Option<bool>,
    auth: String,
  }
}
Response
{
  op: "EditUserMention",
  data: {
    mention: UserMentionView,
  }
}
HTTP

PUT /user/mention

Mark All As Read

Marks all user replies and mentions as read.

Request
{
  op: "MarkAllAsRead",
  data: {
    auth: String
  }
}
Response
{
  op: "MarkAllAsRead",
  data: {
    replies: Vec<ReplyView>,
  }
}
HTTP

POST /user/mark_all_as_read

Delete Account

Permananently deletes your posts and comments

Request
{
  op: "DeleteAccount",
  data: {
    password: String,
    auth: String
  }
}
Response
{
  op: "DeleteAccount",
  data: {
    jwt: String,
  }
}
HTTP

POST /user/delete_account

Add admin

Request
{
  op: "AddAdmin",
  data: {
    user_id: i32,
    added: bool,
    auth: String
  }
}
Response
{
  op: "AddAdmin",
  data: {
    admins: Vec<UserView>,
  }
}
HTTP

POST /admin/add

Ban user

Request
{
  op: "BanUser",
  data: {
    user_id: i32,
    ban: bool,
    reason: Option<String>,
    expires: Option<i64>,
    auth: String
  }
}
Response
{
  op: "BanUser",
  data: {
    user: UserView,
    banned: bool,
  }
}
HTTP

POST /user/ban

Site

List Categories

Request
{
  op: "ListCategories"
}
Response
{
  op: "ListCategories",
  data: {
    categories: Vec<Category>
  }
}
HTTP

GET /categories

Search types are All, Comments, Posts, Communities, Users, Url

Request
{
  op: "Search",
  data: {
    q: String,
    type_: String,
    community_id: Option<i32>,
    sort: String,
    page: Option<i64>,
    limit: Option<i64>,
    auth?: Option<String>,
  }
}
Response
{
  op: "Search",
  data: {
    type_: String,
    comments: Vec<CommentView>,
    posts: Vec<PostView>,
    communities: Vec<CommunityView>,
    users: Vec<UserView>,
  }
}
HTTP

POST /search

Get Modlog

Request
{
  op: "GetModlog",
  data: {
    mod_user_id: Option<i32>,
    community_id: Option<i32>,
    page: Option<i64>,
    limit: Option<i64>,
  }
}
Response
{
  op: "GetModlog",
  data: {
    removed_posts: Vec<ModRemovePostView>,
    locked_posts: Vec<ModLockPostView>,
    removed_comments: Vec<ModRemoveCommentView>,
    removed_communities: Vec<ModRemoveCommunityView>,
    banned_from_community: Vec<ModBanFromCommunityView>,
    banned: Vec<ModBanView>,
    added_to_community: Vec<ModAddCommunityView>,
    added: Vec<ModAddView>,
  }
}
HTTP

GET /modlog

Create Site

Request
{
  op: "CreateSite",
  data: {
    name: String,
    description: Option<String>,
    auth: String
  }
}
Response
{
  op: "CreateSite",
    data: {
    site: SiteView,
  }
}
HTTP

POST /site

Edit Site

Request
{
  op: "EditSite",
  data: {
    name: String,
    description: Option<String>,
    auth: String
  }
}
Response
{
  op: "EditSite",
  data: {
    site: SiteView,
  }
}
HTTP

PUT /site

Get Site

Request
{
  op: "GetSite"
}
Response
{
  op: "GetSite",
  data: {
    site: Option<SiteView>,
    admins: Vec<UserView>,
    banned: Vec<UserView>,
  }
}
HTTP

GET /site

Transfer Site

Request
{
  op: "TransferSite",
  data: {
    user_id: i32,
    auth: String
  }
}
Response
{
  op: "TransferSite",
  data: {
    site: Option<SiteView>,
    admins: Vec<UserView>,
    banned: Vec<UserView>,
  }
}
HTTP

POST /site/transfer

Community

Get Community

Request
{
  op: "GetCommunity",
  data: {
    id: Option<i32>,
    name: Option<String>,
    auth: Option<String>
  }
}
Response
{
  op: "GetCommunity",
  data: {
    community: CommunityView,
    moderators: Vec<CommunityModeratorView>,
    admins: Vec<UserView>,
  }
}
HTTP

GET /community

Create Community

Request
{
  op: "CreateCommunity",
  data: {
    name: String,
    title: String,
    description: Option<String>,
    category_id: i32 ,
    auth: String
  }
}
Response
{
  op: "CreateCommunity",
  data: {
    community: CommunityView
  }
}
HTTP

POST /community

List Communities

Request
{
  op: "ListCommunities",
  data: {
    sort: String,
    page: Option<i64>,
    limit: Option<i64>,
    auth: Option<String>
  }
}
Response
{
  op: "ListCommunities",
  data: {
    communities: Vec<CommunityView>
  }
}
HTTP

GET /community/list

Ban from Community

Request
{
  op: "BanFromCommunity",
  data: {
    community_id: i32,
    user_id: i32,
    ban: bool,
    reason: Option<String>,
    expires: Option<i64>,
    auth: String
  }
}
Response
{
  op: "BanFromCommunity",
  data: {
    user: UserView,
    banned: bool,
  }
}
HTTP

POST /community/ban_user

Add Mod to Community

Request
{
  op: "AddModToCommunity",
  data: {
    community_id: i32,
    user_id: i32,
    added: bool,
    auth: String
  }
}
Response
{
  op: "AddModToCommunity",
  data: {
    moderators: Vec<CommunityModeratorView>,
  }
}
HTTP

POST /community/mod

Edit Community

Mods and admins can remove and lock a community, creators can delete it.

Request
{
  op: "EditCommunity",
  data: {
    edit_id: i32,
    name: String,
    title: String,
    description: Option<String>,
    category_id: i32,
    removed: Option<bool>,
    deleted: Option<bool>,
    reason: Option<String>,
    expires: Option<i64>,
    auth: String
  }
}
Response
{
  op: "EditCommunity",
  data: {
    community: CommunityView
  }
}
HTTP

PUT /community

Follow Community

Request
{
  op: "FollowCommunity",
  data: {
    community_id: i32,
    follow: bool,
    auth: String
  }
}
Response
{
  op: "FollowCommunity",
  data: {
    community: CommunityView
  }
}
HTTP

POST /community/follow

Get Followed Communities

Request
{
  op: "GetFollowedCommunities",
  data: {
    auth: String
  }
}
Response
{
  op: "GetFollowedCommunities",
  data: {
    communities: Vec<CommunityFollowerView>
  }
}
HTTP

GET /user/followed_communities

Transfer Community

Request
{
  op: "TransferCommunity",
  data: {
    community_id: i32,
    user_id: i32,
    auth: String
  }
}
Response
{
  op: "TransferCommunity",
  data: {
    community: CommunityView,
    moderators: Vec<CommunityModeratorView>,
    admins: Vec<UserView>,
  }
}
HTTP

POST /community/transfer

Post

Create Post

Request
{
  op: "CreatePost",
  data: {
    name: String,
    url: Option<String>,
    body: Option<String>,
    community_id: i32,
    auth: String
  }
}
Response
{
  op: "CreatePost",
  data: {
    post: PostView
  }
}
HTTP

POST /post

Get Post

Request
{
  op: "GetPost",
  data: {
    id: i32,
    auth: Option<String>
  }
}
Response
{
  op: "GetPost",
  data: {
    post: PostView,
    comments: Vec<CommentView>,
    community: CommunityView,
    moderators: Vec<CommunityModeratorView>,
    admins: Vec<UserView>,
  }
}
HTTP

GET /post

Get Posts

Post listing types are All, Subscribed, Community

Request
{
  op: "GetPosts",
  data: {
    type_: String,
    sort: String,
    page: Option<i64>,
    limit: Option<i64>,
    community_id: Option<i32>,
    auth: Option<String>
  }
}
Response
{
  op: "GetPosts",
  data: {
    posts: Vec<PostView>,
  }
}
HTTP

GET /post/list

Create Post Like

score can be 0, -1, or 1

Request
{
  op: "CreatePostLike",
  data: {
    post_id: i32,
    score: i16,
    auth: String
  }
}
Response
{
  op: "CreatePostLike",
  data: {
    post: PostView
  }
}
HTTP

POST /post/like

Edit Post

Mods and admins can remove and lock a post, creators can delete it.

Request
{
  op: "EditPost",
  data: {
    edit_id: i32,
    creator_id: i32,
    community_id: i32,
    name: String,
    url: Option<String>,
    body: Option<String>,
    removed: Option<bool>,
    deleted: Option<bool>,
    locked: Option<bool>,
    reason: Option<String>,
    auth: String
  }
}
Response
{
  op: "EditPost",
  data: {
    post: PostView
  }
}
HTTP

PUT /post

Save Post

Request
{
  op: "SavePost",
  data: {
    post_id: i32,
    save: bool,
    auth: String
  }
}
Response
{
  op: "SavePost",
  data: {
    post: PostView
  }
}
HTTP

POST /post/save

Comment

Create Comment

Request
{
  op: "CreateComment",
  data: {
    content: String,
    parent_id: Option<i32>,
    edit_id: Option<i32>,
    post_id: i32,
    auth: String
  }
}
Response
{
  op: "CreateComment",
  data: {
    comment: CommentView
  }
}
HTTP

POST /comment

Edit Comment

Mods and admins can remove a comment, creators can delete it.

Request
{
  op: "EditComment",
  data: {
    content: String,
    parent_id: Option<i32>,
    edit_id: i32,
    creator_id: i32,
    post_id: i32,
    removed: Option<bool>,
    deleted: Option<bool>,
    reason: Option<String>,
    read: Option<bool>,
    auth: String
  }
}
Response
{
  op: "EditComment",
  data: {
    comment: CommentView
  }
}
HTTP

PUT /comment

Save Comment

Request
{
  op: "SaveComment",
  data: {
    comment_id: i32,
    save: bool,
    auth: String
  }
}
Response
{
  op: "SaveComment",
  data: {
    comment: CommentView
  }
}
HTTP

POST /comment/save

Create Comment Like

score can be 0, -1, or 1

Request
{
  op: "CreateCommentLike",
  data: {
    comment_id: i32,
    post_id: i32,
    score: i16,
    auth: String
  }
}
Response
{
  op: "CreateCommentLike",
  data: {
    comment: CommentView
  }
}
HTTP

POST /comment/like

RSS / Atom feeds

All

/feeds/all.xml?sort=Hot

Community

/feeds/c/community-name.xml?sort=Hot

User

/feeds/u/user-name.xml?sort=Hot