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