docs: list available Mastodon API endpoints/methods
This commit is contained in:
parent
140eaf8f16
commit
c1198e3420
5 changed files with 136 additions and 13 deletions
|
@ -8,6 +8,129 @@ Breaking changes are indicated by the :warning: icon.
|
|||
- :warning: The new API uses a new format to manage Mastodon sessions in the database, whereas old implementation uses Misskey sessions. All previous client app and token registrations will not work with the new API. All clients need to be re-registered and all users need to re-authenticate.
|
||||
- :warning: All IDs (of statuses/notes, notifications, users, etc.) will be using the alphanumerical format, aligning with the Firefish/Misskey API. The old numerical IDs will not work when queried against the new API.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Available endpoints (under <code>https://instance-domain/api/</code>)</summary>
|
||||
|
||||
- `POST oauth/token`
|
||||
- `POST oauth/revoke`
|
||||
- `POST v1/apps`
|
||||
- `GET v1/apps/verify_credentials`
|
||||
- `POST v1/firefish/apps/info` (Firefish extension, uses MiAuth)
|
||||
- `POST v1/firefish/auth/code` (Firefish extension, uses MiAuth)
|
||||
|
||||
- `GET v1/accounts/verify_credentials`
|
||||
- `PATCH v1/accounts/update_credentials`
|
||||
- `GET v1/accounts/lookup`
|
||||
- `GET v1/accounts/relationships`
|
||||
- `GET v1/accounts/search`
|
||||
- `GET v1/accounts/:id`
|
||||
- `GET v1/accounts/:id/statuses`
|
||||
- `GET v1/accounts/:id/featured_tags`
|
||||
- `GET v1/accounts/:id/followers`
|
||||
- `GET v1/accounts/:id/following`
|
||||
- `GET v1/accounts/:id/lists`
|
||||
- `POST v1/accounts/:id/follow`
|
||||
- `POST v1/accounts/:id/unfollow`
|
||||
- `POST v1/accounts/:id/block`
|
||||
- `POST v1/accounts/:id/unblock`
|
||||
- `POST v1/accounts/:id/mute`
|
||||
- `POST v1/accounts/:id/unmute`
|
||||
|
||||
- `GET v1/featured_tags` (returns an empty list)
|
||||
- `GET v1/followed_tags` (returns an empty list)
|
||||
- `GET v1/bookmarks`
|
||||
- `GET v1/favourites`
|
||||
|
||||
- `GET v1/mutes`
|
||||
- `GET v1/blocks`
|
||||
- `GET v1/follow_requests`
|
||||
- `POST v1/follow_requests/:id/authorize`
|
||||
- `POST v1/follow_requests/:id/reject`
|
||||
|
||||
- `GET v1/filters`
|
||||
- `POST v1/filters`
|
||||
- `GET v2/filters`
|
||||
- `POST v2/filters`
|
||||
|
||||
- `GET v1/lists`
|
||||
- `POST v1/lists`
|
||||
- `GET v1/lists/:id`
|
||||
- `PUT v1/lists/:id`
|
||||
- `DELETE v1/lists/:id`
|
||||
- `GET v1/lists/:id/accounts`
|
||||
- `POST v1/lists/:id/accounts`
|
||||
- `DELETE v1/lists/:id/accounts`
|
||||
|
||||
- `GET v1/media/:id`
|
||||
- `PUT v1/media/:id`
|
||||
- `POST v1/media`
|
||||
- `POST v2/media`
|
||||
|
||||
- `GET v1/custom_emojis`
|
||||
- `GET v1/instance`
|
||||
- `GET v2/instance`
|
||||
- `GET v1/announcements`
|
||||
- `POST v1/announcements/:id/dismiss`
|
||||
- `GET v1/trends` (pagination is unimplemented)
|
||||
- `GET v1/trends/tags` (pagination is unimplemented)
|
||||
- `GET v1/trends/statuses`
|
||||
- `GET v1/trends/links` (returns an empty list)
|
||||
- `GET v1/preferences`
|
||||
- `GET v2/suggestions`
|
||||
|
||||
- `GET v1/notifications`
|
||||
- `GET v1/notifications/:id`
|
||||
- `POST v1/notifications/clear`
|
||||
- `POST v1/notifications/:id/dismiss`
|
||||
- `POST v1/conversations/:id/read`
|
||||
- `GET v1/push/subscription`
|
||||
- `POST v1/push/subscription`
|
||||
- `DELETE v1/push/subscription`
|
||||
|
||||
- `GET v1/search`
|
||||
- `GET v2/search`
|
||||
|
||||
- `POST v1/statuses`
|
||||
- `PUT v1/statuses/:id`
|
||||
- `GET v1/statuses/:id`
|
||||
- `DELETE v1/statuses/:id`
|
||||
- `GET v1/statuses/:id/context`
|
||||
- `GET v1/statuses/:id/history`
|
||||
- `GET v1/statuses/:id/source`
|
||||
- `GET v1/statuses/:id/reblogged_by`
|
||||
- `GET v1/statuses/:id/favourited_by`
|
||||
- `POST v1/statuses/:id/favourite`
|
||||
- `POST v1/statuses/:id/unfavourite`
|
||||
- `POST v1/statuses/:id/reblog`
|
||||
- `POST v1/statuses/:id/unreblog`
|
||||
- `POST v1/statuses/:id/bookmark`
|
||||
- `POST v1/statuses/:id/unbookmark`
|
||||
- `POST v1/statuses/:id/pin`
|
||||
- `POST v1/statuses/:id/unpin`
|
||||
- `POST v1/statuses/:id/react/:name`
|
||||
- `POST v1/statuses/:id/unreact/:name`
|
||||
- `POST v1/statuses/:id/translate`
|
||||
|
||||
- `GET v1/polls/:id`
|
||||
- `POST v1/polls/:id/votes`
|
||||
|
||||
- `GET v1/scheduled_statuses`
|
||||
- `GET v1/scheduled_statuses/:id` (reschedule (`PUT` method) is unimplemented)
|
||||
- `DELETE v1/scheduled_statuses/:id`
|
||||
|
||||
- `GET v1/streaming/health`
|
||||
|
||||
- `GET v1/timelines/public`
|
||||
- `GET v1/timelines/tag/:hashtag`
|
||||
- `GET v1/timelines/home`
|
||||
- `GET v1/timelines/list/:listId`
|
||||
- `GET v1/conversations`
|
||||
- `GET v1/markers`
|
||||
- `POST v1/markers`
|
||||
|
||||
</details>
|
||||
|
||||
## v20240607
|
||||
|
||||
- `GET` request is now allowed for the `latest-version` endpoint.
|
||||
|
|
|
@ -34,7 +34,7 @@ export function setupEndpointsAccount(router: Router): void {
|
|||
async (ctx) => {
|
||||
const ids =
|
||||
normalizeUrlQuery(ctx.query, ["id[]"])["id[]"] ??
|
||||
normalizeUrlQuery(ctx.query, ["id"])["id"] ??
|
||||
normalizeUrlQuery(ctx.query, ["id"]).id ??
|
||||
[];
|
||||
ctx.body = await UserHelpers.getUserRelationhipToMany(ids, ctx.user.id);
|
||||
},
|
||||
|
|
|
@ -12,17 +12,17 @@ import { auth } from "@/server/api/mastodon/middleware/auth.js";
|
|||
import { MastoApiError } from "@/server/api/mastodon/middleware/catch-errors.js";
|
||||
|
||||
export function setupEndpointsList(router: Router): void {
|
||||
router.get("/v1/lists", auth(true, ["read:lists"]), async (ctx, reply) => {
|
||||
router.get("/v1/lists", auth(true, ["read:lists"]), async (ctx, _reply) => {
|
||||
ctx.body = await ListHelpers.getLists(ctx);
|
||||
});
|
||||
router.get<{ Params: { id: string } }>(
|
||||
"/v1/lists/:id",
|
||||
auth(true, ["read:lists"]),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
ctx.body = await ListHelpers.getListOr404(ctx.params.id, ctx);
|
||||
},
|
||||
);
|
||||
router.post("/v1/lists", auth(true, ["write:lists"]), async (ctx, reply) => {
|
||||
router.post("/v1/lists", auth(true, ["write:lists"]), async (ctx, _reply) => {
|
||||
const body = ctx.request.body as any;
|
||||
const title = (body.title ?? "").trim();
|
||||
ctx.body = await ListHelpers.createList(title, ctx);
|
||||
|
@ -46,7 +46,7 @@ export function setupEndpointsList(router: Router): void {
|
|||
router.delete<{ Params: { id: string } }>(
|
||||
"/v1/lists/:id",
|
||||
auth(true, ["write:lists"]),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
const list = await UserLists.findOneBy({
|
||||
userId: ctx.user.id,
|
||||
id: ctx.params.id,
|
||||
|
|
|
@ -67,7 +67,7 @@ export function setupEndpointsNotifications(router: Router): void {
|
|||
router.post(
|
||||
"/v1/conversations/:id/read",
|
||||
auth(true, ["write:conversations"]),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
await NotificationHelpers.markConversationAsRead(ctx.params.id, ctx);
|
||||
ctx.body = {};
|
||||
},
|
||||
|
|
|
@ -67,7 +67,7 @@ export function setupEndpointsTimeline(router: Router): void {
|
|||
"/v1/timelines/public",
|
||||
auth(true, ["read:statuses"]),
|
||||
filterContext("public"),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
const args = normalizeUrlQuery(argsToBools(limitToInt(ctx.query)));
|
||||
const res = await TimelineHelpers.getPublicTimeline(
|
||||
args.max_id,
|
||||
|
@ -87,7 +87,7 @@ export function setupEndpointsTimeline(router: Router): void {
|
|||
"/v1/timelines/tag/:hashtag",
|
||||
auth(false, ["read:statuses"]),
|
||||
filterContext("public"),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
const tag = (ctx.params.hashtag ?? "").trim().toLowerCase();
|
||||
const args = normalizeUrlQuery(argsToBools(limitToInt(ctx.query)), [
|
||||
"any[]",
|
||||
|
@ -116,7 +116,7 @@ export function setupEndpointsTimeline(router: Router): void {
|
|||
"/v1/timelines/home",
|
||||
auth(true, ["read:statuses"]),
|
||||
filterContext("home"),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
const args = normalizeUrlQuery(limitToInt(ctx.query));
|
||||
const res = await TimelineHelpers.getHomeTimeline(
|
||||
args.max_id,
|
||||
|
@ -133,7 +133,7 @@ export function setupEndpointsTimeline(router: Router): void {
|
|||
"/v1/timelines/list/:listId",
|
||||
auth(true, ["read:lists"]),
|
||||
filterContext("home"),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
const list = await UserLists.findOneBy({
|
||||
userId: ctx.user.id,
|
||||
id: ctx.params.listId,
|
||||
|
@ -156,7 +156,7 @@ export function setupEndpointsTimeline(router: Router): void {
|
|||
router.get(
|
||||
"/v1/conversations",
|
||||
auth(true, ["read:statuses"]),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
const args = normalizeUrlQuery(limitToInt(ctx.query));
|
||||
ctx.body = await TimelineHelpers.getConversations(
|
||||
args.max_id,
|
||||
|
@ -171,7 +171,7 @@ export function setupEndpointsTimeline(router: Router): void {
|
|||
router.get(
|
||||
"/v1/markers",
|
||||
auth(true, ["read:statuses"]),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
const args = normalizeUrlQuery(ctx.query, ["timeline[]"]);
|
||||
ctx.body = await TimelineHelpers.getMarkers(args["timeline[]"], ctx);
|
||||
},
|
||||
|
@ -180,7 +180,7 @@ export function setupEndpointsTimeline(router: Router): void {
|
|||
router.post(
|
||||
"/v1/markers",
|
||||
auth(true, ["write:statuses"]),
|
||||
async (ctx, reply) => {
|
||||
async (ctx, _reply) => {
|
||||
const body = ctx.request.body;
|
||||
ctx.body = await TimelineHelpers.setMarkers(body, ctx);
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue