remove non-translated files

Signed-off-by: Marcin Mikołajczak <me@m4sk.in>
This commit is contained in:
Marcin Mikołajczak 2018-10-09 19:25:35 +02:00
parent 1ebd819bd5
commit 94e5547055
29 changed files with 4 additions and 2194 deletions

View File

@ -13,10 +13,10 @@ enableGitInfo = true
contentDir = "content/en"
languageName = "English"
weight = 1
[languages.pl]
contentDir = "content/pl"
languageName = "Polski"
weight = 1
[languages.pl]
contentDir = "content/pl"
languageName = "Polski"
weight = 1
[menu]
[[menu.docs]]

View File

@ -1,265 +0,0 @@
---
title: Scaling up
description: How to scale Mastodon horizontally to handle more requests
menu:
docs:
parent: administration
weight: 4
---
## Managing concurrency
Mastodon has three types of processes:
- Web (Puma)
- Streaming API
- Background processing (Sidekiq)
### Web (Puma)
The web process serves short-lived HTTP requests for most of the application. The following environment variables control it:
- `WEB_CONCURRENCY` controls the number of worker processes
- `MAX_THREADS` controls the number of threads per process
Threads share the memory of their parent process. Different processes allocate their own memory, though they share some memory via copy-on-write. A larger number of threads maxes out your CPU first, a larger number of processes maxes out your RAM first.
These values affect how many HTTP requests can be served at the same time.
In terms of throughput, more processes are better than more threads.
### Streaming API
The streaming API handles long-lived HTTP and WebSockets connections, through which clients receive real-time updates. The following environment variables control it:
- `STREAMING_CLUSTER_NUM` controls the number of worker processes
- `STREAMING_API_BASE_URL` controls the base URL of the streaming API
One process can handle a reasonably high number of connections. The streaming API can be hosted on a different subdomain if you want to e.g. avoid the overhead of nginx proxying the connections.
### Background processing (Sidekiq)
Many tasks in Mastodon are delegated to background processing to ensure the HTTP requests are fast, and to prevent HTTP request aborts from affecting the execution of those tasks. Sidekiq is a single process, with a configurable number of threads.
#### Number of threads
While the amount of threads in the web process affects the responsiveness of the Mastodon instance to the end-user, the amount of threads allocated to background processing affects how quickly posts can be delivered from the author to anyone else, how soon e-mails are sent out, etc.
The amount of threads is not controlled by an environment variable in this case, but a command line argument in the invocation of Sidekiq, e.g.:
```sh
bundle exec sidekiq -c 15
```
Would start the sidekiq process with 15 threads. Please mind that each threads needs to be able to connect to the database, which means that the database pool needs to be large enough to support all the threads. The database pool size is controlled with the `DB_POOL` environment variable and must be at least the same as the number of threads.
#### Queues
Sidekiq uses different queues for tasks of varying importance, where importance is defined by how much it would impact the user experience of your server's local users if the queue wasn't working, in order of descending importance:
|Queue|Significance|
|:---:|------------|
|`default`|All tasks that affect local users|
|`push`|Delivery of payloads to other servers|
|`mailers`|Delivery of e-mails|
|`pull`|Fetching information from other servers|
The default queues and their priorities are stored in `config/sidekiq.yml`, but can be overridden by the command-line invocation of Sidekiq, e.g.:
```sh
bundle exec sidekiq -q default
```
To run just the `default` queue.
The way Sidekiq works with queues, it first checks for tasks from the first queue, and if there are none, checks the next queue. This means, if the first queue is overfilled, the other queues will lag behind.
As a solution, it is possible to start different Sidekiq processes for the queues to ensure truly parallel execution, by e.g. creating multiple systemd services for Sidekiq with different arguments.
## Transaction pooling with pgBouncer
### Why you might need PgBouncer
If you start running out of available Postgres connections (the default is 100) then you may find PgBouncer to be a good solution. This document describes some common gotchas as well as good configuration defaults for Mastodon.
Note that you can check "PgHero" in the administration view to see how many Postgres connections are currently being used. Typically Mastodon uses as many connections as there are threads both in Puma, Sidekiq and the streaming API combined.
### Installing PgBouncer
On Debian and Ubuntu:
sudo apt install pgbouncer
### Configuring PgBouncer
#### Setting a password
First off, if your `mastodon` user in Postgres is set up wthout a password, you will need to set a password.
Here's how you might reset the password:
psql -p 5432 -U mastodon mastodon_production -w
Then (obviously, use a different password than the word "password"):
ALTER USER mastodon WITH PASSWORD 'password';
Then `\q` to quit.
#### Configuring userlist.txt
Edit `/etc/pgbouncer/userlist.txt`
As long as you specify a user/password in pgbouncer.ini later, the values in userlist.txt do *not* have to correspond to real PostgreSQL roles. You can arbitrarily define users and passwords, but you can reuse the "real" credentials for simplicity's sake. Add the `mastodon` user to the `userlist.txt`:
"mastodon" "md5d75bb2be2d7086c6148944261a00f605"
Here we're using the md5 scheme, where the md5 password is just the md5sum of `password + username` with the string `md5` prepended. For instance, to derive the hash for user `mastodon` with password `password`, you can do:
```bash
# ubuntu, debian, etc.
echo -n "passwordmastodon" | md5sum
# macOS, openBSD, etc.
md5 -s "passwordmastodon"
```
Then just add `md5` to the beginning of that.
You'll also want to create a `pgbouncer` admin user to log in to the PgBouncer admin database. So here's a sample `userlist.txt`:
```
"mastodon" "md5d75bb2be2d7086c6148944261a00f605"
"pgbouncer" "md5a45753afaca0db833a6f7c7b2864b9d9"
```
In both cases the password is just `password`.
#### Configuring pgbouncer.ini
Edit `/etc/pgbouncer/pgbouncer.ini`
Add a line under `[databases]` listing the Postgres databases you want to connect to. Here we'll just have PgBouncer use the same username/password and database name to connect to the underlying Postgres database:
```ini
[databases]
mastodon_production = host=127.0.0.1 port=5432 dbname=mastodon_production user=mastodon password=password
```
The `listen_addr` and `listen_port` tells PgBouncer which address/port to accept connections. The defaults are fine:
```ini
listen_addr = 127.0.0.1
listen_port = 6432
```
Put `md5` as the `auth_type` (assuming you're using the md5 format in `userlist.txt`):
```ini
auth_type = md5
```
Make sure the `pgbouncer` user is an admin:
```ini
admin_users = pgbouncer
```
**This next part is very important!** The default pooling mode is session-based, but for Mastodon we want transaction-based. In other words, a Postgres connection is created when a transaction is created and dropped when the transaction is done. So you'll want to change the `pool_mode` from `session` to `transaction`:
```ini
pool_mode = transaction
```
Next up, `max_client_conn` defines how many connections PgBouncer itself will accept, and `default_pool_size` puts a limit on how many Postgres connections will be opened under the hood. (In PgHero the number of connections reported will correspond to `default_pool_size` because it has no knowledge of PgBouncer.)
The defaults are fine to start, and you can always increase them later:
```ini
max_client_conn = 100
default_pool_size = 20
```
Don't forget to reload or restart pgbouncer after making your changes:
sudo systemctl reload pgbouncer
#### Debugging that it all works
You should be able to connect to PgBouncer just like you would with Postgres:
psql -p 6432 -U mastodon mastodon_production
And then use your password to log in.
You can also check the PgBouncer logs like so:
tail -f /var/log/postgresql/pgbouncer.log
#### Configuring Mastodon to talk to PgBouncer
In your `.env.production` file, first off make sure that this is set:
```bash
PREPARED_STATEMENTS=false
```
Since we're using transaction-based pooling, we can't use prepared statements.
Next up, configure Mastodon to use port 6432 (PgBouncer) instead of 5432 (Postgres) and you should be good to go:
```bash
DB_HOST=localhost
DB_USER=mastodon
DB_NAME=mastodon_production
DB_PASS=password
DB_PORT=6432
```
> **Gotcha:** You cannot use pgBouncer to perform `db:migrate` tasks. But this is easy to work around. If your postgres and pgbouncer are on the same host, it can be as simple as defining `DB_PORT=5432` together with `RAILS_ENV=production` when calling the task, for example: `RAILS_ENV=production DB_PORT=5432 bundle exec rails db:migrate` (you can specify `DB_HOST` too if it's different, etc)
#### Administering PgBouncer
The easiest way to reboot is:
sudo systemctl restart pgbouncer
But if you've set up a PgBouncer admin user, you can also connect as the admin:
psql -p 6432 -U pgbouncer pgbouncer
And then do:
RELOAD;
Then use `\q` to quit.
## Separate Redis for cache
Redis is used widely throughout the application, but some uses are more important than others. Home feeds, list feeds, and Sidekiq queues as well as the streaming API are backed by Redis and that's important data you wouldn't want to lose (even though the loss can be survived, unlike the loss of the PostgreSQL database - never lose that!). However, Redis is also used for volatile cache. If you are at a stage of scaling up where you are worried if your Redis can handle everything, you can use a different Redis database for the cache. In the environment, you can specify `CACHE_REDIS_URL` or individual parts like `CACHE_REDIS_HOST`, `CACHE_REDIS_PORT` etc. Unspecified parts fallback to the same values as without the cache prefix.
As far as configuring the Redis database goes, basically you can get rid of background saving to disk, since it doesn't matter if the data gets lost on restart and you can save some disk I/O on that. You can also add a maximum memory limit and a key eviction policy, for that, see this guide: [Using Redis as an LRU cache](https://redis.io/topics/lru-cache)
## Read-replicas
To reduce the load on your Postgresql server, you may wish to setup hot streaming replication (read replica). [See this guide for an example](https://cloud.google.com/community/tutorials/setting-up-postgres-hot-standby). You can make use of the replica in Mastodon in these ways:
- The streaming API server does not issue writes at all, so you can connect it straight to the replica. But it's not querying the database very often anyway so the impact of this is little.
- Use the Makara driver in the web and sidekiq processes, so that writes go to the master database, while reads go to the replica. Let's talk about that.
You will have to edit the `config/database.yml` file and replace the `production` section as follows:
```yml
production:
<<: *default
adapter: postgresql_makara
prepared_statements: false
makara:
id: postgres
sticky: true
connections:
- role: master
blacklist_duration: 0
url: postgresql://db_user:db_password@db_host:db_port/db_name
- role: slave
url: postgresql://db_user:db_password@db_host:db_port/db_name
```
Make sure the URLs point to wherever your PostgreSQL servers are. You can add multiple replicas. You could have a locally installed pgBouncer with configuration to connect to two different servers based on database name, e.g. "mastodon" going to master, "mastodon_replica" going to the replica, so in the file above both URLs would point to the local pgBouncer with the same user, password, host and port, but different database name. There are many possibilities how this could be setup! For more information on Makara, [see their documentation](https://github.com/taskrabbit/makara#databaseyml).

View File

@ -1,18 +0,0 @@
---
title: Authentication
description: How to authenticate with OAuth 2 on Mastodon
menu:
docs:
parent: api
weight: 1
---
Mastodon is federated, therefore you can't be expected to manually register your application on all potential servers your users might want to login on. For this reason, there is an open app registration API, so obtaining OAuth 2 credentials for OAuth 2 authorization can be automated.
Make sure that you allow your users to specify the domain they want to connect to before login. Use that domain to acquire a client id/secret for OAuth 2 and then proceed with normal OAuth 2 also using that domain to build the URLs.
Mastodon supports the following OAuth 2 flows:
- **Authorization code flow**: For end-users
- **Password grant flow**: For bots and other single-user applications
- **Client credentials flow**: For applications that do not act on behalf of users

View File

@ -1,317 +0,0 @@
---
title: Entities
description: Overview of entities returned from Mastodon's REST API
menu:
docs:
parent: api
weight: 3
---
- All IDs are encoded as strings
- All datetimes are in ISO 8601 format
- All HTML strings are sanitized by the server
- All language codes are in ISO 6391 format
## Account
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `id` | String |{{< no >}}|0.1.0|
| `username` | String |{{< no >}}|0.1.0|
| `acct` | String |{{< no >}}|0.1.0|
| `display_name` | String |{{< no >}}|0.1.0|
| `locked` | Boolean |{{< no >}}|0.1.0|
| `created_at` | String (Datetime) |{{< no >}}|0.1.0|
| `followers_count` | Number |{{< no >}}|0.1.0|
| `following_count` | Number |{{< no >}}|0.1.0|
| `statuses_count` | Number |{{< no >}}|0.1.0|
| `note` | String |{{< no >}}|0.1.0|
| `url` | String (URL) |{{< no >}}|0.1.0|
| `avatar` | String (URL) |{{< no >}}|0.1.0|
| `avatar_static` | String (URL) |{{< no >}}|1.1.2|
| `header` | String (URL) |{{< no >}}|0.1.0|
| `header_static` | String (URL) |{{< no >}}|1.1.2|
| `emojis` | Array of [Emoji](#emoji) |{{< no >}}|2.4.0|
| `moved` | [Account](#account) |{{< yes >}}|2.1.0|
| `fields` | Array of [Hash](#field) |{{< yes >}}|2.4.0|
| `bot` | Boolean |{{< yes >}}|2.4.0|
### Field
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `name` | String |{{< no >}}|2.4.0|
| `value` | String (HTML) |{{< no >}}|2.4.0|
| `verified_at` | String (Datetime) |{{< yes >}}|2.6.0|
### Source
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `privacy` | String |{{< yes >}}|1.5.0|
| `sensitive` | Boolean |{{< yes >}}|1.5.0|
| `language` | String (ISO6391) |{{< yes >}}|2.4.2|
| `note` | String |{{< no >}}|1.5.0|
| `fields` | Array of Hash |{{< no >}}|2.4.0|
## Application
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `name` | String |{{< no >}}|0.9.9|
| `website` | String (URL) |{{< yes >}}|0.9.9|
## Attachment
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `id` | String |{{< no >}}|0.6.0|
| `type` | [String (Enum)](#type) |{{< no >}}|0.6.0|
| `url` | String (URL) |{{< no >}}|0.6.0|
| `remote_url` | String (URL) |{{< yes >}}|0.6.0|
| `preview_url` | String (URL) |{{< no >}}|0.6.0|
| `text_url` | String (URL) |{{< yes >}}|0.6.0|
| `meta` | [Hash](#meta) |{{< yes >}}|1.5.0|
| `description` | String |{{< yes >}}|2.0.0|
### Type
- `unknown`
- `image`
- `gifv`
- `video`
### Meta
May contain subtrees `small` and `original`.
Images may contain `width`, `height`, `size`, `aspect`, while videos (including GIFV) may contain `width`, `height`, `frame_rate`, `duration` and `bitrate`.
There may be another top-level object, `focus` with the coordinates `x` and `y`. These coordinates can be used for smart thumbnail cropping, [see this for reference](https://github.com/jonom/jquery-focuspoint#1-calculate-your-images-focus-point).
## Card
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `url` | String (URL) |{{< no >}}|1.0.0|
| `title` | String |{{< no >}}|1.0.0|
| `description` | String |{{< no >}}|1.0.0|
| `image` | String (URL) |{{< yes >}}|1.0.0|
| `type` | [String (Enum)](#type-1) |{{< no >}}|1.3.0|
| `author_name` | String |{{< yes >}}|1.3.0|
| `author_url` | String (URL) |{{< yes >}}|1.3.0|
| `provider_name` | String |{{< yes >}}|1.3.0|
| `provider_url` | String (URL) |{{< yes >}}|1.3.0|
| `html` | String (HTML) |{{< yes >}}|1.3.0|
| `width` | Number |{{< yes >}}|1.3.0|
| `height` | Number |{{< yes >}}|1.3.0|
### Type
- `link`
- `photo`
- `video`
- `rich`
## Context
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `ancestors` | Array of [Status](#status) |{{< no >}}|0.6.0|
| `descendants` | Array of [Status](#status) |{{< no >}}|0.6.0|
## Emoji
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `shortcode` | String |{{< no >}}|2.0.0|
| `static_url` | String (URL) |{{< no >}}|2.0.0|
| `url` | String (URL) |{{< no >}}|2.0.0|
| `visible_in_picker` | Boolean |{{< no >}}|2.1.0|
## Error
The most important part of an error response is the HTTP status code. Standard semantics are followed. The body of an error is a JSON object with this structure:
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `error` | String |{{< no >}}|0.6.0|
## Filter
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `id` | String |{{< no >}}|2.4.3|
| `phrase` | String |{{< no >}}|2.4.3|
| `context` | Array of [String (Enum)](#context) |{{< no >}}|2.4.3|
| `expires_at` | String (Datetime) |{{< yes >}}|2.4.3|
| `irreversible` | Boolean |{{< no >}}|2.4.3|
| `whole_word` | Boolean |{{< no >}}|2.4.3|
### Context
- `home`
- `notifications`
- `public`
- `thread`
### Implementation notes
If `whole_word` is true , client app should do:
- Define 'word constituent character' for your app. In the official implementation, it's `[A-Za-z0-9_]` in JavaScript, and `[[:word:]]` in Ruby. In Ruby case it's 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.
## Instance
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `uri` | String |{{< no >}}|1.1.0|
| `title` | String |{{< no >}}|1.1.0|
| `description` | String |{{< no >}}|1.1.0|
| `email` | String |{{< no >}}|1.1.0|
| `version` | String |{{< no >}}|1.3.0|#
| `thumbnail` | String (URL) |{{< yes >}}|1.6.1|
| `urls` | [Hash](#urls) |{{< no >}}|1.4.2|
| `stats` | [Hash](#stats) |{{< no >}}|1.6.0|
| `languages` | Array of String (ISO6391) |{{< no >}}|2.3.0|
| `contact_account` | [Account](#account) |{{< yes >}}|2.3.0|
### URLs
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
|`streaming_api`| String (URL) |{{< no >}}|1.4.2|
### Stats
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
|`user_count`| Number |{{< no >}}|1.6.0|
|`status_count`| Number |{{< no >}}|1.6.0|
|`domain_count`| Number |{{< no >}}|1.6.0|
## List
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `id` | String |{{< no >}}|2.1.0|
| `title` | String |{{< no >}}|2.1.0|
## Mention
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `url` | String (URL) |{{< no >}}|0.6.0|
| `username` | String |{{< no >}}|0.6.0|
| `acct` | String |{{< no >}}|0.6.0|
| `id` | String |{{< no >}}|0.6.0|
## Notification
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `id` | String |{{< no >}}|0.9.9|
| `type` | [String (Enum)](#type-2) |{{< no >}}|0.9.9|
| `created_at` | String (Datetime) |{{< no >}}|0.9.9|
| `account` | [Account](#account) |{{< no >}}|0.9.9|
| `status` | [Status](#status) |{{< yes >}}|0.9.9|
### Type
- `follow`
- `mention`
- `reblog`
- `favourite`
## Push subscription
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `id` | String |{{< no >}}|2.4.0|
| `endpoint` | String (URL) |{{< no >}}|2.4.0|
| `server_key` | String |{{< no >}}|2.4.0|
| `alerts` | [Hash](#alerts) |{{< no >}}|2.4.0|
### Alerts
???
## Relationship
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `id` | String |{{< no >}}|0.6.0|
| `following` | Boolean |{{< no >}}|0.6.0|
| `followed_by` | Boolean |{{< no >}}|0.6.0|
| `blocking` | Boolean |{{< no >}}|0.6.0|
| `muting` | Boolean |{{< no >}}|1.1.0|
| `muting_notifications` | Boolean |{{< no >}}|2.1.0|
| `requested` | Boolean |{{< no >}}|0.9.9|
| `domain_blocking` | Boolean |{{< no >}}|1.4.0|
| `showing_reblogs` | Boolean |{{< no >}}|2.1.0|
| `endorsed` | Boolean |{{< no >}}|2.5.0|
## Results
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `accounts` | Array of [Account](#account) |{{< no >}}|1.1.0|
| `statuses` | Array of [Status](#status) |{{< no >}}|1.1.0|
| `hashtags` | Array of [Tag](#tag) |{{< no >}}|1.1.0|
## Status
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `id` | String |{{< no >}}|0.1.0|
| `uri` | String |{{< no >}}|0.1.0|
| `url` | String (URL) |{{< yes >}}|0.1.0|
| `account` | [Account](#account) |{{< no >}}|0.1.0|
| `in_reply_to_id` | String |{{< yes >}}|0.1.0|
| `in_reply_to_account_id` | String |{{< yes >}}|1.0.0|
| `reblog` | [Status](#status) |{{< yes >}}|0.1.0|
| `content` | String (HTML) |{{< no >}}|0.1.0|
| `created_at` | String (Datetime) |{{< no >}}|0.1.0|
| `emojis` | Array of [Emoji](#emoji) |{{< no >}}|2.0.0|
| `replies_count` | Number |{{< no >}}|2.5.0|
| `reblogs_count` | Number |{{< no >}}|0.1.0|
| `favourites_count` | Number |{{< no >}}|0.1.0|
| `reblogged` | Boolean |{{< yes >}}|0.1.0|
| `favourited` | Boolean |{{< yes >}}|0.1.0|
| `muted` | Boolean |{{< yes >}}|1.4.0|
| `sensitive` | Boolean |{{< no >}}|0.9.9|
| `spoiler_text` | String |{{< no >}}|1.0.0|
| `visibility` | [String (Enum)](#visibility) |{{< no >}}|0.9.9|
| `media_attachments` | Array of [Attachment](#attachment) |{{< no >}}|0.6.0|
| `mentions` | Array of [Mention](#mention) |{{< no >}}|0.6.0|
| `tags` | Array of [Tag](#tag) |{{< no >}}|0.9.0|
| `application` | [Application](#application) |{{< no >}}|0.9.9|
| `language` | String (ISO6391) |{{< yes >}}|1.4.0|
| `pinned` | Boolean |{{< yes >}}|1.6.0|
### Visibility
- `public`
- `unlisted`
- `private`
- `direct`
## Tag
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `name` | String |{{< no >}}|0.9.0|
| `url` | String (URL) |{{< no >}}|0.9.0|
| `history` | Array of [History](#history) |{{< yes >}}|2.4.1|
### History
|Attribute|Type|Nullable|Added in|
|---------|-----------|:------:|:------:|
| `day` | String (UNIX timestamp) |{{< no >}}|2.4.1|
| `uses` | Number |{{< no >}}|2.4.1|
| `accounts` | Number |{{< no >}}|2.4.1|

View File

@ -1,52 +0,0 @@
---
title: Guidelines
description: Guidelines that app developers for Mastodon should follow
menu:
docs:
parent: api
weight: -1
---
## Login
**The user must be able to login to any Mastodon server from the app**. This means you must ask for either the full handle, or server domain, and use the app registrations API to dynamically obtain OAuth2 credentials.
## Usernames
**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` (username and domain) somewhere.
## 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**.
### HTML tags
You may expect these tags to appear in the content: `<p>`, `<br>`, `<span>`, `<a>`
### Mentions and hashtags
Mentions and hashtags are `<a>` tags. To give those links 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, which can be matched to a particular tag.
### Custom emoji
Custom emoji remain in their plain text shortcode form. Metadata about the determined custom emoji is included with the status, and the shortcodes must be matched against the text to display the images.
### Other links
Links in Mastodon are not shortened using URL shorteners. However, 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
<a href="https://example.com/page/that/is/very/long">
<span class="invisible">https://</span>
<span class="ellipsis">example.com/page</span>
<span class="invisible">/that/is/very/long</span>
</a>
```
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
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. It is up to clients to delete those filters eventually.

View File

@ -1,102 +0,0 @@
---
title: Libraries
description: List of libraries that work with the Mastodon API in various programming languages
menu:
docs:
parent: api
weight: -1
---
## Apex (Salesforce)
- [apex-mastodon](https://github.com/tzmfreedom/apex-mastodon)
## C# (.NET Standard)
- [Mastodot](https://github.com/yamachu/Mastodot)
- [Mastonet](https://github.com/glacasa/Mastonet)
- [TootNet](https://github.com/cucmberium/TootNet)
- [mastodon-api-cs](https://github.com/pawotter/mastodon-api-cs)
- [Mastodon.Net](https://github.com/Tlaster/Mastodon.Net)
## C++
- [mastodon-cpp](https://github.com/tastytea/mastodon-cpp)
## Crystal
- [mastodon.cr](https://github.com/decors/mastodon.cr)
## Common Lisp
- [tooter](https://github.com/Shinmera/tooter)
## Elixir
- [hunter](https://github.com/milmazz/hunter)
## Go
- [go-mastodon](https://github.com/mattn/go-mastodon)
- [madon](https://github.com/McKael/madon)
## Haskell
- [hastodon](https://github.com/syucream/hastodon)
## Java
- [mastodon4j](https://github.com/sys1yagi/mastodon4j)
## JavaScript
- [libodonjs](https://github.com/Zatnosk/libodonjs)
## JavaScript (Browser)
- [mastodon.js](https://github.com/Kirschn/mastodon.js)
## JavaScript (Node.js)
- [node-mastodon](https://github.com/jessicahayley/node-mastodon)
- [mastodon-api](https://github.com/vanita5/mastodon-api)
## Perl
- [Mastodon::Client](https://metacpan.org/pod/Mastodon::Client)
## 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)
- [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)
## Python
- [Mastodon.py](https://github.com/halcy/Mastodon.py)
## R
- [mastodon](https://github.com/ThomasChln/mastodon)
## Ruby
- [mastodon-api](https://github.com/tootsuite/mastodon-api)
## Rust
- [mammut](https://github.com/Aaronepower/mammut)
- [elefren](https://github.com/pwoolcoc/elefren)
## Scala
- [scaladon](https://github.com/schwitzerm/scaladon)
## Swift
- [MastodonKit](https://github.com/ornithocoder/MastodonKit)

View File

@ -1,44 +0,0 @@
---
title: Parameters
description: Specifics of parameter passing to the Mastodon API
menu:
docs:
parent: api
weight: 3
---
## Parameter format
Query strings, form data, and JSON submitted via POST body is equally understood by the API. It is expected that query strings are used for GET requests, and form data or JSON is used for all other requests.
## Arrays
An array parameter must encoded using bracket notation, e.g. `array[0]=foo&array[1]=bar` would be translated into:
```ruby
array = [
'foo',
'bar',
]
```
## Booleans
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.
## Files
File uploads must be encoded using `multipart/form-data`.
## Nested parameters
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:
```ruby
source = {
privacy: 'public',
language: 'en',
}
```
This can be combined with arrays as well.

View File

@ -1,49 +0,0 @@
---
title: Permissions
description: Overview of OAuth 2 access scopes in Mastodon
menu:
docs:
parent: api
weight: 2
---
The API is divided up into access scopes:
|Scope|Parent(s)|Added in|
|:----|---------|:------:|
|`write`||0.9.0|
|`write:accounts`|`write`|2.4.3|
|`write:blocks`|`write`, `follow`|2.4.3|
|`write:favourites`|`write`|2.4.3|
|`write:filters`|`write`|2.4.3|
|`write:follows`|`write`, `follow`|2.4.3|
|`write:lists`|`write`|2.4.3|
|`write:media`|`write`|2.4.3|
|`write:mutes`|`write`, `follow`|2.4.3|
|`write:notifications`|`write`|2.4.3|
|`write:reports`|`write`|2.4.3|
|`write:statuses`|`write`|2.4.3|
|`read`||0.9.0|
|`read:accounts`|`read`|2.4.3|
|`read:blocks`|`read`, `follow`|2.4.3|
|`read:favourites`|`read`|2.4.3|
|`read:filters`|`read`|2.4.3|
|`read:follows`|`read`, `follow`|2.4.3|
|`read:lists`|`read`|2.4.3|
|`read:mutes`|`read`, `follow`|2.4.3|
|`read:notifications`|`read`|2.4.3|
|`read:reports`|`read`|2.4.3|
|`read:search`|`read`|2.4.3|
|`read:statuses`|`read`|2.4.3|
|`follow`||0.9.0|
|`push`||2.4.0|
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).
> **Note:** 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`.
If you do not specify a `scope` in your authorization request, or a `scopes` in your app creation request, the resulting access token / app will default to `read` access.
The set of scopes saved during app creation must include all the scopes that you will request in the authorization request, otherwise authorization will fail.

View File

@ -1,15 +0,0 @@
---
title: Web Push API
overview: How to use the Web Push API in Mastodon to receive push notifications in a native or browser app
menu:
docs:
parent: api
weight: 5
---
Mastodon natively supports the [Web Push API](https://developer.mozilla.org/en-US/docs/Web/API/Push_API). You can utilize the same mechanisms for your native app. It requires running a proxy server that connects to Android's and Apple's proprietary notification gateways. However, the proxy server does not have access to the contents of the notifications. For a reference, see [Mozilla's web push server](https://github.com/mozilla-services/autopush), or more practically, see:
- [toot-relay](https://github.com/DagAgren/toot-relay)
- [PushToFCM](https://github.com/tateisu/PushToFCM)
Using the Web Push API requires your app to have the `push` scope. To create a new Web Push API subscription, use [POST /api/v1/push/subscription]({{< relref "notifications.md#post-api-v1-push-subscription" >}}).

View File

@ -1,176 +0,0 @@
---
title: Accounts
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/accounts/:id
Returns [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="No" user="No" scope="read read:accounts" version="0.0.0" >}}
## GET /api/v1/accounts/verify_credentials
User's own account.
Returns [Account]({{< relref "entities.md#account" >}}) with an extra [`source` attribute]({{< relref "entities.md#source" >}}).
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:accounts" version="0.0.0" >}}
## PATCH /api/v1/accounts/update_credentials
Update user's own account.
Returns [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:accounts" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `display_name` | Display name | Optional |
| `note` | Biography | Optional |
| `avatar` | Avatar encoded using `multipart/form-data` | Optional |
| `header` | Header image encoded using `multipart/form-data` | Optional |
| `locked` | Enable follow requests | Optional |
| `source[privacy]` | Default post privacy preference | Optional |
| `source[sensitive]`| Whether to mark statuses as sensitive by default | Optional |
| `source[language]` | Override language on statuses by default (ISO6391) | Optional |
| `fields_attributes` | Profile metadata (max. 4) | Optional |
## GET /api/v1/accounts/:id/followers
Accounts which follow the given account.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="No" scope="read read:accounts" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
{{< api_pagination >}}
## GET /api/v1/accounts/:id/following
Accounts which the given account is following.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="No" scope="read read:accounts" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
{{< api_pagination >}}
## GET /api/v1/accounts/:id/statuses
An account's statuses.
Returns array of [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="No" scope="read read:statuses" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `only_media` | Only return statuses that have media attachments | Optional |false|
| `pinned` | Only return statuses that have been pinned | Optional |false|
| `exclude_replies` | Skip statuses that reply to other statuses | Optional |false|
| `max_id` | Return results older than ID | Optional ||
| `since_id` | Return results newer than ID | Optional ||
| `min_id` | Return results immediately newer than ID | Optional ||
| `limit` | Maximum number of results | Optional | 20 |
### Pagination
{{< api_dynamic_pagination >}}
## POST /api/v1/accounts/:id/follow
Follow an account.
Returns [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write:follows follow" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `reblogs` | Whether the followed account's reblogs will show up in the home timeline | Optional | true |
## POST /api/v1/accounts/:id/unfollow
Unfollow an account.
Returns [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write:follows follow" version="0.0.0" >}}
## GET /api/v1/accounts/relationships
Relationship of the user to the given accounts in regards to following, blocking, muting, etc.
Returns array of [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:follows" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `id` | Array of account IDs | Required |
## GET /api/v1/accounts/search
Search for matching accounts by username, domain and display name.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:accounts" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `q` | What to search for | Required ||
| `limit` | Maximum number of results | Optional | 40 |
| `resolve` | Attempt WebFinger look-up | Optional | false |
| `following` | Only who the user is following | Optional | false |

View File

@ -1,38 +0,0 @@
---
title: Apps
menu:
docs:
parent: rest-api
weight: 10
---
## POST /api/v1/apps
Create a new application to obtain OAuth2 credentials.
Returns [App]({{< relref "entities.md#app" >}}) with `client_id` and `client_secret`
### Resource information
{{< api_method_info auth="No" user="No" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `client_name` | Name of your application | Required |
| `redirect_uris` | Where the user should be redirected after authorization | Required |
| `scopes` | Space separated list of [scopes]({{< relref "permissions.md" >}}) | Required |
| `website` | URL to the homepage of your app | Optional |
> To display the authorization code to the end-user instead of redirecting to a web page, use `urn:ietf:wg:oauth:2.0:oob` in `redirect_uris`
## GET /api/v1/apps/verify_credentials
Confirm that the app's OAuth2 credentials work.
Returns [App]({{< relref "entities.md#app" >}})
### Resource information
{{< api_method_info auth="Yes" user="No" version="0.0.0" >}}

View File

@ -1,47 +0,0 @@
---
title: Blocks
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/blocks
Accounts the user has blocked.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read:blocks follow" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
{{< api_pagination >}}
## POST /api/v1/accounts/:id/block
Block an account.
Returns [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write:blocks follow" version="0.0.0" >}}
## POST /api/v1/accounts/:id/unblock
Unblock an account.
Returns [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write:blocks follow" version="0.0.0" >}}

View File

@ -1,17 +0,0 @@
---
title: Custom emoji
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/custom_emojis
Custom emojis that are available on the server.
Returns array of [Emoji]({{< relref "entities.md#emoji" >}})
### Resource information
{{< api_method_info auth="No" user="No" version="0.0.0" >}}

View File

@ -1,55 +0,0 @@
---
title: Domain blocks
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/domain_blocks
Domains the user has blocked.
Returns array of string.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:blocks follow" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
{{< api_pagination >}}
## POST /api/v1/domain_blocks
Block a domain to hide all public posts from it, all notifications from it, and remove all followers from it.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:blocks follow" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `domain` | Domain to block| Required |
## DELETE /api/v1/domain_blocks
Remove a domain block.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:blocks follow" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `domain` | Domain to unblock| Required |

View File

@ -1,41 +0,0 @@
---
title: Endorsements
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/endorsements
Accounts the user chose to endorse.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:account" version="0.0.0" >}}
### Pagination
{{< api_pagination >}}
## POST /api/v1/accounts/:id/pin
Endorse an account, i.e. choose to feature the account on the user's public profile.
Returns [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:accounts" version="0.0.0" >}}
## POST /api/v1/accounts/:id/unpin
Undo endorse of an account.
Returns [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:accounts" version="0.0.0" >}}

View File

@ -1,43 +0,0 @@
---
title: Favourites
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/favourites
Statuses the user has favourited.
Returns array of [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:favourites" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 20 |
### Pagination
{{< api_pagination >}}
## POST /api/v1/statuses/:id/favourite
Favourite a status.
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:favourites" version="0.0.0" >}}
## POST /api/v1/statuses/:id/unfavourite
Undo the favourite of a status.
Returns [Status]({{< relref "entities.md#status" >}})

View File

@ -1,75 +0,0 @@
---
title: Filters
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/filters
Text filters the user has configured that potentially must be applied client-side.
Returns array of [Filter]({{< relref "entities.md#filter" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:filters" version="0.0.0" >}}
## POST /api/v1/filters
Create a new filter.
Returns [Filter]({{< relref "entities.md#filter" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:filters" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `phrase` | Keyword or phrase to filter | Required |
| `context` | Array of strings that means filtering context. Each string is one of `home`, `notifications`, `public`, `thread`. At least one context must be specified. | Required |
| `irreversible` | Irreversible filtering will only work in `home` and `notifications` contexts by fully dropping the records. Otherwise, filtering is up to the client. | Optional |
| `whole_word` | Whether to consider word boundaries when matching | Optional |
| `expires_in` | Number that indicates seconds. Filter will be expire in seconds after API processed. Leave blank for no expiration | Optional |
## GET /api/v1/filters/:id
A text filter.
Returns [Filter]({{< relref "entities.md#filter" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:filters" version="0.0.0" >}}
## PUT /api/v1/filters/:id
Update a text filter.
Returns [Filter]({{< relref "entities.md#filter" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:filters" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `phrase` | Keyword or phrase to filter | Required |
| `context` | Array of strings that means filtering context. Each string is one of `home`, `notifications`, `public`, `thread`. At least one context must be specified. | Required |
| `irreversible` | Irreversible filtering will only work in `home` and `notifications` contexts by fully dropping the records. Otherwise, filtering is up to the client. | Optional |
| `whole_word` | Whether to consider word boundaries when matching | Optional |
| `expires_in` | Number that indicates seconds. Filter will be expire in seconds after API processed. Leave blank to not change | Optional |
## DELETE /api/v1/filters/:id
Delete a text filter.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:filters" version="0.0.0" >}}

View File

@ -1,43 +0,0 @@
---
title: Follow requests
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/follow_requests
Accounts that have requested to follow the user.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:follows follow" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
{{< api_pagination >}}
## POST /api/v1/follow_requests/:id/authorize
Allow the account to follow the user.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write:follows follow" version="0.0.0" >}}
## POST /api/v1/follow_requests/:id/reject
Do not allow the account to follow the user.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write:follows follow" version="0.0.0" >}}

View File

@ -1,25 +0,0 @@
---
title: Follow suggestions
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/suggestions
Accounts the user had past positive interactions with, but is not following yet.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read" version="0.0.0" >}}
## DELETE /api/v1/suggestions/:account_id
Remove account from suggestions.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read" version="0.0.0" >}}

View File

@ -1,17 +0,0 @@
---
title: Instances
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/instance
Information about the server.
Returns [Instance]({{< relref "entities.md#instance" >}})
### Resource information
{{< api_method_info auth="No" user="No" version="0.0.0" >}}

View File

@ -1,127 +0,0 @@
---
title: Lists
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/lists
User's lists.
Returns array of [List]({{< relref "entities.md#list" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:lists" version="0.0.0" >}}
## GET /api/v1/accounts/:id/lists
User's lists that a given account is part of.
Returns array of [List]({{< relref "entities.md#list" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:lists" version="0.0.0" >}}
## GET /api/v1/lists/:id/accounts
Accounts that are in a given list.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:lists" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
>If you specify a `limit` of `0` in the query, all accounts will be returned without pagination. Otherwise, standard account pagination rules apply.
{{< api_pagination >}}
## GET /api/v1/lists/:id
Returns [List]({{< relref "entities.md#list" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:lists" version="0.0.0" >}}
## POST /api/v1/lists
Create a new list.
Returns [List]({{< relref "entities.md#list" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:lists" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `title` | The title of the list | Required |
## PUT /api/v1/lists/:id
Update a list.
Returns [List]({{< relref "entities.md#list" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:lists" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `title` | The title of the list | Required |
## DELETE /api/v1/lists/:id
Remove a list.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:lists" version="0.0.0" >}}
## POST /api/v1/lists/:id/accounts
Add accounts to a list.
> Only accounts already followed by the user can be added to a list.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:lists" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `account_ids` | Array of account IDs | Required |
## DELETE /api/v1/lists/:id/accounts
Remove accounts from a list.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:lists" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `account_ids` | Array of account IDs | Required |

View File

@ -1,46 +0,0 @@
---
title: Media attachments
menu:
docs:
parent: rest-api
weight: 10
---
## POST /api/v1/media
Upload a media attachment that can be used with a new status.
Returns [Attachment]({{< relref "entities.md#attachment" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:media" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `file` | Media file encoded using `multipart/form-data` | Required |
| `description` | A plain-text description of the media for accessibility (max 420 chars) | Optional |
| `focus` | Two floating points, comma-delimited. See [focal points](#focal-points) | Optional |
## PUT /api/v1/media/:id
Update a media attachment. Can only be done before the media is attached to a status.
Returns [Attachment]({{< relref "entities.md#attachment" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:media" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `description` | A plain-text description of the media for accessibility (max 420 chars) | Optional |
| `focus` | Two floating points, comma-delimited. See [focal points](#focal-points) | Optional |
## 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 for how to let users select focal point coordinates](https://github.com/jonom/jquery-focuspoint#1-calculate-your-images-focus-point).

View File

@ -1,73 +0,0 @@
---
title: Mutes
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/mutes
Accounts the user has muted.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read:mutes follow" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
{{< api_pagination >}}
## POST /api/v1/accounts/:id/mute
Mute an account.
Returns [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write:mutes follow" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `notifications` | Whether the mute will mute notifications or not | Optional | true |
## POST /api/v1/accounts/:id/unmute
Unmute an account.
Returns [Relationship]({{< relref "entities.md#relationship" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write:mutes follow" version="0.0.0" >}}
## POST /api/v1/statuses/:id/mute
Mute the conversation the status is part of, to no longer be notified about it.
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:mutes" version="0.0.0" >}}
## POST /api/v1/statuses/:id/unmute
Unmute the conversation the status is part of.
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:mutes" version="0.0.0" >}}

View File

@ -1,120 +0,0 @@
---
title: Notifications
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/notifications
Notifications concerning the user.
Returns array of [Notification]({{< relref "entities.md#notification" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:notifications" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `max_id` | Return results older than ID | Optional ||
| `since_id` | Return results newer than ID | Optional ||
| `min_id` | Return results immediately newer than ID | Optional ||
| `limit` | Maximum number of results | Optional | 20 |
| `exclude_types` | Array of types to exclude (e.g. `follow`, `favourite`, `reblog`, `mention`) | Optional ||
### Pagination
{{< api_dynamic_pagination >}}
## GET /api/v1/notifications/:id
Returns [Notification]({{< relref "entities.md#notification" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:notifications" version="0.0.0" >}}
## POST /api/v1/notifications/clear
Delete all notifications from the server.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:notifications" version="0.0.0" >}}
## POST /api/v1/notifications/dismiss
Delete a single notification from the server.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:notifications" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `id` | Notification ID | Required |
## POST /api/v1/push/subscription
Add a Web Push API subscription to receive notifications. See also: [Web Push API]({{< relref "push.md" >}})
> Each access token can have one push subscription. If you create a new subscription, the old subscription is deleted.
Returns [Push Subscription]({{< relref "entities.md#push-subscription" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="push" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `subscription[endpoint]` | Endpoint URL that called when notification is happen. | Required |
| `subscription[keys][p256dh]` | User agent public key. Base64 encoded string of public key of ECDH key using 'prime256v1' curve. | Required |
| `subscription[keys][auth]` | Auth secret. Base64 encoded string of 16 bytes of random data. | Required |
| `data[alerts][follow]` | Boolean of whether you want to receive follow notification event. | Optional |
| `data[alerts][favourite]` | Boolean of whether you want to receive favourite notification event. | Optional |
| `data[alerts][reblog]` | Boolean of whether you want to receive reblog notification event. | Optional |
| `data[alerts][mention]` | Boolean of whether you want to receive mention notification event. | Optional |
## GET /api/v1/push/subscription
Returns [Push Subscription]({{< relref "entities.md#push-subscription" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="push" version="0.0.0" >}}
## PUT /api/v1/push/subscription
Update current Web Push API subscription. Only the `data` part can be updated, e.g. which types of notifications are desired. To change fundamentals, a new subscription must be created instead.
Returns [Push Subscription]({{< relref "entities.md#push-subscription" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="push" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `data[alerts][follow]` | Boolean of whether you want to receive follow notification event. | Optional |
| `data[alerts][favourite]` | Boolean of whether you want to receive favourite notification event. | Optional |
| `data[alerts][reblog]` | Boolean of whether you want to receive reblog notification event. | Optional |
| `data[alerts][mention]` | Boolean of whether you want to receive mention notification event. | Optional |
## DELETE /api/v1/push/subscription
Remove the current Web Push API subscription.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="push" version="0.0.0" >}}

View File

@ -1,23 +0,0 @@
---
title: Reports
menu:
docs:
parent: rest-api
weight: 10
---
## POST /api/v1/reports
Report an account.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:reports" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `account_id` | The ID of the account to report | Required |
| `status_ids` | The IDs of statuses to report as array | Optional |
| `comment` | Reason for the report (up to 1,000 characters) | Optional |

View File

@ -1,24 +0,0 @@
---
title: Search
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v2/search
Search for content in accounts, statuses and hashtags.
Returns [Results]({{< relref "entities.md#results" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:search" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `q` | The search query | Required ||
| `resolve` | Attempt WebFinger look-up | Optional |false|

View File

@ -1,157 +0,0 @@
---
title: Statuses
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/statuses/:id
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="No" user="No" scope="read read:statuses" version="0.0.0" >}}
## GET /api/v1/statuses/:id/context
What the status replies to, and replies to it.
Returns [Context]({{< relref "entities.md#context" >}})
### Resource information
{{< api_method_info auth="No" user="No" scope="read read:statuses" version="0.0.0" >}}
## GET /api/v1/statuses/:id/card
Link preview card for a status, if available.
Returns [Card]({{< relref "entities.md#card" >}})
### Resource information
{{< api_method_info auth="No" user="No" scope="read read:statuses" version="0.0.0" >}}
## GET /api/v1/statuses/:id/reblogged_by
Accounts that reblogged the status.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="No" user="No" scope="read read:statuses" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
{{< api_pagination >}}
## GET /api/v1/statuses/:id/favourited_by
Accounts that favourited the status.
Returns array of [Account]({{< relref "entities.md#account" >}})
### Resource information
{{< api_method_info auth="No" user="No" scope="read read:statuses" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `limit` | Maximum number of results | Optional | 40 |
### Pagination
{{< api_pagination >}}
## POST /api/v1/statuses
Publish a new status.
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="0.0.0" >}}
### Parameters
|Name|Description|Required|
|----|-----------|:------:|
| `status` | The text of the status | Optional\* |
| `in_reply_to_id` | ID of the status you want to reply to | Optional |
| `media_ids` | Array of media IDs to attach to the status | Optional\* |
| `sensitive` | Mark the media in the status as sensitive | Optional |
| `spoiler_text` | Text to be shown as a warning before the actual content | Optional |
| `visibility` | One of `direct`, `private`, `unlisted` `public` | Optional |
| `language` | Override language code of the toot (ISO 639-2) | Optional |
> You must provide either `status` or `media_ids`, completely empty statuses are not allowed.
### Idempotency
In order to prevent duplicate statuses, this endpoint accepts an `Idempotency-Key` header, which should be set to a unique string for each new status. In the event of a network error, a request can be retried with the same `Idempotency-Key`. Only one status will be created regardless of how many requests with the same `Idempotency-Key` did go through.
See <https://stripe.com/blog/idempotency> for more on idempotency and idempotency keys.
## DELETE /api/v1/statuses/:id
Remove a status. The status may still be available a short while after the call.
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="0.0.0" >}}
## POST /api/v1/statuses/:id/reblog
Reblog a status.
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="0.0.0" >}}
## POST /api/v1/statuses/:id/unreblog
Undo the reblog of a status.
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="0.0.0" >}}
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:favourites" version="0.0.0" >}}
## POST /api/v1/statuses/:id/pin
Pin user's own status to user's profile.
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:accounts" version="0.0.0" >}}
## POST /api/v1/statuses/:id/unpin
Remove pinned status from user's profile.
Returns [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="write write:accounts" version="0.0.0" >}}

View File

@ -1,103 +0,0 @@
---
title: Timelines
menu:
docs:
parent: rest-api
weight: 10
---
## GET /api/v1/timelines/home
Statuses from accounts the user follows.
Returns array of [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:statuses" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `max_id` | Return results older than ID | Optional ||
| `since_id` | Return results newer than ID | Optional ||
| `min_id` | Return results immediately newer than ID | Optional ||
| `limit` | Maximum number of results | Optional | 20 |
### Pagination
{{< api_dynamic_pagination >}}
## GET /api/v1/timelines/public
Public statuses known to the server.
Returns array of [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="No" user="No" scope="read read:statuses" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `local` | Only local statuses | Optional |false|
| `only_media` | Only statuses with media attachments | Optional |false|
| `max_id` | Return results older than ID | Optional ||
| `since_id` | Return results newer than ID | Optional ||
| `min_id` | Return results immediately newer than ID | Optional ||
| `limit` | Maximum number of results | Optional | 20 |
### Pagination
{{< api_dynamic_pagination >}}
## GET /api/v1/timelines/tag/:hashtag
Public statuses known to the server marked with a given hashtag.
Returns array of [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="No" user="No" scope="read read:statuses" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `local` | Only local statuses | Optional |false|
| `only_media` | Only statuses with media attachments | Optional |false|
| `max_id` | Return results older than ID | Optional ||
| `since_id` | Return results newer than ID | Optional ||
| `min_id` | Return results immediately newer than ID | Optional ||
| `limit` | Maximum number of results | Optional | 20 |
### Pagination
{{< api_dynamic_pagination >}}
## GET /api/v1/timelines/list/:list_id
Statuses from accounts on a given list.
Returns array of [Status]({{< relref "entities.md#status" >}})
### Resource information
{{< api_method_info auth="Yes" user="Yes" scope="read read:statuses" version="0.0.0" >}}
### Parameters
|Name|Description|Required|Default|
|----|-----------|:------:|:-----:|
| `max_id` | Return results older than ID | Optional ||
| `since_id` | Return results newer than ID | Optional ||
| `min_id` | Return results immediately newer than ID | Optional ||
| `limit` | Maximum number of results | Optional | 20 |
### Pagination
{{< api_dynamic_pagination >}}

View File

@ -1,78 +0,0 @@
---
title: Streaming API
description: How to use Mastodon's streaming API for live, real-time updates
menu:
docs:
parent: api
weight: 4
---
Your application can use a [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events) endpoint to receive updates in real-time. Server-sent events is an incredibly simple transport method that relies entirely on chunked-encoding transfer, i.e. the HTTP connection is kept open and receives new data periodically.
Alternatively, a WebSocket connection can also be established.
## Server-sent events (HTTP)
### Endpoints
#### GET /api/v1/streaming/user
Returns events that are relevant to the authorized user, i.e. home timeline and notifications
#### GET /api/v1/streaming/public
Returns all public statuses
#### GET /api/v1/streaming/public/local
Returns all local statuses
#### GET /api/v1/streaming/hashtag?tag=:hashtag
Returns all public statuses for a particular hashtag
#### GET /api/v1/streaming/hashtag/local?tag=:hashtag
Returns all local statuses for a particular hashtag
#### GET /api/v1/streaming/list?list=:list_id
Returns statuses for a list
#### GET /api/v1/streaming/direct
Returns all direct messages
### Stream contents
The stream will contain events as well as heartbeat comments. Lines that begin with a colon (`:`) can be ignored by parsers, they are simply there to keep the connection open. Events have this structure:
```
event: name
data: payload
```
## WebSocket
For WebSockets, there is only one URL path (`/api/v1/streaming`). The access token as well as the endpoint you are interested in must be provided with query params, respectively `access_token` and `stream`. Query params `list` and `tag` are likewise supported for relevant endpoints.
Possible `stream` values:
- `user`
- `public`
- `public:local`
- `hashtag`
- `hashtag:local`
- `list`
- `direct`
## Event types
|Event|Description|What's in the payload|
|-----|-----------|---------------------|
|`update`|A new status has appeared|[Status]({{< relref "entities.md#status" >}})|
|`notification`|A new notification has appeared|[Notification]({{< relref "entities.md#notification" >}})|
|`delete`|A status has been deleted|ID of the deleted status|
|`filters_changed`|Keyword filters have been changed||
The payload is JSON-encoded.
> **Note:** In case of `filters_changed` event, `payload` is not defined.