diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..e5df6c88 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,64 @@ +name: Deploy on Github Pages + +on: + push: + branches: + - master + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment +concurrency: + group: "pages" + cancel-in-progress: true + +# Default to bash +defaults: + run: + shell: bash + +jobs: + build: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true # Fetch Hugo themes (true OR recursive) + fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod + + - name: Setup Pages + id: pages + uses: actions/configure-pages@v2 + + - name: Setup Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: "0.105.0" + extended: true + + - name: Build + run: hugo --minify --baseURL "${{ steps.pages.outputs.base_url }}/" + + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: ./public + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 8de94950..00000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Pages - -on: - push: - branches: - - master - -jobs: - build-deploy: - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v1 - - - name: Setup Hugo - uses: peaceiris/actions-hugo@v2 - with: - hugo-version: '0.62.1' - extended: true - - - name: Build - run: hugo --minify - - - name: Deploy - uses: easingthemes/ssh-deploy@v2.0.7 - env: - SSH_PRIVATE_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }} - ARGS: "-rltgoDzvO" - SOURCE: ./public/ - REMOTE_HOST: ${{ secrets.REMOTE_HOST }} - REMOTE_USER: ${{ secrets.REMOTE_USER }} - TARGET: ${{ secrets.REMOTE_TARGET }} diff --git a/.github/workflows/rebase-needed.yml b/.github/workflows/rebase-needed.yml new file mode 100644 index 00000000..05a1deab --- /dev/null +++ b/.github/workflows/rebase-needed.yml @@ -0,0 +1,27 @@ +name: PR Needs Rebase + +on: + schedule: + - cron: '0 * * * *' + +permissions: + pull-requests: write + +jobs: + label-rebase-needed: + runs-on: ubuntu-latest + + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + + steps: + - name: Check for merge conflicts + uses: eps1lon/actions-label-merge-conflict@releases/2.x + with: + dirtyLabel: 'rebase needed :construction:' + repoToken: '${{ secrets.GITHUB_TOKEN }}' + commentOnClean: This pull request has resolved merge conflicts and is ready for review. + commentOnDirty: This pull request has merge conflicts that must be resolved before it can be merged. + retryMax: 30 + continueOnMissingPermissions: false \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0d556621..5cab04f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ public/ static/.sass-cache resources/ +.hugo_build.lock +.vercel diff --git a/README.md b/README.md index 07de0046..53666116 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -![Mastodon](https://i.imgur.com/NhZc40l.png) -==== +
+ +The documentation currently uses Hugo to generate a static site from Markdown. View the documentation at`
+* ` `, ` :ms_rainbow_flag: :ms_bisexual_flagweb: :ms_nonbinary_flag: #awoo#admin#bi#nonbinary#games@dzuk i have approximate knowledge of many things. perpetual student. (nb/ace/they) xmpp/email: a@trwnh.com - my triggers are moths and glitter Looks like there was an issue processing audio attachments without embedded art since yesterday due to an experimental new feature. That issue has now been fixed, so you may see older posts with audio from other servers pop up in your feeds now as they are being finally properly processed. Sorry! For inquiries not related specifically to the operation of this server, such as press inquiries, please contact press@joinmastodon.org. This server is crowdfunded by Patreon donations. For a list of sponsors, see joinmastodon.org. When reporting accounts, please make sure to include at least a few posts that show rule-breaking behaviour, when applicable. If there is any additional context that might help make a decision, please also include it in the comment. This is especially important when the content is in a language nobody on the moderation team speaks. We usually handle reports within 24 hours. Please mind that you are not notified when a report you have made has led to a punitive action, and that not all punitive actions are externally visible. For first time offenses, we may opt to delete offending content, escalating to harsher measures on repeat offenses. Mastodon gGmbH E-Mail-Adresse: hello@joinmastodon.org Vertretungsberechtigt: Eugen Rochko (Geschäftsführer) Umsatzsteuer Identifikationsnummer (USt-ID): DE344258260 Handelsregister Founder, CEO and lead developer @Mastodon, Germany. Baluke Dental Studios is a full service dental lab offering fabrication, staining, and digital services. Advanced technologies and a meticulous process ensure reduced chair time, lower costs, and better patient outcomes with beautiful smiles. Talk to a representative today. cats Cats are inherently good at self-care. #cats",
- ...
-
+ // ...
+ },
+ // ...
],
"hashtags": [
{
@@ -61,8 +67,7 @@ menu:
"uses": "10",
"accounts": "9"
},
- ...
-
+ // ...
]
},
{
@@ -74,40 +79,43 @@ menu:
"uses": "6",
"accounts": "5"
},
- ...
-
+ // ...
]
}
]
}
```
-{{< /code >}}
-## Required attributes
+## Attributes
### `accounts` {#accounts}
**Description:** Accounts which match the given query\
-**Type:** Array of [Account]({{< relref "account.md" >}})\
-**Version history:** Added in x.x.x
+**Type:** Array of [Account]({{< relref "entities/Account" >}})\
+**Version history:**\
+1.1.0 - added
### `statuses` {#statuses}
**Description:** Statuses which match the given query\
-**Type:** Array of [Status]({{< relref "status.md" >}})\
-**Version history:** Added in x.x.x
+**Type:** Array of [Status]({{< relref "entities/Status" >}})\
+**Version history:**\
+1.1.0 - added
### `hashtags` {#hashtags}
**Description:** Hashtags which match the given query\
-**Type:** Array of [Tag]({{< relref "tag.md" >}}) \(v2\). Array of String \(v1\).\
-**Version history:** v1 added in 1.1.0 and deprecated in 3.0.0. v2 added in 2.4.1 and replaced v1 in 3.0.0.
+**Type:** Array of [Tag]({{< relref "entities/Tag" >}})\
+**Version history:**\
+1.1.0 - added\
+2.4.1 - v1/search deprecated because it returns Array of String. v2/search added which returns Array of Tag.\
+3.0.0 - v1 removed
## See also
-{{< page-ref page="methods/search.md" >}}
+{{< page-relref ref="methods/search" caption="search API methods" >}}
-{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/search_serializer.rb" caption="app/serializers/rest/search\_serializer.rb" >}}
+{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/serializers/rest/search_serializer.rb" caption="app/serializers/rest/search_serializer.rb" >}}
diff --git a/content/en/entities/status.md b/content/en/entities/Status.md
similarity index 52%
rename from content/en/entities/status.md
rename to content/en/entities/Status.md
index 7ae2eb0b..c603e209 100644
--- a/content/en/entities/status.md
+++ b/content/en/entities/Status.md
@@ -4,11 +4,21 @@ description: Represents a status posted by an account.
menu:
docs:
parent: entities
+aliases: [
+ "/entities/mention",
+ "/entities/Mention",
+ "/entities/status",
+ "/entities/Status",
+ "/api/entities/mention",
+ "/api/entities/Mention",
+ "/api/entities/status",
+ "/api/entities/Status",
+]
---
## Example
-```javascript
+```json
{
"id": "103270115826048975",
"created_at": "2019-12-08T03:48:33.901Z",
@@ -90,202 +100,296 @@ menu:
}
```
-## Base attributes
+## Attributes
### `id` {#id}
**Description:** ID of the status in the database.\
-**Type:** String \(cast from an integer but not guaranteed to be a number\)\
-**Version history:** Added in 0.1.0
+**Type:** String (cast from an integer but not guaranteed to be a number)\
+**Version history:**\
+0.1.0 - added
### `uri` {#uri}
**Description:** URI of the status used for federation.\
**Type:** String\
-**Version history:** Added in 0.1.0
+**Version history:**\
+0.1.0 - added
### `created_at` {#created_at}
**Description:** The date when this status was created.\
-**Type:** String \(ISO 8601 Datetime\)\
-**Version history:** Added in 0.1.0
+**Type:** String (ISO 8601 Datetime)\
+**Version history:**\
+0.1.0 - added
### `account` {#account}
**Description:** The account that authored this status.\
-**Type:** [Account]({{< relref "account.md" >}})\
-**Version history:** Added in 0.1.0
+**Type:** [Account]({{< relref "entities/Account" >}})\
+**Version history:**\
+0.1.0 - added
### `content` {#content}
**Description:** HTML-encoded status content.\
-**Type:** String \(HTML\)\
-**Version history:** Added in 0.1.0
+**Type:** String (HTML)\
+**Version history:**\
+0.1.0 - added
### `visibility` {#visibility}
**Description:** Visibility of this status.\
-**Type:** String \(Enumerable oneOf\)\
+**Type:** String (Enumerable oneOf)\
`public` = Visible to everyone, shown in public timelines.\
`unlisted` = Visible to public, but not included in public timelines.\
`private` = Visible to followers only, and to any mentioned users.\
`direct` = Visible only to mentioned users.\
-**Version history:** Added in 0.9.9
+**Version history:**\
+0.9.9 - added
### `sensitive` {#sensitive}
**Description:** Is this status marked as sensitive content?\
**Type:** Boolean\
-**Version history:** Added in 0.9.9
+**Version history:**\
+0.9.9 - added
### `spoiler_text` {#spoiler_text}
**Description:** Subject or summary line, below which status content is collapsed until expanded.\
**Type:** String\
-**Version history:** Added in 1.0.0
+**Version history:**\
+1.0.0 - added
### `media_attachments` {#media_attachments}
**Description:** Media that is attached to this status.\
-**Type:** Array of [Attachment]({{< relref "attachment.md" >}})\
-**Version history:** Added in 0.6.0
+**Type:** Array of [MediaAttachment]({{< relref "entities/MediaAttachment" >}})\
+**Version history:**\
+0.6.0 - added
-### `application` {#application}
+### `application` {{%optional%}} {#application}
**Description:** The application used to post this status.\
-**Type:** [Application]({{< relref "application.md" >}})\
-**Version history:** Added in 0.9.9
+**Type:** Hash\
+**Version history:**\
+0.9.9 - added
-## Rendering attributes
+#### `application[name]` {#application-name}
+
+**Description:** The name of the application that posted this status.\
+**Type:** String\
+**Version history:**\
+0.9.9 - added
+
+#### `application[website]` {#application-website}
+
+**Description:** The website associated with the application that posted this status.\
+**Type:** {{ this is a status that has been edited three times. this time a poll has been added. Hola mundo :ms_rainbow_flag: :ms_bisexual_flagweb: :ms_nonbinary_flag: #awoo#admin#bi#nonbinary#games@dzuk Looks like there was an issue processing audio attachments without embedded art since yesterday due to an experimental new feature. That issue has now been fixed, so you may see older posts with audio from other servers pop up in your feeds now as they are being finally properly processed. Sorry! Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff. SF reader, editor, and writer. hi im elise!! this is scribblefrog's new account she/her, 27 Justifiability is in the hands of the beholder the pirate gay a very distinctive nya systems hecker, -1x engineer, server maid, professional yak shaver 🇺🇸/🇭🇺/🏴☠️ b618ac8ac69b6ac7bae267acb1a81e cute,,, a very distinctive nya systems hecker, -1x engineer, server maid, professional yak shaver 🇺🇸/🇭🇺/🏴☠️ b618ac8ac69b6ac7bae267acb1a81e This blog is going to be about what I don't know -- what's the diff between good for me and not? I always to make reasonable choices, but I've been wrong many times. Maybe I'll get better by simply working at it slowly. "If I have the belief that I can do it, My name -- Hakogamae -- comes from the Japanese Kanji Radical 22 匚部 meaning "box." I'm in a box now. At Humblr, I was Fslowly stay at home dad, painter by commission, sidewalk farmer, editor, socialist organizer, home chef, anxiety ridden, he/him
`
+* ``
+* ``
+
+{{< page-relref ref="spec/activitypub#sanitization" caption="ActivityPub > HTML Sanitization" >}}
+
+### Mentions, hashtags, and custom emoji {#tags}
+
+Mentions and hashtags are `` tags. Custom emoji remain in their plain text shortcode form. To give those entities their semantic meaning and add special handling, such as opening a mentioned profile within your app instead of as a web page, metadata is included with the [Status]({{< relref "entities/Status" >}}), which can be matched to a particular tag.
+
+{{< page-relref ref="entities/Status" caption="Status entity" >}}
+
+{{< page-relref ref="entities/Status#mentions" caption="Status#mentions" >}}
+
+{{< page-relref ref="entities/Status#tags" caption="Status#tags" >}}
+
+{{< page-relref ref="entities/Status#emojis" caption="Status#emojis" >}}
+
+### Link shortening {#links}
+
+Links in Mastodon are not shortened using URL shorteners, and the usage of URL shorteners is heavily discouraged. URLs in text always count for 23 characters, and are intended to be shortened visually. For that purpose, a link is marked up like this:
+
+```html
+
+ https://
+ example.com/page
+ /that/is/very/long
+
+```
+
+The spans with the `invisible` class can be hidden. The middle span is intended to remain visible. It may have no class if the URL is not very long; otherwise it will have an `ellipsis` class. No ellipsis (`…`) character is inserted in the markup; instead, you are expected to insert it yourself if you need it in your app.
+
+## Filters {#filters}
+
+### Server-side filtering (v2, Mastodon 4.0 and above) {#server-filtered}
+
+If a filter applies to a Status, a corresponding FilterResult will be included in the `filtered` attribute. Clients should check this attribute for any matches and use them to apply the intended filter action.
+
+However, client implementations may still want to perform their own rule matching client-side, as this would allow retroactively apply filter changes without re-fetching posts from the server. When doing so, they should take care to not ignore `filtered` entries for which there are other attributes than `keyword_matches`, so as to handle extensions of the filtering system (e.g. `status_matches`).
+
+Matched filters need to be filtered based on context (`home`, `notifications`, `public`, `thread` or `profile`) and expiration date.
+
+When at least one active matched filter has `hide` for `filter_action`, the post should not be shown at all. Otherwise, if at least one active matched filter has `warn` for `filter_action`, the post should be hidden with a warning, and the user should be able to reveal the post after being informed of which filters matched (identified by `title` rather than the exact matched keywords).
+
+For extension purposes, unknown values for `filter_action` should be treated as `warn`.
+
+### Client-side filtering (v1, prior to Mastodon 4.0) {#client-filtered}
+
+Clients must do their own text filtering based on filters returned from the API. The server will apply `irreversible` filters for `home` and `notifications` contexts, but **anything else is still up to the client to filter**! If a status is somehow not removed by an `irreversible` filter, the client should still filter it.
+
+Expired filters are not deleted by the server. They should no longer be applied, but they are still stored by the server, as users may update the expiry time to re-enable the filter. It is up to users to delete those filters eventually, if they wish to do so.
+
+If `whole_word` is true, the client app should do the following:
+
+* Define ‘word constituent characters’ for your app. In the official implementation, it’s `[A-Za-z0-9_]` in JavaScript, and `[[:word:]]` in Ruby. Ruby uses the POSIX character class (Letter | Mark | Decimal_Number | Connector_Punctuation).
+* If the phrase starts with a word character, and if the previous character before matched range is a word character, its matched range should be treated to not match.
+* If the phrase ends with a word character, and if the next character after matched range is a word character, its matched range should be treated to not match.
+
+Please check `app/javascript/mastodon/selectors/index.js` and `app/lib/feed_manager.rb` in the Mastodon source code for more details.
+
+{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/javascript/mastodon/selectors/index.js" caption="app/javascript/mastodon/selectors/index.js" >}}
+
+{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/app/lib/feed_manager.rb" caption="app/lib/feed_manager.rb" >}}
+
+## Focal points for cropping media thumbnails {#focal-points}
+
+Server-side preview images are never cropped, to support a variety of apps and user interfaces. Therefore, the cropping must be done by those apps. To crop intelligently, focal points can be used to ensure a certain section of the image is always within the cropped viewport. See this [guide on how focal points are defined](https://github.com/jonom/jquery-focuspoint#1-calculate-your-images-focus-point). In summary, floating points range from -1.0 to 1.0, left-to-right or bottom-to-top. (0,0) is the center of the image. (0.5, 0.5) would be in the center of the upper-right quadrant. (-0.5, -0.5) would be in the center of the lower-left quadrant. For reference, thumbnails in the Mastodon frontend are most commonly 16:9.
+
+{{< figure src="assets/focal-points.jpg" caption="A demonstration of various focal points and their coordinates." >}}
diff --git a/content/en/api/oauth-scopes.md b/content/en/api/oauth-scopes.md
index d14d1697..b42beddf 100644
--- a/content/en/api/oauth-scopes.md
+++ b/content/en/api/oauth-scopes.md
@@ -3,7 +3,7 @@ title: OAuth Scopes
description: Defining what you have permission to do with the API
menu:
docs:
- weight: 10
+ weight: 20
parent: api
---
@@ -11,7 +11,7 @@ menu:
The API is divided up into access scopes. The scopes are hierarchical, i.e. if you have access to `read`, you automatically have access to `read:accounts`. **It is recommended that you request as little as possible for your application.**
-Multiple scopes can be requested at the same time: During app creation with the `scopes` param, and during the authorization phase with the `scope` query param \(space-separate the scopes\).
+Multiple scopes can be requested at the same time: During app creation with the `scopes` param, and during the authorization phase with the `scope` query param (space-separate the scopes).
{{< hint style="info" >}}
Mind the `scope` vs `scopes` difference. This is because `scope` is a standard OAuth parameter name, so it is used in the OAuth methods. Mastodon’s own REST API uses the more appropriate `scopes`.
@@ -25,11 +25,12 @@ The set of scopes saved during app creation must include all the scopes that you
- 0.9.0 - read, write, follow
- 2.4.0 - push
-- 2.4.3 - granular scopes [https://github.com/tootsuite/mastodon/pull/7929](https://github.com/tootsuite/mastodon/pull/7929)
-- 2.6.0 - read:reports deprecated \(unused stub\) [https://github.com/tootsuite/mastodon/pull/8736/commits/adcf23f1d00c8ff6877ca2ee2af258f326ae4e1f](https://github.com/tootsuite/mastodon/pull/8736/commits/adcf23f1d00c8ff6877ca2ee2af258f326ae4e1f)
-- 2.6.0 - write:conversations added [https://github.com/tootsuite/mastodon/pull/9009](https://github.com/tootsuite/mastodon/pull/9009)
-- 2.9.1 - Admin scopes added [https://github.com/tootsuite/mastodon/pull/9387](https://github.com/tootsuite/mastodon/pull/9387)
-- 3.1.0 - Bookmark scopes added
+- 2.4.3 - granular scopes [#7929](https://github.com/mastodon/mastodon/pull/7929)
+- 2.6.0 - read:reports deprecated (unused stub) [#8736/adcf23f](https://github.com/mastodon/mastodon/pull/8736/commits/adcf23f1d00c8ff6877ca2ee2af258f326ae4e1f)
+- 2.6.0 - write:conversations added [#9009](https://github.com/mastodon/mastodon/pull/9009)
+- 2.9.1 - Admin scopes added [#9387](https://github.com/mastodon/mastodon/pull/9387)
+- 3.1.0 - Bookmark scopes added [#7107](https://github.com/mastodon/mastodon/pull/7107)
+- 4.1.0 - Added admin scopes for blocks and allows [#20918](https://github.com/mastodon/mastodon/pull/20918)
## List of scopes
@@ -37,12 +38,45 @@ The set of scopes saved during app creation must include all the scopes that you
Grants access to read data. Requesting `read` will also grant child scopes shown in the left column of the table below.
+* `read`
+ * `read:accounts`
+ * `read:blocks`
+ * `read:bookmarks`
+ * `read:favourites`
+ * `read:filters`
+ * `read:follows`
+ * `read:lists`
+ * `read:mutes`
+ * `read:notifications`
+ * `read:search`
+ * `read:statuses`
+
### `write` {#write}
Grants access to write data. Requesting `write` will also grant child scopes shown in the right column of the table below.
+* `write`
+ * `write:accounts`
+ * `write:blocks`
+ * `write:bookmarks`
+ * `write:conversations`
+ * `write:favourites`
+ * `write:filters`
+ * `write:follows`
+ * `write:lists`
+ * `write:media`
+ * `write:mutes`
+ * `write:notifications`
+ * `write:reports`
+ * `write:statuses`
+
### `follow` {#follow}
+{{< hint style="danger" >}}
+**Deprecated**\
+This scope has been deprecated in 3.5.0 and newer. You should instead request the child scopes individually, or request read/write permission as needed.
+{{< /hint >}}
+
Grants access to manage relationships. Requesting `follow` will also grant the following child scopes, shown in bold in the table:
* `read:blocks`, `write:blocks`
@@ -51,18 +85,28 @@ Grants access to manage relationships. Requesting `follow` will also grant the f
### `push` {#push}
-Grants access to [Web Push API subscriptions.]({{< relref "../methods/notifications/push.md" >}}) Added in Mastodon 2.4.0.
+Grants access to [Web Push API subscriptions.]({{< relref "methods/push" >}}) Added in Mastodon 2.4.0.
### Admin scopes {#admin}
-Used for moderation API. Added in Mastodon 2.9.1. The following granular scopes are available \(note that there is no singular `admin` scope\):
+Used for moderation API. Added in Mastodon 2.9.1. The following granular scopes are available (note that there is no singular `admin` scope):
* `admin:read`
* `admin:read:accounts`
* `admin:read:reports`
+ * `admin:read:domain_allows`
+ * `admin:read:domain_blocks`
+ * `admin:read:ip_blocks`
+ * `admin:read:email_domain_blocks`
+ * `admin:read:canonical_email_blocks`
* `admin:write`
* `admin:write:accounts`
* `admin:write:reports`
+ * `admin:write:domain_allows`
+ * `admin:write:domain_blocks`
+ * `admin:write:ip_blocks`
+ * `admin:write:email_domain_blocks`
+ * `admin:write:canonical_email_blocks`
## Granular scopes {#granular}
@@ -87,4 +131,8 @@ Used for moderation API. Added in Mastodon 2.9.1. The following granular scopes
| :--- | :--- |
| admin:read:accounts | admin:write:accounts |
| admin:read:reports | admin:write:reports |
-
+| admin:read:domain_allows | admin:write:domain_allows |
+| admin:read:domain_blocks | admin:write:domain_blocks |
+| admin:read:ip_blocks | admin:write:ip_blocks |
+| admin:read:email_domain_blocks | admin:write:email_domain_blocks |
+| admin:read:canonical_email_blocks | admin:write:canonical_email_blocks |
\ No newline at end of file
diff --git a/content/en/api/rate-limits.md b/content/en/api/rate-limits.md
index a983c2d7..81ee404f 100644
--- a/content/en/api/rate-limits.md
+++ b/content/en/api/rate-limits.md
@@ -1,31 +1,49 @@
---
title: Rate limits
-description: Defining how often you can hit the REST API
+description: Defining how often you can call the REST API
menu:
docs:
- weight: 20
+ weight: 30
parent: api
---
+## Headers
+
Rate limit information is returned in the response headers:
-|Header|Description|
-| :--- | :--- |
-|`X-RateLimit-Limit`|Number of requests permitted per time period|
-|`X-RateLimit-Remaining`|Number of requests you can still make|
-|`X-RateLimit-Reset`|Timestamp when your rate limit will reset|
+`X-RateLimit-Limit`
+: Number of requests permitted per time period
+
+`X-RateLimit-Remaining`
+: Number of requests you can still make
+
+`X-RateLimit-Reset`
+: Timestamp when your rate limit will reset
{{< hint style="info" >}}
-Mind that an API method can be subject to multiple overlapping rate limits. The headers return information about the one you are closest to exceeding.
+An API method can be subject to multiple overlapping rate limits. The headers return information about the one you are closest to exceeding.
{{ hint >}}
-Here is a list of various rate limits:
+## Limits
-|Endpoint|Bucket|Time period|Limit|Limit type|
-| :--- | :--- | :--- | :--- | :--- |
-|`* /api/*`|Account access|5 minutes|300|Account|
-|`* /api/*`|IP access|5 minutes|300|IP|
-|`POST /api/v1/accounts`|App sign-up|30 minutes|5|IP|
-|`POST /api/v1/media`|Uploading|30 minutes|30|Account|
-|`DELETE /api/v1/statuses/:id`|Deletion|30 minutes|30|Account|
-|`POST /api/v1/statuses/:id/unreblog`|Deletion|30 minutes|30|Account|
+By default, the following limits are hardcoded:
+
+### Per account
+
+All endpoints and methods can be called 300 times within 5 minutes.
+
+#### Uploading media
+
+`POST /api/v1/media` can be called 30 times within 30 minutes.
+
+#### Deleting statuses
+
+Either `DELETE /api/v1/statuses/:id` or `POST /api/v1/statuses/:id/unreblog` can be called 30 times within 30 minutes.
+
+### Per IP
+
+All endpoints and methods can be called 300 times within 5 minutes.
+
+#### Creating accounts
+
+`POST /api/v1/accounts` can be called 5 times within 30 minutes.
diff --git a/content/en/client/authorized.md b/content/en/client/authorized.md
index 7c3b4f3c..b4ec71e0 100644
--- a/content/en/client/authorized.md
+++ b/content/en/client/authorized.md
@@ -11,7 +11,7 @@ menu:
When we registered our app and when we will authorize our user, we need to define what exactly our generated token will have permission to do. This is done through the use of OAuth scopes. Each API method has an associated scope, and can only be called if the token being used for authorization has been generated with the corresponding scope.
-Scopes must be a subset. When we created our app, we specified `read write follow push` -- we could simply request all available scopes by specifying `read write follow push`, but it is a better idea to only request what your app will actually need through granular scopes. See [OAuth Scopes]({{< relref "../api/oauth-scopes.md" >}}) for a full list of scopes. Each API method's documentation will also specify the OAuth access level and scope required to call it.
+Scopes must be a subset. When we created our app, we specified `read write push` -- we could request all available scopes by specifying `read write push`, but it is a better idea to only request what your app will actually need through granular scopes. See [OAuth Scopes]({{< relref "api/oauth-scopes" >}}) for a full list of scopes. Each API method's documentation will also specify the OAuth access level and scope required to call it.
## **Example authorization code flow** {#flow}
@@ -19,29 +19,29 @@ This is similar to the authentication flow from before, but this time, we need t
### Client ID and secret {#client}
-First, if you have not already registered a client application, then see [Creating our application]({{< relref "token.md#creating-our-application" >}}) on the previous page or go directly to [POST /api/v1/apps]({{< relref "../methods/apps.md#create-an-application" >}}) for the full documentation of that method. We will need the `client_id` and `client_secret` for our application.
+First, if you have not already registered a client application, then see [Creating our application]({{< relref "client/token#creating-our-application" >}}) on the previous page or go directly to [POST /api/v1/apps]({{< relref "methods/apps#create" >}}) for the full documentation of that method. We will need the `client_id` and `client_secret` for our application.
### Authorize the user {#login}
-To authorize a user, request [GET /oauth/authorize]({{< relref "../methods/apps/oauth.md#authorize-a-user" >}}) in a browser with the following query parameters:
+To authorize a user, request [GET /oauth/authorize]({{< relref "methods/oauth#authorize" >}}) in a browser with the following query parameters:
```bash
https://mastodon.example/oauth/authorize
?client_id=CLIENT_ID
-&scope=read+write+follow+push
+&scope=read+write+push
&redirect_uri=urn:ietf:wg:oauth:2.0:oob
&response_type=code
```
Note the following:
-* `client_id` and `client_secret` were obtained when registering our application.
-* `scope` must be a subset of our registered app's registered scopes. It is a good idea to only request what you need. See [OAuth Scopes]({{< relref "../api/oauth-scopes.md" >}}) for more information.
+* `client_id` was obtained when registering our application.
+* `scope` must be a subset of our registered app's registered scopes. It is a good idea to only request what you need. See [OAuth Scopes]({{< relref "api/oauth-scopes" >}}) for more information.
* `redirect_uri` is one of the URIs we registered with our app. We are still using "out of band" for this example, which means we will have to manually copy and paste the resulting code, but if you registered your application with a URI that you control, then the code will be returned as a query parameter `code` and can be logged by your request handler. See the response section of the API method documentation for more information on this.
### Obtain the token {#token}
-Now that we have an authorization `code`, let's obtain an access token that will authenticate our requests as the authorized user. To do so, use [POST /oauth/token]({{< relref "../methods/apps/oauth.md#obtain-a-token" >}}) like before, but pass the authorization code we just obtained:
+Now that we have an authorization `code`, let's obtain an access token that will authenticate our requests as the authorized user. To do so, use [POST /oauth/token]({{< relref "methods/oauth#token" >}}) like before, but pass the authorization code we just obtained:
```bash
curl -X POST \
@@ -50,7 +50,7 @@ curl -X POST \
-F 'redirect_uri=urn:ietf:wg:oauth:2.0:oob' \
-F 'grant_type=authorization_code' \
-F 'code=user_authzcode_here' \
- -F 'scope=read write follow push' \
+ -F 'scope=read write push' \
https://mastodon.example/oauth/token
```
@@ -59,9 +59,9 @@ Note the following:
* `client_id` and `client_secret` were provided in the response text when you registered your application.
* `redirect_uri` must be one of the URIs defined when registering the application.
* We are requesting a `grant_type` of `authorization_code`, which still defaults to giving us the `read` scope. However, while authorizing our user, we requested a certain `scope` -- pass the exact same value here.
-* The `code` can only be used once. If you need to obtain a new token, you will need to have the user authorize again by repeating the above [Authorize the user]({{< relref "authorized.md#authorize-the-user" >}}) step.
+* The `code` can only be used once. If you need to obtain a new token, you will need to have the user authorize again by repeating the above [Authorize the user]({{< relref "client/authorized#authorize-the-user" >}}) step.
-The response of this method is a [Token]({{< relref "../entities/token.md" >}}) entity. We will need the `access_token` value. Once you have the access token, save it in your local cache. To use it in requests, add the HTTP header `Authorization: Bearer ...` to any API call that requires OAuth \(i.e., one that is not publicly accessible\). Let's verify that our obtained credentials are working by calling [GET /api/v1/accounts/verify\_credentials]({{< relref "../methods/accounts/#verify-account-credentials" >}}):
+The response of this method is a [Token]({{< relref "entities/token" >}}) entity. We will need the `access_token` value. Once you have the access token, save it in your local cache. To use it in requests, add the HTTP header `Authorization: Bearer ...` to any API call that requires OAuth (i.e., one that is not publicly accessible). Let's verify that our obtained credentials are working by calling [GET /api/v1/accounts/verify_credentials]({{< relref "methods/accounts#verify_credentials" >}}):
```bash
curl \
@@ -69,7 +69,7 @@ curl \
https://mastodon.example/api/v1/accounts/verify_credentials
```
-If we've obtained our token and formatted our request correctly, we should see our details returned to us as an [Account]({{< relref "../entities/account.md" >}}) entity, with the `source` parameter included.
+If we've obtained our token and formatted our request correctly, we should see our details returned to us as an [Account]({{< relref "entities/account" >}}) entity, with the `source` parameter included.
## Performing actions as the authorized user {#actions}
@@ -77,48 +77,48 @@ With our OAuth token for the authorized user, we can now perform any action as t
### Publish and delete statuses {#statuses}
-* See [POST /api/v1/statuses]({{< relref "../methods/statuses/#publish-new-status" >}}) for how to create statuses.
- * See [/api/v1/media]({{< relref "../methods/statuses/media.md" >}}) for creating media attachments.
- * See [/api/v1/scheduled\_statuses]({{< relref "../methods/statuses/scheduled_statuses.md" >}}) for managing scheduled statuses.
+* See [POST /api/v1/statuses]({{< relref "methods/statuses#create" >}}) for how to create statuses.
+ * See [/api/v1/media]({{< relref "methods/media" >}}) for creating media attachments.
+ * See [/api/v1/scheduled_statuses]({{< relref "methods/scheduled_statuses" >}}) for managing scheduled statuses.
### Interact with timelines {#timelines}
-* See [/api/v1/timelines]({{< relref "../methods/timelines/" >}}) for accessing timelines.
-* See [/api/v1/markers]({{< relref "../methods/timelines/markers.md" >}}) for saving and loading positions in timelines.
-* See [/api/v1/statuses]({{< relref "../methods/statuses/" >}}) for performing actions on statuses.
- * See [/api/v1/polls]({{< relref "../methods/statuses/polls.md" >}}) for viewing and voting on polls.
-* See [/api/v1/lists]({{< relref "../methods/timelines/lists.md" >}}) for obtaining list IDs to use with [GET /api/v1/timelines/list/:list\_id]({{< relref "../methods/timelines/#list-timeline" >}}).
-* See [/api/v1/conversations]({{< relref "../methods/timelines/conversations.md" >}}) for obtaining direct conversations.
-* See [/api/v1/favourites]({{< relref "../methods/accounts/favourites.md" >}}) for listing favourites.
-* See [/api/v1/bookmarks]({{< relref "../methods/accounts/bookmarks.md" >}}) for listing bookmarks.
+* See [/api/v1/timelines]({{< relref "methods/timelines" >}}) for accessing timelines.
+* See [/api/v1/markers]({{< relref "methods/markers" >}}) for saving and loading positions in timelines.
+* See [/api/v1/statuses]({{< relref "methods/statuses" >}}) for performing actions on statuses.
+ * See [/api/v1/polls]({{< relref "methods/polls" >}}) for viewing and voting on polls.
+* See [/api/v1/lists]({{< relref "methods/lists" >}}) for obtaining list IDs to use with [GET /api/v1/timelines/list/:list_id]({{< relref "methods/timelines#list" >}}).
+* See [/api/v1/conversations]({{< relref "methods/conversations" >}}) for obtaining direct conversations.
+* See [/api/v1/favourites]({{< relref "methods/favourites" >}}) for listing favourites.
+* See [/api/v1/bookmarks]({{< relref "methods/bookmarks" >}}) for listing bookmarks.
### Interact with other users {#accounts}
-* See [/api/v1/accounts]({{< relref "../methods/accounts/" >}}) for performing actions on other users.
-* See [/api/v1/follow\_requests]({{< relref "../methods/accounts/follow_requests.md" >}}) for handling follow requests.
-* See [/api/v1/mutes]({{< relref "../methods/accounts/mutes.md" >}}) for listing mutes.
-* See [/api/v1/blocks]({{< relref "../methods/accounts/blocks.md" >}}) for listing blocks.
+* See [/api/v1/accounts]({{< relref "methods/accounts" >}}) for performing actions on other users.
+* See [/api/v1/follow_requests]({{< relref "methods/follow_requests" >}}) for handling follow requests.
+* See [/api/v1/mutes]({{< relref "methods/mutes" >}}) for listing mutes.
+* See [/api/v1/blocks]({{< relref "methods/blocks" >}}) for listing blocks.
### Receive notifications {#notifications}
-* See [/api/v1/notifications]({{< relref "../methods/notifications/" >}}) for managing a user's notifications.
-* See [/api/v1/push]({{< relref "../methods/notifications/push.md" >}}) for subscribing to push notifications.
+* See [/api/v1/notifications]({{< relref "methods/notifications" >}}) for managing a user's notifications.
+* See [/api/v1/push]({{< relref "methods/push" >}}) for subscribing to push notifications.
### Discovery features {#discovery}
-* See [/api/v2/search]({{< relref "../methods/search.md" >}}) for querying resources.
-* See [/api/v1/suggestions]({{< relref "../methods/accounts/suggestions.md" >}}) for suggested accounts to follow.
+* See [/api/v2/search]({{< relref "methods/search#v2" >}}) for querying resources.
+* See [/api/v1/suggestions]({{< relref "methods/suggestions" >}}) for suggested accounts to follow.
-### Use safety features {#safety}
+### User safety features {#safety}
-* See [/api/v1/filters]({{< relref "../methods/accounts/filters.md" >}}) for managing filtered keywords.
-* See [/api/v1/domain\_blocks]({{< relref "../methods/accounts/domain_blocks.md" >}}) for managing blocked domains.
-* See [/api/v1/reports]({{< relref "../methods/accounts/reports.md" >}}) for creating reports.
-* See [/api/v1/admin]({{< relref "../methods/admin.md" >}}) for moderator actions.
+* See [/api/v1/filters]({{< relref "methods/filters" >}}) for managing filtered keywords.
+* See [/api/v1/domain_blocks]({{< relref "methods/domain_blocks" >}}) for managing blocked domains.
+* See [/api/v1/reports]({{< relref "methods/reports" >}}) for creating reports.
+* See [/api/v1/admin]({{< relref "methods/admin" >}}) for moderator actions.
### Manage account info {#manage}
-* See [/api/v1/endorsements]({{< relref "../methods/accounts/endorsements.md" >}}) for managing a user profile's featured accounts.
-* See [/api/v1/featured\_tags]({{< relref "../methods/accounts/featured_tags.md" >}}) for managing a user profile's featured hashtags.
-* See [/api/v1/preferences]({{< relref "../methods/accounts/preferences.md" >}}) for reading user preferences.
+* See [/api/v1/endorsements]({{< relref "methods/endorsements" >}}) for managing a user profile's featured accounts.
+* See [/api/v1/featured_tags]({{< relref "methods/featured_tags" >}}) for managing a user profile's featured hashtags.
+* See [/api/v1/preferences]({{< relref "methods/preferences" >}}) for reading user preferences.
diff --git a/content/en/client/guidelines.md b/content/en/client/guidelines.md
deleted file mode 100644
index 84e06c38..00000000
--- a/content/en/client/guidelines.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: Guidelines and best practices
-description: Things to keep in mind when implementing a Mastodon app.
-menu:
- docs:
- weight: 50
- parent: client
----
-
-## Login {#login}
-
-**The user must be able to login to any Mastodon server from the app**. This means you must ask for the server's domain and use the app registrations API to dynamically obtain OAuth2 credentials.
-
-## Usernames {#username}
-
-**Decentralization must be transparent to the user**. It should be possible to see that a given user is from another server, by e.g. displaying their `acct` somewhere. Note that `acct` is equal to username for local users, and equal to username@domain for remote users.
-
-## Handling and sorting IDs {#id}
-
-Vanilla Mastodon entity IDs are generated as integers and cast to string. However, this does not mean that IDs _are_ integers, nor should they be cast to integer! Doing so can lead to broken client apps due to integer overflow, so **always treat IDs as strings.**
-
-With that said, because IDs are string representations of numbers, they can still be sorted chronologically very easily by doing the following:
-
-1. Sort by size. Newer statuses will have longer IDs.
-2. Sort lexically. Newer statuses will have at least one digit that is higher when compared positionally.
-
-## Formatting {#formatting}
-
-Plain text is not available for content from remote servers, and plain text syntax rules may vary wildly between Mastodon and other fediverse applications. For certain attributes, such as the content of statuses, **Mastodon provides sanitized HTML**. You may expect these tags to appear in the content: `
`, ``, ``. See [HTML Sanitization]({{< relref "../spec/activitypub.md#html-sanitization" >}}) for more details.
-
-### Mentions, hashtags, and custom emoji {#tags}
-
-Mentions and hashtags are `` tags. Custom emoji remain in their plain text shortcode form. To give those entities their semantic meaning and add special handling, such as opening a mentioned profile within your app instead of as a web page, metadata is included with the [Status]({{< relref "../entities/status.md" >}}), which can be matched to a particular tag. See [Status > Rendering attributes]({{< relref "../entities/status.md#rendering-attributes" >}}) for more information.
-
-### Link shortening {#links}
-
-Links in Mastodon are not shortened using URL shorteners, and the usage of URL shorteners is heavily discouraged. URLs in text always count for 23 characters, and are intended to be shortened visually. For that purpose, a link is marked up like this:
-
-```markup
-
- https://
- example.com/page
- /that/is/very/long
-
-```
-
-The spans with the `invisible` class can be hidden. The middle span is intended to remain visible. It may have no class if the URL is not very long, otherwise it will have an `ellipsis` class. No ellipsis \(`…`\) character is inserted in the markup, instead, you are expected to insert it yourself if you need it in your app.
-
-## Filters {#filters}
-
-Clients must do their own text filtering based on filters returned from the API. The server will apply `irreversible` filters for home and notifications context, but anything else is still up to the client to filter!
-
-Expired filters are not deleted by the server. They should no longer be applied but they are still stored by the server, as users may update the expiry time to re-enable the filter. It is up to users to delete those filters eventually.
-
diff --git a/content/en/client/intro.md b/content/en/client/intro.md
index 8060da79..2f14aad2 100644
--- a/content/en/client/intro.md
+++ b/content/en/client/intro.md
@@ -20,7 +20,7 @@ REST API endpoints can be called with certain HTTP methods, and more than one me
* **PUT** \| **PATCH**: Update a resource.
* **DELETE**: Removes a resource.
-Your favorite programming language probably has a utility or library to make HTTP requests. For the purposes of this section, the cURL utility will be used for examples, which is a command-line utility included with many operating systems by default \(as `curl`\).
+Your favorite programming language probably has a utility or library to make HTTP requests. For the purposes of this section, the cURL utility will be used for examples, which is a command-line utility included with many operating systems by default (as `curl`).
With cURL, the default HTTP method is GET, but you can specify the type of request to make by using the `--request` or `-X` flag; for example, `curl -X POST` will send a POST request instead of a GET request. You may also want to use the `-i` flag to include additional HTTP headers that may be returned as part of the response where relevant.
@@ -34,7 +34,7 @@ Query strings, form data, and JSON submitted via POST body are equally understoo
### Query strings {#query-strings}
-Simply request the URL, but append query strings to the end. Query strings can be appended by first typing ? and then appending them in the form of parameter=value. Multiple query strings can be appended by separating them with &. For example:
+Request the URL, but append query strings to the end. Query strings can be appended by first typing ? and then appending them in the form of parameter=value. Multiple query strings can be appended by separating them with &. For example:
```bash
curl https://mastodon.example/endpoint?q=test&n=0
@@ -64,6 +64,8 @@ curl -X POST \
### JSON {#json}
+*JavaScript Object Notation* as defined in ECMA-404. Quick one page overview: https://www.json.org/
+
Similar to sending form data, but with an additional header to specify that the data is in JSON format. To send a JSON request with cURL, specify the JSON content type with a header, then send the JSON data as form data:
```bash
@@ -75,7 +77,7 @@ curl -X POST \
## Data types {#types}
-### Multiple values \(Array\) {#array}
+### Multiple values (Array) {#array}
An array parameter must encoded using bracket notation, e.g. `array[]=foo&array[]=bar` would be translated into the following:
@@ -88,13 +90,13 @@ array = [
As JSON, arrays are formatted like so:
-```javascript
+```json
{
"array": ["foo", "bar"]
}
```
-### Nested parameters \(Hash\) {#hash}
+### Nested parameters (Hash) {#hash}
Some parameters need to be nested. For that, bracket notation must also be used. For example, `source[privacy]=public&source[language]=en` would be translated into:
@@ -107,7 +109,7 @@ source = {
As JSON, hashes are formatted like so:
-```javascript
+```json
{
"source": {
"privacy": "public",
@@ -116,7 +118,7 @@ As JSON, hashes are formatted like so:
}
```
-### True-or-false \(Booleans\) {#boolean}
+### True-or-false (Booleans) {#boolean}
A boolean value is considered false for the values `0`, `f`, `F`, `false`, `FALSE`, `off`, `OFF`, considered to not be provided for empty strings, and considered to be true for all other values. When using JSON data, use the literals `true`, `false`, and `null` instead.
diff --git a/content/en/client/libraries.md b/content/en/client/libraries.md
index d858b738..7fc3f124 100644
--- a/content/en/client/libraries.md
+++ b/content/en/client/libraries.md
@@ -1,18 +1,22 @@
---
title: Libraries and implementations
-description: Interface with the Mastodon API in the programming language of your choice.
+description: Code, libraries and SDKs for the Mastodon API in a range of programming languages.
menu:
docs:
weight: 60
parent: client
---
-## Apex \(Salesforce\) {#apex-salesforce}
+Thank you to our awesome developer community, for supporting the project with a wide range of implementations of the API. If you have built a library or SDK for the Mastodon API, [let us know](https://github.com/mastodon/mastodon/discussions) about it, and it may be included below in a future update.
-* [apex-mastodon](https://github.com/tzmfreedom/apex-mastodon)
+Remember to check how recently the library was updated, and whether it includes the API features you may want to use.
-## C\# \(.NET Standard\) {#c-net-standard}
+## Arduino / ESP32 / IoT {#arduino-iot}
+* [lyuba](https://github.com/ringtailsoftware/lyuba)
+## C# (.NET Standard) {#c-net-standard}
+
+* [MastodonAPI](https://github.com/golf1052/MastodonAPI)
* [Mastodot](https://github.com/yamachu/Mastodot)
* [Mastonet](https://github.com/glacasa/Mastonet)
* [TootNet](https://github.com/cucmberium/TootNet)
@@ -23,26 +27,35 @@ menu:
* [mastodonpp](https://schlomp.space/tastytea/mastodonpp)
-## Crystal {#crystal}
-
-* [mastodon.cr](https://github.com/decors/mastodon.cr)
-
## Common Lisp {#common-lisp}
+* [mastodon-cl](https://github.com/compufox/mastodon-cl)
* [tooter](https://github.com/Shinmera/tooter)
+## Crystal {#crystal}
+
+* [mastodon-api-crystal](https://github.com/renatolond/mastodon-api-crystal)
+
## Dart
-* [mastodon_dart](https://pub.dev/packages/mastodon_dart)
+* [mastodon-api](https://github.com/mastodon-dart/mastodon-api)
+* [mastodon-oauth](https://github.com/mastodon-dart/mastodon-oauth2)
+* [mastodon](https://github.com/mykdavies/Mastodon)
+* [dartodon](https://github.com/darkcl/dartodon)
## Elixir {#elixir}
* [hunter](https://github.com/milmazz/hunter)
+## Erlang {#erlang}
+
+* [masterldon](https://github.com/igb/masterldon)
+
## Go {#go}
* [go-mastodon](https://github.com/mattn/go-mastodon)
* [madon](https://github.com/McKael/madon)
+* [go-mastodon-api](https://github.com/aaronland/go-mastodon-api)
## Haskell {#haskell}
@@ -50,59 +63,96 @@ menu:
## Java {#java}
-* [mastodon4j](https://github.com/sys1yagi/mastodon4j)
+* [BigBone](https://github.com/andregasser/bigbone)
+* [Mastodon4J](https://github.com/Mastodon4J/Mastodon4J)
+* [mastodon-jfx](https://github.com/wakingrufus/mastodon-jfx)
## JavaScript {#javascript}
+* [megalodon](https://github.com/h3poteto/megalodon)
* [masto.js](https://github.com/neet/masto.js)
* [libodonjs](https://github.com/Zatnosk/libodonjs)
-## JavaScript \(Browser\) {#javascript-browser}
+## JavaScript (Browser) {#javascript-browser}
* [mastodon.js](https://github.com/Kirschn/mastodon.js)
-## JavaScript \(Node.js\) {#javascript-node-js}
+## JavaScript (Node.js) {#javascript-node-js}
-* [node-mastodon](https://github.com/jessicahayley/node-mastodon)
* [mastodon-api](https://github.com/vanita5/mastodon-api)
+## Kotlin {#kotlin}
+
+* [BigBone](https://github.com/andregasser/bigbone)
+* [mastodonk](https://github.com/outadoc/mastodonk)
+
+## Nim {#nim}
+
+* [Mastonim](https://github.com/matrix07012/Mastonim)
+
+## Objective-C {#objective-c}
+
+* [Cocotodon](https://github.com/shibafu528/Cocotodon)
+
## Perl {#perl}
* [Mastodon::Client](https://metacpan.org/pod/Mastodon::Client)
## PHP {#php}
-* [Mastodon API for Laravel](https://github.com/kawax/laravel-mastodon-api)
-* [Mastodon-api-php](https://github.com/yks118/Mastodon-api-php)
-* [Composer based php API wrapper](https://github.com/r-daneelolivaw/mastodon-api-php)
-* [MastodonOAuthPHP](https://github.com/TheCodingCompany/MastodonOAuthPHP)
+* [mastodon-api-client](https://github.com/vazaha-nl/mastodon-api-client)
* [Phediverse Mastodon REST Client](https://github.com/phediverse/mastodon-rest)
* [TootoPHP](https://framagit.org/MaxKoder/TootoPHP)
* [oauth2-mastodon](https://github.com/lrf141/oauth2-mastodon)
-* [Mastodon Wordpress API](https://github.com/L1am0/mastodon_wordpress_api)
+* [MastodonBotPHP](https://github.com/Eleirbag89/MastodonBotPHP)
+* [mastodon-api-php-oauth](https://github.com/yks118/Mastodon-api-php-oauth)
+* [mastodon-api-php](https://github.com/colorfield/mastodon-api-php)
+* [Mastodon API for Laravel](https://github.com/kawax/laravel-mastodon-api)
+* [Mastodon for Drupal](https://www.drupal.org/project/mastodon)
+* [Mastodon for Socialite](https://github.com/kawax/socialite-mastodon)
+
+## PowerShell {#powershell}
+
+* [Mastodon](https://github.com/JB405/Mastodon)
## Python {#python}
* [Mastodon.py](https://github.com/halcy/Mastodon.py)
+* [mastopy](https://gitlab.com/spla/mastopy)
## R {#r}
* [mastodon](https://github.com/ThomasChln/mastodon)
+* [rtoot](https://github.com/schochastics/rtoot)
## Ruby {#ruby}
-* [mastodon-api](https://github.com/tootsuite/mastodon-api)
+* [mastodon-api](https://github.com/mastodon/mastodon-api)
## Rust {#rust}
-* [mammut](https://github.com/Aaronepower/mammut)
-* [elefren](https://github.com/pwoolcoc/elefren)
+* [megalodon-rs](https://github.com/h3poteto/megalodon-rs)
+* [mastodon-async](https://github.com/dscottboggs/mastodon-async)
## Scala {#scala}
* [scaladon](https://github.com/schwitzerm/scaladon)
+## Scheme {#scheme}
+
+### Guile {#guile}
+
+* [Guile-Mastodon](https://codeberg.org/WammKD/Guile-Mastodon)
+
## Swift {#swift}
-* [MastodonKit](https://github.com/ornithocoder/MastodonKit)
+* [Mastodon.swift](https://github.com/Swiftodon/Mastodon.swift)
+* [MastodonKit](https://github.com/MastodonKit/MastodonKit)
+* [tootsdk](https://github.com/tootsdk/tootsdk)
+* [MastodonAPI](https://github.com/li-bei/MastodonAPI)
+
+## TypeScript {#typescript}
+
+* [tsl-mastodon](https://github.com/typescriptlibs/tsl-mastodon-api)
+
diff --git a/content/en/client/public.md b/content/en/client/public.md
index e2794bba..c7d4d314 100644
--- a/content/en/client/public.md
+++ b/content/en/client/public.md
@@ -19,7 +19,7 @@ Examples will be written using the fictional Mastodon website, mastodon.example,
Let's take a look at one of the most basic use cases for public data from Mastodon -- the public timelines.
-We can try to request [GET /api/v1/timelines/public]({{< relref "../../methods/timelines.md" >}}) like so:
+We can try to request [GET /api/v1/timelines/public]({{< relref "methods/timelines" >}}) like so:
```bash
curl https://mastodon.example/api/v1/timelines/public
@@ -33,32 +33,32 @@ curl https://mastodon.example/api/v1/timelines/public?limit=2
Our response should be more manageable this time. We can parse or beautify this JSON with our chosen utility, and we should see that the response looks something like this:
-```javascript
+```json
[
{
"id": "103206804533200177",
"created_at": "2019-11-26T23:27:31.000Z",
- ...
+ // ...
"visibility": "public",
- ...
+ // ...
},
{
"id": "103206804086086361",
"created_at": "2019-11-26T23:27:32.000Z",
- ...
+ // ...
"visibility": "public",
- ...
+ // ...
}
]
```
-We can do similarly for hashtags by calling [GET /api/v1/timelines/tag/:hashtag]({{< relref "../../methods/timelines.md#hashtag-timeline" >}}) -- here, the colon means that this part of the endpoint is a path parameter. In the case of :hashtag, this means we use the hashtag's name \(and once again, a limit of 2\):
+We can do similarly for hashtags by calling [GET /api/v1/timelines/tag/:hashtag]({{< relref "methods/timelines#tag" >}}) -- here, the colon means that this part of the endpoint is a path parameter. In the case of :hashtag, this means we use the hashtag's name (and once again, a limit of 2):
```bash
curl https://mastodon.example/api/v1/timelines/tag/cats?limit=2
```
-We should once again see 2 statuses have been returned in a JSON array of [Status]({{< relref "../entities/status.md" >}}) entities. We can parse the JSON by array, then by object. If we were using Python, our code might look something like this:
+We should once again see 2 statuses have been returned in a JSON array of [Status]({{< relref "entities/status" >}}) entities. We can parse the JSON by array, then by object. If we were using Python, our code might look something like this:
```python
import requests
@@ -78,17 +78,17 @@ Parsing JSON and using it in your program is outside of the scope of this tutori
[MastoVue](https://mastovue.glitch.me) is an example of an application that lets you browse public timelines.
{{< /hint >}}
-## Fetching public accounts and statuses {#toots}
+## Fetching public accounts and statuses {#posts}
Now that we are familiar with how to make requests and how to handle responses, you can experiment with more public data. The following methods may be of interest:
-* Once you know an account's id, you can use [GET /api/v1/accounts/:id]({{< relref "../../methods/accounts.md" >}}) to view the [Account]({{< relref "../entities/account.md" >}}) entity.
- * To view public statuses posted by that account, you can use [GET /api/v1/accounts/:id/statuses]({{< relref "../../methods/statuses.md" >}}) and parse the resulting array of [Status]({{< relref "../entities/status.md" >}}) entities.
-* Once you know a status's id, you can use [GET /api/v1/statuses/:id]({{< relref "../../methods/statuses.md#view-specific-status" >}}) to view the Status entity.
- * You can also use [GET /api/v1/statuses/:id/reblogged\_by]({{< relref "../../methods/statuses.md#boosted-by" >}}) to view who boosted that status,
- * or [GET /api/v1/statuses/:id/favourited\_by]({{< relref "../../methods/statuses.md#favourited-by" >}}) to view who favourited that status.
- * Requesting [GET /api/v1/statuses/:id/context]({{< relref "../../methods/statuses.md#parent-and-child-statuses" >}}) will show you the ancestors and descendants of that status in the tree that is the conversational thread.
- * If the status has a poll attached, you can use [GET /api/v1/polls/:id]({{< relref "../../methods/statuses/polls.md" >}}) to view the poll separately.
+* Once you know an account's id, you can use [GET /api/v1/accounts/:id]({{< relref "methods/accounts" >}}) to view the [Account]({{< relref "entities/account" >}}) entity.
+ * To view public statuses posted by that account, you can use [GET /api/v1/accounts/:id/statuses]({{< relref "methods/statuses" >}}) and parse the resulting array of [Status]({{< relref "entities/status" >}}) entities.
+* Once you know a status's id, you can use [GET /api/v1/statuses/:id]({{< relref "methods/statuses#get-one" >}}) to view the Status entity.
+ * You can also use [GET /api/v1/statuses/:id/reblogged_by]({{< relref "methods/statuses#boosted_by" >}}) to view who boosted that status,
+ * or [GET /api/v1/statuses/:id/favourited_by]({{< relref "methods/statuses#favourited_by" >}}) to view who favourited that status.
+ * Requesting [GET /api/v1/statuses/:id/context]({{< relref "methods/statuses#context" >}}) will show you the ancestors and descendants of that status in the tree that is the conversational thread.
+ * If the status has a poll attached, you can use [GET /api/v1/polls/:id]({{< relref "methods/polls" >}}) to view the poll separately.
IDs of accounts and statuses are local to the Mastodon website's database and will differ for each Mastodon website.
@@ -96,12 +96,12 @@ IDs of accounts and statuses are local to the Mastodon website's database and wi
One last thing you can do with anonymous requests is to view information about the Mastodon website.
-* View general information with [GET /api/v1/instance]({{< relref "../../methods/instance.md#fetch-instance" >}}),
- * view its peers with [GET /api/v1/instance/peers]({{< relref "../../methods/instance.md#list-of-connected-domains" >}}) or
- * its weekly activity with [GET /api/v1/instance/activity]({{< relref "../../methods/instance.md#weekly-activity" >}}), or to
- * list all custom emoji available with [GET /api/v1/custom\_emojis]({{< relref "../../methods/instance/custom_emojis.md#custom-emoji" >}}).
-* See [GET /api/v1/directory]({{< relref "../../methods/instance/directory.md#view-profile-directory" >}}) for a directory of all available profiles.
-* See [GET /api/v1/trends]({{< relref "../../methods/instance/trends.md#trending-tags" >}}) for currently trending hashtags.
+* View general information with [GET /api/v1/instance]({{< relref "methods/instance#fetch-instance" >}}),
+ * view its peers with [GET /api/v1/instance/peers]({{< relref "methods/instance#peers" >}}) or
+ * its weekly activity with [GET /api/v1/instance/activity]({{< relref "methods/instance#activity" >}}), or to
+ * list all custom emoji available with [GET /api/v1/custom_emojis]({{< relref "methods/custom_emojis" >}}).
+* See [GET /api/v1/directory]({{< relref "methods/directory" >}}) for a directory of all available profiles.
+* See [GET /api/v1/trends]({{< relref "methods/trends" >}}) for currently trending hashtags.
{{< hint style="info" >}}
For a practical example of what you can do with just instance data, see [emojos.in](https://emojos.in/), which lets you preview all custom emoji at a given instance.
diff --git a/content/en/client/token.md b/content/en/client/token.md
index b8206a2e..61d34913 100644
--- a/content/en/client/token.md
+++ b/content/en/client/token.md
@@ -9,9 +9,9 @@ menu:
## Authentication and authorization {#auth}
-Up until this point, we've been working with publicly available information, but not all information is public. Some information requires permission before viewing it, in order to audit who is requesting that information \(and to potentially revoke or deny access\).
+Up until this point, we've been working with publicly available information, but not all information is public. Some information requires permission before viewing it, in order to audit who is requesting that information (and to potentially revoke or deny access).
-This is where [OAuth]({{< relref "../spec/oauth.md" >}}) comes in. OAuth is a mechanism for generating access tokens which can be used to _authenticate \(verify\)_ that a request is coming from a specific client, and ensure that the requested action is _authorized \(allowed\)_ by the server's access control policies.
+This is where [OAuth]({{< relref "spec/oauth" >}}) comes in. OAuth is a mechanism for generating access tokens which can be used to _authenticate (verify)_ that a request is coming from a specific client, and ensure that the requested action is _authorized (allowed)_ by the server's access control policies.
## Creating our application {#app}
@@ -21,7 +21,7 @@ The first thing we will need to do is to register an application, in order to be
curl -X POST \
-F 'client_name=Test Application' \
-F 'redirect_uris=urn:ietf:wg:oauth:2.0:oob' \
- -F 'scopes=read write follow push' \
+ -F 'scopes=read write push' \
-F 'website=https://myapp.example' \
https://mastodon.example/api/v1/apps
```
@@ -29,13 +29,13 @@ curl -X POST \
In the above example, we specify the client name and website, which will be shown on statuses if applicable. But more importantly, note the following two parameters:
* `redirect_uris` has been set to the "out of band" token generation, which means that any generated tokens will have to be copied and pasted manually. The parameter is called `redirect_uris` because it is possible to define more than one redirect URI, but when generating the token, we will need to provide a URI that is included within this list.
-* `scopes` allow us to define what permissions we can request later. However, the requested scope later can be a subset of these registered scopes. See [OAuth Scopes]({{< relref "../api/oauth-scopes.md" >}}) for more information.
+* `scopes` allow us to define what permissions we can request later. However, the requested scope later can be a subset of these registered scopes. See [OAuth Scopes]({{< relref "api/oauth-scopes" >}}) for more information.
-We should see an Application entity returned, but for now we only care about client\_id and client\_secret. These values will be used to generate access tokens, so they should be cached for later use. See [POST /api/v1/apps]({{< relref "../../methods/apps.md#create-an-application" >}}) for more details on registering applications.
+We should see an Application entity returned, but for now we only care about client_id and client_secret. These values will be used to generate access tokens, so they should be cached for later use. See [POST /api/v1/apps]({{< relref "methods/apps#create" >}}) for more details on registering applications.
## Example authentication code flow {#flow}
-Now that we have an application, let's obtain an access token that will authenticate our requests as that client application. To do so, use [POST /oauth/token]({{< relref "../../methods/apps/oauth.md#obtain-a-token" >}}) like so:
+Now that we have an application, let's obtain an access token that will authenticate our requests as that client application. To do so, use [POST /oauth/token]({{< relref "methods/oauth#token" >}}) like so:
```bash
curl -X POST \
@@ -52,7 +52,7 @@ Note the following:
* `redirect_uri` must be one of the URIs defined when registering the application.
* We are requesting a `grant_type` of `client_credentials`, which defaults to giving us the `read` scope.
-The response of this method is a [Token]({{< relref "../entities/token.md" >}}) entity. We will need the `access_token` value. Once you have the access token, save it in your local cache. To use it in requests, add the HTTP header `Authorization: Bearer ...` to any API call that requires OAuth \(i.e., one that is not publicly accessible\). Let's verify that our obtained credentials are working by calling [GET /api/v1/apps/verify\_credentials]({{< relref "../methods/apps.md#verify-your-app-works" >}}):
+The response of this method is a [Token]({{< relref "entities/token" >}}) entity. We will need the `access_token` value. Once you have the access token, save it in your local cache. To use it in requests, add the HTTP header `Authorization: Bearer ...` to any API call that requires OAuth (i.e., one that is not publicly accessible). Let's verify that our obtained credentials are working by calling [GET /api/v1/apps/verify_credentials]({{< relref "methods/apps#verify_credentials" >}}):
```bash
curl \
@@ -60,9 +60,9 @@ curl \
https://mastodon.example/api/v1/apps/verify_credentials
```
-If we've obtained our token and formatted our request correctly, we should see our details returned to us as an [Application]({{< relref "../entities/application.md" >}}) entity.
+If we've obtained our token and formatted our request correctly, we should see our details returned to us as an [Application]({{< relref "entities/application" >}}) entity.
## What we can do with authentication {#methods}
-With our authenticated client application, we can view relations of an account with [GET /api/v1/accounts/:id/following]({{< relref "../methods/accounts.md#following" >}}) and [GET /api/v1/accounts/:id/followers]({{< relref "../methods/accounts.md#followers" >}}). Also, some instances may require authentication for methods that would otherwise be public, so if you encountered any authentication errors while playing around with public methods, then those methods should now work.
+With our authenticated client application, we can view relations of an account with [GET /api/v1/accounts/:id/following]({{< relref "methods/accounts#following" >}}) and [GET /api/v1/accounts/:id/followers]({{< relref "methods/accounts#followers" >}}). Also, some instances may require authentication for methods that would otherwise be public, so if you encountered any authentication errors while playing around with public methods, then those methods should now work.
diff --git a/content/en/dev/code.md b/content/en/dev/code.md
index 7fa3b632..56927084 100644
--- a/content/en/dev/code.md
+++ b/content/en/dev/code.md
@@ -7,55 +7,67 @@ menu:
parent: dev
---
-{{< hint style="danger" >}}
-This page is under construction.
-{{< /hint >}}
-
### Code structure {#structure}
The following overview should not be seen as complete or authoritative, but as a rough guidance to help you find your way in the application.
#### Ruby {#ruby}
-| Path | Description |
-| :--- | :--- |
-| `app/controllers` | Code that binds business logic to templates |
-| `app/helpers` | Code that can be used from views, i.e. common operations |
-| `app/lib` | Code that doesn’t fit in the other categories |
-| `app/models` | Code that represents data entities |
-| `app/serializers` | Code that generates JSON from models |
-| `app/services` | Complex logical operations involving multiple models |
-| `app/views` | Templates for generating HTML or other output |
-| `app/workers` | Code that executes outside the request-response cycle |
-| `spec` | Automated test suite |
+`app/controllers`
+: Code that binds business logic to templates
+
+`app/helpers`
+: Code that can be used from views, i.e. common operations
+
+`app/lib`
+: Code that doesn’t fit in the other categories
+
+`app/models`
+: Representation of data entities and their associated methods
+
+`app/policies`
+: Permission checks and other validations, before calling related methods
+
+`app/serializers`
+: Code that generates JSON from models
+
+`app/services`
+: Complex logical operations involving multiple models
+
+`app/views`
+: Templates for generating HTML or other output
+
+`app/workers`
+: Code that executes outside the request-response cycle
+
+`spec`
+: Automated test suite
#### JavaScript {#javascript}
-| Path | Description |
-| :--- | :--- |
-| `app/javascript/mastodon` | Code for the multi-column React.js application |
-| `app/javascript/packs` | Code for non-React.js pages |
+`app/javascript/mastodon`
+: Code for the frontend React.js application
+
+`app/javascript/packs`
+: Code for non-React.js pages
#### CSS and other assets {#assets}
-| Path | Description |
-| :--- | :--- |
-| `app/javascript/images` | Images |
-| `app/javascript/styles` | Code that turns into CSS via Sass |
+`app/javascript/images`
+: Images
+
+`app/javascript/styles`
+: Code that turns into CSS via Sass
#### Localizations {#localizations}
-| Path | Description |
-| :--- | :--- |
-| `config/locales` | Server-side localizations in the YML format |
-| `app/javascript/mastodon/locales` | Client-side localizations in the JSON format |
+`config/locales`
+: Server-side localizations in the YML format
-### Localization maintenance {#localization-maintenance}
+`app/javascript/mastodon/locales`
+: Client-side localizations in the JSON format
All locale files are normalized to ensure consistent formatting and key order, which minimizes changesets in version control.
-| Command | Description |
-| :--- | :--- |
-| `i18n-tasks normalize` | Normalize server-side translations |
-| `yarn run manage:translations` | Normalize client-side translations |
-
+- Run `bundle exec i18n-tasks normalize` to normalize server-side translations
+- Run `yarn run i18n:extract` to extract and normalize client-side translations into `en.json`
diff --git a/content/en/dev/disclosure.md b/content/en/dev/disclosure.md
index 3342a5b2..b6caaa33 100644
--- a/content/en/dev/disclosure.md
+++ b/content/en/dev/disclosure.md
@@ -7,7 +7,7 @@ menu:
parent: dev
---
-If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you should send the report to **hello@joinmastodon.org**. We will gladly reward such reports in proportion to the severity of the issue through our OpenCollective fund.
+If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you should send the report to **security@joinmastodon.org**. We will gladly reward such reports in proportion to the severity of the issue through our OpenCollective fund.
You should *not* report such issues on GitHub or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk.
diff --git a/content/en/dev/overview.md b/content/en/dev/overview.md
index a6248643..b7d64520 100644
--- a/content/en/dev/overview.md
+++ b/content/en/dev/overview.md
@@ -7,10 +7,6 @@ menu:
parent: dev
---
-{{< hint style="warning" >}}
-This page is under construction.
-{{< /hint >}}
-
Mastodon is a Ruby on Rails application with a React.js front-end. It follows standard practices of those frameworks, so if you are already familiar with Rails or React.js, you will not find any surprises here.
The best way of working with Mastodon in a development environment is installing all the dependencies on your system, rather than using Docker or Vagrant. You need Ruby, Node.js, PostgreSQL and Redis, which is a pretty standard set of dependencies for Rails applications.
diff --git a/content/en/dev/routes.md b/content/en/dev/routes.md
index e056bc4d..17ef4395 100644
--- a/content/en/dev/routes.md
+++ b/content/en/dev/routes.md
@@ -7,7 +7,7 @@ menu:
parent: dev
---
-{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/config/routes.rb" caption="config/routes.rb" >}}
+{{< caption-link url="https://github.com/mastodon/mastodon/blob/main/config/routes.rb" caption="config/routes.rb" >}}
## Explanation of routes {#routes}
@@ -37,7 +37,7 @@ end
The first available resource is :statuses, which is nested under the :api and :v1 namespaces. Thus, the resulting HTTP route will be /api/v1/statuses. The `only` defines certain allowed methods, which are to be defined in the controller at `app/controllers/api/v1/statuses_controller.rb`.
-Within /api/v1/statuses, there is a scope for a module :statuses, where additional resources are defined. The controllers for these resources live in `app/controllers/api/v1/statuses/`. For example, :favourite will be handled by the \#create action within `app/controllers/api/v1/statuses/favourites_controller.rb` and :unfavourite will be handled within the same controller, but by the \#destroy action.
+Within /api/v1/statuses, there is a scope for a module :statuses, where additional resources are defined. The controllers for these resources live in `app/controllers/api/v1/statuses/`. For example, :favourite will be handled by the #create action within `app/controllers/api/v1/statuses/favourites_controller.rb` and :unfavourite will be handled within the same controller, but by the #destroy action.
There is also a custom method defined for any `member` within this scope, or in other words, for any status to be controlled by `app/controllers/api/v1/statuses_controller.rb`, which is mapped to GET /api/v1/statuses/:id/context and handled by the :context action defined within that controller.
@@ -45,37 +45,37 @@ There is also a custom method defined for any `member` within this scope, or in
#### :index
-Maps to HTTP GET, for a list. Handled by the \#index action in a controller.
+Maps to HTTP GET, for a list. Handled by the #index action in a controller.
#### :show
-Maps to HTTP GET, for a single view. Handled by the \#show action in a controller.
+Maps to HTTP GET, for a single view. Handled by the #show action in a controller.
#### :create
-Maps to HTTP POST. Handled by the \#create action in a controller.
+Maps to HTTP POST. Handled by the #create action in a controller.
#### :update
-Maps to HTTP PUT. Handled by the \#update action in a controller.
+Maps to HTTP PUT. Handled by the #update action in a controller.
#### :destroy
-Maps to HTTP DELETE. Handled by the \#destroy action in a controller.
+Maps to HTTP DELETE. Handled by the #destroy action in a controller.
## .well-known {#well-known}
### /.well-known/host-meta {#host-meta}
-Extensible Resource Descriptor \(XRD\). Advertises existence of Webfinger.
+Extensible Resource Descriptor (XRD). Advertises existence of Webfinger.
### /.well-known/nodeinfo {#nodeinfo}
Maps to NodeInfo 2.0 endpoint at `/nodeinfo/2.0`, used for advertising software name and version, protocols, usage statistics, and whether registrations are open.
-### /.well-know/webfinger {#webfinger}
+### /.well-known/webfinger {#webfinger}
-Used for discovering ActivityPub actor id. See [Spec compliance > WebFinger]({{< relref "../spec/webfinger.md" >}}) for more information.
+Used for discovering ActivityPub actor id. See [Spec compliance > WebFinger]({{< relref "spec/webfinger" >}}) for more information.
### /.well-known/change-password {#change-password}
@@ -94,8 +94,8 @@ The sections below this point are under construction.
* `/users/username` = user URI
* `/users/username/remote_follow` = remote follow dialog
* `/users/username/statuses/id` = status URI
-* `/@username` = "toots" tab
-* `/@username/with_replies` = "toots and replies" tab
+* `/@username` = "posts" tab
+* `/@username/with_replies` = "posts and replies" tab
* `/@username/media` = "media" tab
* `/@username/tagged/:hashtag` = tagged statuses by user
* `/@username/:status_id` = status permalink
@@ -113,95 +113,95 @@ The sections below this point are under construction.
* /api/oembed
* /api/proofs
* /api/v1
- * [statuses]({{< relref "../methods/statuses/" >}}) \[create, show, destroy\]
- * reblogged\_by \[index\]
- * favourited\_by \[index\]
- * reblog \[create\]
- * unreblog \[POST reblog\#destroy\]
- * favourite \[create\]
- * unfavourite \[POST favourites\#destroy\]
- * bookmark \[create\]
- * unbookmark \[POST bookmarks\#destroy\]
- * mute \[create\]
- * unmute \[POST mutes\#destroy\]
- * pin \[create\]
- * unpin \[POST pins\#destroy\]
- * context \[GET\]
- * [timelines]({{< relref "../methods/timelines/" >}})
- * home \[show\]
- * public \[show\]
- * tag \[show\]
- * list \[show\]
- * [streaming]({{< relref "../methods/timelines/streaming.md" >}}) \[index\]
- * [custom\_emojis]({{< relref "../methods/instance/custom_emojis.md" >}}) \[index\]
- * [suggestions]({{< relref "../methods/accounts/suggestions.md" >}}) \[index, destroy\]
- * [scheduled\_statuses]({{< relref "../methods/statuses/scheduled_statuses.md" >}}) \[index, show, update, destroy\]
- * [preferences]({{< relref "../methods/accounts/preferences.md" >}}) \[index\]
- * [conversations]({{< relref "../methods/timelines/conversations.md" >}}) \[index, destroy\]
- * read \[POST\]
- * [media]({{< relref "../methods/statuses/media.md" >}}) \[create, update\]
- * [blocks]({{< relref "../methods/accounts/blocks.md" >}}) \[index\]
- * [mutes]({{< relref "../methods/accounts/mutes.md" >}}) \[index\]
- * [favourites]({{< relref "../methods/accounts/favourites.md" >}}) \[index\]
- * [bookmarks]({{< relref "../methods/accounts/bookmarks.md" >}}) \[index\]
- * [reports]({{< relref "../methods/accounts/reports.md" >}}) \[create\]
- * [trends]({{< relref "../methods/instance/trends.md" >}}) \[index\]
- * [filters]({{< relref "../methods/accounts/filters.md" >}}) \[index, create, show, update, destroy\]
- * [endorsements]({{< relref "../methods/accounts/endorsements.md" >}}) \[index\]
- * [markers]({{< relref "../methods/timelines/markers.md" >}}) \[index, create\]
- * [apps]({{< relref "../methods/apps/" >}}) \[create\]
- * verify\_credentials \[credentials\#show\]
- * [instance]({{< relref "../methods/instance/" >}}) \[show\]
- * peers \[index\]
- * activity \[show\]
- * [domain\_blocks]({{< relref "../methods/accounts/domain_blocks.md" >}}) \[show, create, destroy\]
- * [directory]({{< relref "../methods/instance/directory.md" >}}) \[show\]
- * [follow\_requests]({{< relref "../methods/accounts/follow_requests.md" >}}) \[index\]
- * authorize \[POST\]
- * reject \[POST\]
- * [notifications]({{< relref "../methods/notifications/" >}}) \[index, show\]
- * clear \[POST\]
- * dismiss \[POST\]
- * [accounts]({{< relref "../methods/accounts/" >}})
- * verify\_credentials \[GET credentials\#show\]
- * update\_credentials \[PATCH credentials\#update\]
- * search \[show \(search\#index\)\]
- * relationships \[index\]
- * [accounts]({{< relref "../methods/accounts/" >}}) \[create, show\]
- * statuses \[index accounts/statuses\]
- * followers \[index accounts/follower\_accounts\]
- * following \[index accounts/following\_accounts\]
- * lists \[index accounts/lists\]
- * identity\_proofs \[index accounts/identity\_proofs\]
- * follow \[POST\]
- * unfollow \[POST\]
- * block \[POST\]
- * unblock \[POST\]
- * mute \[POST\]
- * unmute \[POST\]
- * pin \[POST\]
- * unpin \[POST\]
- * [lists]({{< relref "../methods/timelines/lists.md" >}}) \[index, create, show, update, destroy\]
- * accounts \[POST accounts/pins\#destroy\]
- * [featured\_tags]({{< relref "../methods/accounts/featured_tags.md" >}}) \[index, create, destroy\]
- * suggestions \[GET suggestions\#index\]
- * [polls]({{< relref "../methods/statuses/polls.md" >}}) \[create, show\]
- * votes \[create polls/votes\]
- * [push]({{< relref "../methods/notifications/push.md" >}})
- * subscription \[create, show, update, destroy\]
- * [admin]({{< relref "../methods/admin.md" >}})
- * accounts \[index, show\]
- * enable \[POST\]
- * unsilence \[POST\]
- * unsuspend \[POST\]
- * approve \[POST\]
- * reject \[POST\]
- * action \[create account\_actions\]
- * reports \[index, show\]
- * assign\_to\_self \[POST\]
- * unassign \[POST\]
- * reopen \[POST\]
- * resolve \[POST\]
+ * [statuses]({{< relref "methods/statuses" >}}) [create, show, destroy]
+ * reblogged_by [index]
+ * favourited_by [index]
+ * reblog [create]
+ * unreblog [POST reblog#destroy]
+ * favourite [create]
+ * unfavourite [POST favourites#destroy]
+ * bookmark [create]
+ * unbookmark [POST bookmarks#destroy]
+ * mute [create]
+ * unmute [POST mutes#destroy]
+ * pin [create]
+ * unpin [POST pins#destroy]
+ * context [GET]
+ * [timelines]({{< relref "methods/timelines" >}})
+ * home [show]
+ * public [show]
+ * tag [show]
+ * list [show]
+ * [streaming]({{< relref "methods/streaming" >}}) [index]
+ * [custom_emojis]({{< relref "methods/custom_emojis" >}}) [index]
+ * [suggestions]({{< relref "methods/suggestions" >}}) [index, destroy]
+ * [scheduled_statuses]({{< relref "methods/scheduled_statuses" >}}) [index, show, update, destroy]
+ * [preferences]({{< relref "methods/preferences" >}}) [index]
+ * [conversations]({{< relref "methods/conversations" >}}) [index, destroy]
+ * read [POST]
+ * [media]({{< relref "methods/media" >}}) [create, update]
+ * [blocks]({{< relref "methods/blocks" >}}) [index]
+ * [mutes]({{< relref "methods/mutes" >}}) [index]
+ * [favourites]({{< relref "methods/favourites" >}}) [index]
+ * [bookmarks]({{< relref "methods/bookmarks" >}}) [index]
+ * [reports]({{< relref "methods/reports" >}}) [create]
+ * [trends]({{< relref "methods/trends" >}}) [index]
+ * [filters]({{< relref "methods/filters" >}}) [index, create, show, update, destroy]
+ * [endorsements]({{< relref "methods/endorsements" >}}) [index]
+ * [markers]({{< relref "methods/markers" >}}) [index, create]
+ * [apps]({{< relref "methods/apps" >}}) [create]
+ * verify_credentials [credentials#show]
+ * [instance]({{< relref "methods/instance" >}}) [show]
+ * peers [index]
+ * activity [show]
+ * [domain_blocks]({{< relref "methods/domain_blocks" >}}) [show, create, destroy]
+ * [directory]({{< relref "methods/directory" >}}) [show]
+ * [follow_requests]({{< relref "methods/follow_requests" >}}) [index]
+ * authorize [POST]
+ * reject [POST]
+ * [notifications]({{< relref "methods/notifications" >}}) [index, show]
+ * clear [POST]
+ * dismiss [POST]
+ * [accounts]({{< relref "methods/accounts" >}})
+ * verify_credentials [GET credentials#show]
+ * update_credentials [PATCH credentials#update]
+ * search [show (search#index)]
+ * relationships [index]
+ * [accounts]({{< relref "methods/accounts" >}}) [create, show]
+ * statuses [index accounts/statuses]
+ * followers [index accounts/follower_accounts]
+ * following [index accounts/following_accounts]
+ * lists [index accounts/lists]
+ * identity_proofs [index accounts/identity_proofs]
+ * follow [POST]
+ * unfollow [POST]
+ * block [POST]
+ * unblock [POST]
+ * mute [POST]
+ * unmute [POST]
+ * pin [POST]
+ * unpin [POST]
+ * [lists]({{< relref "methods/lists" >}}) [index, create, show, update, destroy]
+ * accounts [POST accounts/pins#destroy]
+ * [featured_tags]({{< relref "methods/featured_tags" >}}) [index, create, destroy]
+ * suggestions [GET suggestions#index]
+ * [polls]({{< relref "methods/polls" >}}) [create, show]
+ * votes [create polls/votes]
+ * [push]({{< relref "methods/push" >}})
+ * subscription [create, show, update, destroy]
+ * [admin]({{< relref "methods/admin" >}})
+ * accounts [index, show]
+ * enable [POST]
+ * unsilence [POST]
+ * unsuspend [POST]
+ * approve [POST]
+ * reject [POST]
+ * action [create account_actions]
+ * reports [index, show]
+ * assign_to_self [POST]
+ * unassign [POST]
+ * reopen [POST]
+ * resolve [POST]
* /api/v2
- * [search]({{< relref "../methods/search.md" >}}) \[GET search\#index\]
+ * [search]({{< relref "methods/search" >}}) [GET search#index]
diff --git a/content/en/dev/setup.md b/content/en/dev/setup.md
index b29b3ce2..9477bda7 100644
--- a/content/en/dev/setup.md
+++ b/content/en/dev/setup.md
@@ -7,47 +7,107 @@ menu:
parent: dev
---
-{{< hint style="danger" >}}
-This page is under construction.
-{{< /hint >}}
+## Quick start with Vagrant {#vagrant}
-### Pre-requisites {#prerequisites}
+For convenience, the Mastodon repository includes a Vagrantfile for quickly setting up a development environment without manual configuration. To use this development environment, install [Vagrant](https://vagrantup.com) using a binary executable or through your package manager.
-You can follow the [pre-requisites instructions from the production guide](https://docs.joinmastodon.org/admin/install/), but do not create a `mastodon` user. You also don't have to install `nginx`, `certbot` and `python-certbot-nginx` as the development environment brings its own webserver. Setting up and running a development environment has been proven successful over WSL2 as well if you are on Windows.
+Once you have Vagrant installed, for convenience, it is recommended to install a plugin to automatically update your machine's hosts file. This will allow you to access the dev environment at `http://mastodon.local` without manually editing the hosts file yourself. To do so:
+
+```sh
+vagrant plugin install vagrant-hostsupdater
+```
+
+The virtual machine can then be started:
+
+```sh
+vagrant up
+```
+
+Once the virtual machine has been started, you may launch the Foreman task executor to launch the various Mastodon processes:
+
+```sh
+vagrant ssh -c "cd /vagrant && foreman start"
+```
+
+Once the Mastodon processes have fully started up, you can load `http://mastodon.local` in your browser to access the Mastodon instance within the VM. You can log in as the default admin user with the username `admin@mastodon.local` and the password `mastodonadmin`.
+
+Any changes to the source code will be reflected after saving your files.
+
+To reset the VM to a fresh state, you can destroy it and bring it up again:
+
+```sh
+vagrant destroy
+vagrant up
+```
+
+## Manual install from source {#manual}
+
+You can follow the [pre-requisites instructions from the production guide]({{
https://trwnh.com
help me live: https://liberapay.com/trwnh or paypal
- i have all notifs except mentions turned off, so please interact if you wanna be friends! i literally will not notice otherwise
- dm me if i did something wrong, so i can improve
- purest person on fedi, do not lewd in my presenceFunding
\n\nReporting and moderation
\n\nImpressum
\n\n
\nMühlenstraße 8a
\n14167 Berlin
\nGermany
\nGeführt bei: Amtsgericht Charlottenburg
\nNummer: HRB 230086 B
cats never change
And you just don't know what people will do next
- todd rundgren, \"Zen Archer\"
free software | digital rights | rhythm games | cyberponk | homelab | ham radio | electronics
21; they/them
free software | digital rights | rhythm games | cyberponk | homelab | ham radio | electronics
21; they/them
I shall surely acquire the capacity to
do it even if I may not have it at the
beginning." -- Gandhi
destroyer of bloat @ #pleroma, #pkgconf, #audacious
slayer of techbros
previously #alpinelinux core a few moons ago and #debian much longer ago
she/her",
- "url": "https://pleroma.site/users/kaniini",
- "avatar": "https://files.mastodon.social/accounts/avatars/000/332/766/original/9fae792e5af298f2.png",
- "avatar_static": "https://files.mastodon.social/accounts/avatars/000/332/766/original/9fae792e5af298f2.png",
- "header": "https://files.mastodon.social/accounts/headers/000/332/766/original/fe176d8215ec0f36.jpeg",
- "header_static": "https://files.mastodon.social/accounts/headers/000/332/766/original/fe176d8215ec0f36.jpeg",
- "followers_count": 2442,
- "following_count": 473,
- "statuses_count": 19533,
- "last_status_at": "2019-11-14T01:38:32.193Z",
- "emojis": [
- {
- "shortcode": "abunhdhappyhop",
- "url": "https://files.mastodon.social/custom_emojis/images/000/137/036/original/e102b7869c930411.png",
- "static_url": "https://files.mastodon.social/custom_emojis/images/000/137/036/static/e102b7869c930411.png",
- "visible_in_picker": true
- },
- {
- "shortcode": "abunhdhappy",
- "url": "https://files.mastodon.social/custom_emojis/images/000/137/100/original/d47dd4a8a0a85e19.png",
- "static_url": "https://files.mastodon.social/custom_emojis/images/000/137/100/static/d47dd4a8a0a85e19.png",
- "visible_in_picker": true
- },
- {
- "shortcode": "abunhdhop",
- "url": "https://files.mastodon.social/custom_emojis/images/000/137/102/original/43fa2536760ea5d4.png",
- "static_url": "https://files.mastodon.social/custom_emojis/images/000/137/102/static/43fa2536760ea5d4.png",
- "visible_in_picker": true
- },
- {
- "shortcode": "abunhd",
- "url": "https://files.mastodon.social/custom_emojis/images/000/142/760/original/892a08e7de033e74.png",
- "static_url": "https://files.mastodon.social/custom_emojis/images/000/142/760/static/892a08e7de033e74.png",
- "visible_in_picker": true
- }
- ],
- "fields": []
- },
- {
- "id": "689455",
- "username": "interneteh",
- "acct": "interneteh@sunbeam.city",
- "display_name": "Sid",
- "locked": false,
- "bot": false,
- "created_at": "2019-01-17T00:10:11.059Z",
- "note": "
enby :heart_nb: they/them
🌎 Alt: @DeeUnderscore@be.cutewith.me • A bot: @cubeglobe@beeping.town
💬 XMPP: deeunderscore@xmpp.zone
🔗 https://dee.underscore.world/about",
- "url": "https://fedi.underscore.world/users/Dee",
- "avatar": "https://files.mastodon.social/accounts/avatars/000/764/276/original/86f6bddc26c4b1df.png",
- "avatar_static": "https://files.mastodon.social/accounts/avatars/000/764/276/original/86f6bddc26c4b1df.png",
- "header": "https://files.mastodon.social/accounts/headers/000/764/276/original/c73f0e088c59145c.jpeg",
- "header_static": "https://files.mastodon.social/accounts/headers/000/764/276/original/c73f0e088c59145c.jpeg",
- "followers_count": 528,
- "following_count": 301,
- "statuses_count": 15611,
- "last_status_at": "2019-11-23T03:30:33.738Z",
- "emojis": [
- {
- "shortcode": "heart_nb",
- "url": "https://files.mastodon.social/custom_emojis/images/000/121/156/original/6eabf6eb2ae69bc9.png",
- "static_url": "https://files.mastodon.social/custom_emojis/images/000/121/156/static/6eabf6eb2ae69bc9.png",
- "visible_in_picker": true
- }
- ],
- "fields": []
- }
-]
-```
-{{< endapi-method-response-example >}}
-{{< api-method-response-example httpCode=401 >}}
-{{< api-method-response-example-description >}}
-
-Bad Authorization header
-{{< endapi-method-response-example-description >}}
-
-
-```javascript
-{
- "error": "The access token is invalid"
-}
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="delete" host="https://mastodon.example" path="/api/v1/suggestions/:account_id" title="Remove a suggestion" >}}
-{{< api-method-description >}}
-
-Remove an account from follow suggestions.
-
-**Returns:** n/a\
-**OAuth:** User token + `read`\
-**Version history:**\
-2.4.3 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-id of the account in the database to be removed from suggestions
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-
-A successful call will return an empty object. Note the call will be successful even if the account id provided is invalid or is not a suggested account.
-{{< endapi-method-response-example-description >}}
-
-
-```javascript
-{}
-```
-{{< endapi-method-response-example >}}
-{{< api-method-response-example httpCode=401 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```javascript
-{
- "error": "The access token is invalid"
-}
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-
-
diff --git a/content/en/methods/admin.md b/content/en/methods/admin.md
deleted file mode 100644
index 2bc463b8..00000000
--- a/content/en/methods/admin.md
+++ /dev/null
@@ -1,598 +0,0 @@
----
-title: admin
-description: Perform moderation actions with accounts and reports.
-menu:
- docs:
- weight: 80
- parent: methods
- identifier: methods-admin
----
-
-{{< hint style="warning" >}}
-
-Responses are not currently documented. Exact nature of parameters has not been validated.
-{{< /hint >}}
-
-
-## Account methods
-
-{{< api-method method="get" host="https://mastodon.example" path="/api/v1/admin/accounts" title="View accounts by criteria" >}}
-{{< api-method-description >}}
-
-View accounts matching certain criteria for filtering, up to 100 at a time. Pagination may be done with the HTTP Link header in the response.
-
-**Returns:** Admin::Account\
-**OAuth:** User token + `admin:read:accounts`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< api-method-query-parameters >}}
-{{< api-method-parameter name="local" type="boolean" required=false >}}
-Filter for local accounts?
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="remote" type="boolean" required=false >}}
-Filter for remote accounts?
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="by_domain" type="string" required=false >}}
-Filter by the given domain
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="active" type="boolean" required=false >}}
-Filter for currently active accounts?
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="pending" type="boolean" required=false >}}
-Filter for currently pending accounts?
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="disabled" type="boolean" required=false >}}
-Filter for currently disabled accounts?
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="silenced" type="boolean" required=false >}}
-Filter for currently silenced accounts?
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="suspended" type="boolean" required=false >}}
-Filter for currently suspended accounts?
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="username" type="string" required=false >}}
-Username to search for
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="display_name" type="string" required=false >}}
-Display name to search for
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="email" type="string" required=false >}}
-Lookup a user with this email
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="ip" type="string" required=false >}}
-Lookup users by this IP address
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="staff" type="boolean" required=false >}}
-Filter for staff accounts?
-{{< endapi-method-parameter >}}
-{{< endapi-method-query-parameters >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="get" host="https://mastodon.example" path="/api/v1/admin/accounts/:id" title="View a specific account" >}}
-{{< api-method-description >}}
-
-View admin-level information about the given account.
-
-**Returns:** Admin::Account\
-**OAuth:** User token + `admin:read:accounts`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the account
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/accounts/:account_id/action" title="Perform an action against an account" >}}
-{{< api-method-description >}}
-
-Perform an action against an account and log this action in the moderation history.
-
-**Returns:** empty object\
-**OAuth:** User token + `admin:write:accounts`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":account_id" type="string" required=true >}}
-ID of the account
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< api-method-form-data-parameters >}}
-{{< api-method-parameter name="type" type="string" required=false >}}
-Type of action to be taken. Enumerable oneOf: `none` `disable` `silence` `suspend`
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="report_id" type="string" required=false >}}
-ID of an associated report that caused this action to be taken
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="warning_preset_id" type="string" required=false >}}
-ID of a preset warning
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="text" type="string" required=false >}}
-Additional text for clarification of why this action was taken
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="send_email_notification" type="boolean" required=false >}}
-Whether an email should be sent to the user with the above information.
-{{< endapi-method-parameter >}}
-{{< endapi-method-form-data-parameters >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/accounts/:id/approve" title="Approve pending account" >}}
-{{< api-method-description >}}
-
-Approve the given local account if it is currently pending approval.
-
-**Returns:** Admin::Account\
-**OAuth:** User token + `admin:write:accounts`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the account
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/accounts/:id/reject" title="Reject pending account" >}}
-{{< api-method-description >}}
-
-Reject the given local account if it is currently pending approval.
-
-**Returns:** Admin::Account\
-**OAuth:** User token + `admin:write:accounts`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the account
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/accounts/:id/enable" title="Re-enable account" >}}
-{{< api-method-description >}}
-
-Re-enable a local account whose login is currently disabled.
-
-**Returns:** Admin::Account\
-**OAuth:** User token + `admin:write:accounts`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the account
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/accounts/:id/unsilence" title="Unsilence account" >}}
-{{< api-method-description >}}
-
-Unsilence a currently silenced account.
-
-**Returns:** Admin::Account\
-**OAuth:** User token + `admin:write:accounts`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the account
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/accounts/:id/unsuspend" title="Unsuspend account" >}}
-{{< api-method-description >}}
-
-Unsuspend a currently suspended account.
-
-**Returns:** Admin::Account\
-**OAuth:** User token + `admin:write:accounts`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the account
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-
-
-## Report methods
-
-{{< api-method method="get" host="https://mastodon.example" path="/api/v1/admin/reports" title="View all reports" >}}
-{{< api-method-description >}}
-
-View all reports. Pagination may be done with HTTP Link header in the response.
-
-**Returns:** Array of Admin::Report\
-**OAuth:** User token + `admin:read:reports`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< api-method-query-parameters >}}
-{{< api-method-parameter name="resolved" type="boolean" required=false >}}
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="account_id" type="string" required=false >}}
-{{< endapi-method-parameter >}}
-{{< api-method-parameter name="target_account_id" type="string" required=false >}}
-{{< endapi-method-parameter >}}
-{{< endapi-method-query-parameters >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="get" host="https://mastodon.example" path="/api/v1/admin/reports/:id/" title="View a single report" >}}
-{{< api-method-description >}}
-
-View information about the report with the given ID.
-
-**Returns:** Admin::Report\
-**OAuth:** User token + `admin:read:reports`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the report
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/reports/:id/assign_to_self" title="Assign report to self" >}}
-{{< api-method-description >}}
-
-Claim the handling of this report to yourself.
-
-**Returns:** Admin::Report\
-**OAuth:** User token + `admin:write:reports`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the report
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/reports/:id/unassign" title="Unassign report" >}}
-{{< api-method-description >}}
-
-Unassign a report so that someone else can claim it.
-
-**Returns:** Admin::Report\
-**OAuth:** User token + `admin:write:reports`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the report
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/reports/:id/resolve" title="Mark as resolved" >}}
-{{< api-method-description >}}
-
-Mark a report as resolved with no further action taken.
-
-**Returns:** Admin::Report\
-**OAuth:** User token + `admin:write:reports`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the report
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-{{< api-method method="post" host="https://mastodon.example" path="/api/v1/admin/reports/:id/reopen" title="Re-open report" >}}
-{{< api-method-description >}}
-
-Reopen a currently closed report.
-
-**Returns:** Admin::Report\
-**OAuth:** User token + `admin:write:reports`\
-**Version history:**\
-2.9.1 - added
-
-{{< endapi-method-description >}}
-{{< api-method-spec >}}
-{{< api-method-request >}}
-{{< api-method-path-parameters >}}
-{{< api-method-parameter name=":id" type="string" required=true >}}
-ID of the report
-{{< endapi-method-parameter >}}
-{{< endapi-method-path-parameters >}}
-{{< api-method-headers >}}
-{{< api-method-parameter name="Authorization" type="string" required=true >}}
-Bearer <user token>
-{{< endapi-method-parameter >}}
-{{< endapi-method-headers >}}
-{{< endapi-method-request >}}
-{{< api-method-response >}}
-{{< api-method-response-example httpCode=200 >}}
-{{< api-method-response-example-description >}}
-{{< endapi-method-response-example-description >}}
-
-
-```
-
-```
-{{< endapi-method-response-example >}}
-{{< endapi-method-response >}}
-{{< endapi-method-spec >}}
-{{< endapi-method >}}
-
-
diff --git a/content/en/methods/admin/_index.md b/content/en/methods/admin/_index.md
new file mode 100644
index 00000000..a21e1cfc
--- /dev/null
+++ b/content/en/methods/admin/_index.md
@@ -0,0 +1,10 @@
+---
+title: admin API methods
+description: View and manage administrative information.
+menu:
+ docs:
+ weight: 80
+ name: admin
+ parent: methods
+ identifier: methods-admin
+---
\ No newline at end of file
diff --git a/content/en/methods/admin/accounts.md b/content/en/methods/admin/accounts.md
new file mode 100644
index 00000000..7f53ba32
--- /dev/null
+++ b/content/en/methods/admin/accounts.md
@@ -0,0 +1,1035 @@
+---
+title: admin/accounts API methods
+description: Perform moderation actions with accounts.
+menu:
+ docs:
+ name: admin/accounts
+ parent: methods-admin
+ identifier: methods-admin-accounts
+aliases: [
+ "/methods/admin/accounts",
+ "/api/methods/admin/accounts",
+]
+---
+
+
+
+## View accounts (v1) {#v1}
+
+```http
+GET /api/v1/admin/accounts HTTP/1.1
+```
+
+View all accounts, optionally matching certain criteria for filtering, up to 100 at a time. Pagination may be done with the HTTP Link header in the response. See [Paginating through API responses]({{