]> Untitled Git - lemmy.git/blob - docs/src/contributing_websocket_http_api.md
Added community delete and remove.
[lemmy.git] / docs / src / contributing_websocket_http_api.md
1 # Lemmy API
2
3 *Note: this may lag behind the actual API endpoints [here](../server/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   * [Websocket vs HTTP](#websocket-vs-http)
21   * [User / Authentication / Admin actions](#user--authentication--admin-actions)
22     + [Login](#login)
23       - [Request](#request)
24       - [Response](#response)
25       - [HTTP](#http-1)
26     + [Register](#register)
27       - [Request](#request-1)
28       - [Response](#response-1)
29       - [HTTP](#http-2)
30     + [Get User Details](#get-user-details)
31       - [Request](#request-2)
32       - [Response](#response-2)
33       - [HTTP](#http-3)
34     + [Save User Settings](#save-user-settings)
35       - [Request](#request-3)
36       - [Response](#response-3)
37       - [HTTP](#http-4)
38     + [Get Replies / Inbox](#get-replies--inbox)
39       - [Request](#request-4)
40       - [Response](#response-4)
41       - [HTTP](#http-5)
42     + [Get User Mentions](#get-user-mentions)
43       - [Request](#request-5)
44       - [Response](#response-5)
45       - [HTTP](#http-6)
46     + [Edit User Mention](#edit-user-mention)
47       - [Request](#request-6)
48       - [Response](#response-6)
49       - [HTTP](#http-7)
50     + [Mark All As Read](#mark-all-as-read)
51       - [Request](#request-7)
52       - [Response](#response-7)
53       - [HTTP](#http-8)
54     + [Delete Account](#delete-account)
55       - [Request](#request-8)
56       - [Response](#response-8)
57       - [HTTP](#http-9)
58     + [Add admin](#add-admin)
59       - [Request](#request-9)
60       - [Response](#response-9)
61       - [HTTP](#http-10)
62     + [Ban user](#ban-user)
63       - [Request](#request-10)
64       - [Response](#response-10)
65       - [HTTP](#http-11)
66   * [Site](#site)
67     + [List Categories](#list-categories)
68       - [Request](#request-11)
69       - [Response](#response-11)
70       - [HTTP](#http-12)
71     + [Search](#search)
72       - [Request](#request-12)
73       - [Response](#response-12)
74       - [HTTP](#http-13)
75     + [Get Modlog](#get-modlog)
76       - [Request](#request-13)
77       - [Response](#response-13)
78       - [HTTP](#http-14)
79     + [Create Site](#create-site)
80       - [Request](#request-14)
81       - [Response](#response-14)
82       - [HTTP](#http-15)
83     + [Edit Site](#edit-site)
84       - [Request](#request-15)
85       - [Response](#response-15)
86       - [HTTP](#http-16)
87     + [Get Site](#get-site)
88       - [Request](#request-16)
89       - [Response](#response-16)
90       - [HTTP](#http-17)
91     + [Transfer Site](#transfer-site)
92       - [Request](#request-17)
93       - [Response](#response-17)
94       - [HTTP](#http-18)
95     + [Get Site Config](#get-site-config)
96       - [Request](#request-18)
97       - [Response](#response-18)
98       - [HTTP](#http-19)
99     + [Save Site Config](#save-site-config)
100       - [Request](#request-19)
101       - [Response](#response-19)
102       - [HTTP](#http-20)
103   * [Community](#community)
104     + [Get Community](#get-community)
105       - [Request](#request-20)
106       - [Response](#response-20)
107       - [HTTP](#http-21)
108     + [Create Community](#create-community)
109       - [Request](#request-21)
110       - [Response](#response-21)
111       - [HTTP](#http-22)
112     + [List Communities](#list-communities)
113       - [Request](#request-22)
114       - [Response](#response-22)
115       - [HTTP](#http-23)
116     + [Ban from Community](#ban-from-community)
117       - [Request](#request-23)
118       - [Response](#response-23)
119       - [HTTP](#http-24)
120     + [Add Mod to Community](#add-mod-to-community)
121       - [Request](#request-24)
122       - [Response](#response-24)
123       - [HTTP](#http-25)
124     + [Edit Community](#edit-community)
125       - [Request](#request-25)
126       - [Response](#response-25)
127       - [HTTP](#http-26)
128     + [Follow Community](#follow-community)
129       - [Request](#request-26)
130       - [Response](#response-26)
131       - [HTTP](#http-27)
132     + [Get Followed Communities](#get-followed-communities)
133       - [Request](#request-27)
134       - [Response](#response-27)
135       - [HTTP](#http-28)
136     + [Transfer Community](#transfer-community)
137       - [Request](#request-28)
138       - [Response](#response-28)
139       - [HTTP](#http-29)
140   * [Post](#post)
141     + [Create Post](#create-post)
142       - [Request](#request-29)
143       - [Response](#response-29)
144       - [HTTP](#http-30)
145     + [Get Post](#get-post)
146       - [Request](#request-30)
147       - [Response](#response-30)
148       - [HTTP](#http-31)
149     + [Get Posts](#get-posts)
150       - [Request](#request-31)
151       - [Response](#response-31)
152       - [HTTP](#http-32)
153     + [Create Post Like](#create-post-like)
154       - [Request](#request-32)
155       - [Response](#response-32)
156       - [HTTP](#http-33)
157     + [Edit Post](#edit-post)
158       - [Request](#request-33)
159       - [Response](#response-33)
160       - [HTTP](#http-34)
161     + [Save Post](#save-post)
162       - [Request](#request-34)
163       - [Response](#response-34)
164       - [HTTP](#http-35)
165   * [Comment](#comment)
166     + [Create Comment](#create-comment)
167       - [Request](#request-35)
168       - [Response](#response-35)
169       - [HTTP](#http-36)
170     + [Edit Comment](#edit-comment)
171       - [Request](#request-36)
172       - [Response](#response-36)
173       - [HTTP](#http-37)
174     + [Save Comment](#save-comment)
175       - [Request](#request-37)
176       - [Response](#response-37)
177       - [HTTP](#http-38)
178     + [Create Comment Like](#create-comment-like)
179       - [Request](#request-38)
180       - [Response](#response-38)
181       - [HTTP](#http-39)
182   * [RSS / Atom feeds](#rss--atom-feeds)
183     + [All](#all)
184     + [Community](#community-1)
185     + [User](#user)
186
187 <!-- tocstop -->
188
189 ## Data types
190
191 - `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.
192 - <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***.
193 - <code>Vec<***SomeType***></code> is a list which contains objects of type ***SomeType***.
194 - `chrono::NaiveDateTime` is a timestamp string in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. Timestamps will be UTC.
195 - Other data types are listed [here](../server/src/db).
196
197 ## Basic usage
198
199 Request and response strings are in [JSON format](https://www.json.org).
200
201 ### WebSocket
202
203 Connect to <code>ws://***host***/api/v1/ws</code> to get started.
204
205 If the ***`host`*** supports secure connections, you can use <code>wss://***host***/api/v1/ws</code>.
206
207 #### Testing with Websocat
208
209 [Websocat link](https://github.com/vi/websocat)
210
211 `websocat ws://127.0.0.1:8536/api/v1/ws -nt`
212
213 A simple test command:
214 `{"op": "ListCategories"}`
215
216 #### Testing with the WebSocket JavaScript API
217
218 [WebSocket JavaScript API](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
219 ```javascript
220 var ws = new WebSocket("ws://" + host + "/api/v1/ws");
221 ws.onopen = function () {
222   console.log("Connection succeed!");
223   ws.send(JSON.stringify({
224     op: "ListCategories"
225   }));
226 };
227 ```
228 ### HTTP
229
230 Endpoints are at <code>http://***host***/api/v1/***endpoint***</code>. They'll be listed below for each action.
231
232 #### Testing with Curl
233
234 ##### Get Example
235
236 ```
237 curl /community/list?sort=Hot
238 ```
239
240 ##### Post Example
241
242 ```
243 curl -i -H \
244 "Content-Type: application/json" \
245 -X POST \
246 -d '{
247   "comment_id": X,
248   "post_id": X,
249   "score": X,
250   "auth": "..."
251 }' \
252 /comment/like
253 ```
254
255 ## Rate limits
256
257 - 1 per hour for signups and community creation.
258 - 1 per 10 minutes for post creation.
259 - 30 actions per minute for post voting and comment creation.
260 - Everything else is not rate-limited.
261
262 ## Errors
263 ```rust
264 {
265   op: String,
266   message: String,
267 }
268 ```
269
270 ## API documentation
271
272 ### Sort Types
273
274 These go wherever there is a `sort` field. The available sort types are:
275
276 - `Hot` - the hottest posts/communities, depending on votes, views, comments and publish date
277 - `New` - the newest posts/communities
278 - `TopDay` - the most upvoted posts/communities of the current day.
279 - `TopWeek` - the most upvoted posts/communities of the current week.
280 - `TopMonth` - the most upvoted posts/communities of the current month.
281 - `TopYear` - the most upvoted posts/communities of the current year.
282 - `TopAll` - the most upvoted posts/communities on the current instance.
283
284 ### Websocket vs HTTP
285
286 - Below are the websocket JSON requests / responses. For HTTP, ignore all fields except those inside `data`.
287 - For example, an http login will be a `POST` `{username_or_email: X, password: X}`
288
289 ### User / Authentication / Admin actions
290
291 #### Login
292
293 The `jwt` string should be stored and used anywhere `auth` is called for.
294
295 ##### Request
296 ```rust
297 {
298   op: "Login",
299   data: {
300     username_or_email: String,
301     password: String
302   }
303 }
304 ```
305 ##### Response
306 ```rust
307 {
308   op: "Login",
309   data: {
310     jwt: String,
311   }
312 }
313 ```
314
315 ##### HTTP
316
317 `POST /user/login`
318
319 #### Register
320
321 Only the first user will be able to be the admin.
322
323 ##### Request
324 ```rust
325 {
326   op: "Register",
327   data: {
328     username: String,
329     email: Option<String>,
330     password: String,
331     password_verify: String,
332     admin: bool
333   }
334 }
335 ```
336 ##### Response
337 ```rust
338 {
339   op: "Register",
340   data: {
341     jwt: String,
342   }
343 }
344 ```
345
346 ##### HTTP
347
348 `POST /user/register`
349
350 #### Get User Details
351 ##### Request
352 ```rust
353 {
354   op: "GetUserDetails",
355   data: {
356     user_id: Option<i32>,
357     username: Option<String>,
358     sort: String,
359     page: Option<i64>,
360     limit: Option<i64>,
361     community_id: Option<i32>,
362     saved_only: bool,
363     auth: Option<String>,
364   }
365 }
366 ```
367 ##### Response
368 ```rust
369 {
370   op: "GetUserDetails",
371   data: {
372     user: UserView,
373     follows: Vec<CommunityFollowerView>,
374     moderates: Vec<CommunityModeratorView>,
375     comments: Vec<CommentView>,
376     posts: Vec<PostView>,
377   }
378 }
379 ```
380 ##### HTTP
381
382 `GET /user`
383
384 #### Save User Settings
385 ##### Request
386 ```rust
387 {
388   op: "SaveUserSettings",
389   data: {
390     show_nsfw: bool,
391     theme: String, // Default 'darkly'
392     default_sort_type: i16, // The Sort types from above, zero indexed as a number
393     default_listing_type: i16, // Post listing types are `All, Subscribed, Community`
394     auth: String
395   }
396 }
397 ```
398 ##### Response
399 ```rust
400 {
401   op: "SaveUserSettings",
402   data: {
403     jwt: String
404   }
405 }
406 ```
407 ##### HTTP
408
409 `PUT /save_user_settings`
410
411 #### Get Replies / Inbox
412 ##### Request
413 ```rust
414 {
415   op: "GetReplies",
416   data: {
417     sort: String,
418     page: Option<i64>,
419     limit: Option<i64>,
420     unread_only: bool,
421     auth: String
422   }
423 }
424 ```
425 ##### Response
426 ```rust
427 {
428   op: "GetReplies",
429   data: {
430     replies: Vec<ReplyView>,
431   }
432 }
433 ```
434 ##### HTTP
435
436 `GET /user/replies`
437
438
439 #### Get User Mentions
440 ##### Request
441 ```rust
442 {
443   op: "GetUserMentions",
444   data: {
445     sort: String,
446     page: Option<i64>,
447     limit: Option<i64>,
448     unread_only: bool,
449     auth: String,
450   }
451 }
452 ```
453 ##### Response
454 ```rust
455 {
456   op: "GetUserMentions",
457   data: {
458     mentions: Vec<UserMentionView>,
459   }
460 }
461 ```
462
463 ##### HTTP
464
465 `GET /user/mentions`
466
467 #### Mark User Mention as read
468 ##### Request
469 ```rust
470 {
471   op: "MarkUserMentionAsRead",
472   data: {
473     user_mention_id: i32,
474     read: bool,
475     auth: String,
476   }
477 }
478 ```
479 ##### Response
480 ```rust
481 {
482   op: "MarkUserMentionAsRead",
483   data: {
484     mention: UserMentionView,
485   }
486 }
487 ```
488 ##### HTTP
489
490 `POST /user/mention/mark_as_read`
491
492 #### Get Private Messages
493 ##### Request
494 ```rust
495 {
496   op: "GetPrivateMessages",
497   data: {
498     unread_only: bool,
499     page: Option<i64>,
500     limit: Option<i64>,
501     auth: String,
502   }
503 }
504 ```
505 ##### Response
506 ```rust
507 {
508   op: "GetPrivateMessages",
509   data: {
510     messages: Vec<PrivateMessageView>,
511   }
512 }
513 ```
514
515 ##### HTTP
516
517 `GET /private_message/list`
518
519 #### Create Private Message
520 ##### Request
521 ```rust
522 {
523   op: "CreatePrivateMessage",
524   data: {
525     content: String,
526     recipient_id: i32,
527     auth: String,
528   }
529 }
530 ```
531 ##### Response
532 ```rust
533 {
534   op: "CreatePrivateMessage",
535   data: {
536     message: PrivateMessageView,
537   }
538 }
539 ```
540
541 ##### HTTP
542
543 `POST /private_message`
544
545 #### Edit Private Message
546 ##### Request
547 ```rust
548 {
549   op: "EditPrivateMessage",
550   data: {
551     edit_id: i32,
552     content: String,
553     auth: String,
554   }
555 }
556 ```
557 ##### Response
558 ```rust
559 {
560   op: "EditPrivateMessage",
561   data: {
562     message: PrivateMessageView,
563   }
564 }
565 ```
566
567 ##### HTTP
568
569 `PUT /private_message`
570
571 #### Delete Private Message
572 ##### Request
573 ```rust
574 {
575   op: "DeletePrivateMessage",
576   data: {
577     edit_id: i32,
578     deleted: bool,
579     auth: String,
580   }
581 }
582 ```
583 ##### Response
584 ```rust
585 {
586   op: "DeletePrivateMessage",
587   data: {
588     message: PrivateMessageView,
589   }
590 }
591 ```
592
593 ##### HTTP
594
595 `POST /private_message/delete`
596
597 #### Mark Private Message as Read
598 ##### Request
599 ```rust
600 {
601   op: "MarkPrivateMessageAsRead",
602   data: {
603     edit_id: i32,
604     read: bool,
605     auth: String,
606   }
607 }
608 ```
609 ##### Response
610 ```rust
611 {
612   op: "MarkPrivateMessageAsRead",
613   data: {
614     message: PrivateMessageView,
615   }
616 }
617 ```
618
619 ##### HTTP
620
621 `POST /private_message/mark_as_read`
622
623 #### Mark All As Read
624
625 Marks all user replies and mentions as read.
626
627 ##### Request
628 ```rust
629 {
630   op: "MarkAllAsRead",
631   data: {
632     auth: String
633   }
634 }
635 ```
636 ##### Response
637 ```rust
638 {
639   op: "MarkAllAsRead",
640   data: {
641     replies: Vec<ReplyView>,
642   }
643 }
644 ```
645
646 ##### HTTP
647
648 `POST /user/mark_all_as_read`
649
650 #### Delete Account
651
652 *Permananently deletes your posts and comments*
653
654 ##### Request
655 ```rust
656 {
657   op: "DeleteAccount",
658   data: {
659     password: String,
660     auth: String
661   }
662 }
663 ```
664 ##### Response
665 ```rust
666 {
667   op: "DeleteAccount",
668   data: {
669     jwt: String,
670   }
671 }
672 ```
673
674 ##### HTTP
675
676 `POST /user/delete_account`
677
678 #### Add admin
679 ##### Request
680 ```rust
681 {
682   op: "AddAdmin",
683   data: {
684     user_id: i32,
685     added: bool,
686     auth: String
687   }
688 }
689 ```
690 ##### Response
691 ```rust
692 {
693   op: "AddAdmin",
694   data: {
695     admins: Vec<UserView>,
696   }
697 }
698 ```
699 ##### HTTP
700
701 `POST /admin/add`
702
703 #### Ban user
704 ##### Request
705 ```rust
706 {
707   op: "BanUser",
708   data: {
709     user_id: i32,
710     ban: bool,
711     reason: Option<String>,
712     expires: Option<i64>,
713     auth: String
714   }
715 }
716 ```
717 ##### Response
718 ```rust
719 {
720   op: "BanUser",
721   data: {
722     user: UserView,
723     banned: bool,
724   }
725 }
726 ```
727 ##### HTTP
728
729 `POST /user/ban`
730
731 ### Site
732 #### List Categories
733 ##### Request
734 ```rust
735 {
736   op: "ListCategories"
737 }
738 ```
739 ##### Response
740 ```rust
741 {
742   op: "ListCategories",
743   data: {
744     categories: Vec<Category>
745   }
746 }
747 ```
748 ##### HTTP
749
750 `GET /categories`
751
752 #### Search
753
754 Search types are `All, Comments, Posts, Communities, Users, Url`
755
756 ##### Request
757 ```rust
758 {
759   op: "Search",
760   data: {
761     q: String,
762     type_: String,
763     community_id: Option<i32>,
764     sort: String,
765     page: Option<i64>,
766     limit: Option<i64>,
767     auth?: Option<String>,
768   }
769 }
770 ```
771 ##### Response
772 ```rust
773 {
774   op: "Search",
775   data: {
776     type_: String,
777     comments: Vec<CommentView>,
778     posts: Vec<PostView>,
779     communities: Vec<CommunityView>,
780     users: Vec<UserView>,
781   }
782 }
783 ```
784 ##### HTTP
785
786 `POST /search`
787
788 #### Get Modlog
789 ##### Request
790 ```rust
791 {
792   op: "GetModlog",
793   data: {
794     mod_user_id: Option<i32>,
795     community_id: Option<i32>,
796     page: Option<i64>,
797     limit: Option<i64>,
798   }
799 }
800 ```
801 ##### Response
802 ```rust
803 {
804   op: "GetModlog",
805   data: {
806     removed_posts: Vec<ModRemovePostView>,
807     locked_posts: Vec<ModLockPostView>,
808     removed_comments: Vec<ModRemoveCommentView>,
809     removed_communities: Vec<ModRemoveCommunityView>,
810     banned_from_community: Vec<ModBanFromCommunityView>,
811     banned: Vec<ModBanView>,
812     added_to_community: Vec<ModAddCommunityView>,
813     added: Vec<ModAddView>,
814   }
815 }
816 ```
817
818 ##### HTTP
819
820 `GET /modlog`
821
822 #### Create Site
823 ##### Request
824 ```rust
825 {
826   op: "CreateSite",
827   data: {
828     name: String,
829     description: Option<String>,
830     auth: String
831   }
832 }
833 ```
834 ##### Response
835 ```rust
836 {
837   op: "CreateSite",
838     data: {
839     site: SiteView,
840   }
841 }
842 ```
843
844 ##### HTTP
845
846 `POST /site`
847
848 #### Edit Site
849 ##### Request
850 ```rust
851 {
852   op: "EditSite",
853   data: {
854     name: String,
855     description: Option<String>,
856     auth: String
857   }
858 }
859 ```
860 ##### Response
861 ```rust
862 {
863   op: "EditSite",
864   data: {
865     site: SiteView,
866   }
867 }
868 ```
869 ##### HTTP
870
871 `PUT /site`
872
873 #### Get Site
874 ##### Request
875 ```rust
876 {
877   op: "GetSite"
878 }
879 ```
880 ##### Response
881 ```rust
882 {
883   op: "GetSite",
884   data: {
885     site: Option<SiteView>,
886     admins: Vec<UserView>,
887     banned: Vec<UserView>,
888   }
889 }
890 ```
891 ##### HTTP
892
893 `GET /site`
894
895 #### Transfer Site
896 ##### Request
897 ```rust
898 {
899   op: "TransferSite",
900   data: {
901     user_id: i32,
902     auth: String
903   }
904 }
905 ```
906 ##### Response
907 ```rust
908 {
909   op: "TransferSite",
910   data: {
911     site: Option<SiteView>,
912     admins: Vec<UserView>,
913     banned: Vec<UserView>,
914   }
915 }
916 ```
917 ##### HTTP
918
919 `POST /site/transfer`
920
921 #### Get Site Config
922 ##### Request
923 ```rust
924 {
925   op: "GetSiteConfig",
926   data: {
927     auth: String
928   }
929 }
930 ```
931 ##### Response
932 ```rust
933 {
934   op: "GetSiteConfig",
935   data: {
936     config_hjson: String,
937   }
938 }
939 ```
940 ##### HTTP
941
942 `GET /site/config`
943
944 #### Save Site Config
945 ##### Request
946 ```rust
947 {
948   op: "SaveSiteConfig",
949   data: {
950     config_hjson: String,
951     auth: String
952   }
953 }
954 ```
955 ##### Response
956 ```rust
957 {
958   op: "SaveSiteConfig",
959   data: {
960     config_hjson: String,
961   }
962 }
963 ```
964 ##### HTTP
965
966 `PUT /site/config`
967
968 ### Community
969 #### Get Community
970 ##### Request
971 ```rust
972 {
973   op: "GetCommunity",
974   data: {
975     id: Option<i32>,
976     name: Option<String>,
977     auth: Option<String>
978   }
979 }
980 ```
981 ##### Response
982 ```rust
983 {
984   op: "GetCommunity",
985   data: {
986     community: CommunityView,
987     moderators: Vec<CommunityModeratorView>,
988     admins: Vec<UserView>,
989   }
990 }
991 ```
992 ##### HTTP
993
994 `GET /community`
995
996 #### Create Community
997 ##### Request
998 ```rust
999 {
1000   op: "CreateCommunity",
1001   data: {
1002     name: String,
1003     title: String,
1004     description: Option<String>,
1005     category_id: i32 ,
1006     auth: String
1007   }
1008 }
1009 ```
1010 ##### Response
1011 ```rust
1012 {
1013   op: "CreateCommunity",
1014   data: {
1015     community: CommunityView
1016   }
1017 }
1018 ```
1019 ##### HTTP
1020
1021 `POST /community`
1022
1023 #### List Communities
1024 ##### Request
1025 ```rust
1026 {
1027   op: "ListCommunities",
1028   data: {
1029     sort: String,
1030     page: Option<i64>,
1031     limit: Option<i64>,
1032     auth: Option<String>
1033   }
1034 }
1035 ```
1036 ##### Response
1037 ```rust
1038 {
1039   op: "ListCommunities",
1040   data: {
1041     communities: Vec<CommunityView>
1042   }
1043 }
1044 ```
1045 ##### HTTP
1046
1047 `GET /community/list`
1048
1049 #### Ban from Community
1050 ##### Request
1051 ```rust
1052 {
1053   op: "BanFromCommunity",
1054   data: {
1055     community_id: i32,
1056     user_id: i32,
1057     ban: bool,
1058     reason: Option<String>,
1059     expires: Option<i64>,
1060     auth: String
1061   }
1062 }
1063 ```
1064 ##### Response
1065 ```rust
1066 {
1067   op: "BanFromCommunity",
1068   data: {
1069     user: UserView,
1070     banned: bool,
1071   }
1072 }
1073 ```
1074 ##### HTTP
1075
1076 `POST /community/ban_user`
1077
1078 #### Add Mod to Community
1079 ##### Request
1080 ```rust
1081 {
1082   op: "AddModToCommunity",
1083   data: {
1084     community_id: i32,
1085     user_id: i32,
1086     added: bool,
1087     auth: String
1088   }
1089 }
1090 ```
1091 ##### Response
1092 ```rust
1093 {
1094   op: "AddModToCommunity",
1095   data: {
1096     moderators: Vec<CommunityModeratorView>,
1097   }
1098 }
1099 ```
1100 ##### HTTP
1101
1102 `POST /community/mod`
1103
1104 #### Edit Community
1105 Only mods can edit a community.
1106
1107 ##### Request
1108 ```rust
1109 {
1110   op: "EditCommunity",
1111   data: {
1112     edit_id: i32,
1113     title: String,
1114     description: Option<String>,
1115     category_id: i32,
1116     auth: String
1117   }
1118 }
1119 ```
1120 ##### Response
1121 ```rust
1122 {
1123   op: "EditCommunity",
1124   data: {
1125     community: CommunityView
1126   }
1127 }
1128 ```
1129 ##### HTTP
1130
1131 `PUT /community`
1132
1133 #### Delete Community
1134 Only a creator can delete a community
1135
1136 ##### Request
1137 ```rust
1138 {
1139   op: "DeleteCommunity",
1140   data: {
1141     edit_id: i32,
1142     deleted: bool,
1143     auth: String,
1144   }
1145 }
1146 ```
1147 ##### Response
1148 ```rust
1149 {
1150   op: "DeleteCommunity",
1151   data: {
1152     community: CommunityView
1153   }
1154 }
1155 ```
1156 ##### HTTP
1157
1158 `POST /community/delete`
1159
1160 #### Remove Community
1161 Only admins can remove a community.
1162
1163 ##### Request
1164 ```rust
1165 {
1166   op: "RemoveCommunity",
1167   data: {
1168     edit_id: i32,
1169     removed: bool,
1170     reason: Option<String>,
1171     expires: Option<i64>,
1172     auth: String,
1173   }
1174 }
1175 ```
1176 ##### Response
1177 ```rust
1178 {
1179   op: "RemoveCommunity",
1180   data: {
1181     community: CommunityView
1182   }
1183 }
1184 ```
1185 ##### HTTP
1186
1187 `POST /community/remove`
1188
1189 #### Follow Community
1190 ##### Request
1191 ```rust
1192 {
1193   op: "FollowCommunity",
1194   data: {
1195     community_id: i32,
1196     follow: bool,
1197     auth: String
1198   }
1199 }
1200 ```
1201 ##### Response
1202 ```rust
1203 {
1204   op: "FollowCommunity",
1205   data: {
1206     community: CommunityView
1207   }
1208 }
1209 ```
1210 ##### HTTP
1211
1212 `POST /community/follow`
1213
1214 #### Get Followed Communities
1215 ##### Request
1216 ```rust
1217 {
1218   op: "GetFollowedCommunities",
1219   data: {
1220     auth: String
1221   }
1222 }
1223 ```
1224 ##### Response
1225 ```rust
1226 {
1227   op: "GetFollowedCommunities",
1228   data: {
1229     communities: Vec<CommunityFollowerView>
1230   }
1231 }
1232 ```
1233 ##### HTTP
1234
1235 `GET /user/followed_communities`
1236
1237 #### Transfer Community
1238 ##### Request
1239 ```rust
1240 {
1241   op: "TransferCommunity",
1242   data: {
1243     community_id: i32,
1244     user_id: i32,
1245     auth: String
1246   }
1247 }
1248 ```
1249 ##### Response
1250 ```rust
1251 {
1252   op: "TransferCommunity",
1253   data: {
1254     community: CommunityView,
1255     moderators: Vec<CommunityModeratorView>,
1256     admins: Vec<UserView>,
1257   }
1258 }
1259 ```
1260 ##### HTTP
1261
1262 `POST /community/transfer`
1263
1264 ### Post
1265 #### Create Post
1266 ##### Request
1267 ```rust
1268 {
1269   op: "CreatePost",
1270   data: {
1271     name: String,
1272     url: Option<String>,
1273     body: Option<String>,
1274     community_id: i32,
1275     auth: String
1276   }
1277 }
1278 ```
1279 ##### Response
1280 ```rust
1281 {
1282   op: "CreatePost",
1283   data: {
1284     post: PostView
1285   }
1286 }
1287 ```
1288 ##### HTTP
1289
1290 `POST /post`
1291
1292 #### Get Post
1293 ##### Request
1294 ```rust
1295 {
1296   op: "GetPost",
1297   data: {
1298     id: i32,
1299     auth: Option<String>
1300   }
1301 }
1302 ```
1303 ##### Response
1304 ```rust
1305 {
1306   op: "GetPost",
1307   data: {
1308     post: PostView,
1309     comments: Vec<CommentView>,
1310     community: CommunityView,
1311     moderators: Vec<CommunityModeratorView>,
1312     admins: Vec<UserView>,
1313   }
1314 }
1315 ```
1316 ##### HTTP
1317
1318 `GET /post`
1319
1320 #### Get Posts
1321
1322 Post listing types are `All, Subscribed, Community`
1323
1324 ##### Request
1325 ```rust
1326 {
1327   op: "GetPosts",
1328   data: {
1329     type_: String,
1330     sort: String,
1331     page: Option<i64>,
1332     limit: Option<i64>,
1333     community_id: Option<i32>,
1334     community_name: Option<String>,
1335     auth: Option<String>
1336   }
1337 }
1338 ```
1339 ##### Response
1340 ```rust
1341 {
1342   op: "GetPosts",
1343   data: {
1344     posts: Vec<PostView>,
1345   }
1346 }
1347 ```
1348 ##### HTTP
1349
1350 `GET /post/list`
1351
1352 #### Create Post Like
1353
1354 `score` can be 0, -1, or 1
1355
1356 ##### Request
1357 ```rust
1358 {
1359   op: "CreatePostLike",
1360   data: {
1361     post_id: i32,
1362     score: i16,
1363     auth: String
1364   }
1365 }
1366 ```
1367 ##### Response
1368 ```rust
1369 {
1370   op: "CreatePostLike",
1371   data: {
1372     post: PostView
1373   }
1374 }
1375 ```
1376 ##### HTTP
1377
1378 `POST /post/like`
1379
1380 #### Edit Post
1381
1382 Mods and admins can remove and lock a post, creators can delete it.
1383
1384 ##### Request
1385 ```rust
1386 {
1387   op: "EditPost",
1388   data: {
1389     edit_id: i32,
1390     creator_id: i32,
1391     community_id: i32,
1392     name: String,
1393     url: Option<String>,
1394     body: Option<String>,
1395     removed: Option<bool>,
1396     deleted: Option<bool>,
1397     locked: Option<bool>,
1398     reason: Option<String>,
1399     auth: String
1400   }
1401 }
1402 ```
1403 ##### Response
1404 ```rust
1405 {
1406   op: "EditPost",
1407   data: {
1408     post: PostView
1409   }
1410 }
1411 ```
1412
1413 ##### HTTP
1414
1415 `PUT /post`
1416
1417 #### Save Post
1418 ##### Request
1419 ```rust
1420 {
1421   op: "SavePost",
1422   data: {
1423     post_id: i32,
1424     save: bool,
1425     auth: String
1426   }
1427 }
1428 ```
1429 ##### Response
1430 ```rust
1431 {
1432   op: "SavePost",
1433   data: {
1434     post: PostView
1435   }
1436 }
1437 ```
1438 ##### HTTP
1439
1440 `POST /post/save`
1441
1442 ### Comment
1443 #### Create Comment
1444 ##### Request
1445 ```rust
1446 {
1447   op: "CreateComment",
1448   data: {
1449     content: String,
1450     parent_id: Option<i32>,
1451     edit_id: Option<i32>,
1452     post_id: i32,
1453     auth: String
1454   }
1455 }
1456 ```
1457 ##### Response
1458 ```rust
1459 {
1460   op: "CreateComment",
1461   data: {
1462     comment: CommentView
1463   }
1464 }
1465 ```
1466
1467 ##### HTTP
1468
1469 `POST /comment`
1470
1471 #### Edit Comment
1472
1473 Mods and admins can remove a comment, creators can delete it.
1474
1475 ##### Request
1476 ```rust
1477 {
1478   op: "EditComment",
1479   data: {
1480     content: String,
1481     parent_id: Option<i32>,
1482     edit_id: i32,
1483     creator_id: i32,
1484     post_id: i32,
1485     removed: Option<bool>,
1486     deleted: Option<bool>,
1487     reason: Option<String>,
1488     read: Option<bool>,
1489     auth: String
1490   }
1491 }
1492 ```
1493 ##### Response
1494 ```rust
1495 {
1496   op: "EditComment",
1497   data: {
1498     comment: CommentView
1499   }
1500 }
1501 ```
1502 ##### HTTP
1503
1504 `PUT /comment`
1505
1506 #### Save Comment
1507 ##### Request
1508 ```rust
1509 {
1510   op: "SaveComment",
1511   data: {
1512     comment_id: i32,
1513     save: bool,
1514     auth: String
1515   }
1516 }
1517 ```
1518 ##### Response
1519 ```rust
1520 {
1521   op: "SaveComment",
1522   data: {
1523     comment: CommentView
1524   }
1525 }
1526 ```
1527 ##### HTTP
1528
1529 `POST /comment/save`
1530
1531 #### Create Comment Like
1532
1533 `score` can be 0, -1, or 1
1534
1535 ##### Request
1536 ```rust
1537 {
1538   op: "CreateCommentLike",
1539   data: {
1540     comment_id: i32,
1541     post_id: i32,
1542     score: i16,
1543     auth: String
1544   }
1545 }
1546 ```
1547 ##### Response
1548 ```rust
1549 {
1550   op: "CreateCommentLike",
1551   data: {
1552     comment: CommentView
1553   }
1554 }
1555 ```
1556 ##### HTTP
1557
1558 `POST /comment/like`
1559
1560 ### RSS / Atom feeds
1561
1562 #### All
1563
1564 `/feeds/all.xml?sort=Hot`
1565
1566 #### Community
1567
1568 `/feeds/c/community-name.xml?sort=Hot`
1569
1570 #### User
1571
1572 `/feeds/u/user-name.xml?sort=Hot`
1573