]> Untitled Git - lemmy.git/blob - docs/src/contributing_websocket_http_api.md
Isomorphic docker (#1124)
[lemmy.git] / docs / src / contributing_websocket_http_api.md
1 # Lemmy API
2
3 *Note: this may lag behind the actual API endpoints [here](../src/api). The API should be considered unstable and may change any time.*
4
5 <!-- toc -->
6
7 - [Data types](#data-types)
8 - [Basic usage](#basic-usage)
9   * [WebSocket](#websocket)
10     + [Testing with Websocat](#testing-with-websocat)
11     + [Testing with the WebSocket JavaScript API](#testing-with-the-websocket-javascript-api)
12   * [HTTP](#http)
13     + [Testing with Curl](#testing-with-curl)
14       - [Get Example](#get-example)
15       - [Post Example](#post-example)
16 - [Rate limits](#rate-limits)
17 - [Errors](#errors)
18 - [API documentation](#api-documentation)
19   * [Sort Types](#sort-types)
20   * [Undoing actions](#undoing-actions)
21   * [Websocket vs HTTP](#websocket-vs-http)
22   * [User / Authentication / Admin actions](#user--authentication--admin-actions)
23     + [Login](#login)
24       - [Request](#request)
25       - [Response](#response)
26       - [HTTP](#http-1)
27     + [Register](#register)
28       - [Request](#request-1)
29       - [Response](#response-1)
30       - [HTTP](#http-2)
31     + [Get Captcha](#get-captcha)
32       - [Request](#request-2)
33       - [Response](#response-2)
34       - [HTTP](#http-3)
35     + [Get User Details](#get-user-details)
36       - [Request](#request-3)
37       - [Response](#response-3)
38       - [HTTP](#http-4)
39     + [Save User Settings](#save-user-settings)
40       - [Request](#request-4)
41       - [Response](#response-4)
42       - [HTTP](#http-5)
43     + [Get Replies / Inbox](#get-replies--inbox)
44       - [Request](#request-5)
45       - [Response](#response-5)
46       - [HTTP](#http-6)
47     + [Get User Mentions](#get-user-mentions)
48       - [Request](#request-6)
49       - [Response](#response-6)
50       - [HTTP](#http-7)
51     + [Mark User Mention as read](#mark-user-mention-as-read)
52       - [Request](#request-7)
53       - [Response](#response-7)
54       - [HTTP](#http-8)
55     + [Get Private Messages](#get-private-messages)
56       - [Request](#request-8)
57       - [Response](#response-8)
58       - [HTTP](#http-9)
59     + [Create Private Message](#create-private-message)
60       - [Request](#request-9)
61       - [Response](#response-9)
62       - [HTTP](#http-10)
63     + [Edit Private Message](#edit-private-message)
64       - [Request](#request-10)
65       - [Response](#response-10)
66       - [HTTP](#http-11)
67     + [Delete Private Message](#delete-private-message)
68       - [Request](#request-11)
69       - [Response](#response-11)
70       - [HTTP](#http-12)
71     + [Mark Private Message as Read](#mark-private-message-as-read)
72       - [Request](#request-12)
73       - [Response](#response-12)
74       - [HTTP](#http-13)
75     + [Mark All As Read](#mark-all-as-read)
76       - [Request](#request-13)
77       - [Response](#response-13)
78       - [HTTP](#http-14)
79     + [Delete Account](#delete-account)
80       - [Request](#request-14)
81       - [Response](#response-14)
82       - [HTTP](#http-15)
83     + [Add admin](#add-admin)
84       - [Request](#request-15)
85       - [Response](#response-15)
86       - [HTTP](#http-16)
87     + [Ban user](#ban-user)
88       - [Request](#request-16)
89       - [Response](#response-16)
90       - [HTTP](#http-17)
91     + [User Join](#user-join)
92       - [Request](#request-17)
93       - [Response](#response-17)
94       - [HTTP](#http-18)
95   * [Site](#site)
96     + [List Categories](#list-categories)
97       - [Request](#request-18)
98       - [Response](#response-18)
99       - [HTTP](#http-19)
100     + [Search](#search)
101       - [Request](#request-19)
102       - [Response](#response-19)
103       - [HTTP](#http-20)
104     + [Get Modlog](#get-modlog)
105       - [Request](#request-20)
106       - [Response](#response-20)
107       - [HTTP](#http-21)
108     + [Create Site](#create-site)
109       - [Request](#request-21)
110       - [Response](#response-21)
111       - [HTTP](#http-22)
112     + [Edit Site](#edit-site)
113       - [Request](#request-22)
114       - [Response](#response-22)
115       - [HTTP](#http-23)
116     + [Get Site](#get-site)
117       - [Request](#request-23)
118       - [Response](#response-23)
119       - [HTTP](#http-24)
120     + [Transfer Site](#transfer-site)
121       - [Request](#request-24)
122       - [Response](#response-24)
123       - [HTTP](#http-25)
124     + [Get Site Config](#get-site-config)
125       - [Request](#request-25)
126       - [Response](#response-25)
127       - [HTTP](#http-26)
128     + [Save Site Config](#save-site-config)
129       - [Request](#request-26)
130       - [Response](#response-26)
131       - [HTTP](#http-27)
132   * [Community](#community)
133     + [Get Community](#get-community)
134       - [Request](#request-27)
135       - [Response](#response-27)
136       - [HTTP](#http-28)
137     + [Create Community](#create-community)
138       - [Request](#request-28)
139       - [Response](#response-28)
140       - [HTTP](#http-29)
141     + [List Communities](#list-communities)
142       - [Request](#request-29)
143       - [Response](#response-29)
144       - [HTTP](#http-30)
145     + [Ban from Community](#ban-from-community)
146       - [Request](#request-30)
147       - [Response](#response-30)
148       - [HTTP](#http-31)
149     + [Add Mod to Community](#add-mod-to-community)
150       - [Request](#request-31)
151       - [Response](#response-31)
152       - [HTTP](#http-32)
153     + [Edit Community](#edit-community)
154       - [Request](#request-32)
155       - [Response](#response-32)
156       - [HTTP](#http-33)
157     + [Delete Community](#delete-community)
158       - [Request](#request-33)
159       - [Response](#response-33)
160       - [HTTP](#http-34)
161     + [Remove Community](#remove-community)
162       - [Request](#request-34)
163       - [Response](#response-34)
164       - [HTTP](#http-35)
165     + [Follow Community](#follow-community)
166       - [Request](#request-35)
167       - [Response](#response-35)
168       - [HTTP](#http-36)
169     + [Get Followed Communities](#get-followed-communities)
170       - [Request](#request-36)
171       - [Response](#response-36)
172       - [HTTP](#http-37)
173     + [Transfer Community](#transfer-community)
174       - [Request](#request-37)
175       - [Response](#response-37)
176       - [HTTP](#http-38)
177     + [Community Join](#community-join)
178       - [Request](#request-38)
179       - [Response](#response-38)
180       - [HTTP](#http-39)
181   * [Post](#post)
182     + [Create Post](#create-post)
183       - [Request](#request-39)
184       - [Response](#response-39)
185       - [HTTP](#http-40)
186     + [Get Post](#get-post)
187       - [Request](#request-40)
188       - [Response](#response-40)
189       - [HTTP](#http-41)
190     + [Get Posts](#get-posts)
191       - [Request](#request-41)
192       - [Response](#response-41)
193       - [HTTP](#http-42)
194     + [Create Post Like](#create-post-like)
195       - [Request](#request-42)
196       - [Response](#response-42)
197       - [HTTP](#http-43)
198     + [Edit Post](#edit-post)
199       - [Request](#request-43)
200       - [Response](#response-43)
201       - [HTTP](#http-44)
202     + [Delete Post](#delete-post)
203       - [Request](#request-44)
204       - [Response](#response-44)
205       - [HTTP](#http-45)
206     + [Remove Post](#remove-post)
207       - [Request](#request-45)
208       - [Response](#response-45)
209       - [HTTP](#http-46)
210     + [Lock Post](#lock-post)
211       - [Request](#request-46)
212       - [Response](#response-46)
213       - [HTTP](#http-47)
214     + [Sticky Post](#sticky-post)
215       - [Request](#request-47)
216       - [Response](#response-47)
217       - [HTTP](#http-48)
218     + [Save Post](#save-post)
219       - [Request](#request-48)
220       - [Response](#response-48)
221       - [HTTP](#http-49)
222     + [Post Join](#post-join)
223       - [Request](#request-49)
224       - [Response](#response-49)
225       - [HTTP](#http-50)
226   * [Comment](#comment)
227     + [Create Comment](#create-comment)
228       - [Request](#request-50)
229       - [Response](#response-50)
230       - [HTTP](#http-51)
231     + [Edit Comment](#edit-comment)
232       - [Request](#request-51)
233       - [Response](#response-51)
234       - [HTTP](#http-52)
235     + [Delete Comment](#delete-comment)
236       - [Request](#request-52)
237       - [Response](#response-52)
238       - [HTTP](#http-53)
239     + [Remove Comment](#remove-comment)
240       - [Request](#request-53)
241       - [Response](#response-53)
242       - [HTTP](#http-54)
243     + [Get Comments](#get-comments)
244       - [Request](#request-54)
245       - [Response](#response-54)
246       - [HTTP](#http-55)
247     + [Mark Comment as Read](#mark-comment-as-read)
248       - [Request](#request-55)
249       - [Response](#response-55)
250       - [HTTP](#http-56)
251     + [Save Comment](#save-comment)
252       - [Request](#request-56)
253       - [Response](#response-56)
254       - [HTTP](#http-57)
255     + [Create Comment Like](#create-comment-like)
256       - [Request](#request-57)
257       - [Response](#response-57)
258       - [HTTP](#http-58)
259   * [RSS / Atom feeds](#rss--atom-feeds)
260     + [All](#all)
261     + [Community](#community-1)
262     + [User](#user)
263
264 <!-- tocstop -->
265
266 ## Data types
267
268 - `i16`, `i32` and `i64` are respectively [16-bit](https://en.wikipedia.org/wiki/16-bit), [32-bit](https://en.wikipedia.org/wiki/32-bit) and [64-bit](https://en.wikipedia.org/wiki/64-bit_computing) integers.
269 - <code>Option<***SomeType***></code> designates an option which may be omitted in requests and not be present in responses. It will be of type ***SomeType***.
270 - <code>Vec<***SomeType***></code> is a list which contains objects of type ***SomeType***.
271 - `chrono::NaiveDateTime` is a timestamp string in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. Timestamps will be UTC.
272 - Other data types are listed [here](../src/db).
273
274 ## Basic usage
275
276 Request and response strings are in [JSON format](https://www.json.org).
277
278 ### WebSocket
279
280 Connect to <code>ws://***host***/api/v1/ws</code> to get started.
281
282 If the ***`host`*** supports secure connections, you can use <code>wss://***host***/api/v1/ws</code>.
283
284 To receive websocket messages, you must join a room / context. The three available are:
285
286 - [UserJoin](#user-join). Receives replies, private messages, etc.
287 - [PostJoin](#post-join). Receives new comments on a post.
288 - [CommunityJoin](#community-join). Receives front page / community posts.
289
290 #### Testing with Websocat
291
292 [Websocat link](https://github.com/vi/websocat)
293
294 `websocat ws://127.0.0.1:8536/api/v1/ws -nt`
295
296 A simple test command:
297 `{"op": "ListCategories"}`
298
299 #### Testing with the WebSocket JavaScript API
300
301 [WebSocket JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
302 ```javascript
303 var ws = new WebSocket("ws://" + host + "/api/v1/ws");
304 ws.onopen = function () {
305   console.log("Connection succeed!");
306   ws.send(JSON.stringify({
307     op: "ListCategories"
308   }));
309 };
310 ```
311 ### HTTP
312
313 Endpoints are at <code>http://***host***/api/v1/***endpoint***</code>. They'll be listed below for each action.
314
315 #### Testing with Curl
316
317 ##### Get Example
318
319 ```
320 curl /community/list?sort=Hot
321 ```
322
323 ##### Post Example
324
325 ```
326 curl -i -H \
327 "Content-Type: application/json" \
328 -X POST \
329 -d '{
330   "comment_id": X,
331   "post_id": X,
332   "score": X,
333   "auth": "..."
334 }' \
335 /comment/like
336 ```
337
338 ## Rate limits
339
340 - 1 per hour for signups and community creation.
341 - 1 per 10 minutes for post creation.
342 - 30 actions per minute for post voting and comment creation.
343 - Everything else is not rate-limited.
344
345 ## Errors
346 ```rust
347 {
348   op: String,
349   message: String,
350 }
351 ```
352
353 ## API documentation
354
355 ### Sort Types
356
357 These go wherever there is a `sort` field. The available sort types are:
358
359 - `Active` - the hottest posts/communities, depending on votes, and newest comment publish date.
360 - `Hot` - the hottest posts/communities, depending on votes and publish date.
361 - `New` - the newest posts/communities
362 - `TopDay` - the most upvoted posts/communities of the current day.
363 - `TopWeek` - the most upvoted posts/communities of the current week.
364 - `TopMonth` - the most upvoted posts/communities of the current month.
365 - `TopYear` - the most upvoted posts/communities of the current year.
366 - `TopAll` - the most upvoted posts/communities on the current instance.
367
368 ### Undoing actions
369
370 Whenever you see a `deleted: bool`, `removed: bool`, `read: bool`, `locked: bool`, etc, you can undo this action by sending `false`.
371
372 ### Websocket vs HTTP
373
374 - Below are the websocket JSON requests / responses. For HTTP, ignore all fields except those inside `data`.
375 - For example, an http login will be a `POST` `{username_or_email: X, password: X}`
376
377 ### User / Authentication / Admin actions
378
379 #### Login
380
381 The `jwt` string should be stored and used anywhere `auth` is called for.
382
383 ##### Request
384 ```rust
385 {
386   op: "Login",
387   data: {
388     username_or_email: String,
389     password: String
390   }
391 }
392 ```
393 ##### Response
394 ```rust
395 {
396   op: "Login",
397   data: {
398     jwt: String,
399   }
400 }
401 ```
402
403 ##### HTTP
404
405 `POST /user/login`
406
407 #### Register
408
409 Only the first user will be able to be the admin.
410
411 ##### Request
412 ```rust
413 {
414   op: "Register",
415   data: {
416     username: String,
417     email: Option<String>,
418     password: String,
419     password_verify: String,
420     admin: bool,
421     captcha_uuid: Option<String>, // Only checked if these are enabled in the server
422     captcha_answer: Option<String>,
423   }
424 }
425 ```
426 ##### Response
427 ```rust
428 {
429   op: "Register",
430   data: {
431     jwt: String,
432   }
433 }
434 ```
435
436 ##### HTTP
437
438 `POST /user/register`
439
440 #### Get Captcha
441
442 These expire after 10 minutes.
443
444 ##### Request
445 ```rust
446 {
447   op: "GetCaptcha",
448 }
449 ```
450 ##### Response
451 ```rust
452 {
453   op: "GetCaptcha",
454   data: {
455     ok?: { // Will be undefined if captchas are disabled
456       png: String, // A Base64 encoded png
457       wav: Option<String>, // A Base64 encoded wav audio file
458       uuid: String,
459     }
460   }
461 }
462 ```
463
464 ##### HTTP
465
466 `GET /user/get_captcha`
467
468 #### Get User Details
469 ##### Request
470 ```rust
471 {
472   op: "GetUserDetails",
473   data: {
474     user_id: Option<i32>,
475     username: Option<String>,
476     sort: String,
477     page: Option<i64>,
478     limit: Option<i64>,
479     community_id: Option<i32>,
480     saved_only: bool,
481     auth: Option<String>,
482   }
483 }
484 ```
485 ##### Response
486 ```rust
487 {
488   op: "GetUserDetails",
489   data: {
490     user: UserView,
491     follows: Vec<CommunityFollowerView>,
492     moderates: Vec<CommunityModeratorView>,
493     comments: Vec<CommentView>,
494     posts: Vec<PostView>,
495   }
496 }
497 ```
498 ##### HTTP
499
500 `GET /user`
501
502 #### Save User Settings
503 ##### Request
504 ```rust
505 {
506   op: "SaveUserSettings",
507   data: {
508     show_nsfw: bool,
509     theme: String, // Default 'darkly'
510     default_sort_type: i16, // The Sort types from above, zero indexed as a number
511     default_listing_type: i16, // Post listing types are `All, Subscribed, Community`
512     lang: String,
513     avatar: Option<String>,
514     banner: Option<String>,
515     preferred_username: Option<String>,
516     email: Option<String>,
517     bio: Option<String>,
518     matrix_user_id: Option<String>,
519     new_password: Option<String>,
520     new_password_verify: Option<String>,
521     old_password: Option<String>,
522     show_avatars: bool,
523     send_notifications_to_email: bool,
524     auth: String,
525   }
526 }
527 ```
528 ##### Response
529 ```rust
530 {
531   op: "SaveUserSettings",
532   data: {
533     jwt: String
534   }
535 }
536 ```
537 ##### HTTP
538
539 `PUT /user/save_user_settings`
540
541 #### Get Replies / Inbox
542 ##### Request
543 ```rust
544 {
545   op: "GetReplies",
546   data: {
547     sort: String,
548     page: Option<i64>,
549     limit: Option<i64>,
550     unread_only: bool,
551     auth: String
552   }
553 }
554 ```
555 ##### Response
556 ```rust
557 {
558   op: "GetReplies",
559   data: {
560     replies: Vec<ReplyView>,
561   }
562 }
563 ```
564 ##### HTTP
565
566 `GET /user/replies`
567
568
569 #### Get User Mentions
570 ##### Request
571 ```rust
572 {
573   op: "GetUserMentions",
574   data: {
575     sort: String,
576     page: Option<i64>,
577     limit: Option<i64>,
578     unread_only: bool,
579     auth: String,
580   }
581 }
582 ```
583 ##### Response
584 ```rust
585 {
586   op: "GetUserMentions",
587   data: {
588     mentions: Vec<UserMentionView>,
589   }
590 }
591 ```
592
593 ##### HTTP
594
595 `GET /user/mention`
596
597 #### Mark User Mention as read
598
599 Only the recipient can do this.
600
601 ##### Request
602 ```rust
603 {
604   op: "MarkUserMentionAsRead",
605   data: {
606     user_mention_id: i32,
607     read: bool,
608     auth: String,
609   }
610 }
611 ```
612 ##### Response
613 ```rust
614 {
615   op: "MarkUserMentionAsRead",
616   data: {
617     mention: UserMentionView,
618   }
619 }
620 ```
621 ##### HTTP
622
623 `POST /user/mention/mark_as_read`
624
625 #### Get Private Messages
626 ##### Request
627 ```rust
628 {
629   op: "GetPrivateMessages",
630   data: {
631     unread_only: bool,
632     page: Option<i64>,
633     limit: Option<i64>,
634     auth: String,
635   }
636 }
637 ```
638 ##### Response
639 ```rust
640 {
641   op: "GetPrivateMessages",
642   data: {
643     messages: Vec<PrivateMessageView>,
644   }
645 }
646 ```
647
648 ##### HTTP
649
650 `GET /private_message/list`
651
652 #### Create Private Message
653 ##### Request
654 ```rust
655 {
656   op: "CreatePrivateMessage",
657   data: {
658     content: String,
659     recipient_id: i32,
660     auth: String,
661   }
662 }
663 ```
664 ##### Response
665 ```rust
666 {
667   op: "CreatePrivateMessage",
668   data: {
669     message: PrivateMessageView,
670   }
671 }
672 ```
673
674 ##### HTTP
675
676 `POST /private_message`
677
678 #### Edit Private Message
679 ##### Request
680 ```rust
681 {
682   op: "EditPrivateMessage",
683   data: {
684     edit_id: i32,
685     content: String,
686     auth: String,
687   }
688 }
689 ```
690 ##### Response
691 ```rust
692 {
693   op: "EditPrivateMessage",
694   data: {
695     message: PrivateMessageView,
696   }
697 }
698 ```
699
700 ##### HTTP
701
702 `PUT /private_message`
703
704 #### Delete Private Message
705 ##### Request
706 ```rust
707 {
708   op: "DeletePrivateMessage",
709   data: {
710     edit_id: i32,
711     deleted: bool,
712     auth: String,
713   }
714 }
715 ```
716 ##### Response
717 ```rust
718 {
719   op: "DeletePrivateMessage",
720   data: {
721     message: PrivateMessageView,
722   }
723 }
724 ```
725
726 ##### HTTP
727
728 `POST /private_message/delete`
729
730 #### Mark Private Message as Read
731
732 Only the recipient can do this.
733
734 ##### Request
735 ```rust
736 {
737   op: "MarkPrivateMessageAsRead",
738   data: {
739     edit_id: i32,
740     read: bool,
741     auth: String,
742   }
743 }
744 ```
745 ##### Response
746 ```rust
747 {
748   op: "MarkPrivateMessageAsRead",
749   data: {
750     message: PrivateMessageView,
751   }
752 }
753 ```
754
755 ##### HTTP
756
757 `POST /private_message/mark_as_read`
758
759 #### Mark All As Read
760
761 Marks all user replies and mentions as read.
762
763 ##### Request
764 ```rust
765 {
766   op: "MarkAllAsRead",
767   data: {
768     auth: String
769   }
770 }
771 ```
772 ##### Response
773 ```rust
774 {
775   op: "MarkAllAsRead",
776   data: {
777     replies: Vec<ReplyView>,
778   }
779 }
780 ```
781
782 ##### HTTP
783
784 `POST /user/mark_all_as_read`
785
786 #### Delete Account
787
788 *Permanently deletes your posts and comments*
789
790 ##### Request
791 ```rust
792 {
793   op: "DeleteAccount",
794   data: {
795     password: String,
796     auth: String
797   }
798 }
799 ```
800 ##### Response
801 ```rust
802 {
803   op: "DeleteAccount",
804   data: {
805     jwt: String,
806   }
807 }
808 ```
809
810 ##### HTTP
811
812 `POST /user/delete_account`
813
814 #### Add admin
815 ##### Request
816 ```rust
817 {
818   op: "AddAdmin",
819   data: {
820     user_id: i32,
821     added: bool,
822     auth: String
823   }
824 }
825 ```
826 ##### Response
827 ```rust
828 {
829   op: "AddAdmin",
830   data: {
831     admins: Vec<UserView>,
832   }
833 }
834 ```
835 ##### HTTP
836
837 `POST /admin/add`
838
839 #### Ban user
840 ##### Request
841 ```rust
842 {
843   op: "BanUser",
844   data: {
845     user_id: i32,
846     ban: bool,
847     remove_data: Option<bool>, // Removes/Restores their comments, posts, and communities
848     reason: Option<String>,
849     expires: Option<i64>,
850     auth: String
851   }
852 }
853 ```
854 ##### Response
855 ```rust
856 {
857   op: "BanUser",
858   data: {
859     user: UserView,
860     banned: bool,
861   }
862 }
863 ```
864 ##### HTTP
865
866 `POST /user/ban`
867
868 #### User Join
869 ##### Request
870 ```rust
871 {
872   op: "UserJoin",
873   data: {
874     auth: String
875   }
876 }
877 ```
878 ##### Response
879 ```rust
880 {
881   op: "UserJoin",
882   data: {
883     joined: bool,
884   }
885 }
886 ```
887 ##### HTTP
888
889 `POST /user/join`
890
891 ### Site
892 #### List Categories
893 ##### Request
894 ```rust
895 {
896   op: "ListCategories"
897 }
898 ```
899 ##### Response
900 ```rust
901 {
902   op: "ListCategories",
903   data: {
904     categories: Vec<Category>
905   }
906 }
907 ```
908 ##### HTTP
909
910 `GET /categories`
911
912 #### Search
913
914 Search types are `All, Comments, Posts, Communities, Users, Url`
915
916 ##### Request
917 ```rust
918 {
919   op: "Search",
920   data: {
921     q: String,
922     type_: String,
923     community_id: Option<i32>,
924     sort: String,
925     page: Option<i64>,
926     limit: Option<i64>,
927     auth?: Option<String>,
928   }
929 }
930 ```
931 ##### Response
932 ```rust
933 {
934   op: "Search",
935   data: {
936     type_: String,
937     comments: Vec<CommentView>,
938     posts: Vec<PostView>,
939     communities: Vec<CommunityView>,
940     users: Vec<UserView>,
941   }
942 }
943 ```
944 ##### HTTP
945
946 `GET /search`
947
948 #### Get Modlog
949 ##### Request
950 ```rust
951 {
952   op: "GetModlog",
953   data: {
954     mod_user_id: Option<i32>,
955     community_id: Option<i32>,
956     page: Option<i64>,
957     limit: Option<i64>,
958   }
959 }
960 ```
961 ##### Response
962 ```rust
963 {
964   op: "GetModlog",
965   data: {
966     removed_posts: Vec<ModRemovePostView>,
967     locked_posts: Vec<ModLockPostView>,
968     removed_comments: Vec<ModRemoveCommentView>,
969     removed_communities: Vec<ModRemoveCommunityView>,
970     banned_from_community: Vec<ModBanFromCommunityView>,
971     banned: Vec<ModBanView>,
972     added_to_community: Vec<ModAddCommunityView>,
973     added: Vec<ModAddView>,
974   }
975 }
976 ```
977
978 ##### HTTP
979
980 `GET /modlog`
981
982 #### Create Site
983 ##### Request
984 ```rust
985 {
986   op: "CreateSite",
987   data: {
988     name: String,
989     description: Option<String>,
990     icon: Option<String>,
991     banner: Option<String>,
992     auth: String
993   }
994 }
995 ```
996 ##### Response
997 ```rust
998 {
999   op: "CreateSite",
1000     data: {
1001     site: SiteView,
1002   }
1003 }
1004 ```
1005
1006 ##### HTTP
1007
1008 `POST /site`
1009
1010 #### Edit Site
1011 ##### Request
1012 ```rust
1013 {
1014   op: "EditSite",
1015   data: {
1016     name: String,
1017     description: Option<String>,
1018     icon: Option<String>,
1019     banner: Option<String>,
1020     auth: String
1021   }
1022 }
1023 ```
1024 ##### Response
1025 ```rust
1026 {
1027   op: "EditSite",
1028   data: {
1029     site: SiteView,
1030   }
1031 }
1032 ```
1033 ##### HTTP
1034
1035 `PUT /site`
1036
1037 #### Get Site
1038 ##### Request
1039 ```rust
1040 {
1041   op: "GetSite"
1042   data: {
1043     auth: Option<String>,
1044   }
1045
1046 }
1047 ```
1048 ##### Response
1049 ```rust
1050 {
1051   op: "GetSite",
1052   data: {
1053     site: Option<SiteView>,
1054     admins: Vec<UserView>,
1055     banned: Vec<UserView>,
1056     online: usize, // This is currently broken
1057     version: String,
1058     my_user: Option<User_>, // Gives back your user and settings if logged in
1059   }
1060 }
1061 ```
1062 ##### HTTP
1063
1064 `GET /site`
1065
1066 #### Transfer Site
1067 ##### Request
1068 ```rust
1069 {
1070   op: "TransferSite",
1071   data: {
1072     user_id: i32,
1073     auth: String
1074   }
1075 }
1076 ```
1077 ##### Response
1078 ```rust
1079 {
1080   op: "TransferSite",
1081   data: {
1082     site: Option<SiteView>,
1083     admins: Vec<UserView>,
1084     banned: Vec<UserView>,
1085   }
1086 }
1087 ```
1088 ##### HTTP
1089
1090 `POST /site/transfer`
1091
1092 #### Get Site Config
1093 ##### Request
1094 ```rust
1095 {
1096   op: "GetSiteConfig",
1097   data: {
1098     auth: String
1099   }
1100 }
1101 ```
1102 ##### Response
1103 ```rust
1104 {
1105   op: "GetSiteConfig",
1106   data: {
1107     config_hjson: String,
1108   }
1109 }
1110 ```
1111 ##### HTTP
1112
1113 `GET /site/config`
1114
1115 #### Save Site Config
1116 ##### Request
1117 ```rust
1118 {
1119   op: "SaveSiteConfig",
1120   data: {
1121     config_hjson: String,
1122     auth: String
1123   }
1124 }
1125 ```
1126 ##### Response
1127 ```rust
1128 {
1129   op: "SaveSiteConfig",
1130   data: {
1131     config_hjson: String,
1132   }
1133 }
1134 ```
1135 ##### HTTP
1136
1137 `PUT /site/config`
1138
1139 ### Community
1140 #### Get Community
1141 ##### Request
1142 ```rust
1143 {
1144   op: "GetCommunity",
1145   data: {
1146     id: Option<i32>,
1147     name: Option<String>,
1148     auth: Option<String>
1149   }
1150 }
1151 ```
1152 ##### Response
1153 ```rust
1154 {
1155   op: "GetCommunity",
1156   data: {
1157     community: CommunityView,
1158     moderators: Vec<CommunityModeratorView>,
1159   }
1160 }
1161 ```
1162 ##### HTTP
1163
1164 `GET /community`
1165
1166 #### Create Community
1167 ##### Request
1168 ```rust
1169 {
1170   op: "CreateCommunity",
1171   data: {
1172     name: String,
1173     title: String,
1174     description: Option<String>,
1175     icon: Option<String>,
1176     banner: Option<String>,
1177     category_id: i32 ,
1178     auth: String
1179   }
1180 }
1181 ```
1182 ##### Response
1183 ```rust
1184 {
1185   op: "CreateCommunity",
1186   data: {
1187     community: CommunityView
1188   }
1189 }
1190 ```
1191 ##### HTTP
1192
1193 `POST /community`
1194
1195 #### List Communities
1196 ##### Request
1197 ```rust
1198 {
1199   op: "ListCommunities",
1200   data: {
1201     sort: String,
1202     page: Option<i64>,
1203     limit: Option<i64>,
1204     auth: Option<String>
1205   }
1206 }
1207 ```
1208 ##### Response
1209 ```rust
1210 {
1211   op: "ListCommunities",
1212   data: {
1213     communities: Vec<CommunityView>
1214   }
1215 }
1216 ```
1217 ##### HTTP
1218
1219 `GET /community/list`
1220
1221 #### Ban from Community
1222 ##### Request
1223 ```rust
1224 {
1225   op: "BanFromCommunity",
1226   data: {
1227     community_id: i32,
1228     user_id: i32,
1229     ban: bool,
1230     remove_data: Option<bool>, // Removes/Restores their comments and posts for that community
1231     reason: Option<String>,
1232     expires: Option<i64>,
1233     auth: String
1234   }
1235 }
1236 ```
1237 ##### Response
1238 ```rust
1239 {
1240   op: "BanFromCommunity",
1241   data: {
1242     user: UserView,
1243     banned: bool,
1244   }
1245 }
1246 ```
1247 ##### HTTP
1248
1249 `POST /community/ban_user`
1250
1251 #### Add Mod to Community
1252 ##### Request
1253 ```rust
1254 {
1255   op: "AddModToCommunity",
1256   data: {
1257     community_id: i32,
1258     user_id: i32,
1259     added: bool,
1260     auth: String
1261   }
1262 }
1263 ```
1264 ##### Response
1265 ```rust
1266 {
1267   op: "AddModToCommunity",
1268   data: {
1269     moderators: Vec<CommunityModeratorView>,
1270   }
1271 }
1272 ```
1273 ##### HTTP
1274
1275 `POST /community/mod`
1276
1277 #### Edit Community
1278 Only mods can edit a community.
1279
1280 ##### Request
1281 ```rust
1282 {
1283   op: "EditCommunity",
1284   data: {
1285     edit_id: i32,
1286     title: String,
1287     description: Option<String>,
1288     icon: Option<String>,
1289     banner: Option<String>,
1290     category_id: i32,
1291     auth: String
1292   }
1293 }
1294 ```
1295 ##### Response
1296 ```rust
1297 {
1298   op: "EditCommunity",
1299   data: {
1300     community: CommunityView
1301   }
1302 }
1303 ```
1304 ##### HTTP
1305
1306 `PUT /community`
1307
1308 #### Delete Community
1309 Only a creator can delete a community
1310
1311 ##### Request
1312 ```rust
1313 {
1314   op: "DeleteCommunity",
1315   data: {
1316     edit_id: i32,
1317     deleted: bool,
1318     auth: String,
1319   }
1320 }
1321 ```
1322 ##### Response
1323 ```rust
1324 {
1325   op: "DeleteCommunity",
1326   data: {
1327     community: CommunityView
1328   }
1329 }
1330 ```
1331 ##### HTTP
1332
1333 `POST /community/delete`
1334
1335 #### Remove Community
1336 Only admins can remove a community.
1337
1338 ##### Request
1339 ```rust
1340 {
1341   op: "RemoveCommunity",
1342   data: {
1343     edit_id: i32,
1344     removed: bool,
1345     reason: Option<String>,
1346     expires: Option<i64>,
1347     auth: String,
1348   }
1349 }
1350 ```
1351 ##### Response
1352 ```rust
1353 {
1354   op: "RemoveCommunity",
1355   data: {
1356     community: CommunityView
1357   }
1358 }
1359 ```
1360 ##### HTTP
1361
1362 `POST /community/remove`
1363
1364 #### Follow Community
1365 ##### Request
1366 ```rust
1367 {
1368   op: "FollowCommunity",
1369   data: {
1370     community_id: i32,
1371     follow: bool,
1372     auth: String
1373   }
1374 }
1375 ```
1376 ##### Response
1377 ```rust
1378 {
1379   op: "FollowCommunity",
1380   data: {
1381     community: CommunityView
1382   }
1383 }
1384 ```
1385 ##### HTTP
1386
1387 `POST /community/follow`
1388
1389 #### Get Followed Communities
1390 ##### Request
1391 ```rust
1392 {
1393   op: "GetFollowedCommunities",
1394   data: {
1395     auth: String
1396   }
1397 }
1398 ```
1399 ##### Response
1400 ```rust
1401 {
1402   op: "GetFollowedCommunities",
1403   data: {
1404     communities: Vec<CommunityFollowerView>
1405   }
1406 }
1407 ```
1408 ##### HTTP
1409
1410 `GET /user/followed_communities`
1411
1412 #### Transfer Community
1413 ##### Request
1414 ```rust
1415 {
1416   op: "TransferCommunity",
1417   data: {
1418     community_id: i32,
1419     user_id: i32,
1420     auth: String
1421   }
1422 }
1423 ```
1424 ##### Response
1425 ```rust
1426 {
1427   op: "TransferCommunity",
1428   data: {
1429     community: CommunityView,
1430     moderators: Vec<CommunityModeratorView>,
1431     admins: Vec<UserView>,
1432   }
1433 }
1434 ```
1435 ##### HTTP
1436
1437 `POST /community/transfer`
1438
1439 #### Community Join
1440
1441 The main / frontpage community is `community_id: 0`.
1442
1443 ##### Request
1444 ```rust
1445 {
1446   op: "CommunityJoin",
1447   data: {
1448     community_id: i32
1449   }
1450 }
1451 ```
1452 ##### Response
1453 ```rust
1454 {
1455   op: "CommunityJoin",
1456   data: {
1457     joined: bool,
1458   }
1459 }
1460 ```
1461 ##### HTTP
1462
1463 `POST /community/join`
1464
1465 ### Post
1466 #### Create Post
1467 ##### Request
1468 ```rust
1469 {
1470   op: "CreatePost",
1471   data: {
1472     name: String,
1473     url: Option<String>,
1474     body: Option<String>,
1475     nsfw: bool,
1476     community_id: i32,
1477     auth: String,
1478   }
1479 }
1480 ```
1481 ##### Response
1482 ```rust
1483 {
1484   op: "CreatePost",
1485   data: {
1486     post: PostView
1487   }
1488 }
1489 ```
1490 ##### HTTP
1491
1492 `POST /post`
1493
1494 #### Get Post
1495 ##### Request
1496 ```rust
1497 {
1498   op: "GetPost",
1499   data: {
1500     id: i32,
1501     auth: Option<String>
1502   }
1503 }
1504 ```
1505 ##### Response
1506 ```rust
1507 {
1508   op: "GetPost",
1509   data: {
1510     post: PostView,
1511     comments: Vec<CommentView>,
1512     community: CommunityView,
1513     moderators: Vec<CommunityModeratorView>,
1514   }
1515 }
1516 ```
1517 ##### HTTP
1518
1519 `GET /post`
1520
1521 #### Get Posts
1522
1523 Post listing types are `All, Subscribed, Community`
1524
1525 ##### Request
1526 ```rust
1527 {
1528   op: "GetPosts",
1529   data: {
1530     type_: String,
1531     sort: String,
1532     page: Option<i64>,
1533     limit: Option<i64>,
1534     community_id: Option<i32>,
1535     community_name: Option<String>,
1536     auth: Option<String>
1537   }
1538 }
1539 ```
1540 ##### Response
1541 ```rust
1542 {
1543   op: "GetPosts",
1544   data: {
1545     posts: Vec<PostView>,
1546   }
1547 }
1548 ```
1549 ##### HTTP
1550
1551 `GET /post/list`
1552
1553 #### Create Post Like
1554
1555 `score` can be 0, -1, or 1
1556
1557 ##### Request
1558 ```rust
1559 {
1560   op: "CreatePostLike",
1561   data: {
1562     post_id: i32,
1563     score: i16,
1564     auth: String
1565   }
1566 }
1567 ```
1568 ##### Response
1569 ```rust
1570 {
1571   op: "CreatePostLike",
1572   data: {
1573     post: PostView
1574   }
1575 }
1576 ```
1577 ##### HTTP
1578
1579 `POST /post/like`
1580
1581 #### Edit Post
1582 ##### Request
1583 ```rust
1584 {
1585   op: "EditPost",
1586   data: {
1587     edit_id: i32,
1588     name: String,
1589     url: Option<String>,
1590     body: Option<String>,
1591     nsfw: bool,
1592     auth: String,
1593   }
1594 }
1595 ```
1596 ##### Response
1597 ```rust
1598 {
1599   op: "EditPost",
1600   data: {
1601     post: PostView
1602   }
1603 }
1604 ```
1605
1606 ##### HTTP
1607
1608 `PUT /post`
1609
1610 #### Delete Post
1611 ##### Request
1612 ```rust
1613 {
1614   op: "DeletePost",
1615   data: {
1616     edit_id: i32,
1617     deleted: bool,
1618     auth: String,
1619   }
1620 }
1621 ```
1622 ##### Response
1623 ```rust
1624 {
1625   op: "DeletePost",
1626   data: {
1627     post: PostView
1628   }
1629 }
1630 ```
1631
1632 ##### HTTP
1633
1634 `POST /post/delete`
1635
1636 #### Remove Post
1637
1638 Only admins and mods can remove a post.
1639
1640 ##### Request
1641 ```rust
1642 {
1643   op: "RemovePost",
1644   data: {
1645     edit_id: i32,
1646     removed: bool,
1647     reason: Option<String>,
1648     auth: String,
1649   }
1650 }
1651 ```
1652 ##### Response
1653 ```rust
1654 {
1655   op: "RemovePost",
1656   data: {
1657     post: PostView
1658   }
1659 }
1660 ```
1661
1662 ##### HTTP
1663
1664 `POST /post/remove`
1665
1666 #### Lock Post
1667
1668 Only admins and mods can lock a post.
1669
1670 ##### Request
1671 ```rust
1672 {
1673   op: "LockPost",
1674   data: {
1675     edit_id: i32,
1676     locked: bool,
1677     auth: String,
1678   }
1679 }
1680 ```
1681 ##### Response
1682 ```rust
1683 {
1684   op: "LockPost",
1685   data: {
1686     post: PostView
1687   }
1688 }
1689 ```
1690
1691 ##### HTTP
1692
1693 `POST /post/lock`
1694
1695 #### Sticky Post
1696
1697 Only admins and mods can sticky a post.
1698
1699 ##### Request
1700 ```rust
1701 {
1702   op: "StickyPost",
1703   data: {
1704     edit_id: i32,
1705     stickied: bool,
1706     auth: String,
1707   }
1708 }
1709 ```
1710 ##### Response
1711 ```rust
1712 {
1713   op: "StickyPost",
1714   data: {
1715     post: PostView
1716   }
1717 }
1718 ```
1719
1720 ##### HTTP
1721
1722 `POST /post/sticky`
1723
1724 #### Save Post
1725 ##### Request
1726 ```rust
1727 {
1728   op: "SavePost",
1729   data: {
1730     post_id: i32,
1731     save: bool,
1732     auth: String
1733   }
1734 }
1735 ```
1736 ##### Response
1737 ```rust
1738 {
1739   op: "SavePost",
1740   data: {
1741     post: PostView
1742   }
1743 }
1744 ```
1745 ##### HTTP
1746
1747 `POST /post/save`
1748
1749 #### Post Join
1750 ##### Request
1751 ```rust
1752 {
1753   op: "PostJoin",
1754   data: {
1755     post_id: i32
1756   }
1757 }
1758 ```
1759 ##### Response
1760 ```rust
1761 {
1762   op: "PostJoin",
1763   data: {
1764     joined: bool,
1765   }
1766 }
1767 ```
1768 ##### HTTP
1769
1770 `POST /post/join`
1771
1772 ### Comment
1773 #### Create Comment
1774 ##### Request
1775 ```rust
1776 {
1777   op: "CreateComment",
1778   data: {
1779     content: String,
1780     parent_id: Option<i32>,
1781     post_id: i32,
1782     form_id: Option<String>, // An optional form id, so you know which message came back
1783     auth: String
1784   }
1785 }
1786 ```
1787 ##### Response
1788 ```rust
1789 {
1790   op: "CreateComment",
1791   data: {
1792     comment: CommentView
1793   }
1794 }
1795 ```
1796
1797 ##### HTTP
1798
1799 `POST /comment`
1800
1801 #### Edit Comment
1802
1803 Only the creator can edit the comment.
1804
1805 ##### Request
1806 ```rust
1807 {
1808   op: "EditComment",
1809   data: {
1810     content: String,
1811     edit_id: i32,
1812     form_id: Option<String>,
1813     auth: String,
1814   }
1815 }
1816 ```
1817 ##### Response
1818 ```rust
1819 {
1820   op: "EditComment",
1821   data: {
1822     comment: CommentView
1823   }
1824 }
1825 ```
1826 ##### HTTP
1827
1828 `PUT /comment`
1829
1830 #### Delete Comment
1831
1832 Only the creator can delete the comment.
1833
1834 ##### Request
1835 ```rust
1836 {
1837   op: "DeleteComment",
1838   data: {
1839     edit_id: i32,
1840     deleted: bool,
1841     auth: String,
1842   }
1843 }
1844 ```
1845 ##### Response
1846 ```rust
1847 {
1848   op: "DeleteComment",
1849   data: {
1850     comment: CommentView
1851   }
1852 }
1853 ```
1854 ##### HTTP
1855
1856 `POST /comment/delete`
1857
1858
1859 #### Remove Comment
1860
1861 Only a mod or admin can remove the comment.
1862
1863 ##### Request
1864 ```rust
1865 {
1866   op: "RemoveComment",
1867   data: {
1868     edit_id: i32,
1869     removed: bool,
1870     reason: Option<String>,
1871     auth: String,
1872   }
1873 }
1874 ```
1875 ##### Response
1876 ```rust
1877 {
1878   op: "RemoveComment",
1879   data: {
1880     comment: CommentView
1881   }
1882 }
1883 ```
1884 ##### HTTP
1885
1886 `POST /comment/remove`
1887
1888 #### Get Comments
1889
1890 Comment listing types are `All, Subscribed, Community`
1891
1892 ##### Request
1893 ```rust
1894 {
1895   op: "GetComments",
1896   data: {
1897     type_: String,
1898     sort: String,
1899     page: Option<i64>,
1900     limit: Option<i64>,
1901     community_id: Option<i32>,
1902     community_name: Option<String>,
1903     auth: Option<String>
1904   }
1905 }
1906 ```
1907 ##### Response
1908 ```rust
1909 {
1910   op: "GetComments",
1911   data: {
1912     comments: Vec<CommentView>,
1913   }
1914 }
1915 ```
1916 ##### HTTP
1917
1918 `GET /comment/list`
1919
1920 #### Mark Comment as Read
1921
1922 Only the recipient can do this.
1923
1924 ##### Request
1925 ```rust
1926 {
1927   op: "MarkCommentAsRead",
1928   data: {
1929     edit_id: i32,
1930     read: bool,
1931     auth: String,
1932   }
1933 }
1934 ```
1935 ##### Response
1936 ```rust
1937 {
1938   op: "MarkCommentAsRead",
1939   data: {
1940     comment: CommentView
1941   }
1942 }
1943 ```
1944 ##### HTTP
1945
1946 `POST /comment/mark_as_read`
1947
1948 #### Save Comment
1949 ##### Request
1950 ```rust
1951 {
1952   op: "SaveComment",
1953   data: {
1954     comment_id: i32,
1955     save: bool,
1956     auth: String
1957   }
1958 }
1959 ```
1960 ##### Response
1961 ```rust
1962 {
1963   op: "SaveComment",
1964   data: {
1965     comment: CommentView
1966   }
1967 }
1968 ```
1969 ##### HTTP
1970
1971 `PUT /comment/save`
1972
1973 #### Create Comment Like
1974
1975 `score` can be 0, -1, or 1
1976
1977 ##### Request
1978 ```rust
1979 {
1980   op: "CreateCommentLike",
1981   data: {
1982     comment_id: i32,
1983     score: i16,
1984     auth: String
1985   }
1986 }
1987 ```
1988 ##### Response
1989 ```rust
1990 {
1991   op: "CreateCommentLike",
1992   data: {
1993     comment: CommentView
1994   }
1995 }
1996 ```
1997 ##### HTTP
1998
1999 `POST /comment/like`
2000
2001 ### RSS / Atom feeds
2002
2003 #### All
2004
2005 `/feeds/all.xml?sort=Hot`
2006
2007 #### Community
2008
2009 `/feeds/c/community-name.xml?sort=Hot`
2010
2011 #### User
2012
2013 `/feeds/u/user-name.xml?sort=Hot`
2014