From 33cb69ad072d88850d7ac63cbae192f40d6e8aa5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 1 Jan 2020 22:37:59 +0100 Subject: [PATCH] Update documentation with contents by twrnh --- .gitlab-ci.yml | 2 +- .../fontawesome.scss | 0 assets/main.js | 13 + {static => assets}/style.scss | 250 ++- config.toml | 105 +- content/en/_index.md | 116 +- content/en/admin/backups.md | 55 + content/en/admin/config.md | 222 ++ content/en/admin/install.md | 205 ++ content/en/admin/migrating.md | 93 + content/en/{usage => admin}/moderation.md | 37 +- content/en/admin/optional.md | 9 + content/en/admin/optional/elasticsearch.md | 78 + content/en/admin/optional/sso.md | 12 + .../optional/tor.md} | 99 +- content/en/admin/prerequisites.md | 96 + content/en/admin/scaling.md | 281 +++ content/en/admin/setup.md | 45 + content/en/admin/tootctl.md | 452 ++++ content/en/admin/troubleshooting.md | 28 + .../en/{administration => admin}/upgrading.md | 32 +- content/en/administration/configuration.md | 216 -- content/en/administration/installation.md | 333 --- content/en/administration/migrating.md | 103 - .../en/administration/post-installation.md | 106 - content/en/administration/scaling-up.md | 265 --- content/en/administration/troubleshooting.md | 28 - content/en/api/authentication.md | 48 - content/en/api/entities.md | 380 ---- content/en/api/guidelines.md | 52 - content/en/api/libraries.md | 103 - content/en/api/oauth-scopes.md | 89 + content/en/api/parameters.md | 44 - content/en/api/permissions.md | 49 - content/en/api/push.md | 15 - content/en/api/rest/accounts.md | 203 -- content/en/api/rest/apps.md | 38 - content/en/api/rest/blocks.md | 47 - content/en/api/rest/custom-emojis.md | 17 - content/en/api/rest/domain-blocks.md | 55 - content/en/api/rest/endorsements.md | 41 - content/en/api/rest/favourites.md | 43 - content/en/api/rest/filters.md | 75 - content/en/api/rest/follow-requests.md | 43 - content/en/api/rest/follow-suggestions.md | 25 - content/en/api/rest/instances.md | 17 - content/en/api/rest/lists.md | 127 -- content/en/api/rest/media.md | 46 - content/en/api/rest/mutes.md | 73 - content/en/api/rest/notifications.md | 117 - content/en/api/rest/polls.md | 31 - content/en/api/rest/reports.md | 24 - content/en/api/rest/scheduled-statuses.md | 51 - content/en/api/rest/search.md | 27 - content/en/api/rest/statuses.md | 177 -- content/en/api/rest/timelines.md | 123 -- content/en/api/streaming.md | 82 - content/en/client/authorized.md | 124 ++ content/en/client/guidelines.md | 53 + content/en/client/intro.md | 136 ++ content/en/client/libraries.md | 104 + content/en/client/public.md | 109 + content/en/client/token.md | 68 + content/en/dev/code.md | 60 + content/en/dev/overview.md | 30 + content/en/dev/routes.md | 209 ++ content/en/dev/setup.md | 38 + content/en/development/activitypub.md | 136 -- content/en/development/overview.md | 118 -- content/en/entities/account.md | 221 ++ content/en/entities/activity.md | 55 + content/en/entities/admin-account.md | 130 ++ content/en/entities/admin-report.md | 84 + content/en/entities/application.md | 69 + content/en/entities/attachment.md | 230 ++ content/en/entities/card.md | 168 ++ content/en/entities/context.md | 70 + content/en/entities/conversation.md | 70 + content/en/entities/emoji.md | 68 + content/en/entities/error.md | 87 + content/en/entities/featuredtag.md | 54 + content/en/entities/field.md | 70 + content/en/entities/filter.md | 92 + content/en/entities/history.md | 48 + content/en/entities/identityproof.md | 61 + content/en/entities/instance.md | 173 ++ content/en/entities/list.md | 39 + content/en/entities/marker.md | 66 + content/en/entities/mention.md | 66 + content/en/entities/notification.md | 111 + content/en/entities/poll.md | 119 ++ content/en/entities/preferences.md | 71 + content/en/entities/push-subscription.md | 79 + content/en/entities/relationship.md | 104 + content/en/entities/report.md | 30 + content/en/entities/results.md | 113 + content/en/entities/scheduledstatus.md | 98 + content/en/entities/source.md | 101 + content/en/entities/status.md | 291 +++ content/en/entities/tag.md | 89 + content/en/entities/token.md | 57 + content/en/methods/accounts.md | 1886 +++++++++++++++++ content/en/methods/accounts/blocks.md | 113 + content/en/methods/accounts/bookmarks.md | 54 + content/en/methods/accounts/domain_blocks.md | 232 ++ content/en/methods/accounts/endorsements.md | 122 ++ content/en/methods/accounts/favourites.md | 224 ++ content/en/methods/accounts/featured_tags.md | 299 +++ content/en/methods/accounts/filters.md | 440 ++++ .../en/methods/accounts/follow_requests.md | 225 ++ content/en/methods/accounts/mutes.md | 136 ++ content/en/methods/accounts/preferences.md | 63 + content/en/methods/accounts/reports.md | 60 + content/en/methods/accounts/suggestions.md | 213 ++ content/en/methods/admin.md | 612 ++++++ content/en/methods/apps.md | 131 ++ content/en/methods/apps/oauth.md | 194 ++ content/en/methods/instance.md | 222 ++ content/en/methods/instance/custom_emojis.md | 81 + content/en/methods/instance/directory.md | 70 + content/en/methods/instance/trends.md | 82 + content/en/methods/notifications.md | 387 ++++ content/en/methods/notifications/push.md | 260 +++ content/en/methods/oembed.md | 75 + content/en/methods/proofs.md | 68 + content/en/methods/search.md | 224 ++ content/en/methods/statuses.md | 1518 +++++++++++++ content/en/methods/statuses/media.md | 261 +++ content/en/methods/statuses/polls.md | 231 ++ .../en/methods/statuses/scheduled_statuses.md | 311 +++ content/en/methods/timelines.md | 414 ++++ content/en/methods/timelines/conversations.md | 251 +++ content/en/methods/timelines/lists.md | 578 +++++ content/en/methods/timelines/markers.md | 146 ++ content/en/methods/timelines/streaming.md | 91 + content/en/spec/activitypub.md | 360 ++++ content/en/spec/microformats.md | 98 + content/en/spec/oauth.md | 46 + content/en/spec/security.md | 133 ++ content/en/spec/webfinger.md | 75 + content/en/usage/basics.md | 68 - content/en/usage/decentralization.md | 91 - content/en/usage/privacy.md | 75 - content/en/user/contacts.md | 45 + content/en/user/discoverability.md | 39 + content/en/user/external.md | 21 + content/en/user/moderating.md | 107 + content/en/user/moving.md | 44 + content/en/user/network.md | 89 + content/en/user/posting.md | 134 ++ content/en/user/preferences.md | 89 + content/en/user/profile.md | 77 + content/en/user/signup.md | 58 + content/fr/_index.md | 15 - content/fr/administration/configuration.md | 216 -- content/fr/administration/installation.md | 339 --- content/fr/administration/migrating.md | 98 - .../fr/administration/optional-features.md | 172 -- .../fr/administration/post-installation.md | 106 - content/fr/administration/scaling-up.md | 265 --- content/fr/administration/troubleshooting.md | 28 - content/fr/administration/upgrading.md | 57 - content/fr/api/authentication.md | 48 - content/fr/api/entities.md | 379 ---- content/fr/api/guidelines.md | 52 - content/fr/api/libraries.md | 102 - content/fr/api/parameters.md | 44 - content/fr/api/permissions.md | 49 - content/fr/api/push.md | 15 - content/fr/api/rest/accounts.md | 203 -- content/fr/api/rest/apps.md | 38 - content/fr/api/rest/blocks.md | 47 - content/fr/api/rest/custom-emojis.md | 17 - content/fr/api/rest/domain-blocks.md | 55 - content/fr/api/rest/endorsements.md | 41 - content/fr/api/rest/favourites.md | 43 - content/fr/api/rest/filters.md | 75 - content/fr/api/rest/follow-requests.md | 43 - content/fr/api/rest/follow-suggestions.md | 25 - content/fr/api/rest/instances.md | 17 - content/fr/api/rest/lists.md | 127 -- content/fr/api/rest/media.md | 46 - content/fr/api/rest/mutes.md | 73 - content/fr/api/rest/notifications.md | 120 -- content/fr/api/rest/polls.md | 31 - content/fr/api/rest/reports.md | 24 - content/fr/api/rest/scheduled-statuses.md | 51 - content/fr/api/rest/search.md | 24 - content/fr/api/rest/statuses.md | 177 -- content/fr/api/rest/timelines.md | 123 -- content/fr/api/streaming.md | 78 - content/fr/development/activitypub.md | 136 -- content/fr/development/overview.md | 118 -- content/fr/usage/basics.md | 68 - content/fr/usage/decentralization.md | 91 - content/fr/usage/moderation.md | 73 - content/fr/usage/privacy.md | 75 - content/pl/_index.md | 15 - content/pl/administration/configuration.md | 216 -- content/pl/administration/installation.md | 339 --- content/pl/administration/migrating.md | 98 - .../pl/administration/optional-features.md | 20 - .../pl/administration/post-installation.md | 107 - content/pl/administration/troubleshooting.md | 29 - content/pl/administration/upgrading.md | 57 - content/pl/usage/basics.md | 68 - content/pl/usage/decentralization.md | 91 - content/pl/usage/moderation.md | 73 - content/pl/usage/privacy.md | 75 - data/HttpCodes.toml | 7 + i18n/en.toml | 59 + layouts/_default/single.html | 18 +- layouts/index.html | 23 +- layouts/partials/cta.html | 6 +- layouts/partials/footer.html | 10 +- layouts/partials/head.html | 8 +- layouts/partials/sidebar.html | 44 +- .../shortcodes/api-method-description.html | 1 + .../api-method-form-data-parameters.html | 2 + layouts/shortcodes/api-method-headers.html | 2 + layouts/shortcodes/api-method-parameter.html | 11 + .../api-method-path-parameters.html | 2 + .../api-method-query-parameters.html | 2 + layouts/shortcodes/api-method-request.html | 2 + ...i-method-response-example-description.html | 1 + .../api-method-response-example.html | 5 + layouts/shortcodes/api-method-response.html | 2 + layouts/shortcodes/api-method-spec.html | 1 + layouts/shortcodes/api-method.html | 12 + .../shortcodes/api_dynamic_pagination.html | 1 - layouts/shortcodes/api_method_info.html | 30 - layouts/shortcodes/api_pagination.html | 1 - layouts/shortcodes/caption-link.html | 4 + layouts/shortcodes/code.html | 7 + .../shortcodes/endapi-method-description.html | 1 + .../endapi-method-form-data-parameters.html | 1 + layouts/shortcodes/endapi-method-headers.html | 1 + .../shortcodes/endapi-method-parameter.html | 2 + .../endapi-method-path-parameters.html | 1 + .../endapi-method-query-parameters.html | 1 + layouts/shortcodes/endapi-method-request.html | 1 + ...i-method-response-example-description.html | 1 + .../endapi-method-response-example.html | 1 + .../shortcodes/endapi-method-response.html | 1 + layouts/shortcodes/endapi-method-spec.html | 1 + layouts/shortcodes/endapi-method.html | 1 + layouts/shortcodes/endtab.html | 1 + layouts/shortcodes/endtabs.html | 1 + layouts/shortcodes/hint.html | 5 + layouts/shortcodes/page-ref.html | 7 + layouts/shortcodes/tab.html | 2 + layouts/shortcodes/tabs.html | 1 + layouts/shortcodes/youtube.html | 9 + static/assets/decentralization.png | Bin 0 -> 243704 bytes static/assets/elephant.svg | 1 + static/assets/image (1).png | Bin 0 -> 25592 bytes static/assets/image (10).png | Bin 0 -> 227634 bytes static/assets/image (11).png | Bin 0 -> 167990 bytes static/assets/image (12).png | Bin 0 -> 63520 bytes static/assets/image (13).png | Bin 0 -> 101265 bytes static/assets/image (14).png | Bin 0 -> 45096 bytes static/assets/image (15).png | Bin 0 -> 50353 bytes static/assets/image (16).png | Bin 0 -> 40280 bytes static/assets/image (17).png | Bin 0 -> 4997 bytes static/assets/image (18).png | Bin 0 -> 17361 bytes static/assets/image (19).png | Bin 0 -> 19475 bytes static/assets/image (2).png | Bin 0 -> 2570 bytes static/assets/image (20).png | Bin 0 -> 22401 bytes static/assets/image (21).png | Bin 0 -> 19866 bytes static/assets/image (22).png | Bin 0 -> 215187 bytes static/assets/image (23).png | Bin 0 -> 44207 bytes static/assets/image (24).png | Bin 0 -> 45727 bytes static/assets/image (25).png | Bin 0 -> 17361 bytes static/assets/image (26).png | Bin 0 -> 227634 bytes static/assets/image (27).png | Bin 0 -> 27618 bytes static/assets/image (28).png | Bin 0 -> 12136 bytes static/assets/image (29).png | Bin 0 -> 469837 bytes static/assets/image (3).png | Bin 0 -> 192414 bytes static/assets/image (30).png | Bin 0 -> 294295 bytes static/assets/image (31).png | Bin 0 -> 146979 bytes static/assets/image (32).png | Bin 0 -> 249592 bytes static/assets/image (33).png | Bin 0 -> 29220 bytes static/assets/image (34).png | Bin 0 -> 162621 bytes static/assets/image (35).png | Bin 0 -> 43895 bytes static/assets/image (36).png | Bin 0 -> 21917 bytes static/assets/image (37).png | Bin 0 -> 30964 bytes static/assets/image (38).png | Bin 0 -> 52465 bytes static/assets/image (39).png | Bin 0 -> 41981 bytes static/assets/image (4).png | Bin 0 -> 251292 bytes static/assets/image (40).png | Bin 0 -> 22883 bytes static/assets/image (41).png | Bin 0 -> 9906 bytes static/assets/image (42).png | Bin 0 -> 158123 bytes static/assets/image (43).png | Bin 0 -> 9906 bytes static/assets/image (44).png | Bin 0 -> 58229 bytes static/assets/image (45).png | Bin 0 -> 173276 bytes static/assets/image (46).png | Bin 0 -> 157811 bytes static/assets/image (47).png | Bin 0 -> 73957 bytes static/assets/image (48).png | Bin 0 -> 29361 bytes static/assets/image (49).png | Bin 0 -> 104939 bytes static/assets/image (5).png | Bin 0 -> 215187 bytes static/assets/image (50).png | Bin 0 -> 100355 bytes static/assets/image (51).png | Bin 0 -> 158394 bytes static/assets/image (52).png | Bin 0 -> 27877 bytes static/assets/image (53).png | Bin 0 -> 43567 bytes static/assets/image (54).png | Bin 0 -> 3331 bytes static/assets/image (55).png | Bin 0 -> 179122 bytes static/assets/image (56).png | Bin 0 -> 15249 bytes static/assets/image (57).png | Bin 0 -> 47497 bytes static/assets/image (58).png | Bin 0 -> 7475 bytes static/assets/image (59).png | Bin 0 -> 10241 bytes static/assets/image (6).png | Bin 0 -> 21598 bytes static/assets/image (60).png | Bin 0 -> 3007 bytes static/assets/image (61).png | Bin 0 -> 25091 bytes static/assets/image (62).png | Bin 0 -> 57838 bytes static/assets/image (63).png | Bin 0 -> 676183 bytes static/assets/image (64).png | Bin 0 -> 173276 bytes static/assets/image (7).png | Bin 0 -> 11014 bytes static/assets/image (8).png | Bin 0 -> 157865 bytes static/assets/image (9).png | Bin 0 -> 298144 bytes static/assets/image.png | Bin 0 -> 29676 bytes static/assets/setup.png | Bin 0 -> 106700 bytes static/site.js | 27 - static/style.css | 412 ---- static/style.css.map | 7 - 324 files changed, 18140 insertions(+), 9654 deletions(-) rename static/fontawesome.css => assets/fontawesome.scss (100%) create mode 100644 assets/main.js rename {static => assets}/style.scss (73%) create mode 100644 content/en/admin/backups.md create mode 100644 content/en/admin/config.md create mode 100644 content/en/admin/install.md create mode 100644 content/en/admin/migrating.md rename content/en/{usage => admin}/moderation.md (82%) create mode 100644 content/en/admin/optional.md create mode 100644 content/en/admin/optional/elasticsearch.md create mode 100644 content/en/admin/optional/sso.md rename content/en/{administration/optional-features.md => admin/optional/tor.md} (53%) create mode 100644 content/en/admin/prerequisites.md create mode 100644 content/en/admin/scaling.md create mode 100644 content/en/admin/setup.md create mode 100644 content/en/admin/tootctl.md create mode 100644 content/en/admin/troubleshooting.md rename content/en/{administration => admin}/upgrading.md (63%) delete mode 100644 content/en/administration/configuration.md delete mode 100644 content/en/administration/installation.md delete mode 100644 content/en/administration/migrating.md delete mode 100644 content/en/administration/post-installation.md delete mode 100644 content/en/administration/scaling-up.md delete mode 100644 content/en/administration/troubleshooting.md delete mode 100644 content/en/api/authentication.md delete mode 100644 content/en/api/entities.md delete mode 100644 content/en/api/guidelines.md delete mode 100644 content/en/api/libraries.md create mode 100644 content/en/api/oauth-scopes.md delete mode 100644 content/en/api/parameters.md delete mode 100644 content/en/api/permissions.md delete mode 100644 content/en/api/push.md delete mode 100644 content/en/api/rest/accounts.md delete mode 100644 content/en/api/rest/apps.md delete mode 100644 content/en/api/rest/blocks.md delete mode 100644 content/en/api/rest/custom-emojis.md delete mode 100644 content/en/api/rest/domain-blocks.md delete mode 100644 content/en/api/rest/endorsements.md delete mode 100644 content/en/api/rest/favourites.md delete mode 100644 content/en/api/rest/filters.md delete mode 100644 content/en/api/rest/follow-requests.md delete mode 100644 content/en/api/rest/follow-suggestions.md delete mode 100644 content/en/api/rest/instances.md delete mode 100644 content/en/api/rest/lists.md delete mode 100644 content/en/api/rest/media.md delete mode 100644 content/en/api/rest/mutes.md delete mode 100644 content/en/api/rest/notifications.md delete mode 100644 content/en/api/rest/polls.md delete mode 100644 content/en/api/rest/reports.md delete mode 100644 content/en/api/rest/scheduled-statuses.md delete mode 100644 content/en/api/rest/search.md delete mode 100644 content/en/api/rest/statuses.md delete mode 100644 content/en/api/rest/timelines.md delete mode 100644 content/en/api/streaming.md create mode 100644 content/en/client/authorized.md create mode 100644 content/en/client/guidelines.md create mode 100644 content/en/client/intro.md create mode 100644 content/en/client/libraries.md create mode 100644 content/en/client/public.md create mode 100644 content/en/client/token.md create mode 100644 content/en/dev/code.md create mode 100644 content/en/dev/overview.md create mode 100644 content/en/dev/routes.md create mode 100644 content/en/dev/setup.md delete mode 100644 content/en/development/activitypub.md delete mode 100644 content/en/development/overview.md create mode 100644 content/en/entities/account.md create mode 100644 content/en/entities/activity.md create mode 100644 content/en/entities/admin-account.md create mode 100644 content/en/entities/admin-report.md create mode 100644 content/en/entities/application.md create mode 100644 content/en/entities/attachment.md create mode 100644 content/en/entities/card.md create mode 100644 content/en/entities/context.md create mode 100644 content/en/entities/conversation.md create mode 100644 content/en/entities/emoji.md create mode 100644 content/en/entities/error.md create mode 100644 content/en/entities/featuredtag.md create mode 100644 content/en/entities/field.md create mode 100644 content/en/entities/filter.md create mode 100644 content/en/entities/history.md create mode 100644 content/en/entities/identityproof.md create mode 100644 content/en/entities/instance.md create mode 100644 content/en/entities/list.md create mode 100644 content/en/entities/marker.md create mode 100644 content/en/entities/mention.md create mode 100644 content/en/entities/notification.md create mode 100644 content/en/entities/poll.md create mode 100644 content/en/entities/preferences.md create mode 100644 content/en/entities/push-subscription.md create mode 100644 content/en/entities/relationship.md create mode 100644 content/en/entities/report.md create mode 100644 content/en/entities/results.md create mode 100644 content/en/entities/scheduledstatus.md create mode 100644 content/en/entities/source.md create mode 100644 content/en/entities/status.md create mode 100644 content/en/entities/tag.md create mode 100644 content/en/entities/token.md create mode 100644 content/en/methods/accounts.md create mode 100644 content/en/methods/accounts/blocks.md create mode 100644 content/en/methods/accounts/bookmarks.md create mode 100644 content/en/methods/accounts/domain_blocks.md create mode 100644 content/en/methods/accounts/endorsements.md create mode 100644 content/en/methods/accounts/favourites.md create mode 100644 content/en/methods/accounts/featured_tags.md create mode 100644 content/en/methods/accounts/filters.md create mode 100644 content/en/methods/accounts/follow_requests.md create mode 100644 content/en/methods/accounts/mutes.md create mode 100644 content/en/methods/accounts/preferences.md create mode 100644 content/en/methods/accounts/reports.md create mode 100644 content/en/methods/accounts/suggestions.md create mode 100644 content/en/methods/admin.md create mode 100644 content/en/methods/apps.md create mode 100644 content/en/methods/apps/oauth.md create mode 100644 content/en/methods/instance.md create mode 100644 content/en/methods/instance/custom_emojis.md create mode 100644 content/en/methods/instance/directory.md create mode 100644 content/en/methods/instance/trends.md create mode 100644 content/en/methods/notifications.md create mode 100644 content/en/methods/notifications/push.md create mode 100644 content/en/methods/oembed.md create mode 100644 content/en/methods/proofs.md create mode 100644 content/en/methods/search.md create mode 100644 content/en/methods/statuses.md create mode 100644 content/en/methods/statuses/media.md create mode 100644 content/en/methods/statuses/polls.md create mode 100644 content/en/methods/statuses/scheduled_statuses.md create mode 100644 content/en/methods/timelines.md create mode 100644 content/en/methods/timelines/conversations.md create mode 100644 content/en/methods/timelines/lists.md create mode 100644 content/en/methods/timelines/markers.md create mode 100644 content/en/methods/timelines/streaming.md create mode 100644 content/en/spec/activitypub.md create mode 100644 content/en/spec/microformats.md create mode 100644 content/en/spec/oauth.md create mode 100644 content/en/spec/security.md create mode 100644 content/en/spec/webfinger.md delete mode 100644 content/en/usage/basics.md delete mode 100644 content/en/usage/decentralization.md delete mode 100644 content/en/usage/privacy.md create mode 100644 content/en/user/contacts.md create mode 100644 content/en/user/discoverability.md create mode 100644 content/en/user/external.md create mode 100644 content/en/user/moderating.md create mode 100644 content/en/user/moving.md create mode 100644 content/en/user/network.md create mode 100644 content/en/user/posting.md create mode 100644 content/en/user/preferences.md create mode 100644 content/en/user/profile.md create mode 100644 content/en/user/signup.md delete mode 100644 content/fr/_index.md delete mode 100644 content/fr/administration/configuration.md delete mode 100644 content/fr/administration/installation.md delete mode 100644 content/fr/administration/migrating.md delete mode 100644 content/fr/administration/optional-features.md delete mode 100644 content/fr/administration/post-installation.md delete mode 100644 content/fr/administration/scaling-up.md delete mode 100644 content/fr/administration/troubleshooting.md delete mode 100644 content/fr/administration/upgrading.md delete mode 100644 content/fr/api/authentication.md delete mode 100644 content/fr/api/entities.md delete mode 100644 content/fr/api/guidelines.md delete mode 100644 content/fr/api/libraries.md delete mode 100644 content/fr/api/parameters.md delete mode 100644 content/fr/api/permissions.md delete mode 100644 content/fr/api/push.md delete mode 100644 content/fr/api/rest/accounts.md delete mode 100644 content/fr/api/rest/apps.md delete mode 100644 content/fr/api/rest/blocks.md delete mode 100644 content/fr/api/rest/custom-emojis.md delete mode 100644 content/fr/api/rest/domain-blocks.md delete mode 100644 content/fr/api/rest/endorsements.md delete mode 100644 content/fr/api/rest/favourites.md delete mode 100644 content/fr/api/rest/filters.md delete mode 100644 content/fr/api/rest/follow-requests.md delete mode 100644 content/fr/api/rest/follow-suggestions.md delete mode 100644 content/fr/api/rest/instances.md delete mode 100644 content/fr/api/rest/lists.md delete mode 100644 content/fr/api/rest/media.md delete mode 100644 content/fr/api/rest/mutes.md delete mode 100644 content/fr/api/rest/notifications.md delete mode 100644 content/fr/api/rest/polls.md delete mode 100644 content/fr/api/rest/reports.md delete mode 100644 content/fr/api/rest/scheduled-statuses.md delete mode 100644 content/fr/api/rest/search.md delete mode 100644 content/fr/api/rest/statuses.md delete mode 100644 content/fr/api/rest/timelines.md delete mode 100644 content/fr/api/streaming.md delete mode 100644 content/fr/development/activitypub.md delete mode 100644 content/fr/development/overview.md delete mode 100644 content/fr/usage/basics.md delete mode 100644 content/fr/usage/decentralization.md delete mode 100644 content/fr/usage/moderation.md delete mode 100644 content/fr/usage/privacy.md delete mode 100644 content/pl/_index.md delete mode 100644 content/pl/administration/configuration.md delete mode 100644 content/pl/administration/installation.md delete mode 100644 content/pl/administration/migrating.md delete mode 100644 content/pl/administration/optional-features.md delete mode 100644 content/pl/administration/post-installation.md delete mode 100644 content/pl/administration/troubleshooting.md delete mode 100644 content/pl/administration/upgrading.md delete mode 100644 content/pl/usage/basics.md delete mode 100644 content/pl/usage/decentralization.md delete mode 100644 content/pl/usage/moderation.md delete mode 100644 content/pl/usage/privacy.md create mode 100644 data/HttpCodes.toml create mode 100644 i18n/en.toml create mode 100644 layouts/shortcodes/api-method-description.html create mode 100644 layouts/shortcodes/api-method-form-data-parameters.html create mode 100644 layouts/shortcodes/api-method-headers.html create mode 100644 layouts/shortcodes/api-method-parameter.html create mode 100644 layouts/shortcodes/api-method-path-parameters.html create mode 100644 layouts/shortcodes/api-method-query-parameters.html create mode 100644 layouts/shortcodes/api-method-request.html create mode 100644 layouts/shortcodes/api-method-response-example-description.html create mode 100644 layouts/shortcodes/api-method-response-example.html create mode 100644 layouts/shortcodes/api-method-response.html create mode 100644 layouts/shortcodes/api-method-spec.html create mode 100644 layouts/shortcodes/api-method.html delete mode 100644 layouts/shortcodes/api_dynamic_pagination.html delete mode 100644 layouts/shortcodes/api_method_info.html delete mode 100644 layouts/shortcodes/api_pagination.html create mode 100644 layouts/shortcodes/caption-link.html create mode 100644 layouts/shortcodes/code.html create mode 100644 layouts/shortcodes/endapi-method-description.html create mode 100644 layouts/shortcodes/endapi-method-form-data-parameters.html create mode 100644 layouts/shortcodes/endapi-method-headers.html create mode 100644 layouts/shortcodes/endapi-method-parameter.html create mode 100644 layouts/shortcodes/endapi-method-path-parameters.html create mode 100644 layouts/shortcodes/endapi-method-query-parameters.html create mode 100644 layouts/shortcodes/endapi-method-request.html create mode 100644 layouts/shortcodes/endapi-method-response-example-description.html create mode 100644 layouts/shortcodes/endapi-method-response-example.html create mode 100644 layouts/shortcodes/endapi-method-response.html create mode 100644 layouts/shortcodes/endapi-method-spec.html create mode 100644 layouts/shortcodes/endapi-method.html create mode 100644 layouts/shortcodes/endtab.html create mode 100644 layouts/shortcodes/endtabs.html create mode 100644 layouts/shortcodes/hint.html create mode 100644 layouts/shortcodes/page-ref.html create mode 100644 layouts/shortcodes/tab.html create mode 100644 layouts/shortcodes/tabs.html create mode 100644 layouts/shortcodes/youtube.html create mode 100644 static/assets/decentralization.png create mode 100644 static/assets/elephant.svg create mode 100644 static/assets/image (1).png create mode 100644 static/assets/image (10).png create mode 100644 static/assets/image (11).png create mode 100644 static/assets/image (12).png create mode 100644 static/assets/image (13).png create mode 100644 static/assets/image (14).png create mode 100644 static/assets/image (15).png create mode 100644 static/assets/image (16).png create mode 100644 static/assets/image (17).png create mode 100644 static/assets/image (18).png create mode 100644 static/assets/image (19).png create mode 100644 static/assets/image (2).png create mode 100644 static/assets/image (20).png create mode 100644 static/assets/image (21).png create mode 100644 static/assets/image (22).png create mode 100644 static/assets/image (23).png create mode 100644 static/assets/image (24).png create mode 100644 static/assets/image (25).png create mode 100644 static/assets/image (26).png create mode 100644 static/assets/image (27).png create mode 100644 static/assets/image (28).png create mode 100644 static/assets/image (29).png create mode 100644 static/assets/image (3).png create mode 100644 static/assets/image (30).png create mode 100644 static/assets/image (31).png create mode 100644 static/assets/image (32).png create mode 100644 static/assets/image (33).png create mode 100644 static/assets/image (34).png create mode 100644 static/assets/image (35).png create mode 100644 static/assets/image (36).png create mode 100644 static/assets/image (37).png create mode 100644 static/assets/image (38).png create mode 100644 static/assets/image (39).png create mode 100644 static/assets/image (4).png create mode 100644 static/assets/image (40).png create mode 100644 static/assets/image (41).png create mode 100644 static/assets/image (42).png create mode 100644 static/assets/image (43).png create mode 100644 static/assets/image (44).png create mode 100644 static/assets/image (45).png create mode 100644 static/assets/image (46).png create mode 100644 static/assets/image (47).png create mode 100644 static/assets/image (48).png create mode 100644 static/assets/image (49).png create mode 100644 static/assets/image (5).png create mode 100644 static/assets/image (50).png create mode 100644 static/assets/image (51).png create mode 100644 static/assets/image (52).png create mode 100644 static/assets/image (53).png create mode 100644 static/assets/image (54).png create mode 100644 static/assets/image (55).png create mode 100644 static/assets/image (56).png create mode 100644 static/assets/image (57).png create mode 100644 static/assets/image (58).png create mode 100644 static/assets/image (59).png create mode 100644 static/assets/image (6).png create mode 100644 static/assets/image (60).png create mode 100644 static/assets/image (61).png create mode 100644 static/assets/image (62).png create mode 100644 static/assets/image (63).png create mode 100644 static/assets/image (64).png create mode 100644 static/assets/image (7).png create mode 100644 static/assets/image (8).png create mode 100644 static/assets/image (9).png create mode 100644 static/assets/image.png create mode 100644 static/assets/setup.png delete mode 100644 static/site.js delete mode 100644 static/style.css delete mode 100644 static/style.css.map diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f5391697..15c7adb1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -image: registry.gitlab.com/pages/hugo:latest +image: monachus/hugo:latest variables: GIT_SUBMODULE_STRATEGY: recursive diff --git a/static/fontawesome.css b/assets/fontawesome.scss similarity index 100% rename from static/fontawesome.css rename to assets/fontawesome.scss diff --git a/assets/main.js b/assets/main.js new file mode 100644 index 00000000..35c7f745 --- /dev/null +++ b/assets/main.js @@ -0,0 +1,13 @@ +(function () { + 'use strict'; + + const onLoaded = () => { + // Nothing for now + }; + + if (['interactive', 'complete'].indexOf(document.readyState) !== -1) { + onLoaded(); + } else { + document.addEventListener('DOMContentLoaded', onLoaded); + } +})(); diff --git a/static/style.scss b/assets/style.scss similarity index 73% rename from static/style.scss rename to assets/style.scss index 3f2d0c72..6016ef7b 100644 --- a/static/style.scss +++ b/assets/style.scss @@ -1,5 +1,5 @@ @import url('https://fonts.googleapis.com/css?family=Montserrat:400,600|Roboto:400,500,700|Roboto+Mono:400'); -@import url('https://unpkg.com/ionicons@4.2.0/dist/css/ionicons.min.css'); +@import 'fontawesome.scss'; $white: #fff ; // color5 $lightest: #d9e1e8; // color2 @@ -123,13 +123,11 @@ body { justify-content: flex-start; align-items: center; color: $darkest; + margin-top: 12px; margin-bottom: 52px; img { height: 38px; - position: relative; - left: -14px; - top: -4px; } @media screen and (max-width: $mobile-width) { @@ -141,30 +139,26 @@ body { } } - a { - display: inline-block; - color: $lighter; - text-decoration: none; - font-size: 14px; - padding: 10px 0; - - &:hover, - &:focus, - &:active { - color: lighten($lighter, 8%); - } + & > ul > li { + margin-bottom: 26px; } - & > ul > li > a { - font-size: 18px; - font-family: 'Montserrat', sans-serif; - font-weight: 600; - padding-bottom: 26px; + .sub-title { + display: block; + padding: 10px; + font-weight: 500; + text-transform: uppercase; + } + + & > ul a { + display: block; + color: $white; + text-decoration: none; + font-weight: 500; + padding: 10px; } .sub-menu { - padding-bottom: 26px; - a.active { color: $vibrant; } @@ -172,6 +166,10 @@ body { &.collapsed { display: none; } + + .sub-menu { + padding-left: 15px; + } } } @@ -424,6 +422,10 @@ main { overflow: auto; } + figure pre { + margin-bottom: 0; + } + code { padding: 0.2em 0.4em; margin: 0; @@ -569,3 +571,205 @@ main { } } } + +.hint { + margin: 26px 0; + padding: 16px 16px 16px 56px; + position: relative; + border-left: 4px solid; + border-radius: 4px; + background-color: lighten($darkest, 8%); + color: $white; + font-size: 16px; + line-height: 28px; + + &-info { + border-color: $vibrant; + + .hint-icon { + color: $vibrant; + } + } + + &-warning { + border-color: #ca8f04; + + .hint-icon { + color: #ca8f04; + } + } + + &-success { + border-color: $success; + + .hint-icon { + color: $success; + } + } + + &-danger { + border-color: $error; + + .hint-icon { + color: $error; + } + } + + &-icon { + position: absolute; + top: 18px; + left: 16px; + font-size: 24px; + } +} + +.page-ref { + display: block; + background: lighten($darkest, 4%); + color: $vibrant; + text-decoration: none; + font-weight: 500; + font-size: 18px; + position: relative; + margin: 26px 0; + padding: 24px 24px 24px 50px; + border-radius: 4px; + + &-icon { + position: absolute; + top: 20px; + left: 16px; + font-size: 24px; + } + + &:hover, + &:focus, + &:active { + background: lighten($darkest, 8%); + } +} + +.api-method { + display: flex; + align-items: center; + font-weight: 500; + font-size: 18px; + + &-method { + display: inline-flex; + align-items: center; + padding: 2px 0; + border-radius: 9999px; + height: 21px; + color: $white; + background: $vibrant; + margin: 0; + margin-right: 8px; + + span { + display: inline-block; + padding: 0 8px; + font-size: 12px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 1px; + line-height: 15px; + } + } + + &-url { + background: lighten($darkest, 4%); + border-radius: 4px; + padding: 8px; + font-size: 16px; + margin: 26px 0; + line-height: 1.7; + } + + &-host { + color: $darker; + } + + &-path { + font-weight: 700; + color: $white; + } +} + +.api-method-parameters-list { + border: 1px solid lighten($darkest, 8%); + border-radius: 4px; + margin-bottom: 26px; +} + +.api-method-parameters-type { + font-weight: 400; + color: $darker; +} + +.api-method-parameters-type, +.api-method-response-example h5 { + font-size: 16px; + margin-bottom: 16px; +} + +.api-method-parameter { + display: flex; + border-bottom: 1px solid lighten($darkest, 8%); + + &:last-child { + border-bottom: 0; + } + + &-cell { + box-sizing: border-box; + padding: 16px 10px; + color: $white; + } + + &-required { + text-transform: uppercase; + font-size: 12px; + font-weight: 500; + color: $error; + } + + &-optional { + text-transform: uppercase; + font-size: 12px; + font-weight: 500; + color: $darker; + } + + &-name { + width: 180px; + font-size: 16px; + + & > div:first-child { + margin-bottom: 2px; + } + } + + &-type { + width: 100px; + } + + &-description { + flex: 1 1 0%; + font-size: 15px; + } +} + +.api-method-response-example { + &-indicator { + display: inline-block; + width: 12px; + height: 12px; + border-radius: 50%; + background: $success; + + &-error { + background: $error; + } + } +} diff --git a/config.toml b/config.toml index 4c98db82..ee35dca9 100644 --- a/config.toml +++ b/config.toml @@ -8,69 +8,50 @@ metaDataFormat = "yaml" paginate = 100 enableGitInfo = true +[menu] + [[menu.docs]] + name = "Using Mastodon" + weight = 10 + identifier = "user" + url = "/user/" + [[menu.docs]] + name = "Running Mastodon" + weight = 20 + identifier = "admin" + url = "/admin/" + [[menu.docs]] + name = "Developing Mastodon apps" + weight = 30 + identifier = "client" + url = "/client/" + [[menu.docs]] + name = "Contributing to Mastodon" + weight = 40 + identifier = "dev" + url = "/dev/" + [[menu.docs]] + name = "Spec compliance" + weight = 50 + identifier = "spec" + url = "/spec/" + [[menu.docs]] + name = "REST API" + weight = 60 + identifier = "api" + url = "/api/" + [[menu.docs]] + name = "API Methods" + weight = 70 + identifier = "methods" + url = "/methods/" + [[menu.docs]] + name = "API Entities" + weight = 80 + identifier = "entities" + url = "/entities/" + [languages] [languages.en] contentDir = "content/en" languageName = "English" - weight = 1 - [languages.pl] - contentDir = "content/pl" - languageName = "Polski" - weight = 1 - [languages.fr] - contentDir = "content/fr" - languageName = "Français" - weight = 1 - [languages.fr.menu] - [[languages.fr.menu.docs]] - name = "Guide d'utilisation" - weight = 1 - identifier = "usage" - url = "/usage/" - [[languages.fr.menu.docs]] - name = "Guide d'administration" - weight = 2 - identifier = "administration" - url = "/administration/" - [[languages.fr.menu.docs]] - name = "Guide de développement" - weight = 3 - identifier = "development" - url = "/development/" - [[languages.fr.menu.docs]] - name = "Aperçu de l'API" - weight = 4 - identifier = "api" - url = "/api/" - [[languages.fr.menu.docs]] - name = "API REST" - weight = 5 - identifier = "rest-api" - url = "/api/rest/" - -[menu] - [[menu.docs]] - name = "User guide" - weight = 1 - identifier = "usage" - url = "/usage/" - [[menu.docs]] - name = "Administrator guide" - weight = 2 - identifier = "administration" - url = "/administration/" - [[menu.docs]] - name = "API Overview" - weight = 4 - identifier = "api" - url = "/api/" - [[menu.docs]] - name = "REST API" - weight = 5 - identifier = "rest-api" - url = "/api/rest/" - [[menu.docs]] - name = "Development guide" - weight = 3 - identifier = "development" - url = "/development/" \ No newline at end of file + weight = -99 diff --git a/content/en/_index.md b/content/en/_index.md index 24c14aaf..37d169e4 100644 --- a/content/en/_index.md +++ b/content/en/_index.md @@ -1,15 +1,113 @@ --- -title: Mastodon documentation +title: What is Mastodon? +description: Welcome to the Mastodon documentation! +menu: + docs: + weight: -99 --- -Welcome to the Mastodon documentation! +{{< youtube id="IPSbNdBmWKE" caption="An introductory video explaining basic Mastodon concepts with visual animations" >}} + +## What is a microblog? + +Similar to how blogging is the act of publishing updates to a website, **microblogging** is the act of publishing small updates to a stream of updates on your profile. You can publish text posts and optionally attach media such as pictures, audio, video, or polls. Mastodon lets you follow friends and discover new ones. + +## What is federation? + +**Federation** is a form of decentralization. Instead of a single central service that all people use, there are multiple services, that any number of people can use. + +| Grade of centralization | Examples | +| :--- | :--- | +| Centralized | Twitter, Facebook, Instagram | +| Federated | Email, XMPP, phone networks, physical mail | +| Distributed | BitTorrent, IPFS, Scuttlebutt | + +A Mastodon website can operate alone. Just like a traditional website, people sign up on it, post messages, upload pictures and talk to each other. _Unlike_ a traditional website, Mastodon websites can interoperate, letting their users communicate with each other; just like you can send an email from your Gmail account to someone from Outlook, Fastmail, Protonmail, or any other email provider, as long as you know their email address, **you can mention or message anyone on any website using their address**. + +{{< figure src="/assets/image%20%289%29.png" caption="From left to right: Centralized, Federated, Distributed" >}} + + + +## What is ActivityPub? + +Mastodon uses a standardized, open protocol to implement federation. It is called **ActivityPub**. Any software that likewise implements federation via ActivityPub can seamlessly communicate with Mastodon, just like Mastodon websites communicate with one another. + +The **fediverse** \(“federated universe”\) is the name for all websites that can communicate with each other over ActivityPub and the World Wide Web. That includes all Mastodon servers, but also other implementations: + +* Pleroma, a modular microblogging engine, +* Pixelfed, which lets you share and consume media posts, +* Misskey, which includes microblogging alongside a customizable dashboard, +* PeerTube, which lets you upload videos to channels, +* Plume, which lets you publish longer-form articles, +* and many more, including individual and personal websites! + +The fediverse does not have its own brand, so you might more often hear “follow me on Mastodon” than “follow me on the fediverse”, but technically the latter is more correct. + +## Practical implications + +### Choice of service provider and policy + +Because Mastodon is simply software that can be used to power any website, potential users of Mastodon have the option of choosing a service provider from already-existing Mastodon websites, or to create their own Mastodon website if they wish. The Mastodon project maintains a list of recommended service providers at [joinmastodon.org](https://joinmastodon.org), sortable by category and/or language. Some websites may have moderation policies that go beyond this, such as requiring the use of certain tags on potentially sensitive content, and some websites may have more relaxed moderation policies, but websites listed in the picker all agree to adopt the [Mastodon Server Covenant](https://joinmastodon.org/covenant), meaning that they pledge to actively moderate against hate speech, to take daily backups, to have at least one emergency admin, and to provide at least 3 months advance notice in case of shutdown. + +> Maintaining communities that feel safe for all of its members is not easy. Mastodon provides a lot of foundational framework and tools for doing it, and shifts the power to effect change from one commercial entity to the communities themselves. +> +> -- Eugen Rochko, Jul 6 2018, ["Cage the Mastodon"](https://blog.joinmastodon.org/2018/07/cage-the-mastodon/) + +> A centralized social media platform has a hierarchical structure where rules and their enforcement, as well as the development and direction of the platform, are decided by the CEO \[...\] A decentralized network deliberately relinquishes control of the platform owner, by essentially not having one. +> +> -- Eugen Rochko, Dec 30 2018, ["Why does decentralization matter?"](https://blog.joinmastodon.org/2018/12/why-does-decentralization-matter/) + +### Funding and monetization + +Mastodon websites are operated by different people or organizations completely independently. Mastodon does not implement any monetization strategies in the software. + +Some server operators choose to offer paid accounts, some server operators are companies who can utilize their existing infrastructure, some server operators rely on crowdfunding from their users via Patreon and similar services, and some server operators are just paying out-of-pocket for a personal server for themselves and maybe some friends. So if you want to support the server hosting your account, check if it offers a way to donate. + +Mastodon development is likewise crowdfunded via [Patreon](https://patreon.com/mastodon) and via [OpenCollective](https://opencollective.com/mastodon). **No venture capital is involved.** + +> In my opinion, “instant, public, global messaging and conversation” should, in fact, be _global_. Distributed between independent organizations and actors who can self-govern. A public utility, without incentives to exploit the conversations for profit. +> +> -- Eugen Rochko, Mar 3 2018, ["Twitter is not a public utility"](https://blog.joinmastodon.org/2018/03/twitter-is-not-a-public-utility/) + +### Interoperability between different software + +In practical terms: Imagine if you could follow an Instagram user from your Twitter account and comment on their photos without leaving your account. If Twitter and Instagram were federated services that used the same protocol, that would be possible. With a Mastodon account, **you can communicate with any other compatible website,** _**even if it is not running on Mastodon**_. All that is necessary is that the software support the same subset of the ActivityPub protocol that allows for creating and interacting with status updates. To find out more about the technical specifications required to interoperate with Mastodon, see [ActivityPub](spec/activitypub.md), [WebFinger](spec/webfinger.md), and [Security](spec/security.md). To read more about what ActivityPub allows us to do, see [Why ActivityPub is the future](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/). + +> All of these platforms are different and they focus on different needs. And yet, the foundation is all the same: people subscribing to receive posts from other people. And so, they are all compatible. +> +> -- Eugen Rochko, Jun 27 2018, ["Why ActivityPub is the future"](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/) + +### Free/libre software + +Unlike proprietary services, **anyone has the complete freedom to run, examine, inspect, copy, modify, distribute, and reuse the Mastodon source code, provided they guarantee the same freedoms for any derivative work.** Just like how users of Mastodon can choose their service provider, you as an individual are free to contribute features to Mastodon or publish a modified version of Mastodon that includes different features. These modified versions, also known as software forks, are required to also uphold the same freedoms as the original Mastodon project. For example, [glitch-soc](https://glitch-soc.github.io/docs/) is a software distribution that adds various experimental features. Many individual forks exist as well, perhaps themed slightly differently or including small modifications to the codebase. Because Mastodon is libre software that respects your freedom, personalizations like this are not only allowed but encouraged. + +> The ultimate power is in giving people the ability to create their own spaces, their own communities, to modify the software as they see fit, but without sacrificing the ability of people from different communities to interact with each other. +> +> -- Eugen Rochko, Feb 20 2017, ["The power to build communities: A response to Mark Zuckerberg"](https://blog.joinmastodon.org/2017/02/the-power-to-build-communities/) + +> Decentralization is biodiversity of the digital world, the hallmark of a healthy ecosystem. A decentralized network like the fediverse allows different user interfaces, different software, different forms of government to co-exist and cooperate. +> +> -- Eugen Rochko, Dec 30 2018, ["Why does decentralization matter?"](https://blog.joinmastodon.org/2018/12/why-does-decentralization-matter/) + +## Choose your path + +![](/assets/elephant.svg) + +Learn how to use Mastodon: + +{{< page-ref page="user/signup.md" >}} + +Learn how to install Mastodon: + +{{< page-ref page="admin/prerequisites.md" >}} + +Learn how to write an app for Mastodon: + +{{< page-ref page="client/intro.md" >}} + +Learn about the Mastodon backend and how to contribute: + +{{< page-ref page="dev/overview.md" >}} -
- {{< youtube "IPSbNdBmWKE" >}} -
-**Choose your path:** -- [Learn how to use Mastodon]({{< relref "usage/basics.md" >}}) -- [Learn how to install Mastodon]({{< relref "administration/installation.md" >}}) -- [Learn how to write an app for Mastodon]({{< relref "api/guidelines.md" >}}) diff --git a/content/en/admin/backups.md b/content/en/admin/backups.md new file mode 100644 index 00000000..e68ff412 --- /dev/null +++ b/content/en/admin/backups.md @@ -0,0 +1,55 @@ +--- +title: Backing up your server +menu: + docs: + weight: 80 + parent: admin +--- + +## Setting up regular backups \(optional, but not really\) + +For any real-world use, you should make sure to regularly backup your Mastodon server. + +### Overview + +Things that need to be backed up in order of importance: + +1. PostgreSQL database +2. Application secrets from the `.env.production` file or equivalent +3. User-uploaded files +4. Redis database + +### Failure modes + +There are two failure types that people in general may guard for: The failure of the hardware, such as data corruption on the disk; and human and software error, such as wrongful deletion of particular piece of data. In this documentation, only the former type is considered. + +A lost PostgreSQL database is complete game over. Mastodon stores all the most important data in the PostgreSQL database. If the database disappears, all the accounts, posts and followers on your server will disappear with it. + +If you lose application secrets, some functions of Mastodon will stop working for your users, they will be logged out, two-factor authentication will become unavailable, Web Push API subscriptions will stop working. + +If you lose user-uploaded files, you will lose avatars, headers, and media attachments, but Mastodon _will_ work moving forward. + +Losing the Redis database is almost harmless: The only irrecoverable data will be the contents of the Sidekiq queues and scheduled retries of previously failed jobs. The home and list feeds are stored in Redis, but can be regenerated with tootctl. + +The best backups are so-called off-site backups, i.e. ones that are not stored on the same machine as Mastodon itself. If the server you are hosted on goes on fire and the hard disk drive explodes, backups stored on that same hard drive won’t be of much use. + +### Backing up application secrets + +Application secrets are the easiest to backup, since they never change. You only need to store `.env.production` somewhere safe. + +### Backing up PostgreSQL + +PostgreSQL is at risk of data corruption from power cuts, hard disk drive failure, and botched schema migrations. For that reason, occassionally making a backup with `pg_dump` or `pg_dumpall` is recommended. + +For high-availability setups, it is possible to use hot streaming replication to have a second PostgreSQL server with always up-to-date data, ready to be switched over to if the other server goes down. + +### Backing up user-uploaded files + +If you are using an external object storage provider such as Amazon S3, Google Cloud or Wasabi, then you don’t need to worry about backing those up. The respective companies are responsible for handling hardware failures. + +If you are using local file storage, then it’s up to you to make copies of the sizeable `public/system` directory, where uploaded files are stored by default. + +### Backing up Redis + +Backing up Redis is easy. Redis regularly writes to `/var/lib/redis/dump.rdb` which is the only file you need to make a copy of. + diff --git a/content/en/admin/config.md b/content/en/admin/config.md new file mode 100644 index 00000000..4d78ef04 --- /dev/null +++ b/content/en/admin/config.md @@ -0,0 +1,222 @@ +--- +title: Configuring variables +menu: + docs: + weight: 30 + parent: admin +--- + +{{< hint style="warning" >}} +This page is under construction. +{{< /hint >}} + +Mastodon uses environment variables as its configuration. + +For convenience, it can read them from a flat file called `.env.production` in the Mastodon directory, but they can always be overridden by a specific process. For example, systemd service files can read environment variables from an `EnvironmentFile` or from inline definitions with `Environment`, so you can have different configuration parameters for specific services. They can also be specified when calling Mastodon from the command line. + +### Basic + +#### Federation + +* `LOCAL_DOMAIN` +* `WEB_DOMAIN` +* `ALTERNATE_DOMAINS` + +#### Secrets + +* `SECRET_KEY_BASE` +* `OTP_SECRET` +* `VAPID_PRIVATE_KEY` +* `VAPID_PUBLIC_KEY` + +#### Deployment + +* `RAILS_ENV` +* `RAILS_SERVE_STATIC_FILES` +* `RAILS_LOG_LEVEL` +* `TRUSTED_PROXY_IP` +* `SOCKET` +* `PORT` +* `NODE_ENV` +* `BIND` + +#### Scaling options + +* `WEB_CONCURRENCY` +* `MAX_THREADS` +* `PREPARED_STATEMENTS` +* `STREAMING_API_BASE_URL` +* `STREAMING_CLUSTER_NUM` + +### Database connections + +#### PostgreSQL + +* `DB_HOST` +* `DB_USER` +* `DB_NAME` +* `DB_PASS` +* `DB_PORT` +* `DATABASE_URL` + +#### Redis + +* `REDIS_HOST` +* `REDIS_PORT` +* `REDIS_URL` +* `REDIS_NAMESPACE` +* `CACHE_REDIS_HOST` +* `CACHE_REDIS_PORT` +* `CACHE_REDIS_URL` +* `CACHE_REDIS_NAMESPACE` + +#### ElasticSearch + +* `ES_ENABLED` +* `ES_HOST` +* `ES_PORT` +* `ES_PREFIX` + +#### StatsD + +* `STATSD_ADDR` +* `STATSD_NAMESPACE` + +### Limits + +* `SINGLE_USER_MODE` +* `EMAIL_DOMAIN_WHITELIST` +* `DEFAULT_LOCALE` +* `MAX_SESSION_ACTIVATIONS` +* `USER_ACTIVE_DAYS` + +### E-mail + +* `SMTP_SERVER` +* `SMTP_PORT` +* `SMTP_LOGIN` +* `SMTP_PASSWORD` +* `SMTP_FROM_ADDRESS` +* `SMTP_DOMAIN` +* `SMTP_DELIVERY_METHOD` +* `SMTP_AUTH_METHOD` +* `SMTP_CA_FILE` +* `SMTP_OPENSSL_VERIFY_MODE` +* `SMTP_ENABLE_STARTTLS_AUTO` +* `SMTP_TLS` + +### File storage + +* `CDN_HOST` +* `S3_ALIAS_HOST` + +#### Local file storage + +* `PAPERCLIP_ROOT_PATH` +* `PAPERCLIP_ROOT_URL` + +#### Amazon S3 and compatible + +* `S3_ENABLED` +* `S3_BUCKET` +* `AWS_ACCESS_KEY_ID` +* `AWS_SECRET_ACCESS_KEY` +* `S3_REGION` +* `S3_PROTOCOL` +* `S3_HOSTNAME` +* `S3_ENDPOINT` +* `S3_SIGNATURE_VERSION` + +#### Swift + +* `SWIFT_ENABLED` +* `SWIFT_USERNAME` +* `SWIFT_TENANT` +* `SWIFT_PASSWORD` +* `SWIFT_PROJECT_ID` +* `SWIFT_AUTH_URL` +* `SWIFT_CONTAINER` +* `SWIFT_OBJECT_URL` +* `SWIFT_REGION` +* `SWIFT_DOMAIN_NAME` +* `SWIFT_CACHE_TTL` + +### External authentication + +* `OAUTH_REDIRECT_AT_SIGN_IN` + +#### LDAP + +* `LDAP_ENABLED` +* `LDAP_HOST` +* `LDAP_PORT` +* `LDAP_METHOD` +* `LDAP_BASE` +* `LDAP_BIND_DN` +* `LDAP_PASSWORD` +* `LDAP_UID` +* `LDAP_SEARCH_FILTER` + +#### PAM + +* `PAM_ENABLED` +* `PAM_EMAIL_DOMAIN` +* `PAM_DEFAULT_SERVICE` +* `PAM_CONTROLLED_SERVICE` + +#### CAS + +* `CAS_ENABLED` +* `CAS_URL` +* `CAS_HOST` +* `CAS_PORT` +* `CAS_SSL` +* `CAS_VALIDATE_URL` +* `CAS_CALLBACK_URL` +* `CAS_LOGOUT_URL` +* `CAS_LOGIN_URL` +* `CAS_UID_FIELD` +* `CAS_CA_PATH` +* `CAS_DISABLE_SSL_VERIFICATION` +* `CAS_UID_KEY` +* `CAS_NAME_KEY` +* `CAS_EMAIL_KEY` +* `CAS_NICKNAME_KEY` +* `CAS_FIRST_NAME_KEY` +* `CAS_LAST_NAME_KEY` +* `CAS_LOCATION_KEY` +* `CAS_IMAGE_KEY` +* `CAS_PHONE_KEY` + +#### SAML + +* `SAML_ENABLED` +* `SAML_ACS_URL` +* `SAML_ISSUER` +* `SAML_IDP_SSO_TARGET_URL` +* `SAML_IDP_CERT` +* `SAML_IDP_CERT_FINGERPRINT` +* `SAML_NAME_IDENTIFIER_FORMAT` +* `SAML_CERT` +* `SAML_PRIVATE_KEY` +* `SAML_SECURITY_WANT_ASSERTION_SIGNED` +* `SAML_SECURITY_WANT_ASSERTION_ENCRYPTED` +* `SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED` +* `SAML_ATTRIBUTES_STATEMENTS_UID` +* `SAML_ATTRIBUTES_STATEMENTS_EMAIL` +* `SAML_ATTRIBUTES_STATEMENTS_FULL_NAME` +* `SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME` +* `SAML_ATTRIBUTES_STATEMENTS_LAST_NAME` +* `SAML_UID_ATTRIBUTE` +* `SAML_ATTRIBUTES_STATEMENTS_VERIFIED` +* `SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL` + +### Hidden services + +* `http_proxy` +* `ALLOW_ACCESS_TO_HIDDEN_SERVICE` + +### Other + +* `SKIP_POST_DEPLOYMENT_MIGRATIONS` + diff --git a/content/en/admin/install.md b/content/en/admin/install.md new file mode 100644 index 00000000..7550a2d0 --- /dev/null +++ b/content/en/admin/install.md @@ -0,0 +1,205 @@ +--- +title: Installing from source +menu: + docs: + weight: 20 + parent: admin +--- + +## Pre-requisites + +* A machine running **Ubuntu 18.04** that you have root access to +* A **domain name** \(or a subdomain\) for the Mastodon server, e.g. `example.com` +* An e-mail delivery service or other **SMTP server** + +You will be running the commands as root. If you aren’t already root, switch to root: + +### System repositories + +Make sure curl is installed first: + +#### Node.js + +```bash +curl -sL https://deb.nodesource.com/setup_8.x | bash - +``` + +#### Yarn + +```bash +curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list +``` + +### System packages + +```bash +apt update +apt install -y \ + imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \ + g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \ + bison build-essential libssl-dev libyaml-dev libreadline6-dev \ + zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev \ + nginx redis-server redis-tools postgresql postgresql-contrib \ + certbot python-certbot-nginx yarn libidn11-dev libicu-dev libjemalloc-dev +``` + +### Installing Ruby + +We will be using rbenv to manage Ruby versions, because it’s easier to get the right versions and to update once a newer release comes out. rbenv must be installed for a single Linux user, therefore, first we must create the user Mastodon will be running as: + +```bash +adduser --disabled-login mastodon +``` + +We can then switch to the user: + +And proceed to install rbenv and rbenv-build: + +```bash +git clone https://github.com/rbenv/rbenv.git ~/.rbenv +cd ~/.rbenv && src/configure && make -C src +echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc +echo 'eval "$(rbenv init -)"' >> ~/.bashrc +exec bash +git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build +``` + +Once this is done, we can install the correct Ruby version: + +```bash +RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.6.1 +rbenv global 2.6.1 +``` + +Default gem version shipped with ruby\_2.6.0 is incompatible with latest bundler, so we need to update gem: + +```bash +gem update --system +``` + +We’ll also need to install bundler: + +```bash +gem install bundler --no-document +``` + +Return to the root user: + +## Setup + +### Setting up PostgreSQL + +#### Performance configuration \(optional\) + +For optimal performance, you may use [pgTune](https://pgtune.leopard.in.ua/#/) to generate an appropriate configuration and edit values in `/etc/postgresql/9.6/main/postgresql.conf` before restarting PostgreSQL with `systemctl restart postgresql` + +#### Creating a user + +You will need to create a PostgreSQL user that Mastodon could use. It is easiest to go with “ident” authentication in a simple setup, i.e. the PostgreSQL user does not have a separate password and can be used by the Linux user with the same username. + +Open the prompt: + +In the prompt, execute: + +```sql +CREATE USER mastodon CREATEDB; +\q +``` + +Done! + +### Setting up Mastodon + +It is time to download the Mastodon code. Switch to the mastodon user: + +#### Checking out the code + +Use git to download the latest stable release of Mastodon: + +```bash +git clone https://github.com/tootsuite/mastodon.git live && cd live +git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1) +``` + +#### Installing the last dependencies + +Now to install Ruby and JavaScript dependencies: + +```bash +bundle install \ + -j$(getconf _NPROCESSORS_ONLN) \ + --deployment --without development test +yarn install --pure-lockfile +``` + +#### Generating a configuration + +Run the interactive setup wizard: + +```bash +RAILS_ENV=production bundle exec rake mastodon:setup +``` + +This will: + +* Create a configuration file +* Run asset precompilation +* Create the database schema + +The configuration file is saved as `.env.production`. You can review and edit it to your liking. Refer to the [documentation on configuration.]({{< relref "config.md" >}}) + +You’re done with the mastodon user for now, so switch back to root: + +### Setting up nginx + +Copy the configuration template for nginx from the Mastodon directory: + +```bash +cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon +ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon +``` + +Then edit `/etc/nginx/sites-available/mastodon` to replace `example.com` with your own domain name, and make any other adjustments you might need. + +Reload nginx for the changes to take effect: + +### Acquiring a SSL certificate + +We’ll use Let’s Encrypt to get a free SSL certificate: + +```bash +certbot --nginx -d example.com +``` + +This will obtain the certificate, automatically update `/etc/nginx/sites-available/mastodon` to use the new certificate, and reload nginx for the changes to take effect. + +At this point you should be able to visit your domain in the browser and see the elephant hitting the computer screen error page. This is because we haven’t started the Mastodon process yet. + +### Setting up systemd services + +Copy the systemd service templates from the Mastodon directory: + +```bash +cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/ +``` + +Then edit the files to make sure the username and paths are correct: + +* `/etc/systemd/system/mastodon-web.service` +* `/etc/systemd/system/mastodon-sidekiq.service` +* `/etc/systemd/system/mastodon-streaming.service` + +Finally, start and enable the new systemd services: + +```bash +systemctl start mastodon-web mastodon-sidekiq mastodon-streaming +systemctl enable mastodon-* +``` + +They will now automatically start at boot time. + +{{< hint style="success" >}} +**Hurray! This is it. You can visit your domain in the browser now!** +{{< /hint >}} + diff --git a/content/en/admin/migrating.md b/content/en/admin/migrating.md new file mode 100644 index 00000000..fecc9638 --- /dev/null +++ b/content/en/admin/migrating.md @@ -0,0 +1,93 @@ +--- +title: Migrating to a new machine +menu: + docs: + weight: 90 + parent: admin +--- + +Sometimes, for various reasons, you may want to migrate your Mastodon instance from one server to another. Fortunately this is not too difficult of a process, although it may result in some downtime. + +{{< hint style="info" >}} +This guide was written with Ubuntu Server in mind; your mileage may vary for other setups. +{{< /hint >}} + +## Basic steps + +1. Set up a new Mastodon server using the [Production Guide]({{< relref "install.md" >}}) \(however, don’t run `mastodon:setup`\). +2. Stop Mastodon on the old server \(e.g. `systemctl stop 'mastodon-*.service'`\). +3. Dump and load the Postgres database using the instructions below. +4. Copy the `system/` files using the instructions below. \(Note: if you’re using S3, you can skip this step.\) +5. Copy the `.env.production` file. +6. Run `RAILS_ENV=production bundle exec rails assets:precompile` to compile Mastodon +7. Run `RAILS_ENV=production ./bin/tootctl feeds build` to rebuild the home timelines for each user. +8. Start Mastodon on the new server. +9. Update your DNS settings to point to the new server. +10. Update or copy your Nginx configuration, re-run LetsEncrypt as necessary. +11. Enjoy your new server! + +## Detailed steps + +### What data needs to be migrated + +At a high level, you’ll need to copy over the following: + +* The `~/live/public/system` directory, which contains user-uploaded images and videos \(if using S3, you don’t need this\) +* The Postgres database \(using [pg\_dump](https://www.postgresql.org/docs/9.1/static/backup-dump.html)\) +* The `~/live/.env.production` file, which contains server config and secrets + +Less crucially, you’ll probably also want to copy the following for convenience: + +* The nginx config \(under `/etc/nginx/sites-available/default`\) +* The systemd config files \(`/etc/systemd/system/mastodon-*.service`\), which may contain your server tweaks and customizations +* The pgbouncer configuration under `/etc/pgbouncer` \(if you’re using it\) + +### Dump and load Postgres + +Instead of running `mastodon:setup`, we’re going to create an empty Postgres database using the `template0` database \(which is useful when restoring a Postgres dump, [as described in the pg\_dump documentation](https://www.postgresql.org/docs/9.1/static/backup-dump.html#BACKUP-DUMP-RESTORE)\). + +Run this as the `mastodon` user on your old system: + +```bash +pg_dump -Fc mastodon_production -f backup.dump +``` + +Copy the `backup.dump` file over, using `rsync` or `scp`. Then on the new system, create an empty database as the `mastodon` user: + +```bash +createdb -T template0 mastodon_production +``` + +Then import it: + +```bash +pg_restore -U mastodon -n public --no-owner --role=mastodon \ + -d mastodon_production backup.dump +``` + +\(Note that if the username is not `mastodon` on the new server, you should change the `-U` AND `--role` values above. It’s okay if the username is different between the two servers.\) + +### Copy files + +This will probably take some time, and you’ll want to avoid re-copying unnecessarily, so using `rsync` is recommended. On your old machine, as the `mastodon` user, run: + +```bash +rsync -avz ~/live/public/system/ mastodon@example.com:~/live/public/system/ +``` + +You’ll want to re-run this if any of the files on the old server change. + +You should also copy over the `.env.production` file, which contains secrets. + +Optionally, you may copy over the nginx, systemd, and pgbouncer config files, or rewrite them from scratch. + +### During migration + +You can edit the `~/live/public/500.html` page on the old machine if you want to show a nice error message to let existing users know that a migration is in progress. + +You’ll probably also want to set the DNS TTL to something small \(30-60 minutes\) about a day in advance, so that DNS can propagate quickly once you point it to the new IP address. + +### After migrating + +You can check [whatsmydns.net](https://whatsmydns.net/) to see the progress of DNS propagation. To jumpstart the process, you can always edit your own `/etc/hosts` file to point to your new server so you can start playing around with it early. + diff --git a/content/en/usage/moderation.md b/content/en/admin/moderation.md similarity index 82% rename from content/en/usage/moderation.md rename to content/en/admin/moderation.md index 648ccb7d..8310c284 100644 --- a/content/en/usage/moderation.md +++ b/content/en/admin/moderation.md @@ -1,61 +1,61 @@ --- -title: Moderation -description: Overview of moderation tools on Mastodon +title: Moderation actions menu: docs: - parent: usage - weight: 4 + weight: 110 + parent: admin --- -## Individual moderation + +## Individual moderation Moderation in Mastodon is always applied locally, i.e. as seen from the particular server. An admin or moderator on one server cannot affect a user on another server, they can only affect the local copy on their own server. -### Disable login +### Disable login A Mastodon account can be disabled. This prevents the user from doing anything with the account, but all of the content is still there untouched. This limitation is reversible, the account can be re-enabled at any time. This limitation is only available for local users on your server. -### Silence +### Silence A Mastodon silence is synonymous with sandbox. A silenced account does not appear to users who are not already following it. All of the content is still there, and it can still be found via search, mentioned, and followed, but the content is invisible. -At this moment, silence does not affect federation. A locally silenced account is *not* silenced automatically on other servers. +At this moment, silence does not affect federation. A locally silenced account is _not_ silenced automatically on other servers. This limitation is reversible, the account can be unsilenced at any time. -### Suspend +### Suspend A Mastodon suspension is synonymous with deletion. The account no longer appears in search, the profile page is gone, all of the posts, uploads, followers, and all other data is removed. This limitation is **irreversible**. While the account can be unsuspended, allowing the user to take control of it again, the old data is gone for good. -## Server-wide moderation +## Server-wide moderation Because individually moderating a large volume of users from a misbehaving server can be exhausting, it is possible to pre-emptively moderate against all users from that particular server using a so-called **domain block**, which comes with several different levels of severity. -### Reject media +### Reject media With this option active, no files from the server will be processed locally. That includes avatars, headers, emojis and media attachments. -### Silence +### Silence Applies a silence to all past and future accounts from the server. -### Suspend +### Suspend Applies a suspension to all past and future accounts from the server. No content from the server will be stored locally except for usernames. -## Spam-fighting measures +## Spam-fighting measures There are a few baseline measures for preventing spam in Mastodon: -- Signing up requires confirming an e-mail address -- Signing up is rate-limited by IP +* Signing up requires confirming an e-mail address +* Signing up is rate-limited by IP However, dedicated spammers will get through that. The other measure you can employ is **e-mail domain blacklisting**. During sign up, Mastodon resolves the given e-mail address for an A or MX record, i.e. the IP address of the e-mail server, and checks that IP address against a dynamically stored blacklist. -### Blocking by e-mail server +### Blocking by e-mail server Spammers will often use different e-mail domains so it looks like they are using a lot of different e-mail servers that would all be difficult to blacklist separately. However, sometimes all of those domains resolve to a single e-mail server IP. If you see a lot of spammers signing up at the same time, you can check for this, either using an online DNS lookup tool, or the Linux `dig` utility, e.g. `dig 1.2.3.4` will return all DNS records for that IP. If you notice the IP is the same for all domains, you can add it to the e-mail domain blacklist. -### Blocking by IP +### Blocking by IP It is not possible to block visitors by IP address in Mastodon itself, and it is not a fool-proof strategy. IPs are sometimes shared by a lot of different people, and sometimes change hands. But it is possible to block visitors by IP address in Linux using a firewall. Here is an example using `iptables` and `ipset`: @@ -71,3 +71,4 @@ sudo iptables -I INPUT 1 -m set --match-set spambots src -j DROP ``` Be careful not to lock yourself out of your machine. + diff --git a/content/en/admin/optional.md b/content/en/admin/optional.md new file mode 100644 index 00000000..ae4f036f --- /dev/null +++ b/content/en/admin/optional.md @@ -0,0 +1,9 @@ +--- +title: Installing optional features +menu: + docs: + weight: 40 + parent: admin + identifier: admin-optional +--- + diff --git a/content/en/admin/optional/elasticsearch.md b/content/en/admin/optional/elasticsearch.md new file mode 100644 index 00000000..d8e03c00 --- /dev/null +++ b/content/en/admin/optional/elasticsearch.md @@ -0,0 +1,78 @@ +--- +title: Full-text search +menu: + docs: + weight: 10 + parent: admin-optional +--- + +Mastodon supports full-text search when it ElasticSearch is available. Mastodon’s full-text search allows logged in users to find results from their own toots, their favourites, and their mentions. It deliberately does not allow searching for arbitrary strings in the entire database. + +### Installing ElasticSearch + +ElasticSearch requires a Java runtime. If you don’t have Java already installed, do it now. Assuming you are logged in as `root`: + +```bash +apt install openjdk-8-jre-headless +``` + +Add the official ElasticSearch repository to apt: + +```bash +wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add - +echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | tee -a /etc/apt/sources.list.d/elastic-6.x.list +apt update +``` + +Now you can install ElasticSearch: + +```bash +apt install elasticsearch +``` + +{{< hint style="warning" >}} +**Security warning:** By default, ElasticSearch is supposed to bind to localhost only, i.e. be inaccessible from the outside network. You can check which address ElasticSearch binds to by looking at `network.host` within `/etc/elasticsearch/elasticsearch.yml`. Consider that anyone who can access ElasticSearch can access and modify any data within it, as there is no authentication layer. So it’s really important that the access is secured. Having a firewall that only exposes the 22, 80 and 443 ports is advisable, as outlined in the [main installation instructions](). If you have a multi-host setup, you must know how to secure internal traffic. +{{< /hint >}} + +To start ElasticSearch: + +```bash +systemctl enable elasticsearch +systemctl start elasticsearch +``` + +### Configuring Mastodon + +Edit `.env.production` to add the following variables: + +```bash +ES_ENABLED=true +ES_HOST=localhost +ES_PORT=9200 +``` + +If you have multiple Mastodon servers on the same machine, and you are planning to use the same ElasticSearch installation for all of them, make sure that all of them have unique `REDIS_NAMESPACE` in their configurations, to differentiate the indices. If you need to override the prefix of the ElasticSearch index, you can set `ES_PREFIX` directly. + +After saving the new configuration, create the index in ElasticSearch with: + +```bash +RAILS_ENV=production bundle exec rake chewy:upgrade +``` + +Then restart Mastodon processes for the new configuration to take effect: + +```bash +systemctl restart mastodon-sidekiq +systemctl reload mastodon-web +``` + +Now new statuses will be written to the ElasticSearch index. The last step is importing all of the old data as well. This might take a long while: + +```bash +RAILS_ENV=production bundle exec rake chewy:sync +``` + +{{< hint style="warning" >}} +**Compatibility note:** There is a known bug in Ruby 2.6.0 that prevents the above task from working. Other versions of Ruby, such as 2.6.1, are fine. +{{< /hint >}} + diff --git a/content/en/admin/optional/sso.md b/content/en/admin/optional/sso.md new file mode 100644 index 00000000..7617235d --- /dev/null +++ b/content/en/admin/optional/sso.md @@ -0,0 +1,12 @@ +--- +title: Single Sign On +menu: + docs: + weight: 30 + parent: admin-optional +--- + +{{< hint style="danger" >}} +This page is under construction. +{{< /hint >}} + diff --git a/content/en/administration/optional-features.md b/content/en/admin/optional/tor.md similarity index 53% rename from content/en/administration/optional-features.md rename to content/en/admin/optional/tor.md index 1f7264ca..3508b4b2 100644 --- a/content/en/administration/optional-features.md +++ b/content/en/admin/optional/tor.md @@ -1,75 +1,18 @@ --- -title: Optional features -description: How to enable Mastodon's optional features +title: Hidden services menu: docs: - parent: administration - weight: 5 + weight: 20 + parent: admin-optional --- -## Full-text search +Mastodon can be served through Tor as an onion service. This will give you a \*.onion address that can only be used while connected to the Tor network. -Mastodon supports full-text search when it ElasticSearch is available. Mastodon's full-text search allows logged in users to find results from their own toots, their favourites, and their mentions. It deliberately does not allow searching for arbitrary strings in the entire database. +## Installing Tor -### Install ElasticSearch +First Tor’s Debian archive needs to be added to apt. -ElasticSearch requires a Java runtime. If you don't have Java already installed, do it now. Assuming you are logged in as `root`: - - apt install openjdk-8-jre-headless - -Add the official ElasticSearch repository to apt: - - wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add - - echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | tee -a /etc/apt/sources.list.d/elastic-6.x.list - apt update - -Now you can install ElasticSearch: - - apt install elasticsearch - -> **Security warning:** By default, ElasticSearch is supposed to bind to localhost only, i.e. be inaccessible from the outside network. You can check which address ElasticSearch binds to by looking at `network.host` within `/etc/elasticsearch/elasticsearch.yml`. Consider that anyone who can access ElasticSearch can access and modify any data within it, as there is no authentication layer. So it's really important that the access is secured. Having a firewall that only exposes the 22, 80 and 443 ports is advisable, as outlined in the [main installation instructions]({{< relref "installation.md" >}}). If you have a multi-host setup, you must know how to secure internal traffic. - -To start ElasticSearch: - - systemctl enable elasticsearch - systemctl start elasticsearch - -### Setup Mastodon - -Edit `.env.production` to add the following variables: - -```bash -ES_ENABLED=true -ES_HOST=localhost -ES_PORT=9200 -``` - -If you have multiple Mastodon servers on the same machine, and you are planning to use the same ElasticSearch installation for all of them, make sure that all of them have unique `REDIS_NAMESPACE` in their configurations, to differentiate the indices. If you need to override the prefix of the ElasticSearch index, you can set `ES_PREFIX` directly. - -After saving the new configuration, create the index in ElasticSearch with: - - RAILS_ENV=production bundle exec rake chewy:upgrade - -Then restart Mastodon processes for the new configuration to take effect: - - systemctl restart mastodon-sidekiq - systemctl reload mastodon-web - -Now new statuses will be written to the ElasticSearch index. The last step is importing all of the old data as well. This might take a long while: - - RAILS_ENV=production bundle exec rake chewy:sync - -> **Compatibility note:** There is a known bug in Ruby 2.6.0 that prevents the above task from working. Other versions of Ruby, such as 2.6.1, are fine. - -## Hidden services - -Mastodon can be served through Tor as an onion service. This will give you a *.onion address that can only be used while connected to the Tor network. - -### Installing Tor - -First Tor's Debian archive needs to be added to apt. - -``` +```text deb https://deb.torproject.org/torproject.org stretch main deb-src https://deb.torproject.org/torproject.org stretch main ``` @@ -86,11 +29,11 @@ Finally install the required packages. apt install tor deb.torproject.org-keyring ``` -### Configure Tor +## Configure Tor Edit the file at `/etc/tor/torrc` and add the following configuration. -```bash +```text HiddenServiceDir /var/lib/tor/hidden_service/ HiddenServiceVersion 3 HiddenServicePort 80 127.0.0.1:80 @@ -104,13 +47,13 @@ sudo service tor restart Your tor hostname can now be found at `/var/lib/tor/hidden_service/hostname`. -### Move your Mastodon configuration +## Move your Mastodon configuration We will need to tell Nginx about your Mastodon configuration twice. To keep things [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) we need to move the Mastodon configuration into its own file that can be referenced. Create a new file at `/etc/nginx/snippets/mastodon.conf`. Put all of your Mastodon configuration parameters in this file with the exception of the `listen`, `server_name`, `include` and all of the SSL options. Your new file may look something like this. -``` +```text add_header Referrer-Policy "same-origin"; keepalive_timeout 70; @@ -129,7 +72,7 @@ In place of your old Mastodon configuration add an include directive to this new Your Nginx configuration file will be left looking something like this. -``` +```text server { listen 80; server_name mastodon.myhosting.com; @@ -152,13 +95,13 @@ server { } ``` -### Serve Tor over http +## Serve Tor over http While it may be tempting to serve your Tor version of Mastodon over https it is not a good idea for most people. See [this](https://blog.torproject.org/facebook-hidden-services-and-https-certs) blog post from the Tor Project about why https certificates do not add value. Since you cannot get an SSL cert for an onion domain, you will also be plagued with certificate errors when trying to use your Mastodon instance. A Tor developer has more recently spelled out the reasons why serving a Tor service over https is not beneficial for most use cases [here](https://matt.traudt.xyz/p/o44SnkW2.html). The solution is to serve your Mastodon instance over http, but only for Tor. This can be added by pre-pending an additional configuration to your Nginx configuration. -``` +```text server { listen 80; server_name mastodon.qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7.onion; @@ -170,7 +113,7 @@ server { server_name mastodon.myhosting.com; return 301 https://$server_name$request_uri; } - + map $http_upgrade $connection_upgrade { default upgrade; '' close; @@ -189,7 +132,7 @@ server { Replace the long hash provided here with your Tor domain located in the file at `/var/lib/tor/hidden_service/hostname`. -Note that the onion hostname has been prefixed with "mastodon.". Your Tor address acts a wildcard domain. All subdomains will be routed through, and you can configure Nginx to respond to any subdomain you wish. If you do not wish to host any other services on your tor address you can omit the subdomain, or choose a different subdomain. +Note that the onion hostname has been prefixed with “mastodon.”. Your Tor address acts a wildcard domain. All subdomains will be routed through, and you can configure Nginx to respond to any subdomain you wish. If you do not wish to host any other services on your tor address you can omit the subdomain, or choose a different subdomain. Here you can see the payoff of moving your mastodon configurations to a different file. Without this all of your configurations would have to be copied to both places. Any change to your configuration would have to be made both places. @@ -199,13 +142,9 @@ Restart your web server. service nginx restart ``` -### Gotchas +## Gotchas -There are a few things you will need to be aware of. Certain redirects will push your users to https. They will have to manually replace the URL with http to continue. +There are a few things you will need to be aware of. Certain redirects will push your users to https. They will have to manually replace the URL with http to continue. -Various resources, such as images, will still be offered through your regular non-Tor domain. How much of a problem this is will depend greatly on your user's level of caution. - -## Login via LDAP/PAM/CAS/SAML - -TODO +Various resources, such as images, will still be offered through your regular non-Tor domain. How much of a problem this is will depend greatly on your user’s level of caution. diff --git a/content/en/admin/prerequisites.md b/content/en/admin/prerequisites.md new file mode 100644 index 00000000..5019be02 --- /dev/null +++ b/content/en/admin/prerequisites.md @@ -0,0 +1,96 @@ +--- +title: Preparing your machine +menu: + docs: + weight: 10 + parent: admin +--- + +If you are setting up a fresh machine, it is recommended that you secure it first. Assuming that you are running **Ubuntu 18.04**: + +## Do not allow password-based SSH login \(keys only\) + +First make sure you are actually logging in to the server using keys and not via a password, otherwise this will lock you out. Many hosting providers support uploading a public key and automatically set up key-based root login on new machines for you. + +Edit `/etc/ssh/sshd_config` and find `PasswordAuthentication`. Make sure it’s uncommented and set to `no`. If you made any changes, restart sshd: + +## Update system packages + +```bash +apt update && apt upgrade -y +``` + +## Install fail2ban so it blocks repeated login attempts + +Edit `/etc/fail2ban/jail.local` and put this inside: + +```text +[DEFAULT] +destemail = your@email.here +sendername = Fail2Ban + +[sshd] +enabled = true +port = 22 + +[sshd-ddos] +enabled = true +port = 22 +``` + +Finally restart fail2ban: + +```bash +systemctl restart fail2ban +``` + +## Install a firewall and only whitelist SSH, HTTP and HTTPS ports + +First, install iptables-persistent. During installation it will ask you if you want to keep current rules–decline. + +```bash +apt install -y iptables-persistent +``` + +Edit `/etc/iptables/rules.v4` and put this inside: + +```text +*filter + +# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0 +-A INPUT -i lo -j ACCEPT +-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT + +# Accept all established inbound connections +-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT + +# Allow all outbound traffic - you can modify this to only allow certain traffic +-A OUTPUT -j ACCEPT + +# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL). +-A INPUT -p tcp --dport 80 -j ACCEPT +-A INPUT -p tcp --dport 443 -j ACCEPT + +# Allow SSH connections +# The -dport number should be the same port number you set in sshd_config +-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT + +# Allow ping +-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT + +# Log iptables denied calls +-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 + +# Reject all other inbound - default deny unless explicitly allowed policy +-A INPUT -j REJECT +-A FORWARD -j REJECT + +COMMIT +``` + +With iptables-persistent, that configuration will be loaded at boot time. But since we are not rebooting right now, we need to load it manually for the first time: + +```bash +iptables-restore < /etc/iptables/rules.v4 +``` + diff --git a/content/en/admin/scaling.md b/content/en/admin/scaling.md new file mode 100644 index 00000000..f4cbce8e --- /dev/null +++ b/content/en/admin/scaling.md @@ -0,0 +1,281 @@ +--- +title: Scaling up your server +menu: + docs: + weight: 100 + parent: admin +--- + +## 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.: + +```bash +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.: + +```bash +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: + +```bash +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: + +```bash +psql -p 5432 -U mastodon mastodon_production -w +``` + +Then \(obviously, use a different password than the word “password”\): + +```sql +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`: + +```text +"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`: + +```text +"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: + +```text +[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: + +```text +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`\): + +Make sure the `pgbouncer` user is an admin: + +**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`: + +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: + +```text +max_client_conn = 100 +default_pool_size = 20 +``` + +Don’t forget to reload or restart pgbouncer after making your changes: + +```bash +sudo systemctl reload pgbouncer +``` + +#### Debugging that it all works + +You should be able to connect to PgBouncer just like you would with Postgres: + +```bash +psql -p 6432 -U mastodon mastodon_production +``` + +And then use your password to log in. + +You can also check the PgBouncer logs like so: + +```bash +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 +``` + +{{< hint style="warning" >}} +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\) +{{< /hint >}} + +#### Administering PgBouncer + +The easiest way to reboot is: + +```bash +sudo systemctl restart pgbouncer +``` + +But if you’ve set up a PgBouncer admin user, you can also connect as the admin: + +```bash +psql -p 6432 -U pgbouncer pgbouncer +``` + +And then do: + +```sql +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: + +```yaml +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). + +{{< hint style="warning" >}} +Sidekiq cannot reliably use read-replicas because even the tiniest replication lag leads to failing jobs due to queued up records not being found. +{{< /hint >}} + diff --git a/content/en/admin/setup.md b/content/en/admin/setup.md new file mode 100644 index 00000000..f0393b0c --- /dev/null +++ b/content/en/admin/setup.md @@ -0,0 +1,45 @@ +--- +title: Setting up your new instance +menu: + docs: + weight: 50 + parent: admin +--- + +## Creating an admin account + +### In the browser + +After signing up in the browser, you will need to use the command line to give your newly created account admin privileges. Assuming your username is `alice`: + +```bash +RAILS_ENV=production bin/tootctl accounts modify alice --role admin +``` + +### From the command line + +You can create a new account using the command-line interface. + +```bash +RAILS_ENV=production bin/tootctl accounts create \ + alice \ + --email alice@example.com \ + --confirmed \ + --role admin +``` + +A randomly generated password will be shown in the terminal. + +## Filling in server information + +After logging in, navigate to the **Site settings** page. While there are no technical requirements for filling in this information, it is considered crucial for operating a server for humans. + +| Setting | Meaning | +| :--- | :--- | +| Contact username | Your username so people know who owns the server | +| Business e-mail | An e-mail address so people locked out of their accounts, or people without accounts, can contact you | +| Instance description | Why did you start this server? Who is it for? What makes it different? | +| Custom extended information | You can put all sorts of information in here but a **code of conduct** is recommended | + +After you fill these in, simply hit “Save changes”. + diff --git a/content/en/admin/tootctl.md b/content/en/admin/tootctl.md new file mode 100644 index 00000000..291eee60 --- /dev/null +++ b/content/en/admin/tootctl.md @@ -0,0 +1,452 @@ +--- +title: Using the admin CLI +description: tootctl commands that can be run from the CLI. +menu: + docs: + weight: 60 + parent: admin +--- +--- + +The command-line interface of Mastodon is an executable file called `tootctl` residing in the `bin` directory within the Mastodon root directory. You must specify which environment you intend to use whenever you execute it by specifying the `RAILS_ENV` environment variable. Unless you are a developer working on a local machine, you need to use `RAILS_ENV=production`. If you are sure that you will never need another environment \(for development, testing, or staging\), you can add it to your `.bashrc` file for convenience, e.g.: + +```bash +echo "export RAILS_ENV=production" >> ~/.bashrc +``` + +If so, you won’t need to specify it each time inline. Otherwise, calls to `tootctl` will usually go like this, assuming that the Mastodon code is checked out in `/home/mastodon/live`: + +```bash +cd /home/mastodon/live +RAILS_ENV=production bin/tootctl help +``` + +## Base CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/cli.rb" caption="lib/cli.rb" >}} + +### `tootctl self-destruct` + +Erase this server from the federation by broadcasting account Delete activities to all known other servers. This allows a "clean exit" from running a Mastodon server, as it leaves next to no cache behind on other servers. This command is always interactive and requires confirmation twice. + +No local data is actually deleted, because emptying the database or deleting the entire VPS is faster. If you run this command then continue to operate the instance anyway, then there will be a state mismatch that might lead to glitches and issues with federation. + +{{< hint style="danger" >}} +**Make sure you know exactly what you are doing before running this command.** This operation is NOT reversible, and it can take a long time. The server will be in a BROKEN STATE after this command finishes. A running Sidekiq process is required, so do not shut down the server until the queues are fully cleared. +{{< /hint >}} + +**Version history:** +2.8.0 - added + +| Option | Description | +| :--- | :--- | +| --dry\_run | Print expected results only, without performing any actions. | + +### `tootctl --version` + +Show the version of the currently running Mastodon instance. + +**Version history:** +2.7.0 - added + +## Accounts CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/accounts_cli.rb" caption="lib/mastodon/accounts\_cli.rb" >}} + +### `tootctl accounts rotate` + +Generate and broadcast new RSA keys, as part of security maintenance. + +**Version history:** +2.5.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username for an account. | +| --all | Can be provided instead of USERNAME to rotate keys for all local accounts. | + +### `tootctl accounts create` + +Create a new user account with given USERNAME and provided --email. + +**Version history:** +2.6.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username for the new account. Required. | +| --email EMAIL | Email address to be attached to the user. Required. | +| --confirmed | Skip sending the confirmation email and activate the account immediately. | +| --role ROLE | Define the new account as a `user`, `moderator`, or `admin`. Defaults to `user`. | +| --reattach | Reuse an old USERNAME after its account has been deleted. | +| --force | Forcefully delete any existing account with this USERNAME and reattach the new account in place of the \(just-deleted\) account. | + +### `tootctl accounts modify` + +Modify a user account's role, email, active status, approval mode, or 2FA requirement. + +**Version history:** +2.6.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username for the new account. Required. | +| --role ROLE | Define the account as a `user`, `moderator`, or `admin`. | +| --email EMAIL | Update the user's email address to EMAIL. | +| --confirm | Skip confirmation email, when used with --email. | +| --disable | Lock USERNAME out of their account. | +| --enable | Unlock USERNAME's account if it is currently disabled. | +| --approve | Approve the account, if you are/were in approval mode. | +| --disable\_2fa | Remove additional factors and allow login with password. | + +### `tootctl accounts delete` + +Delete a user account with given USERNAME. + +**Version history:** +2.6.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username for the account. Required. | + +### `tootctl accounts backup` + +Request a backup for a user account with given USERNAME. The backup will be created in Sidekiq asynchronously, and the user will receive an email with a link to it once it's done. + +**Version history:** +2.6.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username for the account. Required. | + +### `tootctl accounts cull` + +Remove remote accounts that no longer exist. Queries every single remote account in the database to determine if it still exists on the origin server, and if it doesn't, then remove it from the database. Accounts that have had confirmed activity within the last week are excluded from the checks, in case the server is just down. + +**Version history:** +2.6.0 - added +2.8.0 - add `--dry_run` + +| Option | Description | +| :--- | :--- | +| --concurrency N | The number of workers to use for this task. Defaults to N=5. | +| --dry\_run | Print expected results only, without performing any actions. | + +### `tootctl accounts refresh` + +Refetch remote user data and files for one or multiple accounts. + +**Version history:** +2.6.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username | +| --all | Can be provided instead of USERNAME to refresh all remote accounts. | +| --domain DOMAIN | Can be provided instead of USERNAME. Operate only on remote accounts from this DOMAIN. | +| --concurrency N | The number of workers to use for this task. Defaults to N=5. | +| --verbose | Print additional information while task is processing. | +| --dry\_run | Print expected results only, without performing any actions. | + +### `tootctl accounts follow` + +Force all local accounts to follow a local account specified by username. + +**Version history:** +2.7.0 - added +3.0.0 - now uses USERNAME instead of ACCT + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username | +| --concurrency N | The number of workers to use for this task. Defaults to N=5. | +| --verbose | Print additional information while task is processing. | + +### `tootctl accounts unfollow` + +Force all local accounts to unfollow an account specified by their address. + +**Version history:** +2.7.0 - added + +| Option | Description | +| :--- | :--- | +| ACCT | `username@domain` address | +| --concurrency N | The number of workers to use for this task. Defaults to N=5. | +| --verbose | Print additional information while task is processing. | + +### `tootctl accounts reset-relationships` + +Reset all follow and/or follower relationships for a local account. + +**Version history:** +2.8.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username | +| --follows | Force USERNAME to unfollow everyone, then re-follow them. | +| --followers | Remove all of USERNAME's followers. | + +### `tootctl accounts approve` + +Approve new registrations when instance is in approval mode. + +**Version history:** +2.8.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Approve the pending account with this username | +| --number N | Approve the N most recent registrations. | +| --all | Approve all pending registrations. | + +## Cache CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/cache_cli.rb" caption="lib/mastodon/cache\_cli.rb" >}} + +### `tootctl cache clear` + +Clear out the cache storage. + +**Version history:** +2.8.1 - added + +### `tootctl cache recount` + +Update hard-cached counters of TYPE by counting referenced records from scratch. It may take a very long time to finish, depending on the size of the database. Accounts will have their follower, following, and status counts refreshed. Statuses will have their reply, boost, and favourite counts refreshed. + +**Version history:** +3.0.0 - added + +| Option | Description | +| :--- | :--- | +| TYPE | Either `accounts` or `statuses` | +| --concurrency N | The number of workers to use for this task. Defaults to N=5. | +| --verbose | Print additional information while task is processing. | + +## Domains CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/domains_cli.rb" caption="lib/mastodon/domains\_cli.rb" >}} + +### `tootctl domains purge` + +Remove all accounts from a given DOMAIN without leaving behind any records. Unlike a suspension, if the DOMAIN still exists in the wild, it means the accounts could return if they are resolved again. + +**Version history:** +2.6.0 - added +2.8.0 - add `--whitelist_mode` +2.9.0 - remove custom emoji as well +3.0.0 - accept multiple domains + +| Option | Description | +| :--- | :--- | +| DOMAIN\[...\] | Domains to purge, separated by space. | +| --whitelist\_mode | Can be provided instead of DOMAIN. Instead of purging from a single domain, all accounts from domains that are not whitelisted will be removed from the database. Use this after enabling whitelist mode and defining your whitelist. | +| --concurrency N | The number of workers to use for this task. Defaults to 5. | +| --verbose | Print additional information while task is processing. | +| --dry\_run | Print expected results only, without performing any actions. | + +### `tootctl domains crawl` + +Crawl the known fediverse by using Mastodon REST API endpoints that expose all known peers, and collect statistics from those peers, as long as those peers support those API endpoints. When no START is given, the command uses the server's own database of known peers to seed the crawl. Returns total servers, total registered users, total active users in the last week, and total users joined in the last week. + +**Version history:** +2.7.0 - added +3.0.0 - add `--exclude_suspended` + +| Option | Description | +| :--- | :--- | +| START | Optionally start from a different domain name. | +| --concurrency N | The number of workers to use for this task. Defaults to 50. | +| --format FORMAT | Control how results are returned. `summary` will print a summary. `domains` will return a newline-delimited list of all discovered peers. `json` will dump aggregated raw data. Defaults to `summary`. | +| --exclude\_suspended | Do not include instances that you have suspended in the output. Also includes any subdomains. | + +## Emoji CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/emoji_cli.rb" caption="lib/mastodon/emoji\_cli.rb" >}} + +### `tootctl emoji import` + +Imports custom emoji from a .tar.gz archive at a given path. The archive should contain PNG or GIF files no larger than 50KB, and the shortcode will be set equal to the filename minus the extension, with optional prefixes and/or suffixes. + +**Version history:** +2.5.0 - added + +| Option | Description | +| :--- | :--- | +| PATH | Path to a .tar.gz archive containing pictures. | +| --prefix PREFIX | Add PREFIX to the beginning of generated shortcodes. | +| --suffix SUFFIX | Add SUFFIX to the end of generated shortcodes. | +| --overwrite | Instead of skipping existing emoji, replace them with any discovered emoji with the same shortcode. | +| --unlisted | Processed emoji will not be shown in the emoji picker, but will be usable only by their direct shortcode. | +| --category CATEGORY | Group the processed emoji under CATEGORY in the picker. | + +### `tootctl emoji purge` + +Remove all custom emoji. + +**Version history:** +2.8.0 - added + +## Feeds CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/feeds_cli.rb" caption="lib/mastodon/feeds\_cli.rb" >}} + +### `tootctl feeds build` + +Build home and list feeds for one or all users. Feeds will be built from the database and cached in-memory with Redis. Mastodon manages home feeds for active users automatically. + +**Version history:** +2.6.0 - added + +| Option | Description | +| :--- | :--- | +| USERNAME | Local username whose feeds will be regenerated. | +| --all | Can be provided instead of USERNAME to refresh all local accounts' feeds. | +| --concurrency N | The number of workers to use for this task. Defaults to N=5. | +| --verbose | Print additional information while task is processing. | +| --dry\_run | Print expected results only, without performing any actions. | + +### `tootctl feeds clear` + +Remove all home and list feeds from Redis. + +**Version history:** +2.6.0 - added + +## Media CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/media_cli.rb" caption="lib/mastodon/media\_cli.rb" >}} + +### `tootctl media remove` + +Remove locally cached copies of media attachments from other servers. + +**Version history:** +2.5.0 - added +2.6.2 - show freed disk space + +| Option | Description | +| :--- | :--- | +| --days | How old media attachments have to be before they are removed. Defaults to 7. | +| --concurrency N | The number of workers to use for this task. Defaults to 5. | +| --verbose | Print additional information while task is processing. | +| --dry\_run | Print expected results only, without performing any actions. | + +### `tootctl media remove-orphans` + +Scans for files that do not belong to existing media attachments, and remove them. Please mind that some storage providers charge for the necessary API requests to list objects. Also, this operation requires iterating over every single file individually, so it will be slow. + +**Version history:** +3.1.0 - added + +| Option | Description | +| :--- | :--- | +| --start\_after | The Paperclip attachment key where the loop will start. Use this option if the command was interrupted before. | +| --dry\_run | Print expected results only, without performing any actions. | + +### `tootctl media refresh` + +Refetch remote media attachments from other servers. You must specify the source of media attachments with either --status, --account, or --domain. If an attachment already exists in the database, it will not be overwritten unless you use --force. + +**Version history:** +3.0.0 - added +3.0.1 - add `--force` and skip already downloaded attachments by default + +| Option | Description | +| :--- | :--- | +| --account ACCT | String `username@domain` handle of the account | +| --domain DOMAIN | FQDN string | +| --status ID | Local numeric ID of the status in the database. | +| --concurrency N | The number of workers to use for this task. Defaults to 5. | +| --verbose | Print additional information while task is processing. | +| --dry\_run | Print expected results only, without performing any actions. | +| --force | Force redownload the remote resource and overwrite the local attachment. | + +### `tootctl media usage` + +Calculate disk space consumed by Mastodon. + +**Version history:** +3.0.1 - added + +### `tootctl media lookup` + +Prompts for a media URL, then looks up where the media is displayed. + +**Version history:** +3.1.0 - added + +## Preview Cards CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/preview_cards_cli.rb" caption="lib/mastodon/preview\_cards\_cli.rb" >}} + +### `tootctl preview_cards remove` + +Remove local thumbnails for preview cards. + +**Version history:** +3.0.0 - added + +| Option | Description | +| :--- | :--- | +| --days | How old media attachments have to be before they are removed. Defaults to 180. \(NOTE: it is not recommended to delete preview cards within the last 14 days, because preview cards will not be refetched unless the link is reposted after 2 weeks from last time.\) | +| --concurrency N | The number of workers to use for this task. Defaults to 5. | +| --verbose | Print additional information while task is processing. | +| --dry\_run | Print expected results only, without performing any actions. | +| --link | Only delete link-type preview cards; leave video and photo cards untouched. | + +## Search CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/search_cli.rb" caption="lib/mastodon/search\_cli.rb" >}} + +### `tootctl search deploy` + +Create or update an ElasticSearch index and populate it. If ElasticSearch is empty, this command will create the necessary indices and then import data from the database into those indices. This command will also upgrade indices if the underlying schema has been changed since the last run. + +**Version history:** +2.8.0 - added +3.0.0 - add `--processes` for parallelization + +| Option | Description | +| :--- | :--- | +| --processes N | Parallelize execution of the command. Defaults to N=2. Can also specify `auto` to derive a number based on available CPUs. | + +## Settings CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/settings_cli.rb" caption="lib/mastodon/settings\_cli.rb" >}} + +### `tootctl settings registrations open` + +Opens registrations. + +**Version history:** +2.6.0 - added + +### `tootctl settings registrations close` + +Closes registrations. + +**Version history:** +2.6.0 - added + +## Statuses CLI + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/lib/mastodon/statuses_cli.rb" caption="lib/mastodon/statuses\_cli.rb" >}} + +### `tootctl statuses remove` + +Remove unreferenced statuses from the database, such as statuses that came from relays or from users who are no longer followed by any local accounts, and have not been replied to or otherwise interacted with. + +This is a computationally heavy procedure that creates extra database indices before commencing, and removes them afterward. + +**Version history:** +2.8.0 - added + +| Option | Description | +| :--- | :--- | +| --days | How old statuses have to be before they are removed. Defaults to 90. | + diff --git a/content/en/admin/troubleshooting.md b/content/en/admin/troubleshooting.md new file mode 100644 index 00000000..fafd7e57 --- /dev/null +++ b/content/en/admin/troubleshooting.md @@ -0,0 +1,28 @@ +--- +title: Troubleshooting errors +menu: + docs: + weight: 120 + parent: admin +--- + +## **I see an error page that says something went wrong. How do I find out what’s wrong?** + +All error messages with stack traces are written to the system log. When using systemd, the logs of each systemd service can be browsed with `journalctl -u mastodon-web` \(substitute with the correct service name\). When using Docker, it’s similar: `docker logs mastodon_web_1` \(substitute with the correct container name\). + +Specific details of server-side errors are _never_ displayed to the public, as they can reveal what your setup looks like internally and give attackers clues how to get in, or how to abuse the system more efficiently. + +Each response from Mastodon’s web server carries a header with a unique request ID, which is also reflected in the logs. By inspecting the headers of the error page, you can easily find the corresponding stack trace in the log. + +## **After an upgrade to a newer version, some pages look weird, like they have unstyled elements. Why?** + +Check that you have run `RAILS_ENV=production bin/rails assets:precompile` after the upgrade, and restarted Mastodon’s web process, because it looks like it’s serving outdated stylesheets and scripts. It’s also possible that the precompilation fails due to a lack of RAM, as webpack is unfortunately extremely memory-hungry. If that is the case, make sure you have some swap space assigned. Alternatively, it’s possible to precompile the assets on a different machine, then copy over the `public/packs` directory. + +## **After an upgrade to a newer version, some requests fail and the logs show error messages about missing columns or tables. Why?** + +Check that you have run `RAILS_ENV=production bin/rails db:migrate` after the upgrade, because it looks like Mastodon’s code is accessing a newer or older database schema. If you are using PgBouncer, make sure this one command connects directly to PostgreSQL, as PgBouncer does not support the kind of table locks that are used within migrations. + +## **I am trying to run a `tootctl` or `rake`/`rails` command, but all I get is an error about uninitialized constants. What’s wrong?** + +Check that you are specifying the correct environment with `RAILS_ENV=production` before the command. By default, the environment is assumed to be development, so the code tries to load development-related gems. However, in production environments, we avoid installing those gems, and that’s where the error comes from. + diff --git a/content/en/administration/upgrading.md b/content/en/admin/upgrading.md similarity index 63% rename from content/en/administration/upgrading.md rename to content/en/admin/upgrading.md index b5399594..501f0901 100644 --- a/content/en/administration/upgrading.md +++ b/content/en/admin/upgrading.md @@ -1,57 +1,55 @@ --- title: Upgrading to a new release -description: How to upgrade Mastodon to a newer version menu: docs: - parent: administration - weight: 5 + weight: 70 + parent: admin --- +{{< hint style="info" >}} When a new version of Mastodon comes out, it appears on the [GitHub releases page](https://github.com/tootsuite/mastodon/releases). Please mind that running unreleased code from the `master` branch, while possible, is not recommended. +{{< /hint >}} Mastodon releases correspond to git tags. First, switch to the `mastodon` user: -```sh +```bash su - mastodon ``` And navigate to the Mastodon root directory: -```sh -cd /home/mastodon/live -``` +Download the releases’s code, assuming that the version is called `v2.5.0`: -Download the releases's code, assuming that the version is called `v2.5.0`: - -```sh +```bash git fetch --tags git checkout v2.5.0 ``` -The release page contains a changelog, and below it, upgrade instructions. This is where you would execute them, for example, if the release mentions that you need to re-compile assets, you would execute: +**The release page contains a changelog, and below it, upgrade instructions**. This is where you would execute them, for example, if the release mentions that you need to re-compile assets, you would execute: -```sh +```bash RAILS_ENV=production bundle exec rails assets:precompile ``` -After you have executed all special release-specific instructions, the last thing remaining is restarting Mastodon. *Usually* the streaming API is not updated, and therefore does not require a restart. Restarting the streaming API can lead to an unusually high load on the server, so it is advised to avoid it if possible. +After you have executed all special release-specific instructions, the last thing remaining is restarting Mastodon. _Usually_ the streaming API is not updated, and therefore does not require a restart. Restarting the streaming API can lead to an unusually high load on the server, so it is advised to avoid it if possible. Switch back to root: -```sh +```bash exit ``` You would restart Sidekiq: -```sh +```bash systemctl restart mastodon-sidekiq ``` And you would reload the web process to avoid downtime: -```sh +```bash systemctl reload mastodon-web ``` -**That's all!** You're running the new version of Mastodon now. +**That’s all!** You’re running the new version of Mastodon now. + diff --git a/content/en/administration/configuration.md b/content/en/administration/configuration.md deleted file mode 100644 index b1cb1136..00000000 --- a/content/en/administration/configuration.md +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: Configuration -description: Overview of Mastodon's configuration options -menu: - docs: - parent: administration - weight: 2 ---- - -Mastodon uses environment variables as its configuration. - -For convenience, it can read them from a flat file called `.env.production` in the Mastodon directory, but they can always be overridden by a specific process. For example, systemd service files can read environment variables from an `EnvironmentFile` or from inline definitions with `Environment`, so you can have different configuration parameters for specific services. They can also be specified when calling Mastodon from the command line. - -## Basic -### Federation - -- `LOCAL_DOMAIN` -- `WEB_DOMAIN` -- `ALTERNATE_DOMAINS` - -### Secrets - -- `SECRET_KEY_BASE` -- `OTP_SECRET` -- `VAPID_PRIVATE_KEY` -- `VAPID_PUBLIC_KEY` - -### Deployment - -- `RAILS_ENV` -- `RAILS_SERVE_STATIC_FILES` -- `RAILS_LOG_LEVEL` -- `TRUSTED_PROXY_IP` -- `SOCKET` -- `PORT` -- `NODE_ENV` -- `BIND` - -### Scaling options - -- `WEB_CONCURRENCY` -- `MAX_THREADS` -- `PREPARED_STATEMENTS` -- `STREAMING_API_BASE_URL` -- `STREAMING_CLUSTER_NUM` - -## Database connections -### PostgreSQL - -- `DB_HOST` -- `DB_USER` -- `DB_NAME` -- `DB_PASS` -- `DB_PORT` -- `DATABASE_URL` - -### Redis - -- `REDIS_HOST` -- `REDIS_PORT` -- `REDIS_URL` -- `REDIS_NAMESPACE` -- `CACHE_REDIS_HOST` -- `CACHE_REDIS_PORT` -- `CACHE_REDIS_URL` -- `CACHE_REDIS_NAMESPACE` - -### ElasticSearch - -- `ES_ENABLED` -- `ES_HOST` -- `ES_PORT` -- `ES_PREFIX` - -### StatsD - -- `STATSD_ADDR` -- `STATSD_NAMESPACE` - -## Limits - -- `SINGLE_USER_MODE` -- `EMAIL_DOMAIN_WHITELIST` -- `DEFAULT_LOCALE` -- `MAX_SESSION_ACTIVATIONS` -- `USER_ACTIVE_DAYS` - -## E-mail - -- `SMTP_SERVER` -- `SMTP_PORT` -- `SMTP_LOGIN` -- `SMTP_PASSWORD` -- `SMTP_FROM_ADDRESS` -- `SMTP_DOMAIN` -- `SMTP_DELIVERY_METHOD` -- `SMTP_AUTH_METHOD` -- `SMTP_CA_FILE` -- `SMTP_OPENSSL_VERIFY_MODE` -- `SMTP_ENABLE_STARTTLS_AUTO` -- `SMTP_TLS` - -## File storage - -- `CDN_HOST` -- `S3_ALIAS_HOST` - -### Local file storage - -- `PAPERCLIP_ROOT_PATH` -- `PAPERCLIP_ROOT_URL` - -### Amazon S3 and compatible - -- `S3_ENABLED` -- `S3_BUCKET` -- `AWS_ACCESS_KEY_ID` -- `AWS_SECRET_ACCESS_KEY` -- `S3_REGION` -- `S3_PROTOCOL` -- `S3_HOSTNAME` -- `S3_ENDPOINT` -- `S3_SIGNATURE_VERSION` - -### Swift - -- `SWIFT_ENABLED` -- `SWIFT_USERNAME` -- `SWIFT_TENANT` -- `SWIFT_PASSWORD` -- `SWIFT_PROJECT_ID` -- `SWIFT_AUTH_URL` -- `SWIFT_CONTAINER` -- `SWIFT_OBJECT_URL` -- `SWIFT_REGION` -- `SWIFT_DOMAIN_NAME` -- `SWIFT_CACHE_TTL` - -## External authentication - -- `OAUTH_REDIRECT_AT_SIGN_IN` - -### LDAP - -- `LDAP_ENABLED` -- `LDAP_HOST` -- `LDAP_PORT` -- `LDAP_METHOD` -- `LDAP_BASE` -- `LDAP_BIND_DN` -- `LDAP_PASSWORD` -- `LDAP_UID` -- `LDAP_SEARCH_FILTER` - -### PAM - -- `PAM_ENABLED` -- `PAM_EMAIL_DOMAIN` -- `PAM_DEFAULT_SERVICE` -- `PAM_CONTROLLED_SERVICE` - -### CAS - -- `CAS_ENABLED` -- `CAS_URL` -- `CAS_HOST` -- `CAS_PORT` -- `CAS_SSL` -- `CAS_VALIDATE_URL` -- `CAS_CALLBACK_URL` -- `CAS_LOGOUT_URL` -- `CAS_LOGIN_URL` -- `CAS_UID_FIELD` -- `CAS_CA_PATH` -- `CAS_DISABLE_SSL_VERIFICATION` -- `CAS_UID_KEY` -- `CAS_NAME_KEY` -- `CAS_EMAIL_KEY` -- `CAS_NICKNAME_KEY` -- `CAS_FIRST_NAME_KEY` -- `CAS_LAST_NAME_KEY` -- `CAS_LOCATION_KEY` -- `CAS_IMAGE_KEY` -- `CAS_PHONE_KEY` - -### SAML - -- `SAML_ENABLED` -- `SAML_ACS_URL` -- `SAML_ISSUER` -- `SAML_IDP_SSO_TARGET_URL` -- `SAML_IDP_CERT` -- `SAML_IDP_CERT_FINGERPRINT` -- `SAML_NAME_IDENTIFIER_FORMAT` -- `SAML_CERT` -- `SAML_PRIVATE_KEY` -- `SAML_SECURITY_WANT_ASSERTION_SIGNED` -- `SAML_SECURITY_WANT_ASSERTION_ENCRYPTED` -- `SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED` -- `SAML_ATTRIBUTES_STATEMENTS_UID` -- `SAML_ATTRIBUTES_STATEMENTS_EMAIL` -- `SAML_ATTRIBUTES_STATEMENTS_FULL_NAME` -- `SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME` -- `SAML_ATTRIBUTES_STATEMENTS_LAST_NAME` -- `SAML_UID_ATTRIBUTE` -- `SAML_ATTRIBUTES_STATEMENTS_VERIFIED` -- `SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL` - -## Hidden services - -- `http_proxy` -- `ALLOW_ACCESS_TO_HIDDEN_SERVICE` - -## Other - -- `SKIP_POST_DEPLOYMENT_MIGRATIONS` diff --git a/content/en/administration/installation.md b/content/en/administration/installation.md deleted file mode 100644 index 653da4da..00000000 --- a/content/en/administration/installation.md +++ /dev/null @@ -1,333 +0,0 @@ ---- -title: Installation -description: How to install Mastodon on an Ubuntu 18.04 server -menu: - docs: - parent: administration - weight: 1 ---- - - - -## Basic server setup (optional) - -If you are setting up a fresh machine, it is recommended that you secure it first. Assuming that you are running **Ubuntu 18.04**: - -### Do not allow password-based SSH login (keys only) - -First make sure you are actually logging in to the server using keys and not via a password, otherwise this will lock you out. Many hosting providers support uploading a public key and automatically set up key-based root login on new machines for you. - -Edit `/etc/ssh/sshd_config` and find `PasswordAuthentication`. Make sure it's uncommented and set to `no`. If you made any changes, restart sshd: - -```sh -systemctl restart ssh -``` - -### Update system packages - -```sh -apt update && apt upgrade -y -``` - -### Install fail2ban so it blocks repeated login attempts - -```sh -apt install fail2ban -``` - -Edit `/etc/fail2ban/jail.local` and put this inside: - -```ini -[DEFAULT] -destemail = your@email.here -sendername = Fail2Ban - -[sshd] -enabled = true -port = 22 - -[sshd-ddos] -enabled = true -port = 22 -``` - -Finally restart fail2ban: - -```sh -systemctl restart fail2ban -``` - -### Install a firewall and only whitelist SSH, HTTP and HTTPS ports - -First, install iptables-persistent. During installation it will ask you if you want to keep current rules--decline. - -```sh -apt install -y iptables-persistent -``` - -Edit `/etc/iptables/rules.v4` and put this inside: - -``` -*filter - -# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0 --A INPUT -i lo -j ACCEPT --A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT - -# Accept all established inbound connections --A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT - -# Allow all outbound traffic - you can modify this to only allow certain traffic --A OUTPUT -j ACCEPT - -# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL). --A INPUT -p tcp --dport 80 -j ACCEPT --A INPUT -p tcp --dport 443 -j ACCEPT - -# Allow SSH connections -# The -dport number should be the same port number you set in sshd_config --A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT - -# Allow ping --A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT - -# Log iptables denied calls --A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 - -# Reject all other inbound - default deny unless explicitly allowed policy --A INPUT -j REJECT --A FORWARD -j REJECT - -COMMIT -``` - -With iptables-persistent, that configuration will be loaded at boot time. But since we are not rebooting right now, we need to load it manually for the first time: - -```sh -iptables-restore < /etc/iptables/rules.v4 -``` - -## Pre-requisites - -- A machine running **Ubuntu 18.04** that you have root access to -- A **domain name** (or a subdomain) for the Mastodon server, e.g. `example.com` -- An e-mail delivery service or other **SMTP server** - -You will be running the commands as root. If you aren't already root, switch to root: - -```sh -sudo -i -``` - -### System repositories - -Make sure curl is installed first: - -```sh -apt install -y curl -``` - -#### Node.js - -```sh -curl -sL https://deb.nodesource.com/setup_8.x | bash - -``` - -#### Yarn - -```sh -curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -``` - -### System packages - -```sh -apt update -apt install -y \ - imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \ - g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \ - bison build-essential libssl-dev libyaml-dev libreadline6-dev \ - zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev \ - nginx redis-server redis-tools postgresql postgresql-contrib \ - certbot python-certbot-nginx yarn libidn11-dev libicu-dev libjemalloc-dev -``` - -### Installing Ruby - -We will be using rbenv to manage Ruby versions, because it's easier to get the right versions and to update once a newer release comes out. rbenv must be installed for a single Linux user, therefore, first we must create the user Mastodon will be running as: - -```sh -adduser --disabled-login mastodon -``` - -We can then switch to the user: - -```sh -su - mastodon -``` - -And proceed to install rbenv and rbenv-build: - -```sh -git clone https://github.com/rbenv/rbenv.git ~/.rbenv -cd ~/.rbenv && src/configure && make -C src -echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc -echo 'eval "$(rbenv init -)"' >> ~/.bashrc -exec bash -git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build -``` - -Once this is done, we can install the correct Ruby version: - -```sh -RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.6.1 -rbenv global 2.6.1 -``` - -Default gem version shipped with ruby_2.6.0 is incompatible with latest bundler, so we need to update gem: - -``` -gem update --system -``` - -We'll also need to install bundler: - -```sh -gem install bundler --no-document -``` - -Return to the root user: - -```sh -exit -``` - -## Setup -### Setting up PostgreSQL -#### Performance configuration (optional) - -For optimal performance, you may use [pgTune](https://pgtune.leopard.in.ua/#/) to generate an appropriate configuration and edit values in `/etc/postgresql/9.6/main/postgresql.conf` before restarting PostgreSQL with `systemctl restart postgresql` - -#### Creating a user - -You will need to create a PostgreSQL user that Mastodon could use. It is easiest to go with "ident" authentication in a simple setup, i.e. the PostgreSQL user does not have a separate password and can be used by the Linux user with the same username. - -Open the prompt: - -```sh -sudo -u postgres psql -``` - -In the prompt, execute: - -``` -CREATE USER mastodon CREATEDB; -\q -``` - -Done! - -### Setting up Mastodon - -It is time to download the Mastodon code. Switch to the mastodon user: - -```sh -su - mastodon -``` - -#### Checking out the code - -Use git to download the latest stable release of Mastodon: - -```sh -git clone https://github.com/tootsuite/mastodon.git live && cd live -git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1) -``` - -#### Installing the last dependencies - -Now to install Ruby and JavaScript dependencies: - -```sh -bundle install \ - -j$(getconf _NPROCESSORS_ONLN) \ - --deployment --without development test -yarn install --pure-lockfile -``` - -#### Generating a configuration - -Run the interactive setup wizard: - -```sh -RAILS_ENV=production bundle exec rake mastodon:setup -``` - -This will: - -- Create a configuration file -- Run asset precompilation -- Create the database schema - -The configuration file is saved as `.env.production`. You can review and edit it to your liking. Refer to the [documentation on configuration]({{< relref "configuration.md" >}}). - -You're done with the mastodon user for now, so switch back to root: - -```sh -exit -``` - -### Setting up nginx - -Copy the configuration template for nginx from the Mastodon directory: - -```sh -cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon -ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon -``` - -Then edit `/etc/nginx/sites-available/mastodon` to replace `example.com` with your own domain name, and make any other adjustments you might need. - -Reload nginx for the changes to take effect: - -```sh -systemctl reload nginx -``` - -### Acquiring a SSL certificate - -We'll use Let's Encrypt to get a free SSL certificate: - -```sh -certbot --nginx -d example.com -``` - -This will obtain the certificate, automatically update `/etc/nginx/sites-available/mastodon` to use the new certificate, and reload nginx for the changes to take effect. - -At this point you should be able to visit your domain in the browser and see the elephant hitting the computer screen error page. This is because we haven't started the Mastodon process yet. - -### Setting up systemd services - -Copy the systemd service templates from the Mastodon directory: - -```sh -cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/ -``` - -Then edit the files to make sure the username and paths are correct: - -- `/etc/systemd/system/mastodon-web.service` -- `/etc/systemd/system/mastodon-sidekiq.service` -- `/etc/systemd/system/mastodon-streaming.service` - -Finally, start and enable the new systemd services: - -```sh -systemctl start mastodon-web mastodon-sidekiq mastodon-streaming -systemctl enable mastodon-* -``` - -They will now automatically start at boot time. - -**Hurray! This is it. You can visit your domain in the browser now!** diff --git a/content/en/administration/migrating.md b/content/en/administration/migrating.md deleted file mode 100644 index 66edcc28..00000000 --- a/content/en/administration/migrating.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Migrating servers -description: How to migrate a Mastodon instance to a new server -menu: - docs: - parent: administration - weight: 6 ---- - -Sometimes, for various reasons, you may want to migrate your Mastodon instance from one server to another. Fortunately this is not too difficult of a process, although it may result in some downtime. - -**Note:** this guide was written with Ubuntu Server in mind; your mileage may vary for other setups. - -Basic steps ----- - -1. Set up a new Mastodon server using the [Production Guide](/administration/installation/) (however, don't run `mastodon:setup`). -2. Stop Mastodon on the old server (e.g. `systemctl stop 'mastodon-*.service'`). -3. Dump and load the Postgres database using the instructions below. -4. Copy the `system/` files using the instructions below. (Note: if you're using S3, you can skip this step.) -5. Copy the `.env.production` file. -6. Run `RAILS_ENV=production bundle exec rails assets:precompile` to compile Mastodon -7. Run `RAILS_ENV=production ./bin/tootctl feeds build` to rebuild the home timelines for each user. -8. Start Mastodon on the new server. -9. Update your DNS settings to point to the new server. -10. Update or copy your Nginx configuration, re-run LetsEncrypt as necessary. -11. Enjoy your new server! - -Detailed steps ----- - -### What data needs to be migrated - -At a high level, you'll need to copy over the following: - -- The `~/live/public/system` directory, which contains user-uploaded images and videos (if using S3, you don't need this) -- The Postgres database (using [pg\_dump](https://www.postgresql.org/docs/9.1/static/backup-dump.html)) -- The `~/live/.env.production` file, which contains server config and secrets - -Less crucially, you'll probably also want to copy the following for convenience: - -- The nginx config (under `/etc/nginx/sites-available/default`) -- The systemd config files (`/etc/systemd/system/mastodon-*.service`), which may contain your server tweaks and customizations -- The pgbouncer configuration under `/etc/pgbouncer` (if you're using it) - -### Dump and load Postgres - -Instead of running `mastodon:setup`, we're going to create an empty Postgres database -using the `template0` database (which is useful when restoring a Postgres dump, -[as described in the pg\_dump documentation](https://www.postgresql.org/docs/9.1/static/backup-dump.html#BACKUP-DUMP-RESTORE)). - -Run this as the `mastodon` user on your old system: - -```bash -pg_dump -Fc mastodon_production -f backup.dump -``` - -Copy the `backup.dump` file over, using `rsync` or `scp`. Then on the new system, -create an empty database as the `mastodon` user: - -```bash -createdb -T template0 mastodon_production -``` - -Then import it: - -```bash -pg_restore -U mastodon -n public --no-owner --role=mastodon \ - -d mastodon_production backup.dump -``` - -(Note that if the username is not `mastodon` on the new server, you should change the -`-U` AND `--role` values above. It's okay if the username is different between the two servers.) - -### Copy files - -This will probably take some time, and you'll want to avoid re-copying unnecessarily, so using `rsync` is recommended. -On your old machine, as the `mastodon` user, run: - -```bash -rsync -avz ~/live/public/system/ mastodon@example.com:~/live/public/system/ -``` - -You'll want to re-run this if any of the files on the old server change. - -You should also copy over the `.env.production` file, which contains secrets. - -Optionally, you may copy over the -nginx, systemd, and pgbouncer config files, or rewrite them from scratch. - -### During migration - -You can edit the `~/live/public/500.html` page on the old machine if you want to show a nice error message to -let existing users know that a migration is in progress. - -You'll probably also want to set the DNS TTL to something small (30-60 minutes) about a day in advance, so -that DNS can propagate quickly once you point it to the new IP address. - -### After migrating - -You can check [whatsmydns.net](http://whatsmydns.net/) to see the progress of DNS propagation. -To jumpstart the process, you can always edit your own `/etc/hosts` file to point to your new server so -you can start playing around with it early. diff --git a/content/en/administration/post-installation.md b/content/en/administration/post-installation.md deleted file mode 100644 index 0b0daff9..00000000 --- a/content/en/administration/post-installation.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: Post-installation steps -description: What to do after the installation of Mastodon is complete -menu: - docs: - parent: administration - weight: 3 ---- - -## Using the command-line interface - -The command-line interface of Mastodon is an executable file called `tootctl` residing in the `bin` directory within the Mastodon root directory. You must specify which environment you intend to use whenever you execute it by specifying the `RAILS_ENV` environment variable. Unless you are a developer working on a local machine, you need to use `RAILS_ENV=production`. If you are sure that you will never need another environment (for development, testing, or staging), you can add it to your `.bashrc` file for convenience, e.g.: - -```bash -echo "export RAILS_ENV=production" >> ~/.bashrc -``` - -If so, you won't need to specify it each time inline. Otherwise, calls to `tootctl` will usually go like this, assuming that the Mastodon code is checked out in `/home/mastodon/live`: - -```bash -cd /home/mastodon/live -RAILS_ENV=production bin/tootctl help -``` - -## Creating an admin account -### In the browser - -After signing up in the browser, you will need to use the command line to give your newly created account admin privileges. Assuming your username is `alice`: - -```bash -RAILS_ENV=production bin/tootctl accounts modify alice --role admin -``` - -### From the command line - -You can create a new account using the command-line interface. - -```bash -RAILS_ENV=production bin/tootctl accounts create \ - alice \ - --email alice@example.com \ - --confirmed \ - --role admin -``` - -A randomly generated password will be shown in the terminal. - -## Filling in server information - -After logging in, navigate to the **Site settings** page. While there are no technical requirements for filling in this information, it is considered crucial for operating a server for humans. - -|Setting|Meaning| -|-------|-------| -|Contact username|Your username so people know who owns the server| -|Business e-mail|An e-mail address so people locked out of their accounts, or people without accounts, can contact you| -|Instance description|Why did you start this server? Who is it for? What makes it different?| -|Custom extended information|You can put all sorts of information in here but a **code of conduct** is recommended| - -After you fill these in, simply hit "Save changes". - -## Setting up regular backups (optional, but not really) - -For any real-world use, you should make sure to regularly backup your Mastodon server. - -### Overview - -Things that need to be backed up in order of importance: - -1. PostgreSQL database -2. Application secrets from the `.env.production` file or equivalent -3. User-uploaded files -4. Redis database - -### Failure modes - -There are two failure types that people in general may guard for: The failure of the hardware, such as data corruption on the disk; and human and software error, such as wrongful deletion of particular piece of data. In this documentation, only the former type is considered. - -A lost PostgreSQL database is complete game over. Mastodon stores all the most important data in the PostgreSQL database. If the database disappears, all the accounts, posts and followers on your server will disappear with it. - -If you lose application secrets, some functions of Mastodon will stop working for your users, they will be logged out, two-factor authentication will become unavailable, Web Push API subscriptions will stop working. - -If you lose user-uploaded files, you will lose avatars, headers, and media attachments, but Mastodon *will* work moving forward. - -Losing the Redis database is almost harmless: The only irrecoverable data will be the contents of the Sidekiq queues and scheduled retries of previously failed jobs. The home and list feeds are stored in Redis, but can be regenerated with tootctl. - -The best backups are so-called off-site backups, i.e. ones that are not stored on the same machine as Mastodon itself. If the server you are hosted on goes on fire and the hard disk drive explodes, backups stored on that same hard drive won't be of much use. - -### Backing up application secrets - -Application secrets are the easiest to backup, since they never change. You only need to store `.env.production` somewhere safe. - -### Backing up PostgreSQL - -PostgreSQL is at risk of data corruption from power cuts, hard disk drive failure, and botched schema migrations. For that reason, occassionally making a backup with `pg_dump` or `pg_dumpall` is recommended. - -For high-availability setups, it is possible to use hot streaming replication to have a second PostgreSQL server with always up-to-date data, ready to be switched over to if the other server goes down. - -### Backing up user-uploaded files - -If you are using an external object storage provider such as Amazon S3, Google Cloud or Wasabi, then you don't need to worry about backing those up. The respective companies are responsible for handling hardware failures. - -If you are using local file storage, then it's up to you to make copies of the sizeable `public/system` directory, where uploaded files are stored by default. - -### Backing up Redis - -Backing up Redis is easy. Redis regularly writes to `/var/lib/redis/dump.rdb` which is the only file you need to make a copy of. diff --git a/content/en/administration/scaling-up.md b/content/en/administration/scaling-up.md deleted file mode 100644 index 563c9176..00000000 --- a/content/en/administration/scaling-up.md +++ /dev/null @@ -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). diff --git a/content/en/administration/troubleshooting.md b/content/en/administration/troubleshooting.md deleted file mode 100644 index de272733..00000000 --- a/content/en/administration/troubleshooting.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Troubleshooting -description: How to figure out what's wrong with your Mastodon installation -menu: - docs: - parent: administration - weight: 99 ---- - -**I see an error page that says something went wrong. How do I find out what's wrong?** - -All error messages with stack traces are written to the system log. When using systemd, the logs of each systemd service can be browsed with `journalctl -u mastodon-web` (substitute with the correct service name). When using Docker, it's similar: `docker logs mastodon_web_1` (substitute with the correct container name). - -Specific details of server-side errors are *never* displayed to the public, as they can reveal what your setup looks like internally and give attackers clues how to get in, or how to abuse the system more efficiently. - -Each response from Mastodon's web server carries a header with a unique request ID, which is also reflected in the logs. By inspecting the headers of the error page, you can easily find the corresponding stack trace in the log. - -**After an upgrade to a newer version, some pages look weird, like they have unstyled elements. Why?** - -Check that you have run `RAILS_ENV=production bin/rails assets:precompile` after the upgrade, and restarted Mastodon's web process, because it looks like it's serving outdated stylesheets and scripts. It's also possible that the precompilation fails due to a lack of RAM, as webpack is unfortunately extremely memory-hungry. If that is the case, make sure you have some swap space assigned. Alternatively, it's possible to precompile the assets on a different machine, then copy over the `public/packs` directory. - -**After an upgrade to a newer version, some requests fail and the logs show error messages about missing columns or tables. Why?** - -Check that you have run `RAILS_ENV=production bin/rails db:migrate` after the upgrade, because it looks like Mastodon's code is accessing a newer or older database schema. If you are using PgBouncer, make sure this one command connects directly to PostgreSQL, as PgBouncer does not support the kind of table locks that are used within migrations. - -**I am trying to run a `tootctl` or `rake`/`rails` command, but all I get is an error about uninitialized constants. What's wrong?** - -Check that you are specifying the correct environment with `RAILS_ENV=production` before the command. By default, the environment is assumed to be development, so the code tries to load development-related gems. However, in production environments, we avoid installing those gems, and that's where the error comes from. \ No newline at end of file diff --git a/content/en/api/authentication.md b/content/en/api/authentication.md deleted file mode 100644 index 7f800152..00000000 --- a/content/en/api/authentication.md +++ /dev/null @@ -1,48 +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 - -## OAuth 2 endpoints - -The following descriptions are taken from the [Doorkeeper documentation](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples). Mastodon uses Doorkeeper to implement OAuth 2. - -### GET /oauth/authorize - -Redirect here with `response_type=code`, `client_id`, `client_secret`, `redirect_uri`, `scope`, and optional `state`. Displays an authorization form to the user. If approved, it will create and return an authorization code, then redirect to the desired `redirect_uri`, or show the authorization code if `urn:ietf:wg:oauth:2.0:oob` was requested. - -### POST /oauth/token - -Post here with `authorization_code` for authorization code grant type or `username` and `password` for password grant type. Returns an access token. This corresponds to the token endpoint, section 3.2 of the OAuth 2 RFC. - -### POST /oauth/revoke - -Post here with client credentials (in basic auth or in params `client_id` and `client_secret`) to revoke an access token. This corresponds to the token endpoint, using the OAuth 2.0 Token Revocation RFC (RFC 7009). - -## Example authorization code flow - -1. Get `client_id` and `client_secret` from your local cache. If you don't have the two, you need to [register the application]({{< relref "api/rest/apps.md#post-api-v1-apps" >}}). Store `client_id` and `client_secret` in your local cache for next time. We actually don't need the `id` returned from this call. -1. Tell the user to visit `/oauth/authorize` with parameters `scope`, `response_type=code`, `redirect_uri`, your `client_id`, and optionally a randomly-generated `state` parameter. The user clicks on the URL and gets shown a page asking them to authorize your app for the scopes you requested. If the user clicks on the right button, they are redirected back to your `redirect_uri` with a `code` param in the query string. That is the authorization code. If you provided a `state` value in the previous step, that will be passed along as well. -1. Send a POST request to `/oauth/token` with the parameters `client_id`, `client_secret`, `grant_type=authorization_code`, `code`, `redirect_uri`. Save the `access_token` you get back in your local cache. Note that an authorization code can only be used once. If it has been used already, you need to repeat step two to get a new one. - -Once you have the access token, add the HTTP header `Authorization: Bearer ...` to any API call. - -## Common gotchas - -- The OAuth param name is `scope`, but when registering the application using Mastodon's REST API, the param name is `scopes`. The OAuth param can be a subset of the scopes you registered initially, but cannot include anything that wasn't in the original set. -- The OAuth param name is `redirect_uri`, but when registering the application using Mastodon's REST API, the param name is `redirect_uris`. The latter can actually consist of multiple allowed URIs, separated by newlines. -- The `redirect_uri` in all OAuth requests must either be the same as the one registered with the application, or one of them, if you registered multiple URIs separated by newlines with the application. \ No newline at end of file diff --git a/content/en/api/entities.md b/content/en/api/entities.md deleted file mode 100644 index c8ab0ba9..00000000 --- a/content/en/api/entities.md +++ /dev/null @@ -1,380 +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 string representations of integers. - - IDs can be sorted first by size, and then lexically, to produce a chronological ordering of resources. -- 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| - -### Token - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `access_token` | String |{{< no >}}|0.1.0| -| `token_type` | String |{{< no >}}|0.1.0| -| `scope` | String |{{< no >}}|0.1.0| -| `created_at` | Number |{{< no >}}|0.1.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-1) |{{< 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 (ISO 639, Part 1-5) |{{< 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` -- `poll` - -## Poll - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `id` | String |{{< no >}}|2.8.0| -| `expires_at` | String (Datetime) |{{< yes >}}|2.8.0| -| `expired` | Boolean |{{< no >}}|2.8.0| -| `multiple` | Boolean |{{< no >}}|2.8.0| -| `votes_count` | Number |{{< no >}}|2.8.0| -| `options` | Array of [Poll option](#poll-option) |{{< no >}}|2.8.0| -| `voted` | Boolean |{{< yes >}}|2.8.0| - -### Poll option - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `title` | String |{{< no >}}|2.8.0| -| `votes_count` | Number |{{< yes >}}|2.8.0| - -## 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| -| `card` | [Card](#card) |{{< yes >}}|2.6.0| -| `poll` | [Poll](#poll) |{{< yes >}}|2.8.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` - -## ScheduledStatus - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `id` | String |{{< no >}}|2.7.0| -| `scheduled_at` | String (Datetime) |{{< no >}}|2.7.0| -| `params` | [StatusParams](#statusparams) |{{< no >}}|2.7.0| -| `media_attachments` | Array of [Attachment](#attachment) |{{< no >}}|2.7.0| - -### StatusParams - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `text` | String |{{< no >}}|2.7.0| -| `in_reply_to_id` | String |{{< yes >}}|2.7.0| -| `media_ids` | Array of String |{{< yes >}}|2.7.0| -| `sensitive` | Boolean |{{< yes >}}|2.7.0| -| `spoiler_text` | String |{{< yes >}}|2.7.0| -| `visibility` | [String (Enum)](#visibility) |{{< no >}}|2.7.0| -| `scheduled_at` | String (Datetime) |{{< yes >}}|2.7.0| -| `application_id` | String |{{< no >}}|2.7.0| - -## 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| - -## Conversation - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `id` | String |{{< no >}}|2.6.0| -| `accounts` | Array of [Account](#account) |{{< no >}}|2.6.0| -| `last_status` | [Status](#status) |{{< yes >}}|2.6.0| -| `unread` | Boolean |{{< no >}}|2.6.0| diff --git a/content/en/api/guidelines.md b/content/en/api/guidelines.md deleted file mode 100644 index b9ef1ec2..00000000 --- a/content/en/api/guidelines.md +++ /dev/null @@ -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: `

`, `
`, ``, `` - -### Mentions and hashtags - -Mentions and hashtags are `` 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 - - - example.com/page - - -``` - -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. diff --git a/content/en/api/libraries.md b/content/en/api/libraries.md deleted file mode 100644 index 1551baa1..00000000 --- a/content/en/api/libraries.md +++ /dev/null @@ -1,103 +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 - -- [masto.js](https://github.com/neet/masto.js) -- [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) diff --git a/content/en/api/oauth-scopes.md b/content/en/api/oauth-scopes.md new file mode 100644 index 00000000..6b7a6cf4 --- /dev/null +++ b/content/en/api/oauth-scopes.md @@ -0,0 +1,89 @@ +--- +title: OAuth Scopes +menu: + docs: + weight: 10 + parent: api +--- + +## OAuth Scopes + +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\). + +{{< 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`. +{{< /hint >}} + +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. + +### Version history + +- 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 + +## List of scopes + +### `read` + +Grants access to read data. Requesting `read` will also grant child scopes shown in the left column of the table below. + +### `write` + +Grants access to write data. Requesting `write` will also grant child scopes shown in the right column of the table below. + +### `follow` + +Grants access to manage relationships. Requesting `follow` will also grant the following child scopes, shown in bold in the table: + +* `read:blocks`, `write:blocks` +* `read:follows`, `write:follows` +* `read:mutes`, `write:mutes` + +### `push` + +Grants access to [Web Push API subscriptions.]({{< relref "../methods/notifications/push.md" >}}) Added in Mastodon 2.4.0. + +### Admin scopes + +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:write` + * `admin:write:accounts` + * `admin:write:reports` + +## Granular scopes + +| read | write | +| :--- | :--- | +| read:accounts | write:accounts | +| **read:blocks** | **write:blocks** | +| read:bookmarks | write:bookmarks | +| | write:conversations | +| read:favourites | write:favourites | +| read:filters | write:filters | +| **read:follows** | **write:follows** | +| read:lists | write:lists | +| | write:media | +| **read:mutes** | **write:mutes** | +| read:notifications | write:notifications | +| | write:reports | +| read:search | | +| read:statuses | write:statuses | + +| admin:read | admin:write | +| :--- | :--- | +| admin:read:accounts | admin:write:accounts | +| admin:read:reports | admin:write:reports | + diff --git a/content/en/api/parameters.md b/content/en/api/parameters.md deleted file mode 100644 index b1054e92..00000000 --- a/content/en/api/parameters.md +++ /dev/null @@ -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. diff --git a/content/en/api/permissions.md b/content/en/api/permissions.md deleted file mode 100644 index 01770a07..00000000 --- a/content/en/api/permissions.md +++ /dev/null @@ -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. diff --git a/content/en/api/push.md b/content/en/api/push.md deleted file mode 100644 index bc763643..00000000 --- a/content/en/api/push.md +++ /dev/null @@ -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" >}}). diff --git a/content/en/api/rest/accounts.md b/content/en/api/rest/accounts.md deleted file mode 100644 index 9ff50292..00000000 --- a/content/en/api/rest/accounts.md +++ /dev/null @@ -1,203 +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" >}} - -## POST /api/v1/accounts - -Returns [Token]({{< relref "entities.md#token" >}}) - -The method is available to apps with a token obtained via the client credentials grant. It creates a user and account records, as well as an access token for the app that initiated the request. The user is unconfirmed, and an e-mail is sent as usual. - -The method returns the access token, which the app should save for later. The REST API is not available to users with unconfirmed accounts, so the app must be smart to wait for the user to click a link in their e-mail inbox. - -The method is rate-limited by IP to 5 requests per 30 minutes. - -### Resource information - -{{< api_method_info auth="Yes" user="No" scope="write write:accounts" version="2.7.0" >}} - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `username` | User name | Required | -| `email` | E-mail address | Required | -| `password` | Password text | Required | -| `agreement` | Agreement to local rules, terms of use, privacy policy (Bool) | Required | -| `locale` | The language of the e-mail to be sent first | Required | - -The `agreement` parameter must be set to true after presenting the local rules, terms of use, privacy policy for the user and obtaining consent. - -## 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|Added in| -|----|-----------|:------:|:-----:|:------:| -| `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 | | | -| `exclude_reblogs` | Skip statuses that are reblogs of other statuses | Optional | false | 2.7.0 | - -### 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 | diff --git a/content/en/api/rest/apps.md b/content/en/api/rest/apps.md deleted file mode 100644 index d35ea028..00000000 --- a/content/en/api/rest/apps.md +++ /dev/null @@ -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="2.0.0" >}} diff --git a/content/en/api/rest/blocks.md b/content/en/api/rest/blocks.md deleted file mode 100644 index bcc455e7..00000000 --- a/content/en/api/rest/blocks.md +++ /dev/null @@ -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" >}} diff --git a/content/en/api/rest/custom-emojis.md b/content/en/api/rest/custom-emojis.md deleted file mode 100644 index 00d412c1..00000000 --- a/content/en/api/rest/custom-emojis.md +++ /dev/null @@ -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="2.0.0" >}} diff --git a/content/en/api/rest/domain-blocks.md b/content/en/api/rest/domain-blocks.md deleted file mode 100644 index 051dc6f8..00000000 --- a/content/en/api/rest/domain-blocks.md +++ /dev/null @@ -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="1.4.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="1.4.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="1.4.0" >}} - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `domain` | Domain to unblock| Required | diff --git a/content/en/api/rest/endorsements.md b/content/en/api/rest/endorsements.md deleted file mode 100644 index 6f317e0b..00000000 --- a/content/en/api/rest/endorsements.md +++ /dev/null @@ -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="2.5.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="2.5.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="2.5.0" >}} diff --git a/content/en/api/rest/favourites.md b/content/en/api/rest/favourites.md deleted file mode 100644 index fa4e15c2..00000000 --- a/content/en/api/rest/favourites.md +++ /dev/null @@ -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" >}}) diff --git a/content/en/api/rest/filters.md b/content/en/api/rest/filters.md deleted file mode 100644 index 93f53706..00000000 --- a/content/en/api/rest/filters.md +++ /dev/null @@ -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="2.4.3" >}} - -## 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="2.4.3" >}} - -### 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="2.4.3" >}} - -## 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="2.4.3" >}} - -### 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="2.4.3" >}} diff --git a/content/en/api/rest/follow-requests.md b/content/en/api/rest/follow-requests.md deleted file mode 100644 index 161df7d1..00000000 --- a/content/en/api/rest/follow-requests.md +++ /dev/null @@ -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" >}} diff --git a/content/en/api/rest/follow-suggestions.md b/content/en/api/rest/follow-suggestions.md deleted file mode 100644 index 31479526..00000000 --- a/content/en/api/rest/follow-suggestions.md +++ /dev/null @@ -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="2.4.3" >}} - -## DELETE /api/v1/suggestions/:account_id - -Remove account from suggestions. - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="read" version="2.4.3" >}} diff --git a/content/en/api/rest/instances.md b/content/en/api/rest/instances.md deleted file mode 100644 index d8355481..00000000 --- a/content/en/api/rest/instances.md +++ /dev/null @@ -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" >}} diff --git a/content/en/api/rest/lists.md b/content/en/api/rest/lists.md deleted file mode 100644 index a4ffcce3..00000000 --- a/content/en/api/rest/lists.md +++ /dev/null @@ -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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.0" >}} - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `account_ids` | Array of account IDs | Required | diff --git a/content/en/api/rest/media.md b/content/en/api/rest/media.md deleted file mode 100644 index 7c4a3c4e..00000000 --- a/content/en/api/rest/media.md +++ /dev/null @@ -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). diff --git a/content/en/api/rest/mutes.md b/content/en/api/rest/mutes.md deleted file mode 100644 index 375c16af..00000000 --- a/content/en/api/rest/mutes.md +++ /dev/null @@ -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="1.4.2" >}} - -## 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="1.4.2" >}} diff --git a/content/en/api/rest/notifications.md b/content/en/api/rest/notifications.md deleted file mode 100644 index a4c41db9..00000000 --- a/content/en/api/rest/notifications.md +++ /dev/null @@ -1,117 +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 || -| `account_id` | Return only notifications sent from given account | 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/:id/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" >}} - -## 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/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="2.4.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 | -| `data[alerts][poll]` | Boolean of whether you want to receive poll result 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="2.4.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="2.4.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 | -| `data[alerts][poll]` | Boolean of whether you want to receive poll result 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="2.4.0" >}} diff --git a/content/en/api/rest/polls.md b/content/en/api/rest/polls.md deleted file mode 100644 index 060cc363..00000000 --- a/content/en/api/rest/polls.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Polls -menu: - docs: - parent: rest-api - weight: 10 ---- - -## GET /api/v1/polls/:id - -Returns [Poll]({{< relref "entities.md#poll" >}}) - -### Resource information - -{{< api_method_info auth="No" user="No" scope="read read:statuses" version="2.8.0" >}} - -## POST /api/v1/polls/:id/votes - -Vote on a poll. - -Returns [Poll]({{< relref "entities.md#poll" >}}) - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `choices` | Array of choice indices | Required | - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="2.8.0" >}} \ No newline at end of file diff --git a/content/en/api/rest/reports.md b/content/en/api/rest/reports.md deleted file mode 100644 index 5fc209fb..00000000 --- a/content/en/api/rest/reports.md +++ /dev/null @@ -1,24 +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="1.1.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 | -| `forward` | Whether to forward to the remote admin (in case of a remote account) | Optional | diff --git a/content/en/api/rest/scheduled-statuses.md b/content/en/api/rest/scheduled-statuses.md deleted file mode 100644 index 07bcfffa..00000000 --- a/content/en/api/rest/scheduled-statuses.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Scheduled Statuses -menu: - docs: - parent: rest-api - weight: 10 ---- - -## GET /api/v1/scheduled_statuses - -Get scheduled statuses. - -Returns array of [ScheduledStatus]({{< relref "entities.md#scheduledstatus" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="read read:statuses" version="2.7.0" >}} - -## GET /api/v1/scheduled_statuses/:id - -Get scheduled status. - -Returns [ScheduledStatus]({{< relref "entities.md#scheduledstatus" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="read read:statuses" version="2.7.0" >}} - -## PUT /api/v1/scheduled_statuses/:id - -Update Scheduled status. Only `scheduled_at` can be changed. To change the content, delete it and post a new status. - -Returns [ScheduledStatus]({{< relref "entities.md#scheduledstatus" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="2.7.0" >}} - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `scheduled_at` | Timestamp string to schedule posting of status (ISO 8601) | Optional | - -## DELETE /api/v1/scheduled_statuses/:id - -Remove Scheduled status. - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="2.7.0" >}} diff --git a/content/en/api/rest/search.md b/content/en/api/rest/search.md deleted file mode 100644 index 91157f65..00000000 --- a/content/en/api/rest/search.md +++ /dev/null @@ -1,27 +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="2.4.1" >}} - -### Parameters - -|Name|Description|Required|Default| -|----|-----------|:------:|:-----:| -| `q` | The search query | Required || -| `resolve` | Attempt WebFinger look-up | Optional |false| -| `limit` | Maximum number of results | Optional | 40 | -| `offset` | Offset in the search results | Optional | 0 | -| `following` | Only include accounts the user is following | Optional | false | diff --git a/content/en/api/rest/statuses.md b/content/en/api/rest/statuses.md deleted file mode 100644 index d32a8a3b..00000000 --- a/content/en/api/rest/statuses.md +++ /dev/null @@ -1,177 +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" >}}) - -When `scheduled_at` option is present, -Returns [ScheduledStatus]({{< relref "entities.md#scheduledstatus" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="0.0.0" >}} - -### Parameters - -|Name|Description|Required|Added in| -|----|-----------|:------:|:------:| -| `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\* | -| `poll` | Nested parameters to attach a poll to the status | Optional\* |2.8.0| -| `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 | -| `scheduled_at` | Timestamp string to schedule posting of status (ISO 8601) | Optional |2.7.0| -| `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. Polls require a `status` and cannot be combined with `media_ids`. - -Poll parameters: - -|Name|Description|Required| -|----|-----------|:------:| -| `poll[options]` | Array of poll answer strings | Required | -| `poll[expires_in]` | Duration the poll should be open for in seconds | Required | -| `poll[multiple]` | Whether multiple choices should be allowed | Optional | -| `poll[hide_totals]` | Whether to hide totals until the poll ends | Optional | - -### 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 for more on idempotency and idempotency keys. - -### Scheduled status - -Allows users to schedule a toot (with media attachments) to be published at a certain future date. - -The scheduled date must be at least 5 minutes into the future. At most, 300 toots can be scheduled at the same time. Only 50 toots can be scheduled for any given day. - -When `scheduled_at` option is present, instead of creating a status, we only run status validation, and if it passes, we create an entry in scheduled_statuses which encodes the status attributes. Every 5 minutes, a scheduler iterates over the scheduled_statuses table to fetch the ones due in the next 5 minutes, and push them into a more precise Sidekiq queue. In Sidekiq, the individual statuses are created, with media attachments being unassigned from the scheduled status and assigned to the real one. - -This option was added since v2.7.0. - -## 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" >}} - -## 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="1.6.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="1.6.0" >}} diff --git a/content/en/api/rest/timelines.md b/content/en/api/rest/timelines.md deleted file mode 100644 index 54257953..00000000 --- a/content/en/api/rest/timelines.md +++ /dev/null @@ -1,123 +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 | - - -## GET /api/v1/conversations - -Conversations for an account - -Returns array of [Conversation]({{< relref "entities.md#conversation" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="read read:statuses" version="2.6.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="2.1.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 >}} diff --git a/content/en/api/streaming.md b/content/en/api/streaming.md deleted file mode 100644 index ebe2a3a4..00000000 --- a/content/en/api/streaming.md +++ /dev/null @@ -1,82 +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/health - -Returns `OK` when streaming service is fine - -#### 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. diff --git a/content/en/client/authorized.md b/content/en/client/authorized.md new file mode 100644 index 00000000..d815a96c --- /dev/null +++ b/content/en/client/authorized.md @@ -0,0 +1,124 @@ +--- +title: Logging in with an account +description: How to obtain authorization from a user and perform actions on their behalf. +menu: + docs: + weight: 40 + parent: user +--- + +## Scopes explained + +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](../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. + +## **Example authorization code flow** + +This is similar to the authentication flow from before, but this time, we need to obtain authorization from a user as well. + +### Client ID and secret + +First, if you have not already registered a client application, then see [Creating our application](token.md#creating-our-application) on the previous page or go directly to [POST /api/v1/apps](../methods/apps/#create-an-application) for the full documentation of that method. We will need the `client_id` and `client_secret` for our application. + +### Authorize the user + +To authorize a user, request [GET /oauth/authorize](../methods/apps/oauth.md#authorize-a-user) in a browser with the following query parameters: + +```bash +https://mastodon.example/oauth/authorize +?client_id=CLIENT_ID +&scope=read+write+follow+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](../api/oauth-scopes.md) 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 + +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](../methods/apps/oauth.md#obtain-a-token) like before, but pass the authorization code we just obtained: + +```bash +curl -X POST \ + -F 'client_id=your_client_id_here' \ + -F 'client_secret=your_client_secret_here' \ + -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' \ + https://mastodon.example/oauth/token +``` + +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](authorized.md#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](../methods/accounts/#verify-account-credentials): + +```bash +curl \ + -H 'Authorization: Bearer our_access_token_here' \ + 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. + +## Performing actions as the authorized user + +With our OAuth token for the authorized user, we can now perform any action as that user that is within our token's scope. + +### Publish and delete statuses + +* See [POST /api/v1/statuses](../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. + +### Interact with 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](../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. + +### Interact with other users + +* 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. + +### Receive 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. + +### Discovery features + +* 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. + +### Use safety features + +* 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. + +### Manage account info + +* 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. + diff --git a/content/en/client/guidelines.md b/content/en/client/guidelines.md new file mode 100644 index 00000000..e8091d00 --- /dev/null +++ b/content/en/client/guidelines.md @@ -0,0 +1,53 @@ +--- +title: Guidelines and best practices +menu: + docs: + weight: 50 + parent: client +--- + +## 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 + +**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 + +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 + +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](../spec/activitypub.md#html-sanitization) for more details. + +### Mentions, hashtags, and custom emoji + +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](../entities/status.md#rendering-attributes) for more information. + +### Link shortening + +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 + + + example.com/page + + +``` + +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, 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 new file mode 100644 index 00000000..47376746 --- /dev/null +++ b/content/en/client/intro.md @@ -0,0 +1,136 @@ +--- +title: Getting started with the API +description: 'A primer on REST APIs, HTTP requests and responses, and parameters.' +menu: + docs: + weight: 10 + parent: client +--- + +## An introduction to REST + +Mastodon provides access to its data over a REST API. REST stands for REpresentational State Transfer, but for our purposes, just think of it as sending and receiving information about various resources based on the request. The Mastodon REST API uses HTTP for its requests, and JSON for its payloads. + +## Understanding HTTP requests and responses + +REST API endpoints can be called with certain HTTP methods, and more than one method can be used on the same endpoint. The Mastodon API will generally use the following HTTP methods: + +* **GET**: Read or view a resource. +* **POST**: Send information to the server. +* **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`\). + +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. + +## Providing parameters + +HTTP requests can include additional parameters in various different ways, but most notably, the Mastodon API understands query strings, form data, and JSON. + +{{< hint style="info" >}} +Query strings, form data, and JSON submitted via POST body are 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. +{{< /hint >}} + +### 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: + +```bash +curl https://mastodon.example/endpoint?q=test&n=0 +``` + +### Form data + +Instead of mutating the URL with query strings, you can send the data separately. With cURL, this is done by passing it with the `--data` or `-d` flag. Data may be sent together similar to query strings, or it may be sent separately as key-value pairs with multiple data flags. You may also use the `--form` or `-F` flag for key-value pairs, which also allows sending multipart data such as files. For example: + +```bash +# send raw data as query strings +curl -X POST \ + -d 'q=test&n=0' \ + https://mastodon.example/endpoint +# send raw data separately +curl -X POST \ + -d 'q=test' \ + -d 'n=0' \ + https://mastodon.example/endpoint +# explicit form-encoded; allows for multipart data +curl -X POST \ + -F 'q=test' \ + -F 'n=0' \ + -F 'file=@filename.jpg' \ + https://mastodon.example/endpoint +``` + +### JSON + +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 +curl -X POST \ + -H 'Content-Type: application/json' \ + -d '{"parameter": "value"}' \ + https://mastodon.example/endpoint +``` + +## Data types + +### Multiple values \(Array\) + +An array parameter must encoded using bracket notation, e.g. `array[]=foo&array[]=bar` would be translated into the following: + +```ruby +array = [ + 'foo', + 'bar', +] +``` + +As JSON, arrays are formatted like so: + +```javascript +{ + "array": ["foo", "bar"] +} +``` + +### Nested parameters \(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: + +```ruby +source = { + privacy: 'public', + language: 'en', +} +``` + +As JSON, hashes are formatted like so: + +```javascript +{ + "source": { + "privacy": "public", + "language", "en" + } +} +``` + +### True-or-false \(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. When using JSON data, use the literals `true`, `false`, and `null` instead. + +### Files + +File uploads must be encoded using `multipart/form-data`. + +This can be combined with arrays as well. + +## How to use API response data + +The Mastodon REST API will return JSON as the response text. It also returns HTTP headers which may be useful in handling the response, as well as an HTTP status code which should let you know how the server handled the request. The following HTTP status codes may be expected: + +* 200 = OK. The request was handled successfully. +* 4xx = Client error. Your request was not correct. Most commonly, you may see 401 Unauthorized, 404 Not Found, 410 Gone, or 422 Unprocessed. +* 5xx = Server error. Something went wrong while handling the request. Most commonly, you may see 503 Unavailable. + diff --git a/content/en/client/libraries.md b/content/en/client/libraries.md new file mode 100644 index 00000000..410b84ce --- /dev/null +++ b/content/en/client/libraries.md @@ -0,0 +1,104 @@ +--- +title: Libraries and implementations +description: Interface with the Mastodon API in the programming language of your choice. +menu: + docs: + weight: 60 + parent: client +--- + +## 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 + +* [masto.js](https://github.com/neet/masto.js) +* [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) + diff --git a/content/en/client/public.md b/content/en/client/public.md new file mode 100644 index 00000000..a5f1e2f1 --- /dev/null +++ b/content/en/client/public.md @@ -0,0 +1,109 @@ +--- +title: Playing with public data +description: Familiarizing yourself with endpoints and entities. +menu: + docs: + weight: 20 + parent: client +--- + +Now that you know how to construct HTTP requests using cURL or your favorite programming language's HTTP utility or library, it is time to learn about endpoints and responses. + +## Endpoints explained + +All HTTP requests are made against a target URL. When you request data to or from a website, you do so by using a specific URL. Depending on the URL, your request will be interpreted by the HTTP server and the appropriate response will be returned to you. + +Examples will be written using the fictional Mastodon website, mastodon.example, which is hosted at `https://mastodon.example`. The root of this website is `/`, and specific subdirectories and paths are known as endpoints. Mastodon's API endpoints are nested under the `/api` namespace, and most methods currently have their endpoints under `/api/v1`. Requests will be listed by their HTTP method and their endpoint; for example, GET /api/v1/endpoint should be interpreted as a GET request made to that endpoint on your domain, or in other words, `https://mastodon.example/api/v1/endpoint`. + +## Fetching public timelines + +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](../methods/timelines/#public-timeline) like so: + +```bash +curl https://mastodon.example/api/v1/timelines/public +``` + +Wow, that's a lot of text in response! The public timeline returns 20 statuses by default. We can use the `limit` parameter to request less than that. Let's try requesting the same endpoint, but with a limit of 2 this time: + +```bash +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 +[ + { + "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](../methods/timelines/#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\): + +```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: + +```python +import requests +import json + +response = requests.get("https://mastodon.example/api/v1/timelines/tag/cats?limit=2") +statuses = json.dumps(response.text) # this converts the json to a python list of dictionary +assert statuses[0]["visibility"] == "public" # we are reading a public timeline +print(statuses[0]["content"]) # this prints the status text +``` + +{{< hint style="info" >}} +Parsing JSON and using it in your program is outside of the scope of this tutorial, as it will be different depending on your choice of programming language and on the design of your program. Look for other tutorials on how to work with JSON in your programming language of choice. +{{< /hint >}} + +{{< hint style="info" >}} +[MastoVue](https://mastovue.glitch.me) is an example of an application that lets you browse public timelines. +{{< /hint >}} + +## Fetching public accounts and statuses + +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](../methods/accounts/#account) 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](../methods/accounts/#statuses) 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](../methods/statuses/#view-specific-status) to view the Status entity. + * You can also use [GET /api/v1/statuses/:id/reblogged\_by](../methods/statuses/#boosted-by) to view who boosted that status, + * or [GET /api/v1/statuses/:id/favourited\_by](../methods/statuses/#favourited-by) to view who favourited that status. + * Requesting [GET /api/v1/statuses/:id/context](../methods/statuses/#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](../methods/statuses/polls.md#view-a-poll) 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. + +## Fetching public instance data + +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](../methods/instance/#fetch-instance), + * view its peers with [GET /api/v1/instance/peers](../methods/instance/#list-of-connected-domains) or + * its weekly activity with [GET /api/v1/instance/activity](../methods/instance/#weekly-activity), or to + * list all custom emoji available with [GET /api/v1/custom\_emojis](../methods/instance/custom_emojis.md#custom-emoji). +* See [GET /api/v1/directory](../methods/instance/directory.md#view-profile-directory) for a directory of all available profiles. +* See [GET /api/v1/trends](../methods/instance/trends.md#trending-tags) 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. +{{< /hint >}} + diff --git a/content/en/client/token.md b/content/en/client/token.md new file mode 100644 index 00000000..37863382 --- /dev/null +++ b/content/en/client/token.md @@ -0,0 +1,68 @@ +--- +title: Obtaining client app access +description: Getting accustomed to the basics of authentication and authorization. +menu: + docs: + weight: 30 + parent: client +--- + +## Authentication and authorization + +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. + +## **Creating our application** + +The first thing we will need to do is to register an application, in order to be able to generate access tokens later. The application can be created like so: + +```bash +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 'website=https://myapp.example' \ + https://mastodon.example/api/v1/apps +``` + +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](../api/oauth-scopes.md) 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](../methods/apps/#create-an-application) for more details on registering applications. + +## **Example authentication code 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](../methods/apps/oauth.md#obtain-a-token) like so: + +```bash +curl -X POST \ + -F 'client_id=your_client_id_here' \ + -F 'client_secret=your_client_secret_here' \ + -F 'redirect_uri=urn:ietf:wg:oauth:2.0:oob' \ + -F 'grant_type=client_credentials' \ + https://mastodon.example/oauth/token +``` + +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 `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](../methods/apps/#verify-your-app-works): + +```bash +curl \ + -H 'Authorization: Bearer our_access_token_here' \ + 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. + +## What we can do with authentication + +With our authenticated client application, we can view relations of an account with [GET /api/v1/accounts/:id/following](../methods/accounts/#following) and [GET /api/v1/accounts/:id/followers](../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 new file mode 100644 index 00000000..8c3c8c9a --- /dev/null +++ b/content/en/dev/code.md @@ -0,0 +1,60 @@ +--- +title: Code structure +menu: + docs: + weight: 30 + parent: dev +--- + +{{< hint style="danger" >}} +This page is under construction. +{{< /hint >}} + +### Code 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 + +| 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 | + +#### JavaScript + +| Path | Description | +| :--- | :--- | +| `app/javascript/mastodon` | Code for the multi-column React.js application | +| `app/javascript/packs` | Code for non-React.js pages | + +#### CSS and other assets + +| Path | Description | +| :--- | :--- | +| `app/javascript/images` | Images | +| `app/javascript/styles` | Code that turns into CSS via Sass | + +#### Localizations + +| Path | Description | +| :--- | :--- | +| `config/locales` | Server-side localizations in the YML format | +| `app/javascript/mastodon/locales` | Client-side localizations in the JSON format | + +### Localization maintenance + +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 | + diff --git a/content/en/dev/overview.md b/content/en/dev/overview.md new file mode 100644 index 00000000..0c15dc98 --- /dev/null +++ b/content/en/dev/overview.md @@ -0,0 +1,30 @@ +--- +title: Technical overview +menu: + docs: + weight: 10 + 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. + +### Environments + +An “environment” is a set of configuration values intended for a specific use case. Some environments could be: development, in which you intend to change the code; test, in which you intend to run the automated test suite; staging, which is meant to preview the code to end-users; and production, which is intended to face end-users. Mastodon comes with configurations for development, test and production. + +The default value of `RAILS_ENV` is `development`, so you don’t need to set anything extra to run Mastodon in development mode. In fact, all of Mastodon’s configuration has correct defaults for the development environment, so you do not need an `.env` file unless you need to customize something. Here are some of the different behaviours between the development environment and the production environment: + +* Ruby code reloads itself when you change it, which means you don’t need to restart the Rails server process to see changes +* All errors you encounter show stack traces in the browser, rather than being hidden behind a generic error page +* Webpack runs continuously and re-compiles JS and CSS assets when you change any of the front-end files, and the pages automatically reload +* Caching is disabled by default +* An admin account with the e-mail `admin@localhost:3000` and password `mastodonadmin` is created automatically during `db:seed` + +It should be noted that the Docker configuration distributed with Mastodon is optimized for the production environment, and so is an extremely bad fit for development. The Vagrant configuration, on the other hand, is meant specifically for development and not production use. + diff --git a/content/en/dev/routes.md b/content/en/dev/routes.md new file mode 100644 index 00000000..873da148 --- /dev/null +++ b/content/en/dev/routes.md @@ -0,0 +1,209 @@ +--- +title: Routes +description: How HTTP methods map to controllers and actions. +menu: + docs: + weight: 40 + parent: dev +--- + + + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/config/routes.rb" caption="config/routes.rb" >}} + +## Explanation of routes + +Mastodon uses Ruby on Rails, which defines its router configuration at config/routes.rb. You may view the [Ruby on Rails routing guide](https://guides.rubyonrails.org/routing.html) for more detailed information, but this page will explain the basics of how Mastodon handles routing. + +### How routes are constructed + +`namespace` is a prefix for routes mapped to a certain controller directory. `resources` are mapped to controllers within that namespace directory. `scope` passes to the `module`'s controller. For example, consider the following abbreviated code: + +{{< code title="config/routes.rb excerpt" >}} +```ruby +namespace :api do + namespace :v1 do + resources :statuses, only [:create, :show, :destroy] do + scope module: :statuses do + resource :favourite, only: :create + resource :unfavourite, to: 'favourites#destroy' + member do + get :context + end + end + end + end +end +``` +{{< /code >}} + +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. + +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. + +### Available methods + +#### :index + +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. + +#### :create + +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. + +#### :destroy + +Maps to HTTP DELETE. Handled by the \#destroy action in a controller. + +## .well-known + +### /.well-known/host-meta + +Extensible Resource Descriptor \(XRD\). Advertises existence of Webfinger. + +### /.well-known/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 + +Used for discovering ActivityPub actor id. See [Spec compliance > WebFinger]({{< relref "../spec/webfinger.md" >}}) for more information. + +### /.well-known/change-password + +Maps to account settings page. + +### /.well-known/keybase-proof-config + +Used for integration with Keybase, defining which usernames are acceptable and where proofs may be checked. + +{{< hint style="warning" >}} +The sections below this point are under construction. +{{< /hint >}} + +## Public URIs + +* `/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/media` = "media" tab +* `/@username/tagged/:hashtag` = tagged statuses by user +* `/@username/:status_id` = status permalink +* `/@username/:status_id/embed` = embeddable version +* `/interact/:status_id` = remote interaction dialog +* `/explore` = profile directory +* `/explore/:hashtag` = profiles with this hashtag in bio +* `/public` = public timeline preview +* `/about` = landing page +* `/about/more` = extended description +* `/terms` = terms of service + +## API + +* /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\] +* /api/v2 + * [search]({{< relref "../methods/search.md" >}}) \[GET search\#index\] + diff --git a/content/en/dev/setup.md b/content/en/dev/setup.md new file mode 100644 index 00000000..32caf158 --- /dev/null +++ b/content/en/dev/setup.md @@ -0,0 +1,38 @@ +--- +title: Setting up a dev environment +menu: + docs: + weight: 20 + parent: dev +--- + +{{< hint style="danger" >}} +This page is under construction. +{{< /hint >}} + +### Setup + +Run following commands in the project directory `bundle install`, `yarn install`. + +In the development environment, Mastodon will use PostgreSQL as the currently signed-in Linux user using the `ident` method, which usually works out of the box. The one command you need to run is `rails db:setup` which will create the databases `mastodon_development` and `mastodon_test`, load the schema into them, and then create seed data defined in `db/seed.rb` in `mastodon_development`. The only seed data is an admin account with the credentials `admin@localhost:3000` / `mastodonadmin`. + +> Please keep in mind, by default Mastodon will run on port 3000. If you configure a different port for it, the generated admin account will use that number. + +### Running + +There are multiple processes that need to be run for the full set of Mastodon’s functionality, although they can be selectively omitted. To run all of them with just one command, you can install Foreman with `gem install foreman --no-document` and then use: + +```text +foreman start +``` + +In the Mastodon directory. This will start processes defined in `Procfile.dev`, which will give you: A Rails server, a Webpack server, a streaming API server, and Sidekiq. Of course, you can run any of those things stand-alone depending on your needs. + +### Testing + +| Command | Description | +| :--- | :--- | +| `rspec` | Run the Ruby test suite | +| `yarn run test` | Run the JavaScript test suite | +| `rubocop` | Check the Ruby code for conformance with our code style | + diff --git a/content/en/development/activitypub.md b/content/en/development/activitypub.md deleted file mode 100644 index a2c908a0..00000000 --- a/content/en/development/activitypub.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: ActivityPub compliance -description: What objects and properties of the ActivityPub spec Mastodon supports -menu: - docs: - parent: development - weight: 5 ---- - -## APIs - -- Mastodon supports the server-to-server part of the [ActivityPub spec](https://www.w3.org/TR/activitypub/). -- It implements the [HTTP signatures spec](https://tools.ietf.org/html/draft-cavage-http-signatures-10) for authentication of inbox deliveries. -- Mastodon also supports [Linked Data Signatures](https://w3c-dvcg.github.io/ld-signatures/) for forwarded payloads. - -## Restrictions - -- All object IDs must use the `https://` schema. -- Servers must offer a [WebFinger](https://tools.ietf.org/html/rfc7033) endpoint for turning usernames into actors. -- Activities attributed to an actor must have an ID on the same host as the actor. - -## Activities - -|Supported activity|Supported objects| -|------------------|-----------------| -|`Accept`|`Follow`| -|`Add`|`Note`| -|`Announce`|`Object`| -|`Block`|`Object`| -|`Create`|`Note`, `Article`, `Image`, `Video`, `Page`| -|`Delete`|`Object`| -|`Flag`|`Object`| -|`Follow`|`Object`| -|`Like`|`Object`| -|`Move`|`Object`| -|`Reject`|`Follow`| -|`Remove`|`Note`| -|`Undo`|`Accept`, `Announce`, `Block`, `Follow`, `Like`| -|`Update`|`Object`| - -As far as the `Create` activity is concerned, only `Note` is a first-class citizen in Mastodon, because Mastodon is a microblogging engine. For other types of supported objects, Mastodon internally creates a toot representation, for example, an `Article` or `Page` becomes a toot with the `name` and `url` of the original object, as users are expected to navigate to the original URL to read the article with rich text formatting. For `Image` and `Video` objects, the `name` is likewise used to fill the content of the toot, with the original file attached to the toot. - -The `Flag` activity allows reporting content on another server, and its `object` can be either one or more actors, or one or more objects attributed to various actors. The `Add` and `Remove` activities only work with [featured collections](#featured-collection). The `Delete` activity can be used to delete all local data of the sender when the `object` of it is the sender. The `Update` activity can only be used to update the profile of the sender. Likewise, the `Move` activity allows re-assigning followers from the sender (`object`) to another actor (`target`), but only if the other actor references the sender in the `alsoKnownAs` property. - -## Extensions -### Featured collection - -What is known in Mastodon as "pinned toots", or statuses that are always featured at the top of people's profiles, is implemented using an extra property `featured` on the actor object that points to a `Collection` of objects. Example: - -```json -{ - "@context": [ - "https://www.w3.org/ns/activitystreams", - - { - "toot": "http://joinmastodon.org/ns#", - "featured": { - "@id": "toot:featured", - "@type": "@id" - } - } - ], - - "id": "https://example.com/@alice", - "type": "Person", - "featured": "https://example.com/@alice/collections/featured" -} -``` - -### Custom emojis - -Mastodon supports arbitrary emojis, that is, small images uploaded by admins and invokable via shortcodes. For this, an `Emoji` type is used. These emojis are listed in the `tag` property just like `Mention` and `Hashtag` objects, since they are entities that affect how the text is rendered. Example: - -```json -{ - "@context": [ - "https://www.w3.org/ns/activitystreams", - - { - "toot": "http://joinmastodon.org/ns#", - "Emoji": "toot:Emoji" - } - ], - - "id": "https://example.com/@alice/hello-world", - "type": "Note", - "content": "Hello world :Kappa:", - "tag": [ - { - "id": "https://example.com/emoji/123", - "type": "Emoji", - "name": ":Kappa:", - "icon": { - "type": "Image", - "mediaType": "image/png", - "url": "https://example.com/files/kappa.png" - } - } - ] -} -``` - -### Focal points - -Mastodon supports setting a focal point on uploaded images, so that wherever that image is displayed, the focal point stays in view. This is implemented using an extra property `focalPoint` on the `Image` objects. The property is simply an array of two floating points between 0 and 1. Example: - -```json -{ - "@context": [ - "https://www.w3.org/ns/activitystreams", - - { - "toot": "http://joinmastodon.org/ns#", - "focalPoint": { - "@container": "@list", - "@id": "toot:focalPoint" - } - } - ], - - "id": "https://example.com/@alice/hello-world", - "type": "Note", - "content": "A picture attached!", - "attachment": [ - { - "type": "Image", - "mediaType": "image/png", - "url": "https://example.com/files/cats.png", - "focalPoint": [ - 0.55, - 0.43 - ] - } - ] -} -``` \ No newline at end of file diff --git a/content/en/development/overview.md b/content/en/development/overview.md deleted file mode 100644 index ef590d3d..00000000 --- a/content/en/development/overview.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Overview -description: How to setup a development environment for Mastodon -menu: - docs: - parent: development - weight: 1 ---- - -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. - -## Environments - -An "environment" is a set of configuration values intended for a specific use case. Some environments could be: development, in which you intend to change the code; test, in which you intend to run the automated test suite; staging, which is meant to preview the code to end-users; and production, which is intended to face end-users. Mastodon comes with configurations for development, test and production. - -The default value of `RAILS_ENV` is `development`, so you don't need to set anything extra to run Mastodon in development mode. In fact, all of Mastodon's configuration has correct defaults for the development environment, so you do not need an `.env` file unless you need to customize something. Here are some of the different behaviours between the development environment and the production environment: - -- Ruby code reloads itself when you change it, which means you don't need to restart the Rails server process to see changes -- All errors you encounter show stack traces in the browser, rather than being hidden behind a generic error page -- Webpack runs continuously and re-compiles JS and CSS assets when you change any of the front-end files, and the pages automatically reload -- Caching is disabled by default -- An admin account with the e-mail `admin@localhost:3000` and password `mastodonadmin` is created automatically during `db:seed` - -It should be noted that the Docker configuration distributed with Mastodon is optimized for the production environment, and so is an extremely bad fit for development. The Vagrant configuration, on the other hand, is meant specifically for development and not production use. - -## Setup - -Run following commands in the project directory `bundle install`, `yarn install`. - -In the development environment, Mastodon will use PostgreSQL as the currently signed-in Linux user using the `ident` method, which usually works out of the box. The one command you need to run is `rails db:setup` which will create the databases `mastodon_development` and `mastodon_test`, load the schema into them, and then create seed data defined in `db/seed.rb` in `mastodon_development`. The only seed data is an admin account with the credentials `admin@localhost:3000` / `mastodonadmin`. - -> Please keep in mind, by default Mastodon will run on port 3000. If you configure a different port for it, the generated admin account will use that number. - -## Running - -There are multiple processes that need to be run for the full set of Mastodon's functionality, although they can be selectively omitted. To run all of them with just one command, you can install Foreman with `gem install foreman --no-document` and then use: - - foreman start - -In the Mastodon directory. This will start processes defined in `Procfile.dev`, which will give you: A Rails server, a Webpack server, a streaming API server, and Sidekiq. Of course, you can run any of those things stand-alone depending on your needs. - -## Testing - -|Command|Description| -|-------|-----------| -|`rspec`|Run the Ruby test suite| -|`yarn run test`|Run the JavaScript test suite| -|`rubocop`|Check the Ruby code for conformance with our code style| - -## Most notable libraries used - -Knowledge and understanding of these libraries will simplify work with the Mastodon code. - -### Ruby - -- `haml`, a templating language -- `devise`, for authentication -- `doorkeeper`, for acting as an OAuth 2 provider -- `paperclip`, for file uploads and attachments -- `sidekiq`, for background processing - -### JavaScript - -- `immutable`, for immutable data structures -- `react`, for rendering the dynamic web application -- `react-redux`, for managing React state -- `react-router-dom`, for navigation within React -- `react-intl`, for localizations within React - -## Code 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 - -|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| - -### JavaScript - -|Path|Description| -|----|-----------| -|`app/javascript/mastodon`|Code for the multi-column React.js application| -|`app/javascript/packs`|Code for non-React.js pages| - -### CSS and other assets - -|Path|Description| -|----|-----------| -|`app/javascript/images`|Images| -|`app/javascript/styles`|Code that turns into CSS via Sass| - -### Localizations - -|Path|Description| -|----|-----------| -|`config/locales`|Server-side localizations in the YML format| -|`app/javascript/mastodon/locales`|Client-side localizations in the JSON format| - -## Localization maintenance - -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| \ No newline at end of file diff --git a/content/en/entities/account.md b/content/en/entities/account.md new file mode 100644 index 00000000..cb0f46a3 --- /dev/null +++ b/content/en/entities/account.md @@ -0,0 +1,221 @@ +--- +title: Account +description: Represents a user of Mastodon and their associated profile. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "id": "23634", + "username": "noiob", + "acct": "noiob@awoo.space", + "display_name": "ikea shark fan account", + "locked": false, + "bot": false, + "created_at": "2017-02-08T02:00:53.274Z", + "note": "

:ms_rainbow_flag:​ :ms_bisexual_flagweb:​ :ms_nonbinary_flag:​ #awoo.space #admin ~ #bi ~ #nonbinary ~ compsci student ~ likes video #games and weird/ old electronics and will post obsessively about both ~ avatar by @dzuk

", + "url": "https://awoo.space/@noiob", + "avatar": "https://files.mastodon.social/accounts/avatars/000/023/634/original/6ca8804dc46800ad.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/023/634/original/6ca8804dc46800ad.png", + "header": "https://files.mastodon.social/accounts/headers/000/023/634/original/256eb8d7ac40f49a.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/023/634/original/256eb8d7ac40f49a.png", + "followers_count": 547, + "following_count": 404, + "statuses_count": 28468, + "last_status_at": "2019-11-17T00:02:23.693Z", + "emojis": [ + { + "shortcode": "ms_rainbow_flag", + "url": "https://files.mastodon.social/custom_emojis/images/000/028/691/original/6de008d6281f4f59.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/028/691/static/6de008d6281f4f59.png", + "visible_in_picker": true + }, + { + "shortcode": "ms_bisexual_flag", + "url": "https://files.mastodon.social/custom_emojis/images/000/050/744/original/02f94a5fca7eaf78.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/050/744/static/02f94a5fca7eaf78.png", + "visible_in_picker": true + }, + { + "shortcode": "ms_nonbinary_flag", + "url": "https://files.mastodon.social/custom_emojis/images/000/105/099/original/8106088bd4782072.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/105/099/static/8106088bd4782072.png", + "visible_in_picker": true + } + ], + "fields": [ + { + "name": "Pronouns", + "value": "they/them", + "verified_at": null + }, + { + "name": "Alt", + "value": "@noiob", + "verified_at": null + }, + { + "name": "Bots", + "value": "@darksouls, @nierautomata, @fedi, code for @awoobot", + "verified_at": null + }, + { + "name": "Website", + "value": "http://shork.xyz", + "verified_at": "2019-11-10T10:31:10.744+00:00" + } + ] +} +``` + +## Base attributes + +### **`id`** + +**Description:** The account id`header`. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 0.1.0 + +### `username` + +**Description:** The username of the account, not including domain. +**Type:** String +**Version history:** Added in 0.1.0 + +### `acct` + +**Description:** The Webfinger account URI. +Equal to `username` for local users, or `username@domain` for remote users. +**Type:** String +**Version history:** Added in 0.1.0 + +### `url` + +**Description:** The location of the user's profile page. +**Type:** String \(HTTPS URL\) +**Version history:** Added in 0.1.0 + +## Display attributes + +### `display_name` + +**Description:** The profile's display name. +**Type:** String +**Version history:** Added in 0.1.0 + +### `note` + +**Description:** The profile's bio / description. +**Type:** String +**Version history:** Added in 0.1.0 + +### `avatar` + +**Description:** An image icon that is shown next to statuses and in the profile. +**Type:** String \(URL\) +**Version history:** Added in 0.1.0 + +### `avatar_static` + +**Description:** A static version of the avatar. +Equal to `avatar` if its value is a static image; different if `avatar` is an animated GIF. +**Type:** String \(URL\) +**Version history:** Added in 1.1.2 + +### `header` + +**Description:** An image banner that is shown above the profile and in profile cards. +**Type:** String \(URL\) +**Version history:** Added in 0.1.0 + +### `header_static` + +**Description:** A static version of the header. +Equal to `header` if its value is a static image; different if `header` is an animated GIF. +**Type:** String \(URL\) +**Version history:** Added in 1.1.2 + +### `locked` + +**Description:** Whether the account manually approves follow requests. +**Type:** Boolean +**Version history:** Added in 0.1.0 + +### `emojis` + +**Description:** Custom emoji entities to be used when rendering the profile. If none, an empty array will be returned. +**Type:** Array of [Emoji](emoji.md) +**Version history:** Added in 2.4.0 + +### `discoverable` + +**Description:** Whether the account has opted into discovery features such as the profile directory. +**Type:** Boolean +**Version history:** Added in 3.1.0 + +## Statistical attributes + +### `created_at` + +**Description:** When the account was created. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 0.1.0 + +### `statuses_count` + +**Description:** How many statuses are attached to this account. +**Type:** Number +**Version history:** Added in 0.1.0 + +### `followers_count` + +**Description:** The reported followers of this profile. +**Type:** Number +**Version history:** Added in 0.1.0 + +### `following_count` + +**Description:** The reported follows of this profile. +**Type:** Number +**Version history:** Added in 0.1.0 + +## Optional attributes + +### `moved` + +**Description:** Indicates that the profile is currently inactive and that its user has moved to a new account. +**Type:** [Account](account.md) +**Version history:** Added in 2.1.0 + +### `fields` + +**Description:** Additional metadata attached to a profile as name-value pairs. +**Type:** Array of [Field]({{< relref "field.md" >}}) +**Version history:** Added in 2.4.0 + +### `bot` + +**Description:** A presentational flag. Indicates that the account may perform automated actions, may not be monitored, or identifies as a robot. +**Type:** Boolean +**Version history:** Added in 2.4.0 + +### `source` + +**Description:** An extra entity to be used with API methods to [verify credentials](../methods/accounts/#verify-account-credentials) and [update credentials](../methods/accounts/#update-account-credentials). +**Type:** [Source](source.md) +**Version history:** Added in 2.4.0 + +## See also + +{{< page-ref page="methods/accounts.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/account_serializer.rb" caption="app/serializers/rest/account\_serializer.rb" >}} + + + + + diff --git a/content/en/entities/activity.md b/content/en/entities/activity.md new file mode 100644 index 00000000..fd27e281 --- /dev/null +++ b/content/en/entities/activity.md @@ -0,0 +1,55 @@ +--- +title: Activity +description: Represents a weekly bucket of instance activity. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "week": "1574640000", + "statuses": "37125", + "logins": "14239", + "registrations": "542" +} +``` + +## Attributes + +### `week` + +**Description:** Midnight at the first day of the week. +**Type:** String \(UNIX Timestamp\) +**Version history:** Added in 2.1.2 + +### `statuses` + +**Description:** Statuses created since the week began. +**Type:** String \(cast from an integer\) +**Version history:** Added in 2.1.2 + +### `logins` + +**Description:** User logins since the week began. +**Type:** String \(cast from an integer\) +**Version history:** Added in 2.1.2 + +### `registrations` + +**Description:** User registrations since the week began. +**Type:** String \(cast from an integer\) +**Version history:** Added in 2.1.2 + +## See also + +* [GET /api/v1/instance/activity](../methods/instance/#weekly-activity) + +{{< page-ref page="methods/instance.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/controllers/api/v1/instances/activity_controller.rb" caption="app/controllers/api/v1/instances/activity\_controller.rb" >}} + + + diff --git a/content/en/entities/admin-account.md b/content/en/entities/admin-account.md new file mode 100644 index 00000000..18f3e272 --- /dev/null +++ b/content/en/entities/admin-account.md @@ -0,0 +1,130 @@ +--- +title: Admin::Account +description: Admin-level information about a given account. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{} +``` + +## Attributes + +### `id` + +**Description:** The ID of the account in the database. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.9.1 + +### `username` + +**Description:** The username of the account. +**Type:** String +**Version history:** Added in 2.9.1 + +### `domain` + +**Description:** The domain of the account. +**Type:** String +**Version history:** Added in 2.9.1 + +### `created_at` + +**Description:** When the account was first discovered. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 2.9.1 + +### `email` + +**Description:** The email address associated with the account. +**Type:** String +**Version history:** Added in 2.9.1 + +### `ip` + +**Description:** The IP address last used to login to this account. +**Type:** String +**Version history:** Added in 2.9.1 + +### `locale` + +**Description:** The locale of the account. +**Type:** String \(ISO 639 Part 1 two-letter language code\) +**Version history:** Added in 2.9.1 + +### `invite_request` + +**Description:** Invite request text ??? +**Type:** String +**Version history:** Added in 2.9.1 + +## State attributes + +### `role` + +**Description:** The current role of the account. +**Type:** String \(Enumerable oneOf\) +**Version history:** Added in 2.9.1 + +### `confirmed` + +**Description:** Whether the account has confirmed their email address. +**Type:** Boolean +**Version history:** Added in 2.9.1 + +### `approved` + +**Description:** Whether the account is currently approved. +**Type:** Boolean +**Version history:** Added in 2.9.1 + +### `disabled` + +**Description:** Whether the account is currently disabled. +**Type:** Boolean +**Version history:** Added in 2.9.1 + +### `silenced` + +**Description:** Whether the account is currently silenced. +**Type:** Boolean +**Version history:** Added in 2.9.1 + +### `suspended` + +**Description:** Whether the account is currently suspended. +**Type:** Boolean +**Version history:** Added in 2.9.1 + +### `account` + +**Description:** User-level information about the account. +**Type:** Account +**Version history:** Added in 2.9.1 + +## Nullable attributes + +### `created_by_application_id` + +**Description:** The ID of the application that created this account. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.9.1 + +### `invited_by_account_id` + +**Description:** The ID of the account that invited this user +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.9.1 + +## See also + +{{< page-ref page="methods/admin.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/admin/account_serializer.rb" caption="app/serializers/rest/admin/account\_serializer.rb" >}} + + + diff --git a/content/en/entities/admin-report.md b/content/en/entities/admin-report.md new file mode 100644 index 00000000..22ee2fdb --- /dev/null +++ b/content/en/entities/admin-report.md @@ -0,0 +1,84 @@ +--- +title: Admin::Report +description: Admin-level information about a filed report. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{} +``` + +## Attributes + +### `id` + +**Description:** The ID of the report in the database. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.9.1 + +### `action_taken` + +**Description:** The action +**Type:** String \(Enumerable oneOf\) +**Version history:** Added in 2.9.1 + +### `comment` + +**Description:** An optional reason for reporting. +**Type:** String +**Version history:** Added in 2.9.1 + +### `created_at` + +**Description:** The time the report was filed. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 2.9.1 + +### `updated_at` + +**Description:** The time of last action on this report. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 2.9.1 + +### `account` + +**Description:** The account which filed the report. +**Type:** [Account](account.md) +**Version history:** Added in 2.9.1 + +### `target_account` + +**Description:** The account being reported. +**Type:** [Account](account.md) +**Version history:** Added in 2.9.1 + +### `assigned_account` + +**Description:** The account of the moderator assigned to this report. +**Type:** [Account](account.md) +**Version history:** Added in 2.9.1 + +### `action_taken_by_account` + +**Description:** The action taken by the moderator who handled the report. +**Type:** String \(Enumerable oneOf\) +**Version history:** Added in 2.9.1 + +### `statuses` + +**Description:** Statuses attached to the report, for context. +**Type:** Array of [Status](status.md) +**Version history:** Added in 2.9.1 + +## See also + +{{< page-ref page="methods/admin.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/admin/report_serializer.rb" caption="app/serializers/rest/admin/report\_serializer.rb" >}} + + + diff --git a/content/en/entities/application.md b/content/en/entities/application.md new file mode 100644 index 00000000..e303b5a4 --- /dev/null +++ b/content/en/entities/application.md @@ -0,0 +1,69 @@ +--- +title: Application +description: >- + Represents an application that interfaces with the REST API to access accounts + or post statuses. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "name": "test app", + "website": null, + "vapid_key": "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=" +} +``` + +## Required attributes + +### `name` + +**Description:** The name of your application. +**Type:** String +**Version history:** Added in 0.9.9 + +## Optional attributes + +### `website` + +**Description:** The website associated with your application. +**Type:** String \(URL\) +**Version history:** Added in 0.9.9 + +### `vapid_key` + +**Description:** Used for Push Streaming API. Returned with [POST /api/v1/apps](../methods/apps/#create-an-application). Equivalent to [PushSubscription\#server\_key](push-subscription.md#server_key) +**Type:** String +**Version history:** Added in 2.8.0 + +## Client attributes + +### client\_id + +**Description:** Client ID key, to be used for obtaining OAuth tokens +**Type:** String +**Version history:** Added in 0.9.9 + +### client\_secret + +**Description:** Client secret key, to be used for obtaining OAuth tokens +**Type:** String +**Version history:** Added in 0.9.9 + +## See also + +* [Status\#application](status.md#application) +* [Create an application \(POST /api/v1/apps\)](../methods/apps/#create-an-application) + +{{< page-ref page="status.md" >}} + +{{< page-ref page="methods/apps.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/application_serializer.rb" caption="app/serializers/rest/application\_serializer.rb" >}} + + + diff --git a/content/en/entities/attachment.md b/content/en/entities/attachment.md new file mode 100644 index 00000000..24237f5c --- /dev/null +++ b/content/en/entities/attachment.md @@ -0,0 +1,230 @@ +--- +title: Attachment +description: Represents a file or media attachment that can be added to a status. +menu: + docs: + parent: entities +--- + +## Example + +{{< tabs >}} +{{< tab title="Image" >}} +```javascript +{ + "id": "22345792", + "type": "image", + "url": "https://files.mastodon.social/media_attachments/files/022/345/792/original/57859aede991da25.jpeg", + "preview_url": "https://files.mastodon.social/media_attachments/files/022/345/792/small/57859aede991da25.jpeg", + "remote_url": null, + "text_url": "https://mastodon.social/media/2N4uvkuUtPVrkZGysms", + "meta": { + "original": { + "width": 640, + "height": 480, + "size": "640x480", + "aspect": 1.3333333333333333 + }, + "small": { + "width": 461, + "height": 346, + "size": "461x346", + "aspect": 1.3323699421965318 + }, + "focus": { + "x": -0.27, + "y": 0.51 + } + }, + "description": "test media description", + "blurhash": "UFBWY:8_0Jxv4mx]t8t64.%M-:IUWGWAt6M}" +} +``` +{{< endtab >}} + +{{< tab title="Video" >}} +```javascript +{ + "id": "22546306", + "type": "video", + "url": "https://files.mastodon.social/media_attachments/files/022/546/306/original/dab9a597f68b9745.mp4", + "preview_url": "https://files.mastodon.social/media_attachments/files/022/546/306/small/dab9a597f68b9745.png", + "remote_url": null, + "text_url": "https://mastodon.social/media/wWd1HJIBmH1MZGDfg50", + "meta": { + "length": "0:01:28.65", + "duration": 88.65, + "fps": 24, + "size": "1280x720", + "width": 1280, + "height": 720, + "aspect": 1.7777777777777777, + "audio_encode": "aac (LC) (mp4a / 0x6134706D)", + "audio_bitrate": "44100 Hz", + "audio_channels": "stereo", + "original": { + "width": 1280, + "height": 720, + "frame_rate": "6159375/249269", + "duration": 88.654, + "bitrate": 862056 + }, + "small": { + "width": 400, + "height": 225, + "size": "400x225", + "aspect": 1.7777777777777777 + } + }, + "description": null, + "blurhash": "U58E0g8_0M.94T?bIr00?bD%NGoM?bD%oLt7" +} +``` +{{< endtab >}} + +{{< tab title="GIFV" >}} +```javascript +{ + "id": "21130559", + "type": "gifv", + "url": "https://files.mastodon.social/media_attachments/files/021/130/559/original/bc84838f77991326.mp4", + "preview_url": "https://files.mastodon.social/media_attachments/files/021/130/559/small/bc84838f77991326.png", + "remote_url": null, + "text_url": "https://mastodon.social/media/2ICiasGyjezmi7cQYM8", + "meta": { + "length": "0:00:01.11", + "duration": 1.11, + "fps": 33, + "size": "600x332", + "width": 600, + "height": 332, + "aspect": 1.8072289156626506, + "original": { + "width": 600, + "height": 332, + "frame_rate": "100/3", + "duration": 1.11, + "bitrate": 1627639 + }, + "small": { + "width": 400, + "height": 221, + "size": "400x221", + "aspect": 1.8099547511312217 + } + }, + "description": null, + "blurhash": "URHT%Jm,2a1d%MRO%LozkrNH$*n*oMn$Rjt7" +} +``` +{{< endtab >}} + +{{< tab title="Audio" >}} +```javascript +{ + "id": "21165404", + "type": "audio", + "url": "https://files.mastodon.social/media_attachments/files/021/165/404/original/a31a4a46cd713cd2.mp3", + "preview_url": "https://files.mastodon.social/media_attachments/files/021/165/404/small/a31a4a46cd713cd2.mp3", + "remote_url": null, + "text_url": "https://mastodon.social/media/5O4uILClVqBWx0NNgvo", + "meta": { + "length": "0:06:42.86", + "duration": 402.86, + "audio_encode": "mp3", + "audio_bitrate": "44100 Hz", + "audio_channels": "stereo", + "original": { + "duration": 402.860408, + "bitrate": 166290 + } + }, + "description": null, + "blurhash": null +} +``` +{{< endtab >}} +{{< endtabs >}} + +## Required attributes + +### `id` + +**Description:** The ID of the attachment in the database. +**Type:** String \(cast from an integer but not guaranteed to be a number\) +**Version history:** Added in 0.6.0. + +### `type` + +**Description:** The type of the attachment. +**Type:** String \(Enumerable, oneOf\) +- `unknown` = unsupported or unrecognized file type +- `image` = Static image +- `gifv` = Looping, soundless animation +- `video` = Video clip +- `audio` = Audio track +**Version history:** Added in 0.6.0. Audio added in 2.9.1. + +### `url` + +**Description:** The location of the original full-size attachment. +**Type:** String \(URL\) +**Version history:** Added in 0.6.0. + +### `preview_url` + +**Description:** The location of a scaled-down preview of the attachment. +**Type:** String \(URL\) +**Version history:** Added in 0.6.0. + +## Optional attributes + +### `remote_url` + +**Description:** The location of the full-size original attachment on the remote website. +**Type:** String \(URL\), or null if the attachment is local +**Version history:** Added in 0.6.0. + +### `text_url` + +**Description:** A shorter URL for the attachment. +**Type:** String \(URL\) +**Version history:** Added in 0.6.0. + +### `meta` + +**Description:** Metadata returned by Paperclip. +**Type:** Hash +**Version history:** Added in 1.5.0. meta\[focus\] added in 2.3.0. + +May contain subtrees `small` and `original`, as well as various other top-level properties. + +More importantly, there may be another top-level `focus` Hash object as of 2.3.0, with coordinates can be used for smart thumbnail cropping -- see [Focal points](../methods/statuses/media.md#focal-points) for more. + +### `description` + +**Description:** Alternate text that describes what is in the media attachment, to be used for the visually impaired or when media attachments do not load. +**Type:** String +**Version history:** Added in 2.0.0 + +### `blurhash` + +**Description:** A hash computed by [the BlurHash algorithm](https://github.com/woltapp/blurhash), for generating colorful preview thumbnails when media has not been downloaded yet. +**Type:** String +**Version history:** Added in 2.8.1 + +## See also + +* Status\#media\_attachments +* /api/v1/media + +{{< page-ref page="status.md" >}} + +{{< page-ref page="methods/statuses/media.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/media_attachment_serializer.rb" caption="app/serializers/rest/media\_attachment\_serializer.rb" >}} + + + + + diff --git a/content/en/entities/card.md b/content/en/entities/card.md new file mode 100644 index 00000000..5d26cb31 --- /dev/null +++ b/content/en/entities/card.md @@ -0,0 +1,168 @@ +--- +title: Card +description: >- + Represents a rich preview card that is generated using OpenGraph tags from a + URL. +menu: + docs: + parent: entities +--- + +{{< tabs >}} +{{< tab title="video" >}} +```javascript +{ + "url": "https://www.youtube.com/watch?v=OMv_EPMED8Y", + "title": "♪ Brand New Friend (Christmas Song!)", + "description": "", + "type": "video", + "author_name": "YOGSCAST Lewis & Simon", + "author_url": "https://www.youtube.com/user/BlueXephos", + "provider_name": "YouTube", + "provider_url": "https://www.youtube.com/", + "html": "", + "width": 480, + "height": 270, + "image": "https://files.mastodon.social/preview_cards/images/014/179/145/original/9cf4b7cf5567b569.jpeg", + "embed_url": "" +} +``` +{{< endtab >}} + +{{< tab title="photo" >}} +```javascript +{ + "url": "https://www.flickr.com/photos/tomfenskephotography/49088768431/", + "title": "Oregon", + "description": "", + "type": "photo", + "author_name": "Tom Fenske Photography", + "author_url": "https://www.flickr.com/photos/tomfenskephotography/", + "provider_name": "Flickr", + "provider_url": "https://www.flickr.com/", + "html": "", + "width": 1024, + "height": 427, + "image": "https://files.mastodon.social/preview_cards/images/014/287/139/original/651b1c6976817824.jpeg", + "embed_url": "https://live.staticflickr.com/65535/49088768431_6a4322b3bb_b.jpg" +} +``` +{{< endtab >}} + +{{< tab title="link" >}} +```javascript +{ + "url": "https://www.theguardian.com/money/2019/dec/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code", + "title": "‘I lost my £193,000 inheritance – with one wrong digit on my sort code’", + "description": "When Peter Teich’s money went to another Barclays customer, the bank offered £25 as a token gesture", + "type": "link", + "author_name": "", + "author_url": "", + "provider_name": "", + "provider_url": "", + "html": "", + "width": 0, + "height": 0, + "image": null, + "embed_url": "" +} +``` +{{< endtab >}} +{{< endtabs >}} + +## Required attributes + +### `url` + +**Description:** Location of linked resource. +**Type:** String \(URL\) +**Version history:** Added in 1.0.0 + +### `title` + +**Description:** Title of linked resource. +**Type:** String +**Version history:** Added in 1.0.0 + +### `description` + +**Description:** Description of preview. +**Type:** String +**Version history:** Added in 1.0.0 + +### `type` + +**Description:** The type of the preview card. +**Type:** String \(Enumerable, oneOf\) +- `link` = Link OEmbed +- `photo` = Photo OEmbed +- `video` = Video OEmbed +- `rich` = iframe OEmbed. Not currently accepted, so won't show up in practice. +**Version history:** Added in 1.3.0 + +## Optional attributes + +### `author_name` + +**Description:** The author of the original resource. +**Type:** String +**Version history:** Added in 1.3.0 + +### `author_url` + +**Description:** A link to the author of the original resource. +**Type:** String \(URL\) +**Version history:** Added in 1.3.0 + +### `provider_name` + +**Description:** The provider of the original resource. +**Type:** String +**Version history:** Added in 1.3.0 + +### `provider_url` + +**Description:** A link to the provider of the original resource. +**Type:** String \(URL\) +**Version history:** Added in 1.3.0 + +### `html` + +**Description:** HTML to be used for generating the preview card. +**Type:** String \(HTML\) +**Version history:** Added in 1.3.0 + +### `width` + +**Description:** Width of preview, in pixels. +**Type:** Number +**Version history:** Added in 1.3.0 + +### `height` + +**Description:** Height of preview, in pixels. +**Type:** Number +**Version history:** Added in 1.3.0 + +### `image` + +**Description:** Preview thumbnail. +**Type:** String \(URL\) +**Version history:** Added in 1.0.0 + +### `embed_url` + +**Description:** Used for photo embeds, instead of custom `html`. +**Type:** String \(URL\) +**Version history:** Added in 2.1.0 + +## See also + +{{< page-ref page="status.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/preview_card_serializer.rb" caption="app/serializers/rest/preview\_card\_serializer.rb" >}} + + + +### + diff --git a/content/en/entities/context.md b/content/en/entities/context.md new file mode 100644 index 00000000..17e0a2ce --- /dev/null +++ b/content/en/entities/context.md @@ -0,0 +1,70 @@ +--- +title: Context +description: >- + Represents the tree around a given status. Used for reconstructing threads of + statuses. +menu: + docs: + parent: entities +--- + +## Example + +{{< code title="Truncated response from GET statuses/:id/context" >}} +```javascript +{ + "ancestors": [ + { + "id": "103188938570975982", + "created_at": "2019-11-23T19:44:00.124Z", + "in_reply_to_id": null, + ... + }, + { + "id": "103188971072973252", + "created_at": "2019-11-23T19:52:23.398Z", + "in_reply_to_id": "103188938570975982", + ... + }, + { + "id": "103188982235527758", + "created_at": "2019-11-23T19:55:08.208Z", + "in_reply_to_id": "103188971072973252", + ... + ], + "descendants": [ + { + "id": "103189026958574542", + "created_at": "2019-11-23T20:06:36.011Z", + "in_reply_to_id": "103189005915505698", + ... + } + ] +} +``` +{{< /code >}} + +## Required attributes + +### `ancestors` + +**Description:** Parents in the thread. +**Type:** Array of [Status](status.md) +**Version history:** Added in 0.6.0 + +### `descendants` + +**Description:** Children in the thread. +**Type:** Array of [Status](status.md) +**Version history:** Added in 0.6.0 + +## See also + +* [GET /api/v1/statuses/:id/context](../methods/statuses/#parent-and-child-statuses) + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/context_serializer.rb" caption="app/serializers/rest/context\_serializer.rb" >}} + + + + + diff --git a/content/en/entities/conversation.md b/content/en/entities/conversation.md new file mode 100644 index 00000000..af44a519 --- /dev/null +++ b/content/en/entities/conversation.md @@ -0,0 +1,70 @@ +--- +title: Conversation +description: Represents a conversation with "direct message" visibility. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "id": "418450", + "unread": true, + "accounts": [ + { + "id": "482403", + "username": "amic", + "acct": "amic@nulled.red", + ... + } + ], + "last_status": { + "id": "103196583826321184", + "created_at": "2019-11-25T04:08:24.000Z", + "in_reply_to_id": "103196540587943467", + "in_reply_to_account_id": "14715", + ... + } +} +``` + +## Required attributes + +### `id` + +**Description:** Local database ID of the conversation. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.6.0 + +### `accounts` + +**Description:** Participants in the conversation. +**Type:** Array of [Account](account.md) +**Version history:** Added in 2.6.0 + +### `unread` + +**Description:** Is the conversation currently marked as unread? +**Type:** Boolean +**Version history:** Added in 2.6.0 + +## Optional attributes + +### `last_status` + +**Description:** The last status in the conversation, to be used for optional display. +**Type:** [Status](status.md) +**Version history:** Added in 2.6.0 + +## See also + +{{< page-ref page="methods/timelines/conversations.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/conversation_serializer.rb" caption="app/serializers/rest/conversation\_serializer.rb" >}} + + + + + diff --git a/content/en/entities/emoji.md b/content/en/entities/emoji.md new file mode 100644 index 00000000..bf98eab9 --- /dev/null +++ b/content/en/entities/emoji.md @@ -0,0 +1,68 @@ +--- +title: Emoji +description: Represents a custom emoji. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "shortcode": "blobaww", + "url": "https://files.mastodon.social/custom_emojis/images/000/011/739/original/blobaww.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/011/739/static/blobaww.png", + "visible_in_picker": true, + "category": "Blobs" +} +``` + +## Required attributes + +### `shortcode` + +**Description:** The name of the custom emoji. +**Type:** String +**Version history:** Added in 2.0.0 + +### `url` + +**Description:** A link to the custom emoji. +**Type:** String \(URL\) +**Version history:** Added in 2.0.0 + +### `static_url` + +**Description:** A link to a static copy of the custom emoji. +**Type:** String \(URL\) +**Version history:** Added in 2.0.0 + +### `visible_in_picker` + +**Description:** Whether this Emoji should be visible in the picker or unlisted. +**Type:** Boolean +**Version history:** Added in 2.0.0 + +## Optional attributes + +### `category` + +**Description:** Used for sorting custom emoji in the picker. +**Type:** String +**Version history:** Added in 3.0.0 + +## See also + +* [Status\#emojis](status.md#emojis) + +{{< page-ref page="status.md" >}} + +{{< page-ref page="methods/instance/custom_emojis.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/custom_emoji_serializer.rb" caption="app/serializers/rest/custom\_emoji\_serializer.rb" >}} + + + + + diff --git a/content/en/entities/error.md b/content/en/entities/error.md new file mode 100644 index 00000000..8e45a723 --- /dev/null +++ b/content/en/entities/error.md @@ -0,0 +1,87 @@ +--- +title: Error +description: Represents an error message. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "error": "invalid_grant", + "error_description": "The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client." +} +``` + +{{< hint style="info" >}} +**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 containing more information, if available. +{{< /hint >}} + +## Required attributes + +### `error` + +**Description:** The error message. +**Type:** String +**Version history:** Added in 0.6.0 + +## Optional attributes + +### `error_description` + +**Description:** A longer description of the error, mainly provided with the OAuth API. +**Type:** String +**Version history:** Added in 0.6.0 + +## Possible reasons + +### 401 - Unauthorized + +#### require\_authenticated\_user! + +Error: This API requires an authenticated user. Appears when the instance is in secure mode, which disables all public use of API methods. + +### 403 - Forbidden + +#### current\_user.disabled? + +Error: Your login is currently disabled. Appears when the OAuth token's authorized user has had their account disabled by a moderator. + +#### !current\_user.confirmed? + +Error: Your login is missing a confirmed e-mail address. Appears when the email address associated with the OAuth token's authorized user's account has not yet been confirmed. + +#### !current\_user.approved? + +Error: Your login is currently pending approval. Appears when the OAuth token's authorized user has signed up on an instance with approval-required registrations, and the user has not yet had their account approved by a moderator. + +### 404 - Not Found + +#### RecordNotFound + +Error: Record not found. Appears when an entity record does not exist, or the authorized user is not within the audience of a private entity.operates on a user. + +### 422 - Unprocessable Entity + +#### RecordInvalid + +Error: {string}. May appear when entity creation failed. + +#### RecordNotUnique + +Error: Duplicate record. Appears when you are trying to pin an account or status that is already pinned. + +#### !current\_user + +Error: This method requires an authenticated user. Appears when using an OAuth token without an authorized user \(or no token at all\), while trying to call an API method that requires a user to be processed. + +## See also + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/controllers/api/base_controller.rb" caption="app/controllers/api/base\_controller.rb" >}} + + + + + diff --git a/content/en/entities/featuredtag.md b/content/en/entities/featuredtag.md new file mode 100644 index 00000000..919bf2c3 --- /dev/null +++ b/content/en/entities/featuredtag.md @@ -0,0 +1,54 @@ +--- +title: FeaturedTag +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "id": "627", + "name": "nowplaying", + "statuses_count": 36, + "last_status_at": "2019-11-15T07:14:43.524Z" +} +``` + +## Attributes + +### `id` + +**Description:** The internal ID of the featured tag in the database. +**Type:** String \(cast from integer but not guaranteed to be a number\) +**Version history:** Added in 3.0.0 + +### `name` + +**Description:** The name of the hashtag being featured. +**Type:** String +**Version history:** Added in 3.0.0 + +### `statuses_count` + +**Description:** The number of authored statuses containing this hashtag. +**Type:** Number +**Version history:** Added in 3.0.0 + +### `last_status_at` + +**Description:** The timestamp of the last authored status containing this hashtag. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 3.0.0 + +## See also + +{{< page-ref page="methods/accounts/featured_tags.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/featured_tag_serializer.rb" caption="app/serializers/rest/featured\_tag\_serializer.rb" >}} + + + + + diff --git a/content/en/entities/field.md b/content/en/entities/field.md new file mode 100644 index 00000000..2aff410d --- /dev/null +++ b/content/en/entities/field.md @@ -0,0 +1,70 @@ +--- +title: Field +description: Represents a profile field as a name-value pair with optional verification. +menu: + docs: + parent: entities +--- + +## Example + +{{< code title="Excerpt from Account\[source\]" >}} +```javascript + "fields": [ + { + "name": "Website", + "value": "https://trwnh.com", + "verified_at": "2019-08-29T04:14:55.571+00:00" + }, + { + "name": "Sponsor", + "value": "https://liberapay.com/at", + "verified_at": "2019-11-15T10:06:15.557+00:00" + }, + { + "name": "Fan of:", + "value": "Punk-rock and post-hardcore (Circa Survive, letlive., La Dispute, THE FEVER 333)Manga (Yu-Gi-Oh!, One Piece, JoJo's Bizarre Adventure, Death Note, Shaman King)Platformers and RPGs (Banjo-Kazooie, Boktai, Final Fantasy Crystal Chronicles)", + "verified_at": null + }, + { + "name": "Main topics:", + "value": "systemic analysis, design patterns, anticapitalism, info/tech freedom, theory and philosophy, and otherwise being a genuine and decent wholesome poster. i'm just here to hang out and talk to cool people!", + "verified_at": null + } + ], +``` +{{< /code >}} + +## Required attributes + +### `name` + +**Description:** The key of a given field's key-value pair. +**Type:** String +**Version history:** Added in 2.4.0 + +### `value` + +**Description:** The value associated with the `name` key. +**Type:** String \(HTML\) +**Version history:** Added in 2.4.0 + +## Optional attributes + +### `verified_at` + +**Description:** Timestamp of when the server verified a URL value for a rel="me" link. +**Type:** String \(ISO 8601 Datetime\) if `value` is a verified URL. Otherwise, null +**Version history:** Added in 2.6.0 + +## See also + +* [Account\#fields](account.md#fields) +* [Source\#fields](source.md#fields) + +{{< page-ref page="account.md" >}} + +{{< page-ref page="source.md" >}} + + + diff --git a/content/en/entities/filter.md b/content/en/entities/filter.md new file mode 100644 index 00000000..a5323466 --- /dev/null +++ b/content/en/entities/filter.md @@ -0,0 +1,92 @@ +--- +title: Filter +description: >- + Represents a user-defined filter for determining which statuses should not be + shown to the user. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "id": "8449", + "phrase": "test", + "context": [ + "home", + "notifications", + "public", + "thread" + ], + "whole_word": false, + "expires_at": "2019-11-26T09:08:06.254Z", + "irreversible": true +} +``` + +## Attributes + +### `id` + +**Description:** The ID of the filter in the database. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.4.3 + +### `phrase` + +**Description:** The text to be filtered. +**Type:** String +**Version history:** Added in 2.4.3 + +### `context` + +**Description:** The contexts in which the filter should be applied. +**Type:** Array of String \(Enumerable anyOf\) +- `home` = home timeline +- `notifications` = notifications timeline +- `public` = public timelines +- `thread` = expanded thread of a detailed status +**Version history:** Added in 2.4.3 + +### `expires_at` + +**Description:** When the filter should no longer be applied +**Type:** String \(ISO 8601 Datetime\), or null if the filter does not expire +**Version history:** Added in 2.4.3 + +### `irreversible` + +**Description:** Should matching entities in home and notifications be dropped by the server? +**Type:** Boolean +**Version history:** Added in 2.4.3 + +### `whole_word` + +**Description:** Should the filter consider word boundaries? +**Type:** Boolean +**Version history:** Added in 2.4.3 + +## 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. 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. + +## See also + +{{< page-ref page="methods/accounts/filters.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/lib/feed_manager.rb" caption="app/lib/feed\_manager.rb" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/javascript/mastodon/selectors/index.js" caption="app/javascript/mastodon/selectors/index.js" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/filter_serializer.rb" caption="app/serializers/rest/filter\_serializer.rb" >}} + + + diff --git a/content/en/entities/history.md b/content/en/entities/history.md new file mode 100644 index 00000000..22cbe474 --- /dev/null +++ b/content/en/entities/history.md @@ -0,0 +1,48 @@ +--- +title: History +description: Represents daily usage history of a hashtag. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "day": "1574553600", + "uses": "200", + "accounts": "31" +} +``` + +## Required attributes + +### `day` + +**Description:** UNIX timestamp on midnight of the given day. +**Type:** String \(UNIX timestamp\) +**Version history:** Added in 2.4.1 + +### `uses` + +**Description:** the counted usage of the tag within that day. +**Type:** String \(cast from an integer\) +**Version history:** Added in 2.4.1 + +### `accounts` + +**Description:** the total of accounts using the tag within that day. +**Type:** String \(cast from an integer\) +**Version history:** Added in 2.4.1 + +## See also + +* [Tag\#history](tag.md#history) + +{{< page-ref page="tag.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/17159625b3e2c6d94509c0c2879ca80efbac6846/app/models/tag.rb\#L101-L115" caption="app/models/tag.rb L101-115 -- history days\[\]" >}} + + + diff --git a/content/en/entities/identityproof.md b/content/en/entities/identityproof.md new file mode 100644 index 00000000..ff694797 --- /dev/null +++ b/content/en/entities/identityproof.md @@ -0,0 +1,61 @@ +--- +title: IdentityProof +menu: + docs: + parent: entities +--- + +```javascript +{ + "provider": "Keybase", + "provider_username": "gargron", + "updated_at": "2019-07-21T20:14:39.596Z", + "proof_url": "https://keybase.io/gargron/sigchain#5cfc20c7018f2beefb42a68836da59a792e55daa4d118498c9b1898de7e845690f", + "profile_url": "https://keybase.io/gargron" +} +``` + +## Attributes + +### `provider` + +**Description:** The name of the identity provider. +**Type:** String +**Version history:** Added in 2.8.0 + +### `provider_username` + +**Description:** The account owner's username on the identity provider's service. +**Type:** String +**Version history:** Added in 2.8.0 + +### `profile_url` + +**Description:** The account owner's profile URL on the identity provider. +**Type:** String \(URL\) +**Version history:** Added in 2.8.0 + +### `proof_url` + +**Description:** A link to a statement of identity proof, hosted by the identity provider. +**Type:** String \(URL\) +**Version history:** Added in 2.8.0 + +### `updated_at` + +**Description:** The name of the identity provider. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 2.8.0 + +## See also + +* [GET /api/v1/accounts/:id/identity\_proofs](../methods/accounts/#identity-proofs) +* /api/proofs +* [About identity proofs](../user/contacts.md#identity-proofs) + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/identity_proof_serializer.rb" caption="app/serializers/rest/identity\_proof\_serializer.rb" >}} + + + + + diff --git a/content/en/entities/instance.md b/content/en/entities/instance.md new file mode 100644 index 00000000..18a68a82 --- /dev/null +++ b/content/en/entities/instance.md @@ -0,0 +1,173 @@ +--- +title: Instance +description: Represents the software instance of Mastodon running on this domain. +menu: + docs: + parent: entities +--- + +## Example + +```javascript + + "uri": "mastodon.social", + "title": "Mastodon", + "short_description": "Server run by the main developers of the project \"🐘\" It is not focused on any particular niche interest - everyone is welcome as long as you follow our code of conduct!", + "description": "Server run by the main developers of the project \"🐘\" It is not focused on any particular niche interest - everyone is welcome as long as you follow our code of conduct!", + "email": "staff@mastodon.social", + "version": "3.0.1", + "urls": { + "streaming_api": "wss://mastodon.social" + }, + "stats": { + "user_count": 415526, + "status_count": 17085754, + "domain_count": 11834 + }, + "thumbnail": "https://files.mastodon.social/site_uploads/files/000/000/001/original/vlcsnap-2018-08-27-16h43m11s127.png", + "languages": [ + "en" + ], + "registrations": true, + "approval_required": false, + "contact_account": { + "id": "1", + "username": "Gargron", + "acct": "Gargron", + "display_name": "Eugen", + "locked": false, + "bot": false, + "created_at": "2016-03-16T14:34:26.392Z", + "note": "

Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.

", + "url": "https://mastodon.social/@Gargron", + "avatar": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "header": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "followers_count": 317112, + "following_count": 453, + "statuses_count": 60903, + "last_status_at": "2019-11-26T21:14:44.522Z", + "emojis": [], + "fields": [ + { + "name": "Patreon", + "value": "https://www.patreon.com/mastodon", + "verified_at": null + }, + { + "name": "Homepage", + "value": "https://zeonfederated.com", + "verified_at": "2019-07-15T18:29:57.191+00:00" + } + ] + } +} +``` + +## Required attributes + +### `uri` + +**Description:** The domain name of the instance. +**Type:** String +**Version history:** Added in 1.1.0 + +### `title` + +**Description:** The title of the website. +**Type:** String +**Version history:** Added in 1.1.0 + +### `description` + +**Description:** Admin-defined description of the Mastodon site. +**Type:** String +**Version history:** Added in 1.1.0 + +### `short_description` + +**Description:** A shorter description defined by the admin. +**Type:** String +**Version history:** Added in 2.9.2 + +### `email` + +**Description:** An email that may be contacted for any inquiries. +**Type:** String +**Version history:** Added in 1.1.0 + +### `version` + +**Description:** The version of Mastodon installed on the instance. +**Type:** String +**Version history:** Added in 1.3.0 + +### `languages` + +**Description:** Primary langauges of the website and its staff. +**Type:** Array of String \(ISO 639 Part 1-5 language codes\) +**Version history:** Added in 2.3.0 + +### `registrations` + +**Description:** Whether registrations are enabled. +**Type:** Boolean +**Version history:** Added in 2.7.2 + +### `approval_required` + +**Description:** Whether registrations require moderator approval. +**Type:** Boolean +**Version history:** Added in 2.9.2 + +### `urls` + +**Description:** URLs of interest for clients apps. +**Type:** Hash \(`streaming_api`\) +**Version history:** Added in 1.4.2 + +#### `urls[streaming_api]` + +Websockets address for push streaming. String \(URL\). + +### `stats` + +**Description:** Statistics about how much information the instance contains. +**Type:** Hash \(`user_count`, `status_count`, `domain_count`\) +**Version history:** Added in 1.6.0 + +#### `user_count` + +Users registered on this instance. Number. + +#### `status_count` + +Statuses authored by users on instance. Number. + +#### `domain_count` + +Domains federated with this instance. Number. + +## Optional attributes + +### `thumbnail` + +**Description:** Banner image for the website. +**Type:** String \(URL\) or null +**Version history:** Added in 1.6.1 + +### `contact_account` + +**Description:** A user that can be contacted, as an alternative to `email`. +**Type:** [Account](account.md) or null +**Version history:** Added in 2.3.0 + +## See also + +{{< page-ref page="methods/instance.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/instance_serializer.rb" caption="app/serializers/rest/instance\_serializer.rb" >}} + + + diff --git a/content/en/entities/list.md b/content/en/entities/list.md new file mode 100644 index 00000000..589d9bfb --- /dev/null +++ b/content/en/entities/list.md @@ -0,0 +1,39 @@ +--- +title: List +description: Represents a list of some users that the authenticated user follows. +menu: + docs: + parent: entities +--- + +## Example + +```javascript + { + "id": "12249", + "title": "Friends" + } +``` + +## Required attributes + +### `id` + +**Description:** The internal database ID of the list. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.1.0 + +### `title` + +**Description:** The user-defined title of the list. +**Type:** String +**Version history:** Added in 2.1.0 + +## See also + +{{< page-ref page="methods/timelines/lists.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/list_serializer.rb" caption="app/serializers/rest/list\_serializer.rb" >}} + + + diff --git a/content/en/entities/marker.md b/content/en/entities/marker.md new file mode 100644 index 00000000..3e884936 --- /dev/null +++ b/content/en/entities/marker.md @@ -0,0 +1,66 @@ +--- +title: Marker +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "home": { + "last_read_id": "103194548672408537", + "version": 462, + "updated_at": "2019-11-24T19:39:39.337Z" + }, + "notifications": { + "last_read_id": "35050107", + "version": 356, + "updated_at": "2019-11-25T13:47:31.333Z" + } +} +``` + +## Base attributes + +### `home` + +**Description:** Information about the user's position in the home timeline. +**Type:** Hash +**Version history:** Added in 3.0.0 + +### `notifications` + +**Description:** Information about the user's position in their notifications. +**Type:** Hash +**Version history:** Added in 3.0.0 + +## Nested attributes + +### `last_read_id` + +**Description:** The ID of the most recently viewed entity. +**Type:** String \(cast from integer but not guaranteed to be a number\) +**Version history:** Added in 3.0.0 + +### `updated_at` + +**Description:** The timestamp of when the marker was set. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 3.0.0 + +### `version` + +**Description:** Used for locking to prevent write conflicts. +**Type:** Number +**Version history:** Added in 3.0.0 + +## See also + +{{< page-ref page="methods/timelines/markers.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/marker_serializer.rb" caption="app/serializers/rest/marker\_serializer.rb" >}} + + + diff --git a/content/en/entities/mention.md b/content/en/entities/mention.md new file mode 100644 index 00000000..ffff6e48 --- /dev/null +++ b/content/en/entities/mention.md @@ -0,0 +1,66 @@ +--- +title: Mention +description: Represents a mention of a user within the content of a status. +menu: + docs: + parent: entities +--- + +## Example + +{{< code title="excerpt from GET status:" >}} +```javascript +{ + "mentions": [ + { + "id": "952529", + "username": "alayna", + "url": "https://desvox.es/users/alayna", + "acct": "alayna@desvox.es" + }, + { + "id": "14715", + "username": "trwnh", + "url": "https://mastodon.social/@trwnh", + "acct": "trwnh" + } + ] +} +``` +{{< /code >}} + +## Required attributes + +### `id` + +**Description:** The account id of the mentioned user. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 0.6.0 + +### `username` + +**Description:** The username of the mentioned user. +**Type:** String +**Version history:** Added in 0.6.0 + +### `acct` + +**Description:** The webfinger acct: URI of the mentioned user. Equivalent to `username` for local users, or `username@domain` for remote users. +**Type:** String +**Version history:** Added in 0.6.0 + +### `url` + +**Description:** The location of the mentioned user's profile. +**Type:** String \(URL\) +**Version history:** Added in 0.6.0 + +## See also + +* [GET /api/v1/statuses/:id](../methods/statuses/#view-specific-status) +* [Status\#mentions](status.md#mentions) + +{{< page-ref page="status.md" >}} + + + diff --git a/content/en/entities/notification.md b/content/en/entities/notification.md new file mode 100644 index 00000000..37847e11 --- /dev/null +++ b/content/en/entities/notification.md @@ -0,0 +1,111 @@ +--- +title: Notification +description: Represents a notification of an event relevant to the user. +menu: + docs: + parent: entities +--- + +## Example + +{{< code title="excerpt from GET notifications" >}} +```javascript +[ + { + "id": "34975861", + "type": "mention", + "created_at": "2019-11-23T07:49:02.064Z", + "account": { + "id": "971724", + "username": "zsc", + "acct": "zsc", + ... + }, + "status": { + "id": "103186126728896492", + "created_at": "2019-11-23T07:49:01.940Z", + "in_reply_to_id": "103186038209478945", + "in_reply_to_account_id": "14715", + ... + } + }, + { + "id": "34975535", + "type": "favourite", + "created_at": "2019-11-23T07:29:18.903Z", + "account": { + "id": "297420", + "username": "haskal", + "acct": "haskal@cybre.space", + ... + }, + "status": { + "id": "103186046267791694", + "created_at": "2019-11-23T07:28:34.210Z", + ... + }, + "account": { + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + ... + }, + ... + } + }, + ... +] +``` +{{< /code >}} + +## Required attributes + +### `id` + +**Description:** The id of the notification in the database. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 0.9.9 + +### `type` + +**Description:** The type of event that resulted in the notification. +**Type:** String \(Enumerable oneOf\) +- `follow` = Someone followed you +- `mention` = Someone mentioned you in their status +- `reblog` = Someone boosted one of your statuses +- `favourite` = Someone favourited one of your statuses +- `poll` = A poll you have voted in or created has ended +**Version history:** Added in 0.9.9. `poll` added in 2.8.0. + +### `created_at` + +**Description:** The timestamp of the notification. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 0.9.9 + +### `account` + +**Description:** The account that performed the action that generated the notification. +**Type:** [Account](account.md) +**Version history:** Added in 0.9.9 + +## Optional attributes + +### `status` + +**Description:** Status that was the object of the notification, e.g. in mentions, reblogs, favourites, or polls. +**Type:** [Status](status.md) +**Version history:** Added in 0.9.9 + +## See also + +{{< page-ref page="account.md" >}} + +{{< page-ref page="status.md" >}} + +{{< page-ref page="methods/notifications.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/notification_serializer.rb" caption="app/serializers/rest/notification\_serializer.rb" >}} + + + diff --git a/content/en/entities/poll.md b/content/en/entities/poll.md new file mode 100644 index 00000000..484632eb --- /dev/null +++ b/content/en/entities/poll.md @@ -0,0 +1,119 @@ +--- +title: Poll +description: Represents a poll attached to a status. +menu: + docs: + parent: entities +--- + +```javascript +{ + "id": "34830", + "expires_at": "2019-12-05T04:05:08.302Z", + "expired": true, + "multiple": false, + "votes_count": 10, + "voters_count": null, + "voted": true, + "own_votes": [ + 1 + ], + "options": [ + { + "title": "accept", + "votes_count": 6 + }, + { + "title": "deny", + "votes_count": 4 + } + ], + "emojis": [] +} +``` + +## Poll attributes + +### `id` + +**Description:** The ID of the poll in the database. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.8.0 + +### `expires_at` + +**Description:** When the poll ends. +**Type:** String \(ISO 8601 Datetime\), or null if the poll does not end +**Version history:** Added in 2.8.0 + +### `expired` + +**Description:** Is the poll currently expired? +**Type:** Boolean +**Version history:** Added in 2.8.0 + +### `multiple` + +**Description:** Does the poll allow multiple-choice answers? +**Type:** Boolean +**Version history:** Added in 2.8.0 + +### `votes_count` + +**Description:** How many votes have been received. +**Type:** Number +**Version history:** Added in 2.8.0 + +### `voters_count` + +**Description:** How many unique accounts have voted on a multiple-choice poll. +**Type:** Number, or null if `multiple` is false. +**Version history:** Added in 2.8.0 + +### `voted` + +**Description:** When called with a user token, has the authorized user voted? +**Type:** Boolean, or null if no current user +**Version history:** Added in 2.8.0 + +### `own_votes` + +**Description:** When called with a user token, which options has the authorized user chosen? Contains an array of index values for `options`. +**Type:** Array of Number, or null if no current user +**Version history:** Added in 2.8.0 + +### `options[]` + +**Description:** Possible answers for the poll. +**Type:** Array of Hash +**Version history:** Added in 2.8.0 + +#### `options[][title]` + +The text value of the poll option. String. + +#### `options[][votes_count]` + +The number of received votes for this option. Number, or null if results are not published yet. + +### `emojis` + +**Description:** Custom emoji to be used for rendering poll options. +**Type:** Array of Emoji +**Version history:** Added in 2.8.0 + +## See also + +* [Status\#poll](status.md#poll) +* [/api/v1/polls]({{< relref "../methods/statuses/polls.md" >}}) + +{{< page-ref page="status.md" >}} + +{{< page-ref page="methods/statuses/polls.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/poll_serializer.rb" caption="app/serializers/rest/poll\_serializer.rb" >}} + + + + + diff --git a/content/en/entities/preferences.md b/content/en/entities/preferences.md new file mode 100644 index 00000000..86f9b8c8 --- /dev/null +++ b/content/en/entities/preferences.md @@ -0,0 +1,71 @@ +--- +title: Preferences +description: Represents a user's preferences. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "posting:default:visibility": "public", + "posting:default:sensitive": false, + "posting:default:language": null, + "reading:expand:media": "default", + "reading:expand:spoilers": false +} +``` + +## Attributes + +### `posting:default:visibility` + +**Description:** Default visibility for new posts. Equivalent to [Source\#privacy](source.md#privacy). +**Type:** String \(Enumerable, oneOf\) +- `public` = Public post +- `unlisted` = Unlisted post +- `private` = Followers-only post +- `direct` = Direct post +**Version history:** Added in 2.8.0 + +### `posting:default:sensitive` + +**Description:** Default sensitivity flag for new posts. Equivalent to [Source\#sensitive](source.md#sensitive). +**Type:** Boolean +**Version history:** Added in 2.8.0 + +### `posting:default:language` + +**Description:** Default language for new posts. Equivalent to [Source\#language](source.md#language) +**Type:** String \(ISO 639-1 language two-letter code\), or null +**Version history:** Added in 2.8.0 + +### `reading:expand:media` + +**Description:** Whether media attachments should be automatically displayed or blurred/hidden. +**Type:** String \(Enumerable, oneOf\) +- `default` = Hide media marked as sensitive +- `show_all` = Always show all media by default, regardless of sensitivity +- `hide_all` = Always hide all media by default, regardless of sensitivity +**Version history:** Added in 2.8.0 + +### `reading:expand:spoilers` + +**Description:** Whether CWs should be expanded by default. +**Type:** Boolean +**Version history:** Added in 2.8.0 + +## See also + +* [GET /api/v1/accounts/verify\_credentials](../methods/accounts/#verify-account-credentials) +* [PATCH /api/v1/accounts/update\_credentials](../methods/accounts/#update-account-credentials) +* [GET /api/v1/preferences](../methods/accounts/preferences.md#view-user-preferences) + +{{< page-ref page="methods/accounts/preferences.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/preferences_serializer.rb" caption="app/serializers/rest/preferences\_serializer.rb" >}} + + + diff --git a/content/en/entities/push-subscription.md b/content/en/entities/push-subscription.md new file mode 100644 index 00000000..76ac3236 --- /dev/null +++ b/content/en/entities/push-subscription.md @@ -0,0 +1,79 @@ +--- +title: PushSubscription +description: Represents a subscription to the push streaming server. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "id": 328183, + "endpoint": "https://yourdomain.example/listener", + "alerts": { + "follow": false, + "favourite": false, + "reblog": false, + "mention": true, + "poll": false + }, + "server_key": "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=" +} +``` + +## Required attributes + +### `id` + +**Description:** The id of the push subscription in the database. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 2.4.0 + +### `endpoint` + +**Description:** Where push alerts will be sent to. +**Type:** String \(URL\) +**Version history:** Added in 2.4.0 + +### `server_key` + +**Description:** The streaming server's VAPID key. +**Type:** String +**Version history:** Added in 2.4.0 + +### `alerts` + +**Description:** Which alerts should be delivered to the `endpoint`. +**Type:** Hash +**Version history:** Added in 2.4.0. `alerts[poll]` added in 2.8.0. + +#### `alerts[follow]` + +Receive a push notification when someone has followed you? Boolean. + +#### `alerts[favourite]` + +Receive a push notification when a status you created has been favourited by someone else? Boolean. + +#### `alerts[mention]` + +Receive a push notification when someone else has mentioned you in a status? Boolean. + +#### `alerts[reblog]` + +Receive a push notification when a status you created has been boosted by someone else? Boolean. + +#### `alerts[poll]` + +Receive a push notification when a poll you voted in or created has ended? Boolean. Added in 2.8.0 + +## See also + +{{< page-ref page="methods/notifications/push.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/web_push_subscription_serializer.rb" caption="app/serializers/rest/web\_push\_subscription\_serializer.rb" >}} + + + diff --git a/content/en/entities/relationship.md b/content/en/entities/relationship.md new file mode 100644 index 00000000..af72aa8f --- /dev/null +++ b/content/en/entities/relationship.md @@ -0,0 +1,104 @@ +--- +title: Relationship +description: >- + Represents the relationship between accounts, such as following / blocking / + muting / etc. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "id": "1", + "following": true, + "showing_reblogs": true, + "followed_by": true, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` + +## Required attributes + +### `id` + +**Description:** The account id. +**Type:** String \(cast from an integer, but not guaranteed to be a number\) +**Version history:** Added in 0.6.0 + +### `following` + +**Description:** Are you following this user? +**Type:** Boolean +**Version history:** Added in 0.6.0 + +### `requested` + +**Description:** Do you have a pending follow request for this user? +**Type:** Boolean +**Version history:** Added in 0.9.9 + +### `endorsed` + +**Description:** Are you featuring this user on your profile? +**Type:** Boolean +**Version history:** Added in 2.5.0 + +### `followed_by` + +**Description:** Are you followed by this user? +**Type:** Boolean +**Version history:** Added in 0.6.0 + +### `muting` + +**Description:** Are you muting this user? +**Type:** Boolean +**Version history:** Added in 1.1.0 + +### `muting_notifications` + +**Description:** Are you muting notifications from this user? +**Type:** Boolean +**Version history:** Added in 2.1.0 + +### `showing_reblogs` + +**Description:** Are you receiving this user's boosts in your home timeline? +**Type:** Boolean +**Version history:** Added in 2.1.0 + +### `blocking` + +**Description:** Are you blocking this user? +**Type:** Boolean +**Version history:** Added in 0.6.0 + +### `domain_blocking` + +**Description:** Are you blocking this user's domain? +**Type:** Boolean +**Version history:** Added in 1.4.0 + +### `blocked_by` + +**Description:** Is this user blocking you? +**Type:** Boolean +**Version history:** Added in 2.8.0 + +## See also + +* [GET /api/v1/accounts/relationships](../methods/accounts/#check-relationships-to-other-accounts) + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/relationship_serializer.rb" caption="app/serializers/rest/relationship\_serializer.rb" >}} + + + diff --git a/content/en/entities/report.md b/content/en/entities/report.md new file mode 100644 index 00000000..6703f9eb --- /dev/null +++ b/content/en/entities/report.md @@ -0,0 +1,30 @@ +--- +title: Report +description: >- + Reports filed against users and/or statuses, to be taken action on by + moderators. +menu: + docs: + parent: entities +--- + +{{< hint style="danger" >}} +This page is currently under construction. +{{< /hint >}} + +## Example + +```text + +``` + +## Attributes + +## See also + +{{< page-ref page="methods/accounts/reports.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/report_serializer.rb" caption="app/serializers/rest/report\_serializer.rb" >}} + + + diff --git a/content/en/entities/results.md b/content/en/entities/results.md new file mode 100644 index 00000000..ee727eca --- /dev/null +++ b/content/en/entities/results.md @@ -0,0 +1,113 @@ +--- +title: Results +description: Represents the results of a search. +menu: + docs: + parent: entities +--- + +## Example + +{{< code title="Truncated sample search for q=cats limit=2" >}} +```javascript +{ + "accounts": [ + { + "id": "180744", + "username": "catstar", + "acct": "catstar@catgram.jp", + "display_name": "catstar", + ... + + }, + { + "id": "214293", + "username": "catsareweird", + "acct": "catsareweird", + "display_name": "Cats Are Weird", + ... + + } + ], + "statuses": [ + { + "id": "103085519055545958", + "created_at": "2019-11-05T13:23:09.000Z", + ... + + "content": "

cats
cats never change

", + ... + + }, + { + "id": "101068121469614510", + "created_at": "2018-11-14T06:31:48.000Z", + ... + + "spoiler_text": "Cats", + ... + + "content": "

Cats are inherently good at self-care.

#cats

", + ... + + ], + "hashtags": [ + { + "name": "cats", + "url": "https://mastodon.social/tags/cats", + "history": [ + { + "day": "1574553600", + "uses": "10", + "accounts": "9" + }, + ... + + ] + }, + { + "name": "catsofmastodon", + "url": "https://mastodon.social/tags/catsofmastodon", + "history": [ + { + "day": "1574553600", + "uses": "6", + "accounts": "5" + }, + ... + + ] + } + ] +} +``` +{{< /code >}} + +## Required attributes + +### `accounts` + +**Description:** Accounts which match the given query +**Type:** Array of [Account](account.md) +**Version history:** Added in x.x.x + +### `statuses` + +**Description:** Statuses which match the given query +**Type:** Array of [Status](status.md) +**Version history:** Added in x.x.x + +### `hashtags` + +**Description:** Hashtags which match the given query +**Type:** Array of [Tag](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. + +## See also + +{{< page-ref page="methods/search.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/search_serializer.rb" caption="app/serializers/rest/search\_serializer.rb" >}} + + + diff --git a/content/en/entities/scheduledstatus.md b/content/en/entities/scheduledstatus.md new file mode 100644 index 00000000..5e3588d6 --- /dev/null +++ b/content/en/entities/scheduledstatus.md @@ -0,0 +1,98 @@ +--- +title: ScheduledStatus +description: Represents a status that will be published at a future scheduled date. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "id": "3221", + "scheduled_at": "2019-12-05T12:33:01.000Z", + "params": { + "text": "test content", + "media_ids": null, + "sensitive": null, + "spoiler_text": null, + "visibility": null, + "scheduled_at": null, + "poll": null, + "idempotency": null, + "in_reply_to_id": null, + "application_id": 596551 + }, + "media_attachments": [] +} +``` + +## Required attributes + +### id + +**Description:** ID of the scheduled status in the database. +**Type:** String \(cast from an integer but not guaranteed to be a number\) +**Version history:** Added in 2.7.0 + +### scheduled\_at + +**Description:** ID of the status in the database. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 2.7.0 + +### params + +#### params\[text\] + +#### params\[visibility\] + +#### params\[application\_id\] + +### media\_attachments + +## Optional attributes + +### params + +#### in\_reply\_to\_id + +#### media\_ids + +#### sensitive + +#### spoiler\_text + +#### scheduled\_at + +## ScheduledStatus + +| Attribute | Type | Nullable | Added in | +| :--- | :--- | :--- | :--- | +| `id` | String | No | 2.7.0 | +| `scheduled_at` | String \(Datetime\) | No | 2.7.0 | +| `params` | [StatusParams]() | No | 2.7.0 | +| `media_attachments` | Array of [Attachment]() | No | 2.7.0 | + +### StatusParams + +| Attribute | Type | Nullable | Added in | +| :--- | :--- | :--- | :--- | +| `text` | String | No | 2.7.0 | +| `in_reply_to_id` | String | | 2.7.0 | +| `media_ids` | Array of String | | 2.7.0 | +| `sensitive` | Boolean | | 2.7.0 | +| `spoiler_text` | String | | 2.7.0 | +| `visibility` | [String \(Enum\)]() | No | 2.7.0 | +| `scheduled_at` | String \(Datetime\) | | 2.7.0 | +| `application_id` | String | No | 2.7.0 | + +## See also + +{{< page-ref page="methods/statuses/scheduled_statuses.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/scheduled_status_serializer.rb" caption="app/serializers/rest/scheduled\_status\_serializer.rb" >}} + + + diff --git a/content/en/entities/source.md b/content/en/entities/source.md new file mode 100644 index 00000000..ae639a45 --- /dev/null +++ b/content/en/entities/source.md @@ -0,0 +1,101 @@ +--- +title: Source +description: >- + Represents display or publishing preferences of user's own account. Returned + as an additional entity when verifying and updated credentials, as an + attribute of Account. +menu: + docs: + parent: entities +--- + +## Example + +{{< code title="Excerpt from GET accounts/verify\_credentials" >}} +```javascript + "source": { + "privacy": "public", + "sensitive": false, + "language": "", + "note": "i have approximate knowledge of many things. perpetual student. (nb/ace/they)\r\n\r\nxmpp/email: a@trwnh.com\r\nhttps://trwnh.com\r\nhelp me live: https://liberapay.com/at or https://paypal.me/trwnh\r\n\r\n- my triggers are moths and glitter\r\n- i have all notifs except mentions turned off, so please interact if you wanna be friends! i literally will not notice otherwise\r\n- dm me if i did something wrong, so i can improve\r\n- purest person on fedi, do not lewd in my presence\r\n- #1 ami cole fan account\r\n\r\n:fatyoshi:", + "fields": [ + { + "name": "Website", + "value": "https://trwnh.com", + "verified_at": "2019-08-29T04:14:55.571+00:00" + }, + { + "name": "Sponsor", + "value": "https://liberapay.com/at", + "verified_at": "2019-11-15T10:06:15.557+00:00" + }, + { + "name": "Fan of:", + "value": "Punk-rock and post-hardcore (Circa Survive, letlive., La Dispute, THE FEVER 333)Manga (Yu-Gi-Oh!, One Piece, JoJo's Bizarre Adventure, Death Note, Shaman King)Platformers and RPGs (Banjo-Kazooie, Boktai, Final Fantasy Crystal Chronicles)", + "verified_at": null + }, + { + "name": "Main topics:", + "value": "systemic analysis, design patterns, anticapitalism, info/tech freedom, theory and philosophy, and otherwise being a genuine and decent wholesome poster. i'm just here to hang out and talk to cool people!", + "verified_at": null + } + ], + "follow_requests_count": 0 + } +``` +{{< /code >}} + +## Base attributes + +### `note` + +**Description:** Profile bio. +**Type:** String +**Version history:** Added in 1.5.0 + +### `fields` + +**Description:** Metadata about the account. +**Type:** Array of [Field]({{< relref "field.md" >}}) +**Version history:** Added in 2.4.0 + +## Nullable attributes + +### `privacy` + +**Description:** The default post privacy to be used for new statuses. +**Type:** String \(Enumerable, oneOf\) +- `public` = Public post +- `unlisted` = Unlisted post +- `private` = Followers-only post +- `direct` = Direct post +**Version history:** Added in 1.5.0 + +### `sensitive` + +**Description:** Whether new statuses should be marked sensitive by default. +**Type:** Boolean +**Version history:** Added in 1.5.0 + +### `language` + +**Description:** The default posting language for new statuses. +**Type:** String \(ISO 639-1 language two-letter code\) +**Version history:** Added in 2.4.2 + +### `follow_requests_count` + +**Description:** The number of pending follow requests. +**Type:** Number +**Version history:** Added in 3.0.0 + +## See also + +* [Account\#source](account.md#source) +* [POST /api/v1/accounts/verify\_credentials](../methods/accounts/#verify-account-credentials) +* [PATCH /api/v1/accounts/update\_credentials](../methods/accounts/#update-account-credentials) + +{{< page-ref page="account.md" >}} + + + diff --git a/content/en/entities/status.md b/content/en/entities/status.md new file mode 100644 index 00000000..3c87930f --- /dev/null +++ b/content/en/entities/status.md @@ -0,0 +1,291 @@ +--- +title: Status +description: Represents a status posted by an account. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "id": "103270115826048975", + "created_at": "2019-12-08T03:48:33.901Z", + "in_reply_to_id": null, + "in_reply_to_account_id": null, + "sensitive": false, + "spoiler_text": "", + "visibility": "public", + "language": "en", + "uri": "https://mastodon.social/users/Gargron/statuses/103270115826048975", + "url": "https://mastodon.social/@Gargron/103270115826048975", + "replies_count": 5, + "reblogs_count": 6, + "favourites_count": 11, + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "content": "

"I lost my inheritance with one wrong digit on my sort code"

https://www.theguardian.com/money/2019/dec/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code

", + "reblog": null, + "application": { + "name": "Web", + "website": null + }, + "account": { + "id": "1", + "username": "Gargron", + "acct": "Gargron", + "display_name": "Eugen", + "locked": false, + "bot": false, + "discoverable": true, + "group": false, + "created_at": "2016-03-16T14:34:26.392Z", + "note": "

Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.

", + "url": "https://mastodon.social/@Gargron", + "avatar": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "header": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "followers_count": 322930, + "following_count": 459, + "statuses_count": 61323, + "last_status_at": "2019-12-10T08:14:44.811Z", + "emojis": [], + "fields": [ + { + "name": "Patreon", + "value": "https://www.patreon.com/mastodon", + "verified_at": null + }, + { + "name": "Homepage", + "value": "https://zeonfederated.com", + "verified_at": "2019-07-15T18:29:57.191+00:00" + } + ] + }, + "media_attachments": [], + "mentions": [], + "tags": [], + "emojis": [], + "card": { + "url": "https://www.theguardian.com/money/2019/dec/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code", + "title": "‘I lost my £193,000 inheritance – with one wrong digit on my sort code’", + "description": "When Peter Teich’s money went to another Barclays customer, the bank offered £25 as a token gesture", + "type": "link", + "author_name": "", + "author_url": "", + "provider_name": "", + "provider_url": "", + "html": "", + "width": 0, + "height": 0, + "image": null, + "embed_url": "" + }, + "poll": null +} +``` + +## Base attributes + +### `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 + +### `uri` + +**Description:** URI of the status used for federation. +**Type:** String +**Version history:** Added in 0.1.0 + +### `created_at` + +**Description:** HTML-encoded status content. +**Type:** String \(ISO 8601 Datetime\) +**Version history:** Added in 0.1.0 + +### `account` + +**Description:** The account that authored this status. +**Type:** [Account](account.md) +**Version history:** Added in 0.1.0 + +### `content` + +**Description:** HTML-encoded status content. +**Type:** String \(HTML\) +**Version history:** Added in 0.1.0 + +### `text` + +**Description:** Plain-text source of a status. Returned instead of `content` when status is deleted, so the user may redraft from the source text without the client having to reverse-engineer the original text from the HTML content. +**Type:** String +**Version history:** Added in 2.9.0 + +### `visibility` + +**Description:** HTML-encoded status content. +**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 + +### `sensitive` + +**Description:** Is this status marked as sensitive content? +**Type:** Boolean +**Version history:** Added in 0.9.9 + +### `spoiler_text` + +**Description:** Subject or summary line, below which status content is collapsed until expanded. +**Type:** String +**Version history:** Added in 1.0.0 + +### `media_attachments` + +**Description:** Media that is attached to this status. +**Type:** Array of [Attachment](attachment.md) +**Version history:** Added in 0.6.0 + +### `application` + +**Description:** The application used to post this status. +**Type:** [Application](application.md) +**Version history:** Added in 0.9.9 + +## Rendering attributes + +### `mentions` + +**Description:** Mentions of users within the status content. +**Type:** Array of [Mention]({{< relref "mention.md" >}}) +**Version history:** Added in 0.6.0 + +### `tags` + +**Description:** Hashtags used within the status content. +**Type:** Array of [Tag](tag.md) +**Version history:** Added in 0.9.0 + +### `emojis` + +**Description:** Custom emoji to be used when rendering status content. +**Type:** Array of [Emoji](emoji.md) +**Version history:** Added in 2.0.0 + +## Informational attributes + +### `reblogs_count` + +**Description:** How many boosts this status has received. +**Type:** Number +**Version history:** Added in 0.1.0 + +### `favourites_count` + +**Description:** How many favourites this status has received. +**Type:** Number +**Version history:** Added in 0.1.0 + +### `replies_count` + +**Description:** How many replies this status has received. +**Type:** Number +**Version history:** Added in 2.5.0 + +## Nullable attributes + +### `url` + +**Description:** A link to the status's HTML representation. +**Type:** String \(URL\) +**Version history:** Added in 0.1.0 + +### `in_reply_to_id` + +**Description:** ID of the status being replied. +**Type:** String \(cast from an integer but not guaranteed to be a number\) +**Version history:** Added in 0.1.0 + +### `in_reply_to_account_id` + +**Description:** ID of the account being replied to. +**Type:** String \(cast from an integer but not guaranteed to be a number\) +**Version history:** Added in 1.0.0 + +### `reblog` + +**Description:** ID of the status in the database. +**Type:** [Status](status.md) +**Version history:** Added in 0.1.0 + +### `poll` + +**Description:** The poll attached to the status. +**Type:** [Poll]({{< relref "poll.md" >}}) +**Version history:** Added in 2.8.0 + +### `card` + +**Description:** Preview card for links included within status content. +**Type:** [Card]({{< relref "card.md" >}}) +**Version history:** Added in 2.6.0 + +### `language` + +**Description:** A link to the status's HTML representation. +**Type:** String \(ISO 639 Part 1 two-letter language code\) +**Version history:** Added in 1.4.0 + +## Authorized user attributes + +### `favourited` + +**Description:** Have you favourited this status? +**Type:** Boolean +**Version history:** Added in 0.1.0 + +### `reblogged` + +**Description:** Have you boosted this status? +**Type:** Boolean +**Version history:** Added in 0.1.0 + +### `muted` + +**Description:** Have you muted notifications for this status's conversation? +**Type:** Boolean +**Version history:** Added in 1.4.0 + +### `bookmarked` + +**Description:** Have you bookmarked this status? +**Type:** Boolean +**Version history:** Added in 3.1.0 + +### `pinned` + +**Description:** Have you pinned this status? Only appears if the status is pinnable. +**Type:** Boolean +**Version history:** Added in 1.6.0 + +## See also + +* GET accounts/:id/statuses +* GET /api/v2/search + +{{< page-ref page="methods/statuses.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/status_serializer.rb" caption="app/serializers/rest/status\_serializer.rb" >}} + + + diff --git a/content/en/entities/tag.md b/content/en/entities/tag.md new file mode 100644 index 00000000..7455b044 --- /dev/null +++ b/content/en/entities/tag.md @@ -0,0 +1,89 @@ +--- +title: Tag +description: Represents a hashtag used within the content of a status. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "name": "nowplaying", + "url": "https://mastodon.social/tags/nowplaying", + "history": [ + { + "day": "1574553600", + "uses": "200", + "accounts": "31" + }, + { + "day": "1574467200", + "uses": "272", + "accounts": "39" + }, + { + "day": "1574380800", + "uses": "345", + "accounts": "40" + }, + { + "day": "1574294400", + "uses": "366", + "accounts": "46" + }, + { + "day": "1574208000", + "uses": "226", + "accounts": "32" + }, + { + "day": "1574121600", + "uses": "217", + "accounts": "42" + }, + { + "day": "1574035200", + "uses": "214", + "accounts": "34" + } + ] +} +``` + +## Base attributes + +### `name` + +**Description:** The value of the hashtag after the \# sign. +**Type:** String +**Version history:** Added in 0.9.0 + +### `url` + +**Description:** A link to the hashtag on the instance. +**Type:** String \(URL\) +**Version history:** Added in 0.9.0 + +## Optional attributes + +### `history` + +**Description:** Usage statistics for given days. +**Type:** Array of [History]({{< relref "history.md" >}}) +**Version history:** Added in 2.4.1 + +## See also + +* [Status\#tags](status.md#tags) +* [GET /api/v1/featured\_tags/suggestions](../methods/accounts/featured_tags.md#suggested-tags-to-feature) + +{{< page-ref page="status.md" >}} + +{{< page-ref page="methods/search.md" >}} + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/serializers/rest/tag_serializer.rb" caption="app/serializers/rest/tag\_serializer.rb" >}} + + + diff --git a/content/en/entities/token.md b/content/en/entities/token.md new file mode 100644 index 00000000..de1354ee --- /dev/null +++ b/content/en/entities/token.md @@ -0,0 +1,57 @@ +--- +title: Token +description: >- + Represents an OAuth token used for authenticating with the API and performing + actions. +menu: + docs: + parent: entities +--- + +## Example + +```javascript +{ + "access_token": "ZA-Yj3aBD8U8Cm7lKUp-lm9O9BmDgdhHzDeqsY8tlL0", + "token_type": "Bearer", + "scope": "read write follow push", + "created_at": 1573979017 +} +``` + +## Attributes + +### `access_token` + +**Description:** An OAuth token to be used for authorization. +**Type:** String +**Version history:** Added in 0.1.0 + +### `token_type` + +**Description:** The OAuth token type. Mastodon uses `Bearer` tokens. +**Type:** String +**Version history:** Added in 0.1.0 + +### `scope` + +**Description:** The OAuth scopes granted by this token, space-separated. +**Type:** String +**Version history:** Added in 0.1.0 + +### `created_at` + +**Description:** When the token was generated. +**Type:** Number \(UNIX Timestamp\) +**Version history:** Added in 0.1.0 + +## See also + +* [Example authorization code flow](../client/token.md#example-authorization-code-flow) +* [OAuth Scopes](../api/oauth-scopes.md) +* [POST /oauth/token](../methods/apps/oauth.md#obtain-a-token) + +{{< page-ref page="methods/apps/oauth.md" >}} + + + diff --git a/content/en/methods/accounts.md b/content/en/methods/accounts.md new file mode 100644 index 00000000..96a20622 --- /dev/null +++ b/content/en/methods/accounts.md @@ -0,0 +1,1886 @@ +--- +title: accounts +description: Methods concerning user accounts and related information. +menu: + docs: + weight: 20 + parent: methods + identifier: methods-accounts +--- + +## Account credentials + +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/accounts" title="Register an account" >}} +{{< api-method-description >}} + +Creates a user and account records. Returns an account access token for the app that initiated the request. The app should save this token for later, and should wait for the user to confirm their account by clicking a link in their email inbox. + +**Returns:** Token\ +**OAuth:** App token + `write:accounts`\ +**Version:** + +- 2.7.0 - added +- 3.0.0 - added `reason` parameter + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=true >}} +Bearer <app token> +{{< endapi-method-parameter >}} +{{< endapi-method-headers >}} +{{< api-method-form-data-parameters >}} +{{< api-method-parameter name="reason" type="string" required=false >}} +Text that will be reviewed by moderators if registrations require manual approval. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="username" type="string" required=true >}} +The desired username for the account +{{< endapi-method-parameter >}} +{{< api-method-parameter name="email" type="string" required=true >}} +The email address to be used for login +{{< endapi-method-parameter >}} +{{< api-method-parameter name="password" type="string" required=true >}} +The password to be used for login +{{< endapi-method-parameter >}} +{{< api-method-parameter name="agreement" type="boolean" required=true >}} +Whether the user agrees to the local rules, terms, and policies. These should be presented to the user in order to allow them to consent before setting this parameter to TRUE. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="locale" type="string" required=true >}} +The language of the confirmation email that will be sent +{{< 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 >}} +{{< api-method-response-example httpCode=401 >}} +{{< 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/accounts/verify_credentials" title="Verify account credentials" >}} +{{< api-method-description >}} + +Test to make sure that the user token works. + +**Returns:** the user's own Account with Source\ +**OAuth**: User token + `read:accounts`\ +**Version history:** + +- 0.0.0 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Note the extra `source` property, which is not visible on accounts other than your own. Also note that plain-text is used within `source` and HTML is used for their corresponding properties such as `note` and `fields`. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + "display_name": "infinite love ⴳ", + "locked": false, + "bot": false, + "created_at": "2016-11-24T10:02:12.085Z", + "note": "

i have approximate knowledge of many things. perpetual student. (nb/ace/they)

xmpp/email: a@trwnh.com
https://trwnh.com
help me live: https://liberapay.com/at or https://paypal.me/trwnh

- my triggers are moths and glitter
- 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 presence
- #1 ami cole fan account

:fatyoshi:

", + "url": "https://mastodon.social/@trwnh", + "avatar": "https://files.mastodon.social/accounts/avatars/000/014/715/original/34aa222f4ae2e0a9.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/014/715/original/34aa222f4ae2e0a9.png", + "header": "https://files.mastodon.social/accounts/headers/000/014/715/original/5c6fc24edb3bb873.jpg", + "header_static": "https://files.mastodon.social/accounts/headers/000/014/715/original/5c6fc24edb3bb873.jpg", + "followers_count": 821, + "following_count": 178, + "statuses_count": 33120, + "last_status_at": "2019-11-24T15:49:42.251Z", + "source": { + "privacy": "public", + "sensitive": false, + "language": "", + "note": "i have approximate knowledge of many things. perpetual student. (nb/ace/they)\r\n\r\nxmpp/email: a@trwnh.com\r\nhttps://trwnh.com\r\nhelp me live: https://liberapay.com/at or https://paypal.me/trwnh\r\n\r\n- my triggers are moths and glitter\r\n- i have all notifs except mentions turned off, so please interact if you wanna be friends! i literally will not notice otherwise\r\n- dm me if i did something wrong, so i can improve\r\n- purest person on fedi, do not lewd in my presence\r\n- #1 ami cole fan account\r\n\r\n:fatyoshi:", + "fields": [ + { + "name": "Website", + "value": "https://trwnh.com", + "verified_at": "2019-08-29T04:14:55.571+00:00" + }, + { + "name": "Sponsor", + "value": "https://liberapay.com/at", + "verified_at": "2019-11-15T10:06:15.557+00:00" + }, + { + "name": "Fan of:", + "value": "Punk-rock and post-hardcore (Circa Survive, letlive., La Dispute, THE FEVER 333)Manga (Yu-Gi-Oh!, One Piece, JoJo's Bizarre Adventure, Death Note, Shaman King)Platformers and RPGs (Banjo-Kazooie, Boktai, Final Fantasy Crystal Chronicles)", + "verified_at": null + }, + { + "name": "Main topics:", + "value": "systemic analysis, design patterns, anticapitalism, info/tech freedom, theory and philosophy, and otherwise being a genuine and decent wholesome poster. i'm just here to hang out and talk to cool people!", + "verified_at": null + } + ], + "follow_requests_count": 0 + }, + "emojis": [ + { + "shortcode": "fatyoshi", + "url": "https://files.mastodon.social/custom_emojis/images/000/023/920/original/e57ecb623faa0dc9.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/023/920/static/e57ecb623faa0dc9.png", + "visible_in_picker": true + } + ], + "fields": [ + { + "name": "Website", + "value": "https://trwnh.com", + "verified_at": "2019-08-29T04:14:55.571+00:00" + }, + { + "name": "Sponsor", + "value": "https://liberapay.com/at", + "verified_at": "2019-11-15T10:06:15.557+00:00" + }, + { + "name": "Fan of:", + "value": "Punk-rock and post-hardcore (Circa Survive, letlive., La Dispute, THE FEVER 333)Manga (Yu-Gi-Oh!, One Piece, JoJo's Bizarre Adventure, Death Note, Shaman King)Platformers and RPGs (Banjo-Kazooie, Boktai, Final Fantasy Crystal Chronicles)", + "verified_at": null + }, + { + "name": "Main topics:", + "value": "systemic analysis, design patterns, anticapitalism, info/tech freedom, theory and philosophy, and otherwise being a genuine and decent wholesome poster. i'm just here to hang out and talk to cool people!", + "verified_at": null + } + ] +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Your credential verification will fail if the token is invalid or incorrect. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=403 >}} +{{< api-method-response-example-description >}} + +Your user account is currently disabled, missing a confirmed email address, or pending approval. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="disabled" >}} +```javascript +{ + "error": "Your login is currently disabled" +} +``` +{{< endtab >}} + +{{< tab title="unconfirmed" >}} +```javascript +{ + "error": "Your login is missing a confirmed e-mail address" +} +``` +{{< endtab >}} + +{{< tab title="unapproved" >}} +```javascript +{ + "error": "Your login is currently pending approval" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="patch" host="https://mastodon.example" path="/api/v1/accounts/update_credentials" title="Update account credentials" >}} +{{< api-method-description >}} + +Update the user's display and preferences. + +**Returns:** the user's own Account with Source\ +**OAuth:** User token + `write:accounts`\ +**Version history:** + +- 1.1.1 - added +- 2.3.0 - added `locked` parameter +- 2.4.0 - added `source[privacy,sensitive]` parameters +- 2.7.0 - added `discoverable` parameter + +{{< 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-form-data-parameters >}} +{{< api-method-parameter name="discoverable" type="string" required=false >}} +Whether the account should be shown in the profile directory. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="bot" type="boolean" required=false >}} +Whether the account has a bot flag. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="display_name" type="string" required=false >}} +The display name to use for the profile. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="note" type="string" required=false >}} +The account bio. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="avatar" type="string" required=false >}} +Avatar image encoded using multipart/form-data +{{< endapi-method-parameter >}} +{{< api-method-parameter name="header" type="string" required=false >}} +Header image encoded using multipart/form-data +{{< endapi-method-parameter >}} +{{< api-method-parameter name="locked" type="boolean" required=false >}} +Whether manual approval of follow requests is required. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="source\[privacy\]" type="string" required=false >}} +Default post privacy for authored statuses. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="source\[sensitive\]" type="boolean" required=false >}} +Whether to mark authored statuses as sensitive by default. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="source\[language\]" type="string" required=false >}} +Default language to use for authored statuses. \(ISO 6391\) +{{< endapi-method-parameter >}} +{{< api-method-parameter name="fields_attributes" type="array" required=false >}} +Profile metadata `name` and `value`. \(By default, max 4 fields and 255 characters per property/value\) +{{< 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 >}} + +You should use accounts/verify_credentials to first obtain plaintext representations from within the `source` parameter, then allow the user to edit these plaintext representations before submitting them through this API. The server will generate the corresponding HTML. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + "display_name": "infinite love ⴳ", + "locked": false, + "bot": false, + "created_at": "2016-11-24T10:02:12.085Z", + "note": "

i have approximate knowledge of many things. perpetual student. (nb/ace/they)

xmpp/email: a@trwnh.com
https://trwnh.com
help me live: https://liberapay.com/at or https://paypal.me/trwnh

- my triggers are moths and glitter
- 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 presence
- #1 ami cole fan account

:fatyoshi:

", + "url": "https://mastodon.social/@trwnh", + "avatar": "https://files.mastodon.social/accounts/avatars/000/014/715/original/34aa222f4ae2e0a9.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/014/715/original/34aa222f4ae2e0a9.png", + "header": "https://files.mastodon.social/accounts/headers/000/014/715/original/5c6fc24edb3bb873.jpg", + "header_static": "https://files.mastodon.social/accounts/headers/000/014/715/original/5c6fc24edb3bb873.jpg", + "followers_count": 834, + "following_count": 182, + "statuses_count": 33760, + "last_status_at": "2019-12-01T00:12:08.731Z", + "source": { + "privacy": "public", + "sensitive": false, + "language": "", + "note": "i have approximate knowledge of many things. perpetual student. (nb/ace/they)\r\n\r\nxmpp/email: a@trwnh.com\r\nhttps://trwnh.com\r\nhelp me live: https://liberapay.com/at or https://paypal.me/trwnh\r\n\r\n- my triggers are moths and glitter\r\n- i have all notifs except mentions turned off, so please interact if you wanna be friends! i literally will not notice otherwise\r\n- dm me if i did something wrong, so i can improve\r\n- purest person on fedi, do not lewd in my presence\r\n- #1 ami cole fan account\r\n\r\n:fatyoshi:", + "fields": [ + { + "name": "Website", + "value": "https://trwnh.com", + "verified_at": "2019-08-29T04:14:55.571+00:00" + }, + { + "name": "Sponsor", + "value": "https://liberapay.com/at", + "verified_at": "2019-11-15T10:06:15.557+00:00" + }, + { + "name": "Fan of:", + "value": "Punk-rock and post-hardcore (Circa Survive, letlive., La Dispute, THE FEVER 333)Manga (Yu-Gi-Oh!, One Piece, JoJo's Bizarre Adventure, Death Note, Shaman King)Platformers and RPGs (Banjo-Kazooie, Boktai, Final Fantasy Crystal Chronicles)", + "verified_at": null + }, + { + "name": "Main topics:", + "value": "systemic analysis, design patterns, anticapitalism, info/tech freedom, theory and philosophy, and otherwise being a genuine and decent wholesome poster. i'm just here to hang out and talk to cool people!", + "verified_at": null + } + ], + "follow_requests_count": 0 + }, + "emojis": [ + { + "shortcode": "fatyoshi", + "url": "https://files.mastodon.social/custom_emojis/images/000/023/920/original/e57ecb623faa0dc9.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/023/920/static/e57ecb623faa0dc9.png", + "visible_in_picker": true + } + ], + "fields": [ + { + "name": "Website", + "value": "https://trwnh.com", + "verified_at": "2019-08-29T04:14:55.571+00:00" + }, + { + "name": "Sponsor", + "value": "https://liberapay.com/at", + "verified_at": "2019-11-15T10:06:15.557+00:00" + }, + { + "name": "Fan of:", + "value": "Punk-rock and post-hardcore (Circa Survive, letlive., La Dispute, THE FEVER 333)Manga (Yu-Gi-Oh!, One Piece, JoJo's Bizarre Adventure, Death Note, Shaman King)Platformers and RPGs (Banjo-Kazooie, Boktai, Final Fantasy Crystal Chronicles)", + "verified_at": null + }, + { + "name": "Main topics:", + "value": "systemic analysis, design patterns, anticapitalism, info/tech freedom, theory and philosophy, and otherwise being a genuine and decent wholesome poster. i'm just here to hang out and talk to cool people!", + "verified_at": null + } + ] +} +``` +{{< 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 >}} + + +## Retrieve information + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/accounts/:id" title="Account" >}} +{{< api-method-description >}} + +View information about a profile. + +**Returns:** Account\ +**OAuth:** Public\ +**Version history:** + +- 0.0.0 - added +- 2.4.0 - returns 410 if account is suspended + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Account record will be returned. Note that `acct` of local users does not include the domain name. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="Local user" >}} +```javascript +{ + "id": "1", + "username": "Gargron", + "acct": "Gargron", + "display_name": "Eugen", + "locked": false, + "bot": false, + "created_at": "2016-03-16T14:34:26.392Z", + "note": "

Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.

", + "url": "https://mastodon.social/@Gargron", + "avatar": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "header": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "followers_count": 318699, + "following_count": 453, + "statuses_count": 61013, + "last_status_at": "2019-11-30T20:02:08.277Z", + "emojis": [], + "fields": [ + { + "name": "Patreon", + "value": "https://www.patreon.com/mastodon", + "verified_at": null + }, + { + "name": "Homepage", + "value": "https://zeonfederated.com", + "verified_at": "2019-07-15T18:29:57.191+00:00" + } + ] +} +``` +{{< endtab >}} + +{{< tab title="Remote user" >}} +```javascript +{ + "id": "23634", + "username": "noiob", + "acct": "noiob@awoo.space", + "display_name": "shork", + "locked": false, + "bot": false, + "created_at": "2017-02-08T02:00:53.274Z", + "note": "

:ms_rainbow_flag:​ :ms_bisexual_flag:​ :ms_nonbinary_flag:​ #awoo.space #admin ~ #bi ~ #nonbinary ~ compsci student ~ likes video #games and weird/ old electronics and will post obsessively about both ~ avatar by @dzuk

", + "url": "https://awoo.space/@noiob", + "avatar": "https://files.mastodon.social/accounts/avatars/000/023/634/original/6ca8804dc46800ad.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/023/634/original/6ca8804dc46800ad.png", + "header": "https://files.mastodon.social/accounts/headers/000/023/634/original/256eb8d7ac40f49a.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/023/634/original/256eb8d7ac40f49a.png", + "followers_count": 553, + "following_count": 405, + "statuses_count": 28982, + "last_status_at": "2019-12-01T00:39:57.264Z", + "emojis": [ + { + "shortcode": "ms_rainbow_flag", + "url": "https://files.mastodon.social/custom_emojis/images/000/028/691/original/6de008d6281f4f59.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/028/691/static/6de008d6281f4f59.png", + "visible_in_picker": true + }, + { + "shortcode": "ms_bisexual_flag", + "url": "https://files.mastodon.social/custom_emojis/images/000/050/744/original/02f94a5fca7eaf78.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/050/744/static/02f94a5fca7eaf78.png", + "visible_in_picker": true + }, + { + "shortcode": "ms_nonbinary_flag", + "url": "https://files.mastodon.social/custom_emojis/images/000/105/099/original/8106088bd4782072.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/105/099/static/8106088bd4782072.png", + "visible_in_picker": true + } + ], + "fields": [ + { + "name": "Pronouns", + "value": "they/them", + "verified_at": null + }, + { + "name": "Alt", + "value": "@noiob", + "verified_at": null + }, + { + "name": "Bots", + "value": "@darksouls, @nierautomata, code for @awoobot", + "verified_at": null + }, + { + "name": "Website", + "value": "http://shork.xyz", + "verified_at": "2019-11-23T20:25:47.907+00:00" + } + ] +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +If the instance is in whitelist mode and the Authorization header is missing or invalid +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "This API requires an authenticated user" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Account does not exist +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=410 >}} +{{< api-method-response-example-description >}} + +Account is suspended +{{< endapi-method-response-example-description >}} + + +```markup + +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/accounts/:id/statuses" title="Statuses" >}} +{{< api-method-description >}} + +Statuses posted to the given account. + +**Returns:** Array of Status\ +**OAuth:** Public \(for public statuses only\), or user token + `read:statuses` \(for private statuses the user is authorized to see\)\ +**Version history:** + +- 0.0.0 - added +- 2.6.0 - add min_id +- 2.7.0 - add exclude_reblogs and allow unauthed use +- 2.8.0 - add tagged parameter + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=false >}} +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 >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Instance is in whitelist mode or running a version of Mastodon older than 2.7.0, and the Authorization header is invalid or missing +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="whitelist" >}} +```javascript +{ + "error": "This API requires an authenticated user" +} +``` +{{< endtab >}} + +{{< tab title="pre-2.7.0" >}} +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Account is deleted or does not exist +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=410 >}} +{{< api-method-response-example-description >}} + +Account is suspended +{{< 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/accounts/:id/followers" title="Followers" >}} +{{< api-method-description >}} + +Accounts which follow the given account, if network is not hidden by the account owner. + +**Returns:** Array of Account\ +**OAuth:** App token + `read:accounts`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=true >}} +Bearer <app token> +{{< endapi-method-parameter >}} +{{< endapi-method-headers >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="number" 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 >}} + +Sample output with limit=2. Because the ID of follow relationships is not generally used or provided with any API calls, an HTTP `Link` header is used instead to indicate next and previous pages. You will have to parse this header yourself to extract the paging URLs. +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; rel="prev" + +[ + { + "id": "1020382", + "username": "atul13061987", + "acct": "atul13061987", + "display_name": "", + "locked": false, + "bot": false, + "created_at": "2019-12-04T07:17:02.745Z", + "note": "

", + "url": "https://mastodon.social/@atul13061987", + "avatar": "https://mastodon.social/avatars/original/missing.png", + "avatar_static": "https://mastodon.social/avatars/original/missing.png", + "header": "https://mastodon.social/headers/original/missing.png", + "header_static": "https://mastodon.social/headers/original/missing.png", + "followers_count": 0, + "following_count": 2, + "statuses_count": 0, + "last_status_at": null, + "emojis": [], + "fields": [] + }, + { + "id": "1020381", + "username": "linuxliner", + "acct": "linuxliner", + "display_name": "", + "locked": false, + "bot": false, + "created_at": "2019-12-04T07:15:56.426Z", + "note": "

", + "url": "https://mastodon.social/@linuxliner", + "avatar": "https://mastodon.social/avatars/original/missing.png", + "avatar_static": "https://mastodon.social/avatars/original/missing.png", + "header": "https://mastodon.social/headers/original/missing.png", + "header_static": "https://mastodon.social/headers/original/missing.png", + "followers_count": 0, + "following_count": 2, + "statuses_count": 0, + "last_status_at": null, + "emojis": [], + "fields": [] + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header, or instance is in whitelist mode and your token is not authorized with a user +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="header" >}} +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endtab >}} + +{{< tab title="whitelist" >}} +```javascript +{ + "error": "This API requires an authenticated user" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Account is deleted or does not exist +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=410 >}} +{{< api-method-response-example-description >}} + +Account is suspended +{{< 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/accounts/:id/following" title="Following" >}} +{{< api-method-description >}} + +Accounts which the given account is following, if network is not hidden by the account owner. + +**Returns:** Array of Account\ +**OAuth:** App token + `read:accounts`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=true >}} +Bearer <app token> +{{< endapi-method-parameter >}} +{{< endapi-method-headers >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +**Internal parameter.** Use HTTP `Link` header for pagination. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +**Internal parameter.** Use HTTP `Link` header for pagination. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +Maximum number of results to return. Defaults to 40. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample output with limit=2. Because the ID of follow relationships is not generally used or provided with any API calls, an HTTP `Link` header is used instead to indicate next and previous pages. You will have to parse this header yourself to extract the paging URLs. +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; rel="prev" + +[ + { + "id": "963410", + "username": "gautambhatia", + "acct": "gautambhatia", + "display_name": "Gautam Bhatia", + "locked": false, + "bot": false, + "created_at": "2019-11-07T13:06:57.442Z", + "note": "

SF reader, editor, and writer.

", + "url": "https://mastodon.social/@gautambhatia", + "avatar": "https://files.mastodon.social/accounts/avatars/000/963/410/original/d8e0fd5cefcf9687.jpg", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/963/410/original/d8e0fd5cefcf9687.jpg", + "header": "https://mastodon.social/headers/original/missing.png", + "header_static": "https://mastodon.social/headers/original/missing.png", + "followers_count": 1900, + "following_count": 52, + "statuses_count": 183, + "last_status_at": "2019-12-02T17:52:39.463Z", + "emojis": [], + "fields": [] + }, + { + "id": "1007400", + "username": "seafrog", + "acct": "seafrog@glitterkitten.co.uk", + "display_name": "🐓🦃 Heck Partridge 🤠 🦆", + "locked": false, + "bot": false, + "created_at": "2019-11-19T18:46:49.977Z", + "note": "

hi im elise!! this is scribblefrog's new account

she/her, 27

", + "url": "https://glitterkitten.co.uk/@seafrog", + "avatar": "https://files.mastodon.social/accounts/avatars/001/007/400/original/306cd22c1b118693.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/001/007/400/original/306cd22c1b118693.png", + "header": "https://files.mastodon.social/accounts/headers/001/007/400/original/fd9728559f7265f5.jpeg", + "header_static": "https://files.mastodon.social/accounts/headers/001/007/400/original/fd9728559f7265f5.jpeg", + "followers_count": 168, + "following_count": 223, + "statuses_count": 944, + "last_status_at": "2019-12-04T00:44:08.603Z", + "emojis": [], + "fields": [ + { + "name": "gotdamb", + "value": "frog", + "verified_at": null + }, + { + "name": "whomst lov", + "value": "the oceane", + "verified_at": null + } + ] + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="header" >}} +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endtab >}} + +{{< tab title="whitelist" >}} +``` +{ + "error": "This API requires an authenticated user" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Account is deleted or does not exist +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=410 >}} +{{< api-method-response-example-description >}} + +Account is suspended +{{< 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/accounts/:id/lists" title="Lists containing this account" >}} +{{< api-method-description >}} + +User lists that you have added this account to. + +**Returns:** Array of List\ +**OAuth:** User token + `read:lists`\ +**Version history:** + +- 2.1.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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 >}} + +If the account is part of any lists, those entities will be returned. If the account is not part of any of your lists, then an empty array will be returned. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="part of lists" >}} +```javascript +[ + { + "id": "13694", + "title": "dev" + } +] +``` +{{< endtab >}} + +{{< tab title="not in any lists" >}} +```javascript +[] +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Account with given id does not exist or is deleted +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=410 >}} +{{< api-method-response-example-description >}} + +Account with given id is suspended +{{< 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/accounts/:id/identity_proofs" title="Identity proofs" >}} +{{< api-method-description >}} + +**Returns:** Array of IdentityProof\ +**OAuth:** User token\ +**Version history:** + +- 2.8.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "provider": "Keybase", + "provider_username": "gargron", + "updated_at": "2019-07-21T20:14:39.596Z", + "proof_url": "https://keybase.io/gargron/sigchain#5cfc20c7018f2beefb42a68836da59a792e55daa4d118498c9b1898de7e845690f", + "profile_url": "https://keybase.io/gargron" + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Account with given id is deleted or does not exist +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=410 >}} +{{< api-method-response-example-description >}} + +Account with given id is suspended +{{< endapi-method-response-example-description >}} + + +``` + +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "This method requires an authenticated user" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + +## Perform actions on an account + +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/accounts/:id/follow" title="Follow" >}} +{{< api-method-description >}} + +Follow the given account. + +**Returns:** Relationship\ +**OAuth:** User token + `write:follows` or `follow`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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="reblogs" type="boolean" required=false >}} +Receive this account's reblogs in home timeline? Defaults to true. +{{< 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 >}} + +Successfully followed, or account was already followed +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "3", + "following": true, + "showing_reblogs": false, + "followed_by": false, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=403 >}} +{{< api-method-response-example-description >}} + +Trying to follow someone that you block or that blocks you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "This action is not allowed" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/accounts/:id/unfollow" title="Unfollow" >}} +{{< api-method-description >}} + +Unfollow the given account. + +**Returns:** Relationship\ +**OAuth:** User token + `write:follows` or `follow`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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 >}} + +Successfully unfollowed, or account was already not followed +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "3", + "following": false, + "showing_reblogs": false, + "followed_by": false, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/accounts/:id/block" title="Block" >}} +{{< api-method-description >}} + +Block the given account. Clients should filter statuses from this account if received \(e.g. due to a boost in the Home timeline\) + +**Returns:** Relationship\ +**OAuth:** User token + `write:blocks` or `follow`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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 >}} + +Successfully blocked, or account was already blocked +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "3", + "following": false, + "showing_reblogs": false, + "followed_by": false, + "blocking": true, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/accounts/:id/unblock" title="Unblock" >}} +{{< api-method-description >}} + +Unblock the given account. + +**Returns:** Relationship\ +**OAuth:** User token + `write:blocks` or `follow`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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 >}} + +Successfully unblocked, or account was already not blocked +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "3", + "following": false, + "showing_reblogs": false, + "followed_by": false, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/accounts/:id/mute" title="Mute" >}} +{{< api-method-description >}} + +Mute the given account. Clients should filter statuses and notifications from this account, if received \(e.g. due to a boost in the Home timeline\). + +**Returns:** Relationship\ +**OAuth:** User token + `write:mutes` or `follow`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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="notifications" type="boolean" required=false >}} +Mute notifications in addition to statuses? Defaults to true. +{{< 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 >}} + +Successfully muted, or account was already muted. Note that you can call this API method again with notifications=false to update the relationship so that only statuses are muted. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "3", + "following": false, + "showing_reblogs": false, + "followed_by": false, + "blocking": false, + "blocked_by": false, + "muting": true, + "muting_notifications": true, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/accounts/:id/unmute" title="Unmute" >}} +{{< api-method-description >}} + +Unmute the given account. + +**Returns:** Relationship\ +**OAuth:** User token + `write:mutes` or `follow`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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 >}} + +Successfully unmuted, or account was already unmuted +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "3", + "following": false, + "showing_reblogs": false, + "followed_by": false, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/accounts/:id/pin" title="Feature on profile" >}} +{{< api-method-description >}} + +Add the given account to the user's featured profiles. \(Featured profiles are currently shown on the user's own public profile.\) + +**Returns:** Relationship\ +**OAuth:** User token + `write:accounts`\ +**Version history:** + +- 2.5.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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 >}} + +Successfully endorsed. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "1", + "following": true, + "showing_reblogs": true, + "followed_by": true, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": true +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=403 >}} +{{< api-method-response-example-description >}} + +Token is not authorized with a valid user or is missing a required scope +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "This action is outside the authorized scopes" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +You are not following this account +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Validation failed: You must be already following the person you want to endorse" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=500 >}} +{{< api-method-response-example-description >}} + +Account already endorsed +{{< 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/accounts/:id/unpin" title="Unfeature on profile" >}} +{{< api-method-description >}} + +Remove the given account from the user's featured profiles. + +**Returns:** Relationship\ +**OAuth:** User + `write:accounts`\ +**Version history:** + +- 2.5.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the account in the database +{{< 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 >}} + +Successfully unendorsed, or account was already not endorsed +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "1", + "following": true, + "showing_reblogs": true, + "followed_by": true, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< 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 >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +``` + +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + +## General account actions + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/accounts/relationships" title="Check relationships to other accounts" >}} +{{< api-method-description >}} + +Find out whether a given account is followed, blocked, muted, etc. + +**Returns:** Array of Relationship\ +**OAuth:** User token + `read:follows`\ +**Version history:** + +- 0.0.0 - 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="id\[\]" type="array" required=true >}} +Array of account IDs to check +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample call with id\[\]=1&id\[\]=2 +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "1", + "following": true, + "showing_reblogs": true, + "followed_by": true, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false + }, + { + "id": "2", + "following": false, + "showing_reblogs": false, + "followed_by": false, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +Token does not have an authorized user +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "This method requires an authenticated user" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/accounts/search" title="Search for matching accounts" >}} +{{< api-method-description >}} + +Search for matching accounts by username or display name. + +**Returns:** Array of Account\ +**OAuth:** User token + `read:accounts`\ +**Version history:** + +- 0.0.0 - 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="q" type="string" required=true >}} +What to search for +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +Maximum number of results. Defaults to 40. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="resolve" type="string" required=false >}} +Attempt WebFinger lookup. Defaults to false. Use this when `q` is an exact address. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="following" type="string" required=false >}} +Only who the user is following. Defaults to 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 >}} + +Accounts matching "trwnh" in username or display name +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + "display_name": "infinite love ⴳ", + ... + }, + { + "id": "418714", + "username": "trwnh", + "acct": "trwnh@pixelfed.social", + "display_name": "Abdullah Tarawneh", + ... + }, + { + "id": "419674", + "username": "trwnh", + "acct": "trwnh@write.as", + "display_name": "trwnh", + ... + }, + ... +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=503 >}} +{{< api-method-response-example-description >}} + +resolve=true, but the domain part of the user@domain address is not a currently live website +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Remote data could not be fetched" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/accounts/blocks.md b/content/en/methods/accounts/blocks.md new file mode 100644 index 00000000..390a40fd --- /dev/null +++ b/content/en/methods/accounts/blocks.md @@ -0,0 +1,113 @@ +--- +title: blocks +description: 'View your blocks. See also accounts/:id/{block,unblock}' +menu: + docs: + weight: 40 + parent: methods-accounts +--- + +{{< api-method method="get" host="" path="/api/v1/blocks" title="Blocked users" >}} +{{< api-method-description >}} + +**Returns:** Array of Account\ +**OAuth:** User token + `read:blocks`\ +**Version history:** + +- 0.0.0 - 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="max_id" type="string" required=false >}} +**Internal parameter.** Use HTTP Link header for pagination instead. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +**Internal parameter.** Use HTTP Link header for pagination instead. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +Maximum number of results. Defaults to 40. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample call with limit=2. Because block ids are private, you must parse the HTTP `Link` header to find next and previous pages. +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; rel="prev" + +[ + { + "id": "585315", + "username": "admin", + "acct": "admin@happylittle.cloudns.cc", + "display_name": "☁️ ⛅ Happy Little Clouds ⛅ ☁️", + "locked": false, + "bot": false, + "created_at": "2018-11-09T21:37:50.982Z", + "note": "Novice programmer. Freedom lover. Distributed network software enthusiast.", + "url": "https://happylittle.cloudns.cc/users/admin", + "avatar": "https://files.mastodon.social/accounts/avatars/000/585/315/original/5a2d62acfe7f6e7d.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/585/315/original/5a2d62acfe7f6e7d.png", + "header": "https://files.mastodon.social/accounts/headers/000/585/315/original/122940e256a42ac8.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/585/315/original/122940e256a42ac8.png", + "followers_count": 25, + "following_count": 41, + "statuses_count": 173, + "last_status_at": "2019-11-21T14:59:07.345Z", + "emojis": [], + "fields": [] + }, + { + "id": "650568", + "username": "Nikolai_Kingsley", + "acct": "Nikolai_Kingsley@dobbs.town", + "display_name": "Rev.Dr. Nikolai Kingsley", + "locked": false, + "bot": false, + "created_at": "2018-12-15T02:25:57.424Z", + "note": "

Justifiability is in the hands of the beholder
And you just don't know what people will do next
- todd rundgren, \"Zen Archer\"

", + "url": "https://dobbs.town/@Nikolai_Kingsley", + "avatar": "https://files.mastodon.social/accounts/avatars/000/650/568/original/2e80c95aab9f8071.gif", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/650/568/static/2e80c95aab9f8071.png", + "header": "https://files.mastodon.social/accounts/headers/000/650/568/original/10c19760ca5bbae5.jpeg", + "header_static": "https://files.mastodon.social/accounts/headers/000/650/568/original/10c19760ca5bbae5.jpeg", + "followers_count": 135, + "following_count": 130, + "statuses_count": 10807, + "last_status_at": "2019-11-23T08:07:34.745Z", + "emojis": [], + "fields": [] + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +If the Authorization header contains an invalid token, is malformed, or is not present, an error will be returned indicating an authorization failure. +{{< 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/accounts/bookmarks.md b/content/en/methods/accounts/bookmarks.md new file mode 100644 index 00000000..4de227fc --- /dev/null +++ b/content/en/methods/accounts/bookmarks.md @@ -0,0 +1,54 @@ +--- +title: bookmarks +description: 'View your bookmarks. See also statuses/:id/{bookmark,unbookmark}' +menu: + docs: + weight: 10 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/bookmarks" title="Bookmarked statuses" >}} +{{< api-method-description >}} + +Statuses the user has bookmarked. + +**Returns:** Array of Status\ +**OAuth:** User token + `read:bookmarks`\ +**Version history:** + +- 3.1.0 - 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="limit" type="string" required=false >}} +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_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 >}} + + diff --git a/content/en/methods/accounts/domain_blocks.md b/content/en/methods/accounts/domain_blocks.md new file mode 100644 index 00000000..6eea9fa1 --- /dev/null +++ b/content/en/methods/accounts/domain_blocks.md @@ -0,0 +1,232 @@ +--- +title: domain_blocks +description: View and update domain blocks. +menu: + docs: + weight: 50 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/domain_blocks" title="Fetch domain blocks" >}} +{{< api-method-description >}} + +View domains the user has blocked. + +**Returns:** Array of strings\ +**OAuth:** User token + `read:blocks` or `follow`\ +**Version:** + +- 1.4.0 - 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="max_id" type="string" required=false >}} +**Internal parameter.** Use HTTP Link header from response for pagination. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +**Internal parameter.** Use HTTP Link header from response for pagination. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +Maximum number of results to return per page. Defaults to 40. NOTE: Pagination is done with the Link header from the response. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample call with limit=2. Because domain ids are not public, you must parse the HTTP Link header to access next and previous pages. +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; rel="prev" + +["nsfw.social","artalley.social"] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Incorrect 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="post" host="https://mastodon.example" path="/api/v1/domain_blocks" title="Block a domain" >}} +{{< api-method-description >}} + +Block a domain to: +- hide all public posts from it +- hide all notifications from it +- remove all followers from it +- prevent following new users from it \(but does not remove existing follows\) + +**Returns:** n/a\ +**OAuth:** User token + ****`write:blocks` or `follow`\ +**Version:** + +- 1.4.0 - 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-form-data-parameters >}} +{{< api-method-parameter name="domain" type="string" required=true >}} +Domain to block. +{{< 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 >}} + +If the call was successful, an empty object will be returned. Note that the call will be successful even if the domain is already blocked or if the domain does not exist or if the domain is not a domain. +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Incorrect Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +If `domain` is not provided or contains spaces, the request will fail. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="empty" >}} +```javascript +{ + "error": "Validation failed: Domain can't be blank" +} +``` +{{< endtab >}} + +{{< tab title="invalid" >}} +```javascript +{ + "error": "Validation failed: Domain is not a valid domain name" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="delete" host="https://mastodon.example" path="/api/v1/domain_blocks" title="Unblock a domain" >}} +{{< api-method-description >}} + +Remove a domain block, if it exists in the user's array of blocked domains. + +**Returns:** n/a\ +**OAuth:** User token + ****`write:blocks` or `follow`\ +**Version history:** + +- 1.4.0 - 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-form-data-parameters >}} +{{< api-method-parameter name="domain" type="string" required=true >}} +Domain to unblock. +{{< 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 >}} + +If the call was successful, an empty object will be returned. Note that the call will be successful even if the domain was not previously blocked. +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Incorrect Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +If `domain` is not provided or contains spaces, the request will fail. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="empty" >}} +```javascript +{ + "error": "Validation failed: Domain can't be blank" +} +``` +{{< endtab >}} + +{{< tab title="invalid domain" >}} +```javascript +{ + "error": "Validation failed: Domain is not a valid domain name" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/accounts/endorsements.md b/content/en/methods/accounts/endorsements.md new file mode 100644 index 00000000..7b9a3c3d --- /dev/null +++ b/content/en/methods/accounts/endorsements.md @@ -0,0 +1,122 @@ +--- +title: endorsements +description: 'Feature other profiles on your own profile. See also accounts/:id/{pin,unpin}' +menu: + docs: + weight: 90 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/endorsements" title="View currently featured profiles" >}} +{{< api-method-description >}} + +Accounts that the user is currently featuring on their profile. + +**Returns:** Array of Account\ +**OAuth:** User token + `read:accounts`\ +**Version history:** + +- 2.5.0 - 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="limit" type="string" required=false >}} +Maximum number of results to return. Defaults to 40. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Internal parameter. Use HTTP `Link` header from response for pagination +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Internal parameter. Use HTTP `Link` header from response for pagination. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample call with limit=2. Because endorsement ids are private, you must parse the HTTP Link header to find next and previous pages. +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; rel="prev" + +[ + { + "id": "952529", + "username": "alayna", + "acct": "alayna@desvox.es", + "display_name": "Alayna Desirae", + "locked": true, + "bot": false, + "created_at": "2019-10-26T23:12:06.570Z", + "note": "experiencing ________ difficulties
22y/o INFP in Oklahoma", + "url": "https://desvox.es/users/alayna", + "avatar": "https://files.mastodon.social/accounts/avatars/000/952/529/original/6534122046d050d5.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/952/529/original/6534122046d050d5.png", + "header": "https://files.mastodon.social/accounts/headers/000/952/529/original/496f1f817e042ade.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/952/529/original/496f1f817e042ade.png", + "followers_count": 0, + "following_count": 0, + "statuses_count": 955, + "last_status_at": "2019-11-23T07:05:50.682Z", + "emojis": [], + "fields": [] + }, + { + "id": "832844", + "username": "a9", + "acct": "a9@broadcast.wolfgirl.engineering", + "display_name": "vivienne :collar: ", + "locked": true, + "bot": false, + "created_at": "2019-06-12T18:55:12.053Z", + "note": "borderline nsfw, considered a schedule I drug by nixon
waiting for the year of the illumos desktop", + "url": "https://broadcast.wolfgirl.engineering/users/a9", + "avatar": "https://files.mastodon.social/accounts/avatars/000/832/844/original/ae1de0b8fb63d1c6.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/832/844/original/ae1de0b8fb63d1c6.png", + "header": "https://files.mastodon.social/accounts/headers/000/832/844/original/5088e4a16e6d8736.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/832/844/original/5088e4a16e6d8736.png", + "followers_count": 43, + "following_count": 67, + "statuses_count": 5906, + "last_status_at": "2019-11-23T05:23:47.911Z", + "emojis": [ + { + "shortcode": "collar", + "url": "https://files.mastodon.social/custom_emojis/images/000/106/920/original/80953b9cd96ec4dc.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/106/920/static/80953b9cd96ec4dc.png", + "visible_in_picker": true + } + ], + "fields": [] + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +If Authorization header is not provided correctly +{{< 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/accounts/favourites.md b/content/en/methods/accounts/favourites.md new file mode 100644 index 00000000..6a9a2b84 --- /dev/null +++ b/content/en/methods/accounts/favourites.md @@ -0,0 +1,224 @@ +--- +title: favourites +description: 'View your favourites. See also statuses/:id/{favourite,unfavourite}' +menu: + docs: + weight: 20 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/favourites" title="Favourited statuses" >}} +{{< api-method-description >}} + +Statuses the user has favourited. + +**Returns:** Array of Status\ +**OAuth:** User token + `read:favourites`\ +**Version:** + +- 0.0.0 - added +- 2.6.0 - min_id 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="limit" type="string" required=false >}} +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Internal parameter. Use HTTP `Link` header for pagination instead. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Internal parameter. Use HTTP `Link` header for pagination instead. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +An example call with limit=2. Results will be returned as a Status entity with embedded Account entity. Because the id of a favourite is not public, an HTTP `Link` header can be parsed for next and previous pages.Internal +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; rel="prev" + +[ + "id": "103186075217296344", + "created_at": "2019-11-23T07:35:52.000Z", + "in_reply_to_id": null, + "in_reply_to_account_id": null, + "sensitive": false, + "spoiler_text": "", + "visibility": "unlisted", + "language": "enCy", + "uri": "https://cybre.space/users/haskal/statuses/103186075002013902", + "url": "https://cybre.space/@haskal/103186075002013902", + "replies_count": 0, + "reblogs_count": 1, + "favourites_count": 1, + "favourited": true, + "reblogged": false, + "muted": false, + "bookmarked": false, + "content": "

the pirate gay

", + "reblog": null, + "account": { + "id": "297420", + "username": "haskal", + "acct": "haskal@cybre.space", + "display_name": "soft nb friend :blobcatsleep:", + "locked": false, + "bot": false, + "created_at": "2018-03-16T00:47:36.470Z", + "note": "

a very distinctive nya

systems hecker, -1x engineer, server maid, professional yak shaver
free software | digital rights | rhythm games | cyberponk | homelab | ham radio | electronics

🇺🇸/🇭🇺/🏴‍☠️
21; they/them

b618ac8ac69b6ac7bae267acb1a81e

", + "url": "https://cybre.space/@haskal", + "avatar": "https://files.mastodon.social/accounts/avatars/000/297/420/original/5e2def6e305cecee.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/297/420/original/5e2def6e305cecee.png", + "header": "https://files.mastodon.social/accounts/headers/000/297/420/original/2df598299cc677db.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/297/420/original/2df598299cc677db.png", + "followers_count": 268, + "following_count": 258, + "statuses_count": 8743, + "last_status_at": "2019-11-23T07:49:39.880Z", + "emojis": [ + { + "shortcode": "blobcatsleep", + "url": "https://files.mastodon.social/custom_emojis/images/000/077/451/original/fc39ac6778d2ca02.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/077/451/static/fc39ac6778d2ca02.png", + "visible_in_picker": true + } + ], + "fields": [ + { + "name": "web", + "value": "https://tilde.town/~haskal", + "verified_at": "2019-11-22T21:16:30.009+00:00" + }, + { + "name": "other web", + "value": "https://awoo.systems", + "verified_at": "2019-11-22T21:16:30.578+00:00" + }, + { + "name": "xmpp", + "value": "haskal@lain.faith", + "verified_at": null + }, + { + "name": "matrix", + "value": "@haskal:matrix.org", + "verified_at": null + } + ] + }, + "media_attachments": [], + "mentions": [], + "tags": [], + "emojis": [], + "card": null, + "poll": null + }, + { + "id": "103186044372624124", + "created_at": "2019-11-23T07:28:03.000Z", + "in_reply_to_id": null, + "in_reply_to_account_id": null, + "sensitive": true, + "spoiler_text": "no context", + "visibility": "unlisted", + "language": "enCy", + "uri": "https://cybre.space/users/haskal/statuses/103186044253681902", + "url": "https://cybre.space/@haskal/103186044253681902", + "replies_count": 1, + "reblogs_count": 0, + "favourites_count": 1, + "favourited": true, + "reblogged": false, + "muted": false, + "bookmarked": false, + "content": "

cute,,,

", + "reblog": null, + "account": { + "id": "297420", + "username": "haskal", + "acct": "haskal@cybre.space", + "display_name": "soft nb friend :blobcatsleep:", + "locked": false, + "bot": false, + "created_at": "2018-03-16T00:47:36.470Z", + "note": "

a very distinctive nya

systems hecker, -1x engineer, server maid, professional yak shaver
free software | digital rights | rhythm games | cyberponk | homelab | ham radio | electronics

🇺🇸/🇭🇺/🏴‍☠️
21; they/them

b618ac8ac69b6ac7bae267acb1a81e

", + "url": "https://cybre.space/@haskal", + "avatar": "https://files.mastodon.social/accounts/avatars/000/297/420/original/5e2def6e305cecee.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/297/420/original/5e2def6e305cecee.png", + "header": "https://files.mastodon.social/accounts/headers/000/297/420/original/2df598299cc677db.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/297/420/original/2df598299cc677db.png", + "followers_count": 268, + "following_count": 258, + "statuses_count": 8743, + "last_status_at": "2019-11-23T07:49:39.880Z", + "emojis": [ + { + "shortcode": "blobcatsleep", + "url": "https://files.mastodon.social/custom_emojis/images/000/077/451/original/fc39ac6778d2ca02.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/077/451/static/fc39ac6778d2ca02.png", + "visible_in_picker": true + } + ], + "fields": [ + { + "name": "web", + "value": "https://tilde.town/~haskal", + "verified_at": "2019-11-22T21:16:30.009+00:00" + }, + { + "name": "other web", + "value": "https://awoo.systems", + "verified_at": "2019-11-22T21:16:30.578+00:00" + }, + { + "name": "xmpp", + "value": "haskal@lain.faith", + "verified_at": null + }, + { + "name": "matrix", + "value": "@haskal:matrix.org", + "verified_at": null + } + ] + }, + "media_attachments": [], + "mentions": [], + "tags": [], + "emojis": [], + "card": null, + "poll": null + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +If a user token is not provided or is incorrect, the request will fail. +{{< 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/accounts/featured_tags.md b/content/en/methods/accounts/featured_tags.md new file mode 100644 index 00000000..efa4cba2 --- /dev/null +++ b/content/en/methods/accounts/featured_tags.md @@ -0,0 +1,299 @@ +--- +title: featured_tags +description: Feature tags that you use frequently. +menu: + docs: + weight: 100 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/featured_tags" title="View your featured tags" >}} +{{< api-method-description >}} + +**Returns:** Array of FeaturedTag\ +**OAuth:** User token + `read:accounts`\ +**Version history:** + +- 3.0.0 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "627", + "name": "nowplaying", + "statuses_count": 36, + "last_status_at": "2019-11-15T07:14:43.524Z" + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/featured_tags" title="Feature a tag" >}} +{{< api-method-description >}} + +**Returns:** FeaturedTag\ +**OAuth:** User token + `write:accounts`\ +**Version history:** + +- 3.0.0 - 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-form-data-parameters >}} +{{< api-method-parameter name="name" type="string" required=true >}} +The hashtag to be featured. +{{< 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 >}} + +A FeaturedTag will be created with the specified `name`. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "13174", + "name": "circasurvive", + "statuses_count": 11, + "last_status_at": "2019-11-15T06:20:32.769Z" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +If `name` is not a valid hashtag, e.g. contains illegal characters or only numbers +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Validation failed: Tag 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/featured_tags/:id" title="Unfeature a tag" >}} +{{< api-method-description >}} + +**Returns:** empty object\ +**OAuth:** User token + `write:accounts`\ +**Version history:** + +- 3.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the FeaturedTag to be unfeatured. +{{< 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 >}} + +An empty object will be returned if the featured tag was successfully deleted. +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +If the ID does not exist or is not owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/featured_tags/suggestions" title="Suggested tags to feature" >}} +{{< api-method-description >}} + +Shows your 10 most-used tags, with usage history for the past week. + +**Returns:** Array of Tag with History\ +**OAuth:** User token + `read:accounts`\ +**Version history:** + +- 3.0.0 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Truncated results to first and last tag. +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "name": "nowplaying", + "url": "https://mastodon.social/tags/nowplaying", + "history": [ + { + "day": "1574553600", + "uses": "200", + "accounts": "31" + }, + { + "day": "1574467200", + "uses": "272", + "accounts": "39" + }, + { + "day": "1574380800", + "uses": "345", + "accounts": "40" + }, + { + "day": "1574294400", + "uses": "366", + "accounts": "46" + }, + { + "day": "1574208000", + "uses": "226", + "accounts": "32" + }, + { + "day": "1574121600", + "uses": "217", + "accounts": "42" + }, + { + "day": "1574035200", + "uses": "214", + "accounts": "34" + } + ] + }, + ... + { + "name": "mastothemes", + "url": "https://mastodon.social/tags/mastothemes", + "history": [ + { + "day": "1574553600", + "uses": "0", + "accounts": "0" + }, + { + "day": "1574467200", + "uses": "0", + "accounts": "0" + }, + { + "day": "1574380800", + "uses": "0", + "accounts": "0" + }, + { + "day": "1574294400", + "uses": "0", + "accounts": "0" + }, + { + "day": "1574208000", + "uses": "0", + "accounts": "0" + }, + { + "day": "1574121600", + "uses": "0", + "accounts": "0" + }, + { + "day": "1574035200", + "uses": "0", + "accounts": "0" + } + ] + } +] +``` +{{< 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/accounts/filters.md b/content/en/methods/accounts/filters.md new file mode 100644 index 00000000..a5b51910 --- /dev/null +++ b/content/en/methods/accounts/filters.md @@ -0,0 +1,440 @@ +--- +title: filters +description: Create and manage filters. +menu: + docs: + weight: 60 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/filters" title="View all filters" >}} +{{< api-method-description >}} + +**Returns:** Filter\ +**OAuth:** User token + `read:filters`\ +**Version history:** + +- 2.4.3 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Excerpts of various filters in different contexts. +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "6191", + "phrase": ":eurovision2019:", + "context": [ + "home" + ], + "whole_word": true, + "expires_at": "2019-05-21T13:47:31.333Z", + "irreversible": false + }, + ... + { + "id": "5580", + "phrase": "@twitter.com", + "context": [ + "home", + "notifications", + "public", + "thread" + ], + "whole_word": false, + "expires_at": null, + "irreversible": true + }, + ... +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="get" host="https://mastodon.example" path="/api/v1/filters/:id" title="View a single filter" >}} +{{< api-method-description >}} + +**Returns:** Filter\ +**OAuth:** User token + `read:filters`\ +**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 >}} +{{< 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 >}} + +Filter returned successfully +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "8449", + "phrase": "test", + "context": [ + "home", + "notifications", + "public", + "thread" + ], + "whole_word": false, + "expires_at": "2019-11-26T09:08:06.254Z", + "irreversible": true +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Filter ID does not exist, or is not owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/filters" title="Create a filter" >}} +{{< api-method-description >}} + +**Returns:** Filter\ +**OAuth:** User token + `write:filters`\ +**Version history:** + +- 2.4.3 - 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-form-data-parameters >}} +{{< api-method-parameter name="phrase" type="string" required=true >}} +Text to be filtered +{{< endapi-method-parameter >}} +{{< api-method-parameter name="context" type="array" required=true >}} +Array of enumerable strings `home`, `notifications`, `public`, `thread`. At least one context must be specified. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="irreversible" type="boolean" required=false >}} +Should the server irreversibly drop matching entities from home and notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="whole_word" type="boolean" required=false >}} +Consider word boundaries? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="expires_in" type="string" required=false >}} +ISO 8601 Datetime for when the filter expires. Otherwise, null for a filter that doesn't expire. +{{< 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 >}} + +The newly-created filter will be returned. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "8449", + "phrase": "test", + "context": [ + "home", + "notifications", + "public", + "thread" + ], + "whole_word": false, + "expires_at": "2019-11-26T09:08:06.254Z", + "irreversible": true +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +If phrase or context are not provided properly +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="phrase" >}} +```javascript +{ + "error": "Validation failed: Phrase can't be blank" +} +``` +{{< endtab >}} + +{{< tab title="context" >}} +```javascript +{ + "error": "Validation failed: Context can't be blank, Context None or invalid context supplied" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="put" host="https://mastodon.example" path="/api/v1/filters/:id" title="Update a filter" >}} +{{< api-method-description >}} + +**Returns:** Filter\ +**OAuth:** User token + `write:filters`\ +**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 filter in the database +{{< 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="phrase" type="string" required=true >}} +Text to be filtered +{{< endapi-method-parameter >}} +{{< api-method-parameter name="context" type="array" required=true >}} +Array of enumerable strings `home`, `notifications`, `public`, `thread`. At least one context must be specified. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="irreversible" type="boolean" required=false >}} +Should the server irreversibly drop matching entities from home and notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="whole_word" type="boolean" required=false >}} +Consider word boundaries? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="expires_in" type="string" required=false >}} +ISO 8601 Datetime for when the filter expires. Otherwise, null for a filter that doesn't expire. +{{< 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 >}} + +Filter updated successfully +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "8449", + "phrase": "test", + "context": [ + "home", + "notifications", + "public", + "thread" + ], + "whole_word": false, + "expires_at": null, + "irreversible": true +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +The filter does not exist or is not owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +If phrase or context are not provided properly +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="phrase" >}} +```javascript +{ + "error": "Validation failed: Phrase can't be blank" +} +``` +{{< endtab >}} + +{{< tab title="context" >}} +```javascript +{ + "error": "Validation failed: Context can't be blank, Context None or invalid context supplied" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="delete" host="https://mastodon.example" path="/api/v1/filters/:id" title="Remove a filter" >}} +{{< api-method-description >}} + +**Returns:** Filter\ +**OAuth:** User token + `write:filters`\ +**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 filter in the database +{{< 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 >}} + +The filter has been deleted successfully, so an empty object will be returned. +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +The filter does not exist or is not owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/accounts/follow_requests.md b/content/en/methods/accounts/follow_requests.md new file mode 100644 index 00000000..9a39e860 --- /dev/null +++ b/content/en/methods/accounts/follow_requests.md @@ -0,0 +1,225 @@ +--- +title: follow_requests +description: View and manage follow requests. +menu: + docs: + weight: 80 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/follow_requests" title="Pending Follows" >}} +{{< api-method-description >}} + +**Returns:** Array of Account\ +**OAuth:** User token + `read:follows` or `follow`\ +**Version history:** + +- 0.0.0 - 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="limit" type="string" required=false >}} +Maximum number of results to return. Defaults to 40. Paginate using the HTTP Link header. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Accounts that are requesting a follow +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; rel="prev" + +[ + { + "id": "8889777", + "username": "example", + "acct": "example@social.example", + ... + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/follow_requests/:id/authorize" title="Accept Follow" >}} +{{< api-method-description >}} + +**Returns:** Relationship\ +**OAuth:** User token + `write:follows` or `follow`\ +**Version history:** + +- 0.0.0 - added +- 3.0.0 - now returns Relationship instead of nothing + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=false >}} +ID of the account in the database +{{< 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 >}} + +Your Relationship with this account should be updated so that you are `followed_by` this account. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "8889777", + "following": false, + "showing_reblogs": false, + "followed_by": true, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +No pending follow request from that user ID +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/follow_requests/:id/reject" title="Reject Follow" >}} +{{< api-method-description >}} + +**Returns:** Relationship\ +**OAuth:** User token + `write:follows` or `follow`\ +**Version history:** + +- 0.0.0 - added +- 3.0.0 - now returns Relationship instead of nothing + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=false >}} +ID of the account in the database +{{< 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 >}} + +Your Relationship with this Account should be unchanged. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "8889777", + "following": false, + "showing_reblogs": false, + "followed_by": false, + "blocking": false, + "blocked_by": false, + "muting": false, + "muting_notifications": false, + "requested": false, + "domain_blocking": false, + "endorsed": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +No pending follow request for that user ID +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/accounts/mutes.md b/content/en/methods/accounts/mutes.md new file mode 100644 index 00000000..5dabd93c --- /dev/null +++ b/content/en/methods/accounts/mutes.md @@ -0,0 +1,136 @@ +--- +title: mutes +description: 'View your mutes. See also accounts/:id/{mute,unmute}' +menu: + docs: + weight: 30 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/mutes" title="Muted accounts" >}} +{{< api-method-description >}} + +Accounts the user has muted. + +**Returns:** Array of Account\ +**OAuth:** User token + `read:mutes` or `follow`\ +**Version history:** + +- 0.0.0 - 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-form-data-parameters >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +Maximum number of results to return per page. Defaults to 40. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +**Internal parameter.** Use the HTTP Link header for pagination instead. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +**Internal parameter.** Use the HTTP Link header for pagination instead. +{{< 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 >}} + +Sample response with limit=2. The id of mutes is private, so parse the HTTP `Link` header to find links to next and previous pages. +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; rel="prev" + +[ + { + "id": "963076", + "username": "Simia91", + "acct": "Simia91", + "display_name": "", + "locked": false, + "bot": false, + "created_at": "2019-11-07T10:31:17.428Z", + "note": "

", + "url": "https://mastodon.social/@Simia91", + "avatar": "https://files.mastodon.social/accounts/avatars/000/963/076/original/30d3e0502c419cca.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/963/076/original/30d3e0502c419cca.png", + "header": "https://files.mastodon.social/accounts/headers/000/963/076/original/53ba9b1ad4922418.jpg", + "header_static": "https://files.mastodon.social/accounts/headers/000/963/076/original/53ba9b1ad4922418.jpg", + "followers_count": 18, + "following_count": 73, + "statuses_count": 640, + "last_status_at": "2019-11-19T15:14:47.088Z", + "emojis": [], + "fields": [] + }, + { + "id": "1001524", + "username": "hakogamae", + "acct": "hakogamae", + "display_name": "Hakogamae 🔞", + "locked": false, + "bot": false, + "created_at": "2019-11-15T13:01:55.538Z", + "note": "

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,
I shall surely acquire the capacity to
do it even if I may not have it at the
beginning." -- Gandhi

My name -- Hakogamae -- comes from the Japanese Kanji Radical 22 匚部 meaning "box." I'm in a box now.

At Humblr, I was Fslowly

", + "url": "https://mastodon.social/@hakogamae", + "avatar": "https://files.mastodon.social/accounts/avatars/001/001/524/original/dd6ab3001057a144.jpg", + "avatar_static": "https://files.mastodon.social/accounts/avatars/001/001/524/original/dd6ab3001057a144.jpg", + "header": "https://files.mastodon.social/accounts/headers/001/001/524/original/09187eeac3fa6d0d.jpg", + "header_static": "https://files.mastodon.social/accounts/headers/001/001/524/original/09187eeac3fa6d0d.jpg", + "followers_count": 23, + "following_count": 0, + "statuses_count": 137, + "last_status_at": "2019-11-21T18:44:25.570Z", + "emojis": [], + "fields": [ + { + "name": "Men", + "value": "living, alive", + "verified_at": null + }, + { + "name": "Carpe diem", + "value": "匚部", + "verified_at": null + }, + { + "name": "Photographs", + "value": "capturing time", + "verified_at": null + }, + { + "name": "Feedback", + "value": "always helps", + "verified_at": null + } + ] + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +If the Authorization header is not provided or contains an invalid token, the request will fail. +{{< 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/accounts/preferences.md b/content/en/methods/accounts/preferences.md new file mode 100644 index 00000000..6ed8b785 --- /dev/null +++ b/content/en/methods/accounts/preferences.md @@ -0,0 +1,63 @@ +--- +title: preferences +description: Preferred common behaviors to be shared across clients. +menu: + docs: + weight: 110 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/preferences" title="View user preferences" >}} +{{< api-method-description >}} + +Preferences defined by the user in their account settings. + +**Returns:** Preferences by key and value\ +**OAuth:** User token + `read:accounts`\ +**Version history:** + +- 2.8.0 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "posting:default:visibility": "public", + "posting:default:sensitive": false, + "posting:default:language": null, + "reading:expand:media": "default", + "reading:expand:spoilers": false +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Incorrect 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 >}} + + diff --git a/content/en/methods/accounts/reports.md b/content/en/methods/accounts/reports.md new file mode 100644 index 00000000..f78a9c71 --- /dev/null +++ b/content/en/methods/accounts/reports.md @@ -0,0 +1,60 @@ +--- +title: reports +description: Report problematic users to your moderators. +menu: + docs: + weight: 70 + parent: methods-accounts +--- + +{{< hint style="warning" >}} + +Responses are not currently documented. +{{< /hint >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/reports" title="File a report" >}} +{{< api-method-description >}} + +**Returns:** Report\ +**OAuth:** User token + `write:reports`\ +**Version history:**\ +1.1 - added +- 2.3.0 - add `forward` parameter + +{{< 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-form-data-parameters >}} +{{< api-method-parameter name="account_id" type="string" required=true >}} +ID of the account to report +{{< endapi-method-parameter >}} +{{< api-method-parameter name="status_ids" type="array" required=false >}} +Array of Statuses to attach to the report, for context +{{< endapi-method-parameter >}} +{{< api-method-parameter name="comment" type="string" required=false >}} +Reason for the report \(default max 1000 characters\) +{{< endapi-method-parameter >}} +{{< api-method-parameter name="forward" type="boolean" required=false >}} +If the account is remote, should the report be forwarded to the remote admin? +{{< 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 >}} + + diff --git a/content/en/methods/accounts/suggestions.md b/content/en/methods/accounts/suggestions.md new file mode 100644 index 00000000..0dac5869 --- /dev/null +++ b/content/en/methods/accounts/suggestions.md @@ -0,0 +1,213 @@ +--- +title: suggestions +description: >- + Server-generated suggestions on who to follow, based on previous positive + interactions. +menu: + docs: + weight: 120 + parent: methods-accounts +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/suggestions" title="Follow suggestions" >}} +{{< api-method-description >}} + +Accounts the user has had past positive interactions with, but is not yet following. + +**Returns:** Array of Account\ +**OAuth:** User token + `read`\ +**Version history:** + +- 2.4.3 - 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="limit" type="string" required=false >}} +Maximum number of results to return. Defaults to 40. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample call with limit=2 +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "332766", + "username": "kaniini", + "acct": "kaniini@pleroma.site", + "display_name": ":abunhdhappyhop: :abunhdhappy: :abunhdhop: :abunhd: :abunhdhappyhop: :abunhdhappy:", + "locked": false, + "bot": false, + "created_at": "2018-04-18T13:56:23.167Z", + "note": "a friendly #collectivist 🐰

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": "

stay at home dad, painter by commission, sidewalk farmer, editor, socialist organizer, home chef, anxiety ridden, he/him

", + "url": "https://sunbeam.city/@interneteh", + "avatar": "https://files.mastodon.social/accounts/avatars/000/689/455/original/e7a1ba67e373296e.png", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/689/455/original/e7a1ba67e373296e.png", + "header": "https://files.mastodon.social/accounts/headers/000/689/455/original/2e83fd31bd530745.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/689/455/original/2e83fd31bd530745.png", + "followers_count": 1180, + "following_count": 1707, + "statuses_count": 26320, + "last_status_at": "2019-11-23T04:58:36.907Z", + "emojis": [], + "fields": [] + }, + { + "id": "764276", + "username": "Dee", + "acct": "Dee@fedi.underscore.world", + "display_name": "Dee 🧡", + "locked": false, + "bot": false, + "created_at": "2019-03-15T17:22:26.925Z", + "note": "This instance exists. People tell me I exist, but who knows?


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 new file mode 100644 index 00000000..ef1d1ec5 --- /dev/null +++ b/content/en/methods/admin.md @@ -0,0 +1,612 @@ +--- +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/apps.md b/content/en/methods/apps.md new file mode 100644 index 00000000..834cdba8 --- /dev/null +++ b/content/en/methods/apps.md @@ -0,0 +1,131 @@ +--- +title: apps +description: Register client applications that can be used to obtain OAuth tokens. +menu: + docs: + weight: 10 + parent: methods + identifier: methods-apps +--- + +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/apps" title="Create an application" >}} +{{< api-method-description >}} + +Create a new application to obtain OAuth2 credentials. + +**Returns:** Application, with `client_id` and `client_secret`\ +**OAuth:** Public\ +**Version history:** + +- 0.0.0 - added +- 2.7.2 - now returns vapid_key + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-form-data-parameters >}} +{{< api-method-parameter name="client_name" type="string" required=true >}} +A name for your application +{{< endapi-method-parameter >}} +{{< api-method-parameter name="redirect_uris" type="string" required=true >}} +Where the user should be redirected after authorization. To display the authorization code to the user instead of redirecting to a web page, use `urn:ietf:wg:oauth:2.0:oob` in this parameter. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="scopes" type="string" required=false >}} +Space separated list of scopes. If none is provided, defaults to `read`. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="website" type="string" required=false >}} +A URL to the homepage of your app +{{< 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 >}} + +Store the `client_id` and `client_secret` in your cache, as these will be used to obtain OAuth tokens. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "563419", + "name": "test app", + "website": null, + "redirect_uri": "urn:ietf:wg:oauth:2.0:oob", + "client_id": "TWhM-tNSuncnqN7DBJmoyeLnk6K3iJJ71KKXxgL1hPM", + "client_secret": "ZEaFUFmF0umgBX1qKJDjaU99Q31lDkOU8NutzTOoliw", + "vapid_key": "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +If a required parameter is missing or improperly formatted, the request will fail. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Validation failed: Redirect URI must be an absolute URI." +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/apps/verify_credentials" title="Verify your app works" >}} +{{< api-method-description >}} + +Confirm that the app's OAuth2 credentials work. + +**Returns:** Application\ +**OAuth level:** App token\ +**Version history:** + +- 2.0.0 - added +- 2.7.2 - now returns vapid_key + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=true >}} +Bearer <app token> +{{< endapi-method-parameter >}} +{{< endapi-method-headers >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +If the Authorization header was provided with a valid token, you should see your app returned as an Application entity. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "name": "test app", + "website": null, + "vapid_key": "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +If the Authorization header contains an invalid token, is malformed, or is not present, an error will be returned indicating an authorization failure. +{{< 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/apps/oauth.md b/content/en/methods/apps/oauth.md new file mode 100644 index 00000000..a0161fff --- /dev/null +++ b/content/en/methods/apps/oauth.md @@ -0,0 +1,194 @@ +--- +title: oauth +description: Generate and manage OAuth tokens. +menu: + docs: + weight: 10 + parent: methods-apps +--- + +{{< api-method method="get" host="https://mastodon.example" path="/oauth/authorize" title="Authorize a user" >}} +{{< api-method-description >}} + +Displays an authorization form to the user. If approved, it will create and return an authorization code, then redirect to the desired `redirect_uri`, or show the authorization code if `urn:ietf:wg:oauth:2.0:oob` was requested. The authorization code can be used while requesting a token to obtain access to user-level methods. + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-form-data-parameters >}} +{{< api-method-parameter name="force_login" type="string" required=false >}} +Added in 2.6.0. Forces the user to re-login, which is necessary for authorizing with multiple accounts from the same instance. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="response_type" type="string" required=true >}} +Should be set equal to `code`. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="client_id" type="string" required=true >}} +Client ID, obtained during app registration. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="redirect_uri" type="string" required=true >}} +Set a URI to redirect the user to. If this parameter is set to `urn:ietf:wg:oauth:2.0:oob` then the authorization code will be shown instead. Must match one of the redirect URIs declared during app registration. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="scope" type="string" required=false >}} +List of requested OAuth scopes, separated by spaces \(or by pluses, if using query parameters\). Must be a subset of scopes declared during app registration. If not provided, defaults to `read`. +{{< 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 >}} + +The authorization code will be returned as a query parameter named `code`. +{{< endapi-method-response-example-description >}} + + +```http +redirect_uri?code=qDFUEaYrRK5c-HNmTCJbAzazwLRInJ7VHFat0wcMgCU +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=400 >}} +{{< api-method-response-example-description >}} + +If the authorization code is incorrect or has been used already, the request will fail. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "invalid_grant", + "error_description": "The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client." +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/oauth/token" title="Obtain a token" >}} +{{< api-method-description >}} + +Returns an access token, to be used during API calls that are not public. + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-form-data-parameters >}} +{{< api-method-parameter name="client_id" type="string" required=true >}} +Client ID, obtained during app registration +{{< endapi-method-parameter >}} +{{< api-method-parameter name="client_secret" type="string" required=true >}} +Client secret, obtained during app registration +{{< endapi-method-parameter >}} +{{< api-method-parameter name="redirect_uri" type="string" required=true >}} +Set a URI to redirect the user to. If this parameter is set to urn:ietf:wg:oauth:2.0:oob then the token will be shown instead. Must match one of the redirect URIs declared during app registration. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="scope" type="string" required=false >}} +List of requested OAuth scopes, separated by spaces. Must be a subset of scopes declared during app registration. If not provided, defaults to `read`. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="code" type="string" required=false >}} +A user authorization code, obtained via /oauth/authorize +{{< endapi-method-parameter >}} +{{< api-method-parameter name="grant_type" type="string" required=true >}} +Set equal to `authorization_code` if `code` is provided in order to gain user-level access. Otherwise, set equal to `client_credentials` to obtain app-level access only. +{{< 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 >}} + +Store this access_token for later use with auth-required methods. The token should be passed as an HTTP `Authorization` header when making API calls, with the value `Bearer access_token` +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "access_token": "ZA-Yj3aBD8U8Cm7lKUp-lm9O9BmDgdhHzDeqsY8tlL0", + "token_type": "Bearer", + "scope": "read write follow push", + "created_at": 1573979017 +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=400 >}} +{{< api-method-response-example-description >}} + +If you try to request a scope that was not included when registering the app, the request will fail. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "invalid_scope", + "error_description": "The requested scope is invalid, unknown, or malformed." +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +If client_id and client_secret do not match or are invalid, the request will fail. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "invalid_client", + "error_description": "Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method." +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/oauth/revoke" title="Revoke token" >}} +{{< api-method-description >}} + +Revoke an access token to make it no longer valid for use. + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-form-data-parameters >}} +{{< api-method-parameter name="client_id" type="string" required=true >}} +Client ID, obtained during app registration +{{< endapi-method-parameter >}} +{{< api-method-parameter name="client_secret" type="string" required=true >}} +Client secret, obtained during app registration +{{< endapi-method-parameter >}} +{{< api-method-parameter name="token" type="string" required=true >}} +The previously obtained token, to be invalidated +{{< 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 >}} + +If you own the provided token, the API call will provide an empty response. This operation is idempotent, so calling this API multiple times will still return OK. +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=403 >}} +{{< api-method-response-example-description >}} + +If you provide a token you do not own, or no token at all, the API call will return a 403 error. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "unauthorized_client", + "error_description": "You are not authorized to revoke this token" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + +## + diff --git a/content/en/methods/instance.md b/content/en/methods/instance.md new file mode 100644 index 00000000..aa6f1276 --- /dev/null +++ b/content/en/methods/instance.md @@ -0,0 +1,222 @@ +--- +title: instance +description: Informational endpoint to discover information about a Mastodon website. +menu: + docs: + weight: 70 + parent: methods + identifier: methods-instance +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/instance" title="Fetch instance" >}} +{{< api-method-description >}} + +Information about the server. + +**Returns:** Instance\ +**OAuth:** Public\ +**Version history:** + +- 1.1.0 - added +- 3.0.0 - requires user token if instance is in whitelist mode + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript + + "uri": "mastodon.social", + "title": "Mastodon", + "short_description": "Server run by the main developers of the project \"🐘\" It is not focused on any particular niche interest - everyone is welcome as long as you follow our code of conduct!", + "description": "Server run by the main developers of the project \"🐘\" It is not focused on any particular niche interest - everyone is welcome as long as you follow our code of conduct!", + "email": "staff@mastodon.social", + "version": "3.0.1", + "urls": { + "streaming_api": "wss://mastodon.social" + }, + "stats": { + "user_count": 415526, + "status_count": 17085754, + "domain_count": 11834 + }, + "thumbnail": "https://files.mastodon.social/site_uploads/files/000/000/001/original/vlcsnap-2018-08-27-16h43m11s127.png", + "languages": [ + "en" + ], + "registrations": true, + "approval_required": false, + "contact_account": { + "id": "1", + "username": "Gargron", + "acct": "Gargron", + "display_name": "Eugen", + "locked": false, + "bot": false, + "created_at": "2016-03-16T14:34:26.392Z", + "note": "

Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.

", + "url": "https://mastodon.social/@Gargron", + "avatar": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "header": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "followers_count": 317112, + "following_count": 453, + "statuses_count": 60903, + "last_status_at": "2019-11-26T21:14:44.522Z", + "emojis": [], + "fields": [ + { + "name": "Patreon", + "value": "https://www.patreon.com/mastodon", + "verified_at": null + }, + { + "name": "Homepage", + "value": "https://zeonfederated.com", + "verified_at": "2019-07-15T18:29:57.191+00:00" + } + ] + } +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/instance/peers" title="List of connected domains" >}} +{{< api-method-description >}} + +Domains that this instance is aware of. + +**Returns:** Array of String\ +**OAuth:** Public\ +**Version history:** + +- 2.1.2 - added +- 3.0.0 - requires user token if instance is in whitelist mode + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +["tilde.zone","mspsocial.net",...,"conf.tube"] +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/instance/activity" title="Weekly activity" >}} +{{< api-method-description >}} + +Instance activity over the last 3 months, binned weekly. + +**Returns:** Array of Activity\ +**OAuth:** Public\ +**Version history:** + +- 2.1.2 - added +- 3.0.0 - requires user token if instance is in whitelist mode + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +``` +[ + { + "week": "1574640000", + "statuses": "37125", + "logins": "14239", + "registrations": "542" + }, + { + "week": "1574035200", + "statuses": "244447", + "logins": "28820", + "registrations": "4425" + }, + { + "week": "1573430400", + "statuses": "270615", + "logins": "35388", + "registrations": "8781" + }, + { + "week": "1572825600", + "statuses": "309722", + "logins": "44433", + "registrations": "26165" + }, + { + "week": "1572220800", + "statuses": "116227", + "logins": "19739", + "registrations": "2926" + }, + { + "week": "1571616000", + "statuses": "119932", + "logins": "19247", + "registrations": "3188" + }, + { + "week": "1571011200", + "statuses": "117892", + "logins": "19164", + "registrations": "3107" + }, + { + "week": "1570406400", + "statuses": "109092", + "logins": "18763", + "registrations": "2986" + }, + { + "week": "1569801600", + "statuses": "107554", + "logins": "19614", + "registrations": "2904" + }, + { + "week": "1569196800", + "statuses": "118067", + "logins": "19703", + "registrations": "3295" + }, + { + "week": "1568592000", + "statuses": "110199", + "logins": "19791", + "registrations": "3026" + }, + { + "week": "1567987200", + "statuses": "106029", + "logins": "19089", + "registrations": "2769" + } +] +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/instance/custom_emojis.md b/content/en/methods/instance/custom_emojis.md new file mode 100644 index 00000000..bb14f2fa --- /dev/null +++ b/content/en/methods/instance/custom_emojis.md @@ -0,0 +1,81 @@ +--- +title: custom_emojis +description: >- + Each site can define and upload its own custom emoji to be attached to + profiles or statuses. +menu: + docs: + weight: 30 + parent: methods-instance +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/custom_emojis" title="Custom emoji" >}} +{{< api-method-description >}} + +Returns custom emojis that are available on the server. + +**Returns:** Array of Emoji\ +**OAuth:** Public\ +**Version history:** + +- 2.0.0 - added +- 3.0.0 - optional `category` added to response + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample response from mastodon.social +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "shortcode": "aaaa", + "url": "https://files.mastodon.social/custom_emojis/images/000/007/118/original/aaaa.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/007/118/static/aaaa.png", + "visible_in_picker": true + }, + { + "shortcode": "AAAAAA", + "url": "https://files.mastodon.social/custom_emojis/images/000/071/387/original/AAAAAA.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/071/387/static/AAAAAA.png", + "visible_in_picker": true + }, + + // [...] + + { + "shortcode": "blobaww", + "url": "https://files.mastodon.social/custom_emojis/images/000/011/739/original/blobaww.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/011/739/static/blobaww.png", + "visible_in_picker": true, + "category": "Blobs" + }, + + // [...] + + { + "shortcode": "yikes", + "url": "https://files.mastodon.social/custom_emojis/images/000/031/275/original/yikes.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/031/275/static/yikes.png", + "visible_in_picker": true + }, + { + "shortcode": "ziltoid", + "url": "https://files.mastodon.social/custom_emojis/images/000/017/094/original/05252745eb087806.png", + "static_url": "https://files.mastodon.social/custom_emojis/images/000/017/094/static/05252745eb087806.png", + "visible_in_picker": true + } +] +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/instance/directory.md b/content/en/methods/instance/directory.md new file mode 100644 index 00000000..631a09ce --- /dev/null +++ b/content/en/methods/instance/directory.md @@ -0,0 +1,70 @@ +--- +title: directory +description: A directory of profiles that your website is aware of. +menu: + docs: + weight: 20 + parent: methods-instance +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/directory" title="View profile directory" >}} +{{< api-method-description >}} + +List accounts visible in the directory. + +**Returns:** Array of Account\ +**OAuth:** Public\ +**Version history:** + +- 3.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="offset" type="string" required=false >}} +How many accounts to skip before returning results. Default 0. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +How many accounts to load. Default 40. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="order" type="string" required=false >}} +`active` to sort by most recently posted statuses \(default\) or `new` to sort by most recently created profiles. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="local" type="boolean" required=false >}} +Only return local 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 >}} + +Sample results with limit=2 +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "796927", + "username": "eternalNo3", + "acct": "eternalNo3@best-friends.chat", + "display_name": "ESD@┓(谷)┏", + ... + }, + { + "id": "787648", + "username": "ariel", + "acct": "ariel@best-friends.chat", + "display_name": "あやっしー🧜🏻‍♀️", + ... + } +] +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/instance/trends.md b/content/en/methods/instance/trends.md new file mode 100644 index 00000000..8e703232 --- /dev/null +++ b/content/en/methods/instance/trends.md @@ -0,0 +1,82 @@ +--- +title: trends +description: View hashtags that are currently being used more frequently than usual. +menu: + docs: + weight: 10 + parent: methods-instance +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/trends" title="Trending tags" >}} +{{< api-method-description >}} + +Tags that are being used more frequently within the past week. + +**Returns:** Array of Tag with History\ +**OAuth:** Public\ +**Version history:** + +- 3.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="limit" type="number" required=false >}} +Maximum number of results to return. Defaults to 10. +{{< 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 >}} + + +```javascript +[ + { + "name": "hola", + "url": "https://mastodon.social/tags/hola", + "history": [ + { + "day": "1574726400", + "uses": "13", + "accounts": "10" + }, + ... + ] + }, + { + "name": "SaveDotOrg", + "url": "https://mastodon.social/tags/SaveDotOrg", + "history": [ + { + "day": "1574726400", + "uses": "9", + "accounts": "9" + }, + ... + ] + }, + { + "name": "introduction", + "url": "https://mastodon.social/tags/introduction", + "history": [ + { + "day": "1574726400", + "uses": "15", + "accounts": "14" + }, + ... + ] + }, + ... +] +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/notifications.md b/content/en/methods/notifications.md new file mode 100644 index 00000000..515dde20 --- /dev/null +++ b/content/en/methods/notifications.md @@ -0,0 +1,387 @@ +--- +title: notifications +description: Receive notifications for activity on your account or statuses. +menu: + docs: + weight: 50 + parent: methods + identifier: methods-notifications +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/notifications" title="Get all notifications" >}} +{{< api-method-description >}} + +Notifications concerning the user. This API returns Link headers containing links to the next/previous page. However, the links can also be constructed dynamically using query params and `id` values. + +**Returns:** Array of Notification\ +**OAuth:** User token + `read:notifications`\ +**Version history:** + +- 0.0.0 - added +- 2.6.0 - add min_id +- 2.9.0 - add account_id + +{{< 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="max_id" type="string" required=false >}} +Return results older than this ID +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Return results newer than this ID +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than this ID +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +Maximum number of results to return \(default 20\) +{{< endapi-method-parameter >}} +{{< api-method-parameter name="exclude_types" type="array" required=false >}} +Array of types to exclude \(`follow`, `favourite`, `reblog`, `mention`, `poll`\) +{{< endapi-method-parameter >}} +{{< api-method-parameter name="account_id" type="string" required=false >}} +Return only notifications received from this account +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample call with limit=2. Use the Link header for pagination +{{< endapi-method-response-example-description >}} + + +```javascript +Link: ; rel="next", ; + +[ + { + "id": "34975861", + "type": "mention", + "created_at": "2019-11-23T07:49:02.064Z", + "account": { + "id": "971724", + "username": "zsc", + "acct": "zsc", + ... + }, + "status": { + "id": "103186126728896492", + "created_at": "2019-11-23T07:49:01.940Z", + "in_reply_to_id": "103186038209478945", + "in_reply_to_account_id": "14715", + ... + "content": "

@trwnh sup!

", + ... + "account": { + "id": "971724", + "username": "zsc", + "acct": "zsc", + ... + }, + ... + "mentions": [ + { + "id": "14715", + "username": "trwnh", + "url": "https://mastodon.social/@trwnh", + "acct": "trwnh" + } + ], + ... + } + }, + { + "id": "34975535", + "type": "favourite", + "created_at": "2019-11-23T07:29:18.903Z", + "account": { + "id": "297420", + "username": "haskal", + "acct": "haskal@cybre.space", + ... + }, + "status": { + "id": "103186046267791694", + "created_at": "2019-11-23T07:28:34.210Z", + "in_reply_to_id": "103186044372624124", + "in_reply_to_account_id": "297420", + ... + "account": { + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + ... + } + } + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="get" host="https://mastodon.example" path="/api/v1/notifications/:id" title="Get a single notification" >}} +{{< api-method-description >}} + +View information about a notification with a given ID. + +**Returns:** Notification\ +**OAuth:** User token + `read:notifications`\ +**Version history:** + +- 0.0.0 - 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 notification in the database. +{{< 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 single Notification +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "34975861", + "type": "mention", + "created_at": "2019-11-23T07:49:02.064Z", + "account": { + "id": "971724", + "username": "zsc", + "acct": "zsc", + ... + }, + "status": { + "id": "103186126728896492", + "created_at": "2019-11-23T07:49:01.940Z", + "in_reply_to_id": "103186038209478945", + "in_reply_to_account_id": "14715", + ... + "content": "

@trwnh sup!

", + ... + "account": { + "id": "971724", + "username": "zsc", + "acct": "zsc", + ... + }, + ... + "mentions": [ + { + "id": "14715", + "username": "trwnh", + "url": "https://mastodon.social/@trwnh", + "acct": "trwnh" + } + ], + ... + } +}, +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/notifications/clear" title="Dismiss all notifications" >}} +{{< api-method-description >}} + +Clear all notifications from the server. + +**Returns:** empty object\ +**OAuth:** User token + `write:notifications`\ +**Version history:** + +- 0.0.0 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Notifications successfully cleared +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/notifications/:id/dismiss" title="Dismiss a single notification" >}} +{{< api-method-description >}} + +Clear a single notification from the server. + +**Returns:** empty object\ +**OAuth:** User token + `write:notifications`\ +**Version history:** + +- 1.3.0 - 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 notification to be cleared +{{< 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 >}} + +Notification with given ID successfully dismissed +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/notifications/dismiss" title="\(DEPRECATED\) Dismiss a single notification" >}} +{{< api-method-description >}} + +Delete a single notification from the server. + +**Returns:** empty object\ +**OAuth:** User token + `write:notifications`\ +**Version history**: +- 0.0.0 - available +- 3.0.0 - removed + +{{< 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-form-data-parameters >}} +{{< api-method-parameter name="id" type="string" required=true >}} +ID of the notification to be cleared, passed as a parameter +{{< 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 >}} + +Notification with given ID successfully dismissed +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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 >}} + + diff --git a/content/en/methods/notifications/push.md b/content/en/methods/notifications/push.md new file mode 100644 index 00000000..638b52fb --- /dev/null +++ b/content/en/methods/notifications/push.md @@ -0,0 +1,260 @@ +--- +title: push +description: >- + Subscribe to and receive push notifications when a server-side notification is + received, via the Web Push API +menu: + docs: + weight: 10 + parent: methods-notifications +--- + +## Web Push API + +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) + +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/push/subscription" title="Subscribe to push notifications" >}} +{{< api-method-description >}} + +Add a Web Push API subscription to receive notifications. Each access token can have one push subscription. If you create a new subscription, the old subscription is deleted. + +**Returns:** PushSubscription\ +**OAuth:** User token + `push`\ +**Version history:** + +- 2.4.0 - 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-form-data-parameters >}} +{{< api-method-parameter name="subscription\[endpoint\]" type="string" required=true >}} +Endpoint URL that is called when a notification event occurs. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="subscription\[keys\]\[p256dh\]" type="string" required=true >}} +User agent public key. Base64 encoded string of public key of ECDH key using `prime256v1` curve. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="subscription\[keys\]\[auth\]" type="string" required=true >}} +Auth secret. Base64 encoded string of 16 bytes of random data. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[follow\]" type="boolean" required=false >}} +Receive follow notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[favourite\]" type="boolean" required=false >}} +Receive favourite notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[reblog\]" type="boolean" required=false >}} +Receive reblog notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[mention\]" type="boolean" required=false >}} +Receive mention notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[poll\]" type="boolean" required=false >}} +Receive poll notifications? +{{< 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 >}} + +A new PushSubscription has been generated, which will send the requested alerts to your endpoint. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": 328183, + "endpoint": "https://yourdomain.example/listener", + "alerts": { + "follow": true, + "favourite": true, + "reblog": true, + "mention": true, + "poll": true + }, + "server_key": "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/push/subscription" title="Get current subscription" >}} +{{< api-method-description >}} + +View the PushSubscription currently associated with this access token. + +**Returns:** PushSubscription\ +**OAuth:** User token + `push`\ +**Version history:** + +- 2.4.0 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": 328183, + "endpoint": "https://yourdomain.example/listener", + "alerts": { + "follow": true, + "favourite": true, + "reblog": true, + "mention": true, + "poll": true + }, + "server_key": "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +A PushSubscription does not exist for this token. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="put" host="https://mastodon.example" path="/api/v1/push/subscription" title="Change types of notifications" >}} +{{< api-method-description >}} + +Updates the current push subscription. Only the data part can be updated. To change fundamentals, a new subscription must be created instead. + +**Returns:** PushSubscription\ +**OAuth:** User token + `push`\ +**Version history:** + +- 2.4.0 - 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-form-data-parameters >}} +{{< api-method-parameter name="data\[alerts\]\[follow\]" type="boolean" required=false >}} +Receive follow notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[favourite\]" type="boolean" required=false >}} +Receive favourite notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[reblog\]" type="boolean" required=false >}} +Receive reblog notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[mention\]" type="boolean" required=false >}} +Receive mention notifications? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="data\[alerts\]\[poll\]" type="boolean" required=false >}} +Receive poll notifications? +{{< 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 >}} + +Updating a PushSubscription to only receive mention alerts +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": 328183, + "endpoint": "https://yourdomain.example/listener", + "alerts": { + "follow": false, + "favourite": false, + "reblog": false, + "mention": true, + "poll": false + }, + "server_key": "BCk-QqERU0q-CfYZjcuB6lnyyOYfJ2AifKqfeGIm7Z-HiTU5T9eTG5GxVA0_OH5mMlI4UkkDTpaZwozy0TzdZ2M=" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +No existing PushSubscription for this token +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="delete" host="https://mastodon.example" path="/api/v1/push/subscription" title="Remove current subscription" >}} +{{< api-method-description >}} + +Removes the current Web Push API subscription. + +**Returns:** none\ +**OAuth:** User token + `push`\ +**Version history:** + +- 2.4.0 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +PushSubscription successfully deleted or did not exist previously +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/oembed.md b/content/en/methods/oembed.md new file mode 100644 index 00000000..9e29aaea --- /dev/null +++ b/content/en/methods/oembed.md @@ -0,0 +1,75 @@ +--- +title: oembed +description: For generating OEmbed previews. +menu: + docs: + weight: 100 + parent: methods +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/oembed" title="OEmbed as JSON" >}} +{{< api-method-description >}} + +**Returns:** OEmbed metadata\ +**OAuth:** Public\ +**Version history:** + +- 1.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="url" type="string" required=true >}} +URL of a status +{{< endapi-method-parameter >}} +{{< api-method-parameter name="maxwidth" type="number" required=false >}} +width of the iframe. Defaults to 400 +{{< endapi-method-parameter >}} +{{< api-method-parameter name="maxheight" type="number" required=false >}} +height of the iframe. Defaults to null +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Represents OEmbed "rich" preview, with associated iframe and metadata. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "type": "rich", + "version": "1.0", + "title": "New status by trwnh", + "author_name": "infinite love ⴳ", + "author_url": "https://mastodon.social/@trwnh", + "provider_name": "mastodon.social", + "provider_url": "https://mastodon.social/", + "cache_age": 86400, + "html": "", + "width": 400, + "height": null +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status not found +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/proofs.md b/content/en/methods/proofs.md new file mode 100644 index 00000000..939c913b --- /dev/null +++ b/content/en/methods/proofs.md @@ -0,0 +1,68 @@ +--- +title: proofs +description: For use by identity providers. +menu: + docs: + weight: 90 + parent: methods +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/proofs" title="View identity proof" >}} +{{< api-method-description >}} + +**Returns:** custom response defined by provider\ +**OAuth:** Public\ +**Version history:** + +- 2.8.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="provider" type="string" required=false >}} +The identity provider to be looked up. Currently only supports `keybase` \(case-sensitive\) +{{< endapi-method-parameter >}} +{{< api-method-parameter name="username" type="string" required=false >}} +The username on the selected identity provider +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +`gargron` on `keybase` +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "avatar": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "signatures": [ + { + "sig_hash": "5cfc20c7018f2beefb42a68836da59a792e55daa4d118498c9b1898de7e845690f", + "kb_username": "gargron" + } + ] +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +No identity proof found for `username` on `provider` +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/search.md b/content/en/methods/search.md new file mode 100644 index 00000000..2a8772de --- /dev/null +++ b/content/en/methods/search.md @@ -0,0 +1,224 @@ +--- +title: search +description: 'Search for content in accounts, statuses and hashtags.' +menu: + docs: + weight: 60 + parent: methods +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v2/search" title="Search results" >}} +{{< api-method-description >}} + +**Returns:** Results\ +**OAuth:** User token + `read:search`\ +**Version history:** + +- 2.4.1 - added, limit hardcoded to 5 +- 2.8.0 - add type, limit, offset, min_id, max_id, account_id +- 3.0.0 - add `exclude_unreviewed` param + +{{< 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="account_id" type="string" required=false >}} +If provided, statuses returned will be authored only by this account +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Return results older than this id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than this id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="type" type="string" required=false >}} +Enum\(accounts, hashtags, statuses\) +{{< endapi-method-parameter >}} +{{< api-method-parameter name="exclude_unreviewed" type="boolean" required=false >}} +Filter out unreviewed tags? Defaults to false. Use true when trying to find trending tags. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="q" type="string" required=true >}} +The search query +{{< endapi-method-parameter >}} +{{< api-method-parameter name="resolve" type="boolean" required=false >}} +Attempt WebFinger lookup. Defaults to false. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="integer" required=false >}} +Maximum number of results to load, per type. Defaults to 20. Max 40. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="offset" type="integer" required=false >}} +Offset in search results. Used for pagination. Defaults to 0. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="following" type="boolean" required=false >}} +Only include accounts that the user is following. Defaults to 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 >}} + +Truncated results of a sample search for "cats" with limit=2. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "accounts": [ + { + "id": "180744", + "username": "catstar", + "acct": "catstar@catgram.jp", + "display_name": "catstar", + ... + }, + { + "id": "214293", + "username": "catsareweird", + "acct": "catsareweird", + "display_name": "Cats Are Weird", + ... + } + ], + "statuses": [ + { + "id": "103085519055545958", + "created_at": "2019-11-05T13:23:09.000Z", + ... + "content": "

cats
cats never change

", + ... + }, + { + "id": "101068121469614510", + "created_at": "2018-11-14T06:31:48.000Z", + ... + "spoiler_text": "Cats", + ... + "content": "

Cats are inherently good at self-care.

#cats

", + ... + ], + "hashtags": [ + { + "name": "cats", + "url": "https://mastodon.social/tags/cats", + "history": [ + { + "day": "1574553600", + "uses": "10", + "accounts": "9" + }, + ... + ] + }, + { + "name": "catsofmastodon", + "url": "https://mastodon.social/tags/catsofmastodon", + "history": [ + { + "day": "1574553600", + "uses": "6", + "accounts": "5" + }, + ... + ] + } + ] +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="get" host="https://mastodon.example" path="/api/v1/search" title="\(DEPRECATED\) Search results" >}} +{{< api-method-description >}} + +**Returns:** Results, but hashtags is an array of strings instead of an array of Tag.\ +**OAuth:** User token + `read:search`\ +**Version history:**\ +1.1 - added, limit hardcoded to 5 +- 1.5.0 - now requires authentication +- 2.8.0 - added limit, pagination, and account options +- 3.0.0 - removed; use v2 instead + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="q" type="string" required=true >}} +The search query +{{< endapi-method-parameter >}} +{{< api-method-parameter name="resolve" type="string" required=false >}} +Attempt Webfinger lookup. Defaults to false. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +Max number of results to load per type. Defaults to 20 +{{< endapi-method-parameter >}} +{{< api-method-parameter name="type" type="string" required=false >}} +Enum\(accounts,hashtags,statuses\) +{{< endapi-method-parameter >}} +{{< api-method-parameter name="offset" type="string" required=false >}} +Offset in search results. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than this id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Return results older than this id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="account_id" type="string" required=false >}} +Return statuses only from this account +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +v1 search was deprecated because hashtags were returned as strings instead of as Tag entities. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "accounts": [...], + "statuses": [...], + "hashtags": ["cats","catsofmastodon"] +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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 >}} + + diff --git a/content/en/methods/statuses.md b/content/en/methods/statuses.md new file mode 100644 index 00000000..8243950e --- /dev/null +++ b/content/en/methods/statuses.md @@ -0,0 +1,1518 @@ +--- +title: statuses +description: 'Publish, interact, and view information about statuses.' +menu: + docs: + weight: 30 + parent: methods + identifier: methods-statuses +--- + +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses" title="Publish new status" >}} +{{< api-method-description >}} + +Post a new status. + +**Returns:** Status. When `scheduled_at` is present, ScheduledStatus is returned instead.\ +**OAuth:** User + `write:statuses`\ +**Version history:** + +- 0.0.0 - added +- 2.7.0 - `scheduled_at` added +- 2.8.0 - `poll` added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Idempotency-Key" type="string" required=false >}} +Prevent duplicate submissions of the same status. Idempotency keys are stored for up to 1 hour, and can be any arbitrary string. Consider using a hash or UUID generated client-side. +{{< endapi-method-parameter >}} +{{< 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="status" type="string" required=true >}} +Text content of the status. If `media_ids` is provided, this becomes optional. Attaching a `poll` is optional while `status` is provided. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="media_ids\[\]" type="array" required=true >}} +Array of Attachment ids to be attached as media. If provided, `status` becomes optional, and `poll` cannot be used. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="poll\[options\]\[\]" type="array" required=true >}} +Array of possible answers. If provided, `media_ids` cannot be used, and `poll[expires_in]` must be provided. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="poll\[expires_in\]" type="number" required=true >}} +Duration the poll should be open, in seconds. If provided, `media_ids` cannot be used, and `poll[options]` must be provided. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="poll\[multiple\]" type="boolean" required=false >}} +Allow multiple choices? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="poll\[hide_totals\]" type="boolean" required=false >}} +Hide vote counts until the poll ends? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="in_reply_to_id" type="string" required=false >}} +ID of the status being replied to, if status is a reply +{{< endapi-method-parameter >}} +{{< api-method-parameter name="sensitive" type="boolean" required=false >}} +Mark status and attached media as sensitive? +{{< endapi-method-parameter >}} +{{< api-method-parameter name="spoiler_text" type="string" required=false >}} +Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="visibility" type="string" required=false >}} +Visibility of the posted status. Enumerable oneOf public, unlisted, private, direct. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="scheduled_at" type="string" required=false >}} +ISO 8601 Datetime at which to schedule a status. Providing this paramter will cause ScheduledStatus to be returned instead of Status. Must be at least 5 minutes in the future. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="language" type="string" required=false >}} +ISO 639 language code for this status. +{{< 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 >}} + +Status will be posted with chosen parameters. If scheduled_at is provided, then a ScheduledStatus will be returned instead. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="status" >}} +```javascript +{ + "id": "103254962155278888", + "created_at": "2019-12-05T11:34:47.196Z", + ... + "content": "

test content

", + ... + "application": { + "name": "test app", + "website": null + }, + ... +} +``` +{{< endtab >}} + +{{< tab title="scheduled_at ScheduledStatus" >}} +```javascript +{ + "id": "3221", + "scheduled_at": "2019-12-05T12:33:01.000Z", + "params": { + "text": "test content", + "media_ids": null, + "sensitive": null, + "spoiler_text": null, + "visibility": null, + "scheduled_at": null, + "poll": null, + "idempotency": null, + "in_reply_to_id": null, + "application_id": 596551 + }, + "media_attachments": [] +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/statuses/:id" title="View specific status" >}} +{{< api-method-description >}} + +View information about a status. + +**Returns:** Status\ +**OAuth:** Public for public statuses, user token + `read:statuses` for private statuses\ +**Version history:** + +- 0.0.0 - added +- 2.7.0 - public statuses no longer require token + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=false >}} +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 >}} + + +```javascript +{ + "id": "1", + "created_at": "2016-03-16T14:44:31.580Z", + "in_reply_to_id": null, + "in_reply_to_account_id": null, + "sensitive": false, + "spoiler_text": "", + "visibility": "public", + "language": "en", + "uri": "https://mastodon.social/users/Gargron/statuses/1", + "url": "https://mastodon.social/@Gargron/1", + "replies_count": 7, + "reblogs_count": 98, + "favourites_count": 112, + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "content": "

Hello world

", + "reblog": null, + "application": null, + "account": { + "id": "1", + "username": "Gargron", + "acct": "Gargron", + "display_name": "Eugen", + "locked": false, + "bot": false, + "created_at": "2016-03-16T14:34:26.392Z", + "note": "

Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.

", + "url": "https://mastodon.social/@Gargron", + "avatar": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "avatar_static": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg", + "header": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "header_static": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png", + "followers_count": 320472, + "following_count": 453, + "statuses_count": 61163, + "last_status_at": "2019-12-05T03:03:02.595Z", + "emojis": [], + "fields": [ + { + "name": "Patreon", + "value": "https://www.patreon.com/mastodon", + "verified_at": null + }, + { + "name": "Homepage", + "value": "https://zeonfederated.com", + "verified_at": "2019-07-15T18:29:57.191+00:00" + } + ] + }, + "media_attachments": [], + "mentions": [], + "tags": [], + "emojis": [], + "card": null, + "poll": null +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +instance is in whitelist mode +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "This API requires an authenticated user" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="delete" host="https://mastodon.example" path="/api/v1/statuses/:id" title="Delete status" >}} +{{< api-method-description >}} + +Delete one of your own statuses. + +**Returns:** Status with source `text` and `media_attachments` or `poll`\ +**OAuth:** User token + `write:statuses`\ +**Version history:** + +- 0.0.0 - added +- 2.9.0 - return source properties, for use with delete and redraft + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. Must be owned by authenticated 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 >}} + +Note the special properties `text` and `media_attachments` or `poll` which may be used to repost the status, e.g. in case of delete-and-redraft functionality. With POST /api/v1/statuses, use `text` as the value for `status` parameter, `media_attachments[n]["id"]` for the `media_ids` array parameter, and `poll` properties with the corresponding parameters \(e.g. `poll[multiple]` and `poll[options]`, with a new `poll[expires_in]` and `poll[hide_totals]` per user input. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="with media" >}} +```javascript +{ + "id": "103254193998341330", + "created_at": "2019-12-05T08:19:26.052Z", + "in_reply_to_id": null, + "in_reply_to_account_id": null, + "sensitive": false, + "spoiler_text": "", + "visibility": "public", + "language": "en", + "uri": "https://mastodon.social/users/trwnh/statuses/103254193998341330", + "url": "https://mastodon.social/@trwnh/103254193998341330", + "replies_count": 0, + "reblogs_count": 0, + "favourites_count": 0, + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": false, + "text": "test", + "reblog": null, + "application": { + "name": "Web", + "website": null + }, + "account": { + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + "display_name": "infinite love ⴳ", + ... + }, + "media_attachments": [ + { + "id": "22345792", + "type": "image", + "url": "https://files.mastodon.social/media_attachments/files/022/345/792/original/57859aede991da25.jpeg", + "preview_url": "https://files.mastodon.social/media_attachments/files/022/345/792/small/57859aede991da25.jpeg", + "remote_url": null, + "text_url": "https://mastodon.social/media/2N4uvkuUtPVrkZGysms", + "meta": { + "original": { + "width": 640, + "height": 480, + "size": "640x480", + "aspect": 1.3333333333333333 + }, + "small": { + "width": 461, + "height": 346, + "size": "461x346", + "aspect": 1.3323699421965318 + }, + "focus": { + "x": -0.27, + "y": 0.51 + } + }, + "description": "test media description", + "blurhash": "UFBWY:8_0Jxv4mx]t8t64.%M-:IUWGWAt6M}" + } + ], + "mentions": [], + "tags": [], + "emojis": [], + "card": null, + "poll": null +} +``` +{{< endtab >}} + +{{< tab title="with poll" >}} +```javascript +{ + "id": "103254222827484720", + "created_at": "2019-12-05T08:26:45.958Z", + "in_reply_to_id": null, + "in_reply_to_account_id": null, + "sensitive": false, + "spoiler_text": "", + "visibility": "public", + "language": "en", + "uri": "https://mastodon.social/users/trwnh/statuses/103254222827484720", + "url": "https://mastodon.social/@trwnh/103254222827484720", + "replies_count": 0, + "reblogs_count": 0, + "favourites_count": 0, + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": false, + "text": "test", + "reblog": null, + "application": { + "name": "Web", + "website": null + }, + "account": { + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + "display_name": "infinite love ⴳ", + ... + }, + "media_attachments": [], + "mentions": [], + "tags": [], + "emojis": [], + "card": null, + "poll": { + "id": "34858", + "expires_at": "2019-12-06T08:26:45.945Z", + "expired": false, + "multiple": false, + "votes_count": 1, + "voters_count": 1, + "voted": true, + "own_votes": [], + "options": [ + { + "title": "test 1", + "votes_count": 1 + }, + { + "title": "test 2", + "votes_count": 0 + } + ], + "emojis": [] + } +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status already deleted, does not exist, or is not owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/statuses/:id/context" title="Parent and child statuses" >}} +{{< api-method-description >}} + +View statuses above and below this status in the thread. + +**Returns:** Context\ +**OAuth:** Public for public statuses. User token + `read:statuses` for private statuses.\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=false >}} +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 >}} + + +```javascript +{ + "ancestors": [ + { + "id": "103188938570975982", + "created_at": "2019-11-23T19:44:00.124Z", + "in_reply_to_id": null, + "in_reply_to_account_id": null, + ... + }, + { + "id": "103188971072973252", + "created_at": "2019-11-23T19:52:23.398Z", + "in_reply_to_id": "103188938570975982", + "in_reply_to_account_id": "634458", + ... + }, + { + "id": "103188982235527758", + "created_at": "2019-11-23T19:55:08.208Z", + "in_reply_to_id": "103188971072973252", + "in_reply_to_account_id": "14715", + ... + } + ], + "descendants": [ + { + "id": "103189026958574542", + "created_at": "2019-11-23T20:06:36.011Z", + "in_reply_to_id": "103189005915505698", + "in_reply_to_account_id": "634458", + ... + } + ] +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/statuses/:id/reblogged_by" title="Boosted by" >}} +{{< api-method-description >}} + +View who boosted a given status. + +**Returns:** Array of Account\ +**OAuth:** Public +Version history: +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "711345", + "username": "Norman_Doors", + "acct": "Norman_Doors@witches.live", + ... + }, + ... +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/statuses/:id/favourited_by" title="Favourited by" >}} +{{< api-method-description >}} + +View who favourited a given status. + +**Returns:** Array of Account\ +**OAuth:** Public\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "828600", + "username": "fructose_dealer", + "acct": "fructose_dealer@radical.town", + ... + }, + ... +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/favourite" title="Favourite" >}} +{{< api-method-description >}} + +Add a status to your favourites list. + +**Returns:** Status\ +**OAuth:** User token + `write:favourites`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< 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 >}} + +Status favourited or was already favourited +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": true, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": false, + ... +} +``` +{{< 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 >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/unfavourite" title="Undo favourite" >}} +{{< api-method-description >}} + +Remove a status from your favourites list. + +**Returns:** Status\ +**OAuth:** User token + `write:favourites`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< 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 >}} + +Status unfavourited or was already not favourited +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": false, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/reblog" title="Boost" >}} +{{< api-method-description >}} + +Reshare a status. + +**Returns:** Status\ +**OAuth:** User token + `write:statuses`\ +**Version history:** + +- 0.0.0 - added +- 2.8.0 - add visibility parameter + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< 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="visibility" type="string" required=false >}} +any visibility except limited or direct \(i.e. public, unlisted, private\). Defaults to public. Currently unused in UI. +{{< 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 >}} + +Status has been reblogged. Note that the top-level id has changed. The id of the boosted status is now inside the `reblog` property. The top-level id is the id of the reblog itself. Also note that reblogs cannot be pinned. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "103254401326800919", + "created_at": "2019-12-05T09:12:09.625Z", + ... + "favourited": false, + "reblogged": true, + "muted": false, + "bookmarked": false, + ... + "reblog": { + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": true, + "muted": false, + "bookmarked": false, + "pinned": false, + ... + }, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/unreblog" title="Undo boost" >}} +{{< api-method-description >}} + +Undo a reshare of a status. + +**Returns:** Status\ +**OAuth:** User token + `write:statuses`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< 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 >}} + +Status no longer reblogged +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": false, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status deleted, does not exist, or no reblog exists +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/bookmark" title="Bookmark" >}} +{{< api-method-description >}} + +Privately bookmark a status. + +**Returns:** Status\ +**OAuth:** User token + `write:bookmarks`\ +**Version history:** + +- 3.1.0 - 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 status in the database +{{< 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 >}} + +Status bookmarked +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": true, + "pinned": false, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/unbookmark" title="Undo bookmark" >}} +{{< api-method-description >}} + +Remove a status from your private bookmarks. + +**Returns:** Status\ +**OAuth:** User token + `write:bookmarks`\ +**Version history:** + +- 3.1.0 - 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 status in the database +{{< 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 >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": false, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, is private, or was already not bookmarked +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/mute" title="Mute conversation" >}} +{{< api-method-description >}} + +Do not receive notifications for the thread that this status is part of. Must be a thread in which you are a participant. + +**Returns:** Status\ +**OAuth:** User token + `write:mutes`\ +**Version history:** + +- 1.4.2 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< 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 >}} + +Status's conversation muted, or was already muted +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": false, + "muted": true, + "bookmarked": false, + "pinned": false, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/unmute" title="Unmute conversation" >}} +{{< api-method-description >}} + +Start receiving notifications again for the thread that this status is part of. + +**Returns:** Status\ +**OAuth:** User token + `write:mutes`\ +**Version history:** + +- 1.4.2 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< 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 >}} + +Status's conversation unmuted, or was already unmuted +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": false, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/pin" title="Pin to profile" >}} +{{< api-method-description >}} + +Feature one of your own public statuses at the top of your profile. + +**Returns:** Status\ +**OAuth:** User token + `write:accounts`\ +**Version history:** + +- 1.6.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. The status should be public and authored by the authorized 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 >}} + +Status pinned. Note the status is not a reblog and its authoring account is your own. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": true, + ... + "reblog": null, + ... + "account": { + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + ... + }, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or you are not authorized to see it. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +Status is not owned by you, or is not public. You cannot pin one of your private statuses because private statuses cannot be fetched from remote sites, and must be delivered. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="Not yours" >}} +```javascript +{ + "error": "Validation failed: Someone else's toot cannot be pinned" +} +``` +{{< endtab >}} + +{{< tab title="Private" >}} +```javascript +{ + "error": "Validation failed: Non-public toot cannot be pinned" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/statuses/:id/unpin" title="Unpin to profile" >}} +{{< api-method-description >}} + +Unfeature a status from the top of your profile. + +**Returns:** Status\ +**OAuth:** User token + `write:accounts`\ +**Version history:** + +- 1.6.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +Local ID of a status in the database. +{{< 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 >}} + +Status unpinned, or was already not pinned +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "99734435964706331", + "created_at": "2018-03-23T17:38:40.700Z", + ... + "favourited": false, + "reblogged": false, + "muted": false, + "bookmarked": false, + "pinned": false, + ... + "reblog": null, + ... + "account": { + "id": "14715", + "username": "trwnh", + "acct": "trwnh", + ... + }, + ... +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + +## Deprecated methods + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/statuses/:id/card" title="Preview card" >}} +{{< api-method-description >}} + +**Returns:** Card\ +**OAuth:** Public\ +**Version history:** + +- 0.0.0 - added +- 2.6.0 - deprecated in favor of card property inlined on Status entity +- 3.0.0 - removed + +{{< 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 status in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "url": "https://www.youtube.com/watch?v=OMv_EPMED8Y", + "title": "♪ Brand New Friend (Christmas Song!)", + "description": "", + "type": "video", + "author_name": "YOGSCAST Lewis & Simon", + "author_url": "https://www.youtube.com/user/BlueXephos", + "provider_name": "YouTube", + "provider_url": "https://www.youtube.com/", + "html": "", + "width": 480, + "height": 270, + "image": "https://files.mastodon.social/preview_cards/images/014/179/145/original/9cf4b7cf5567b569.jpeg", + "embed_url": "" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Status does not exist, is deleted, or is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/statuses/media.md b/content/en/methods/statuses/media.md new file mode 100644 index 00000000..5a8d3f28 --- /dev/null +++ b/content/en/methods/statuses/media.md @@ -0,0 +1,261 @@ +--- +title: media +description: >- + Attach media to authored statuses. See Using Mastodon > Posting toots > + Attachments for more information about size and format limits. +menu: + docs: + weight: 10 + parent: methods-statuses +--- + +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/media" title="Upload media as attachment" >}} +{{< api-method-description >}} + +Creates an attachment to be used with a new status. + +**Returns:** Attachment\ +**OAuth:** User token + `write:media`\ +**Version history:** + +- 0.0.0 - added +- 2.3.0 - add `focus` parameter + +{{< 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-form-data-parameters >}} +{{< api-method-parameter name="file" type="object" required=true >}} +The file to be attached, using multipart form data. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="description" type="string" required=false >}} +A plain-text description of the media, for accessibility purposes. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="focus" type="string" required=false >}} +Two floating points \(x,y\), comma-delimited, ranging from -1.0 to 1.0 +{{< 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 >}} + +Attachment created successfully. Note that the Attachment will be created even if the file is not understood correctly. +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="file correct" >}} +```javascript +{ + "id": "22348641", + "type": "image", + "url": "https://files.mastodon.social/media_attachments/files/022/348/641/original/cebc6d51be03e509.jpeg", + "preview_url": "https://files.mastodon.social/media_attachments/files/022/348/641/small/cebc6d51be03e509.jpeg", + "remote_url": null, + "text_url": "https://mastodon.social/media/4Zj6ewxzzzDi0g8JnZQ", + "meta": { + "focus": { + "x": -0.69, + "y": 0.42 + }, + "original": { + "width": 640, + "height": 480, + "size": "640x480", + "aspect": 1.3333333333333333 + }, + "small": { + "width": 461, + "height": 346, + "size": "461x346", + "aspect": 1.3323699421965318 + } + }, + "description": "test uploaded via api", + "blurhash": "UFBWY:8_0Jxv4mx]t8t64.%M-:IUWGWAt6M}" +} +``` +{{< endtab >}} + +{{< tab title="file not correct" >}} +```javascript +{ + "id": "22348456", + "type": "unknown", + "url": "https://mastodon.social/files/original/missing.png", + "preview_url": "https://mastodon.social/files/small/missing.png", + "remote_url": null, + "text_url": "https://mastodon.social/media/Ao2nvQoQNHROpKgEyoA", + "meta": { + "focus": { + "x": -0.69, + "y": 0.42 + } + }, + "description": "test uploaded via api", + "blurhash": null +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +File or file type is unsupported or invalid +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Validation failed: File content type is invalid, File is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="put" host="https://mastodon.example" path="/api/v1/media/:id" title="Update attachment" >}} +{{< api-method-description >}} + +Update an Attachment, before it is attached to a status and posted. + +**Returns:** Attachment\ +**OAuth:** User token + `write:media`\ +**Version history:** + +- 0.0.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=true >}} +The id of the Attachment entity to be updated +{{< 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="file" type="object" required=false >}} +The file to be attached, using multipart form data. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="description" type="string" required=false >}} +A plain-text description of the media, for accessibility purposes. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="focus" type="string" required=false >}} +Two floating points \(x,y\), comma-delimited ranging from -1.0 to 1.0 +{{< 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 >}} + + +```javascript +{ + "id": "22348641", + "type": "image", + "url": "https://files.mastodon.social/media_attachments/files/022/348/641/original/e96382f26c72a29c.jpeg", + "preview_url": "https://files.mastodon.social/media_attachments/files/022/348/641/small/e96382f26c72a29c.jpeg", + "remote_url": null, + "text_url": "https://mastodon.social/media/4Zj6ewxzzzDi0g8JnZQ", + "meta": { + "focus": { + "x": -0.42, + "y": 0.69 + }, + "original": { + "width": 640, + "height": 480, + "size": "640x480", + "aspect": 1.3333333333333333 + }, + "small": { + "width": 461, + "height": 346, + "size": "461x346", + "aspect": 1.3323699421965318 + } + }, + "description": "test uploaded via api, but updated", + "blurhash": "UFBWY:8_0Jxv4mx]t8t64.%M-:IUWGWAt6M}" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Attachment does not exist, is deleted, or was not created by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +File or file type is unsupported or invalid +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Validation failed: File content type is invalid, File is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + +## 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/image%20%2856%29.png" caption="A demonstration of various focal points and their coordinates." >}} +{{< figure src="..//assets/image%20%2856%29.png" caption="A demonstration of various focal points and their coordinates." >}} + + diff --git a/content/en/methods/statuses/polls.md b/content/en/methods/statuses/polls.md new file mode 100644 index 00000000..bd3a118f --- /dev/null +++ b/content/en/methods/statuses/polls.md @@ -0,0 +1,231 @@ +--- +title: polls +description: >- + View and vote on polls attached to statuses. To discover poll ID, you will + need to GET a Status first and then check for a `poll` property. +menu: + docs: + weight: 20 + parent: methods-statuses +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/polls/:id" title="View a poll" >}} +{{< api-method-description >}} + +**Returns:** Poll\ +**OAuth:** Public if parent status is public. User token + `read:statuses` if parent status is private.\ +**Version history:** + +- 2.8.0 - 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 poll in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "34830", + "expires_at": "2019-12-05T04:05:08.302Z", + "expired": true, + "multiple": false, + "votes_count": 10, + "voters_count": null, + "voted": true, + "own_votes": [ + 1 + ], + "options": [ + { + "title": "accept", + "votes_count": 6 + }, + { + "title": "deny", + "votes_count": 4 + } + ], + "emojis": [] +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Poll does not exist, or poll's parent status is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/polls/:id/votes" title="Vote on a poll" >}} +{{< api-method-description >}} + +**Returns:** Poll\ +**OAuth:** User token + `write:statuses`\ +**Version history:** + +- 2.8.0 - 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 poll in the database +{{< 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="choices\[\]" type="array" required=true >}} +Array of own votes containing index for each option \(starting from 0\) +{{< 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 >}} + +Poll was voted on +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "34873", + "expires_at": "2019-12-05T11:16:17.426Z", + "expired": false, + "multiple": true, + "votes_count": 5, + "voters_count": null, + "voted": true, + "own_votes": [ + 0, + 2, + 4, + 9, + 6 + ], + "options": [ + { + "title": "option 0", + "votes_count": 1 + }, + { + "title": "option 1", + "votes_count": 0 + }, + { + "title": "option 2", + "votes_count": 1 + }, + { + "title": "option 3", + "votes_count": 0 + }, + { + "title": "option 4", + "votes_count": 1 + }, + { + "title": "option 5", + "votes_count": 0 + }, + { + "title": "option 6", + "votes_count": 1 + }, + { + "title": "option 7", + "votes_count": 0 + }, + { + "title": "option 8", + "votes_count": 0 + }, + { + "title": "option 9", + "votes_count": 1 + } + ], + "emojis": [] +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +Poll does not exist, or poll's parent status is private +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +Already voted or poll is expired +{{< endapi-method-response-example-description >}} + + +{{< tabs >}} +{{< tab title="already voted" >}} +```javascript +{ + "error": "Validation failed: You have already voted on this poll" +} +``` +{{< endtab >}} + +{{< tab title="expired" >}} +```javascript +{ + "error": "Validation failed: The poll has already ended" +} +``` +{{< endtab >}} +{{< endtabs >}} +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/statuses/scheduled_statuses.md b/content/en/methods/statuses/scheduled_statuses.md new file mode 100644 index 00000000..dfc8dd3b --- /dev/null +++ b/content/en/methods/statuses/scheduled_statuses.md @@ -0,0 +1,311 @@ +--- +title: scheduled_statuses +description: Schedule statuses for your instance to publish later. +menu: + docs: + weight: 30 + parent: methods-statuses +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/scheduled_statuses" title="View scheduled statuses" >}} +{{< api-method-description >}} + +**Returns:** Array of ScheduledStatus\ +**OAuth:** User token + `read:statuses`\ +**Version history:** + +- 2.7.0 - 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="limit" type="number" required=false >}} +Max number of results to return. Defaults to 20. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Return results older than ID +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Return results newer than ID +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than ID +{{< 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 >}} + + +```javascript +[ + { + "id": "3221", + "scheduled_at": "2019-12-05T12:33:01.000Z", + "params": { + "poll": null, + "text": "test content", + "media_ids": null, + "sensitive": null, + "visibility": null, + "idempotency": null, + "scheduled_at": null, + "spoiler_text": null, + "application_id": 596551, + "in_reply_to_id": null + }, + "media_attachments": [] + } +] +``` +{{< 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 >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/scheduled_statuses/:id" title="View a single scheduled status" >}} +{{< api-method-description >}} + +**Returns:** ScheduledStatus\ +**OAuth:** User token + `read:statuses`\ +**Version history:** + +- 2.7.0 - 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 scheduled status in the database. +{{< 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 >}} + + +```javascript +{ + "id": "3221", + "scheduled_at": "2019-12-05T12:33:01.000Z", + "params": { + "poll": null, + "text": "test content", + "media_ids": null, + "sensitive": null, + "visibility": null, + "idempotency": null, + "scheduled_at": null, + "spoiler_text": null, + "application_id": 596551, + "in_reply_to_id": null + }, + "media_attachments": [] +} +``` +{{< 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 >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="put" host="https://mastodon.example" path="/api/v1/scheduled_statuses/:id" title="Schedule a status" >}} +{{< api-method-description >}} + +**Returns:** ScheduledStatus\ +**OAuth:** User token + `write:statuses`\ +**Version history:** + +- 2.7.0 - 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 Status to be scheduled +{{< 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="scheduled_at" type="string" required=false >}} +ISO 8601 Datetime at which the status will be published. Must be at least 5 minutes into the future. +{{< 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 >}} + + +```javascript +{ + "id": "3221", + "scheduled_at": "2019-12-05T13:33:01.000Z", + "params": { + "poll": null, + "text": "test content", + "media_ids": null, + "sensitive": null, + "visibility": null, + "idempotency": null, + "scheduled_at": null, + "spoiler_text": null, + "application_id": 596551, + "in_reply_to_id": null + }, + "media_attachments": [] +} +``` +{{< 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 >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Validation failed: Scheduled at The scheduled date must be in the future" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="delete" host="https://mastodon.example" path="/api/v1/scheduled_statuses/:id" title="Cancel a scheduled status" >}} +{{< api-method-description >}} + +**Returns:** empty object\ +**OAuth:** User token + `write:statuses`\ +**Version history:** + +- 2.7.0 - 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 scheduled status in the database. +{{< 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 >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +No ScheduledStatus at that id, or you do not own it +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/timelines.md b/content/en/methods/timelines.md new file mode 100644 index 00000000..8cbe6898 --- /dev/null +++ b/content/en/methods/timelines.md @@ -0,0 +1,414 @@ +--- +title: timelines +description: Read and view timelines of statuses. +menu: + docs: + weight: 40 + parent: methods + identifier: methods-timelines +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/timelines/public" title="Public timeline" >}} +{{< api-method-description >}} + +**Returns:** Array of Status\ +**OAuth:** Public. Requires app token + `read:statuses` if the instance has disabled public preview.\ +**Version history:** + +- 0.0.0 - added +- 2.3.0 - added `only_media` +- 2.6.0 - add `min_id` +- 3.0.0 - auth is required if public preview is disabled + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="local" type="boolean" required=false >}} +Show only local statuses? Defaults to false. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="only_media" type="boolean" required=false >}} +Show only statuses with media attached? Defaults to false. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Return results older than this id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Return results newer than this id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than this id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="integer" required=false >}} +Maximum number of results to return. Defaults to 20. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample API call with limit=2 +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "103206804533200177", + "created_at": "2019-11-26T23:27:31.000Z", + ... + "visibility": "public", + ... + }, + { + "id": "103206804086086361", + "created_at": "2019-11-26T23:27:32.000Z", + ... + "visibility": "public", + ... + } +] +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/timelines/tag/:hashtag" title="Hashtag timeline" >}} +{{< api-method-description >}} + +View public statuses containing the given hashtag. + +**Returns:** Array of Status\ +**OAuth:** Public. Requires app token + `read:statuses` if the instance has disabled public preview.\ +**Version history:** + +- 0.0.0 - added +- 2.3.0 - added `only_media` +- 2.6.0 - add `min_id` +- 3.0.0 - auth is required if public preview is disabled + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":hashtag" type="string" required=true >}} +Content of a \#hashtag, not including \# symbol. +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< api-method-query-parameters >}} +{{< api-method-parameter name="local" type="boolean" required=false >}} +If true, return only local statuses. Defaults to false. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="only_media" type="boolean" required=false >}} +If true, return only statuses with media attachments. Defaults to false. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Return results older than this ID. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Return results newer than this ID. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than this ID. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="integer" required=false >}} +Maximum number of results to return. Defaults to 20. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Sample timeline for the hashtag \#cats and limit=2 +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "103206185588894565", + "created_at": "2019-11-26T20:50:15.866Z", + ... + "visibility": "public", + ... + "content": "

#cats

", + ... + "tags": [ + { + "name": "cats", + "url": "https://mastodon.social/tags/cats" + } + ], + ... + }, + { + "id": "103203659567597966", + "created_at": "2019-11-26T10:07:49.000Z", + ... + "visibility": "public", + ... + "content": "

Caught on the hop. 😺

#Qualitätskatzen #cats #mastocats #catsofmastodon #Greece #Agistri
(photo: @kernpanik | license: CC BY-NC-SA 4.0)

", + ... + "tags": [ + { + "name": "qualitätskatzen", + "url": "https://mastodon.social/tags/qualit%C3%A4tskatzen" + }, + { + "name": "cats", + "url": "https://mastodon.social/tags/cats" + }, + { + "name": "mastocats", + "url": "https://mastodon.social/tags/mastocats" + }, + { + "name": "catsofmastodon", + "url": "https://mastodon.social/tags/catsofmastodon" + }, + { + "name": "greece", + "url": "https://mastodon.social/tags/greece" + }, + { + "name": "agistri", + "url": "https://mastodon.social/tags/agistri" + } + ], + ... + } +] +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/timelines/home" title="Home timeline" >}} +{{< api-method-description >}} + +View statuses from followed users. + +**Returns:** Array of Status\ +**OAuth:** User + `read:statuses`\ +**Version history:** + +- 0.0.0 - added +- 2.6.0 - add `min_id` + +{{< 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="max_id" type="string" required=false >}} +Return results older than id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Return results newer than id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than id +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="string" required=false >}} +Maximum number of results to return. Defaults to 20. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="local" type="boolean" required=false >}} +Return only local statuses? +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Statuses in your home timeline will be returned +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "103206791453397862", + "created_at": "2019-11-26T23:24:13.113Z", + ... + }, + ... +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=206 >}} +{{< api-method-response-example-description >}} + +Home feed is regenerating +{{< endapi-method-response-example-description >}} + + +``` + +``` +{{< 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 >}} +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/timelines/list/:list_id" title="List timeline" >}} +{{< api-method-description >}} + +View statuses in the given list timeline. + +**Returns:** Array of Status\ +**OAuth:** User token + `read:lists`\ +**Version history:** + +- 2.1.0 - added +- 2.6.0 - add `min_id` + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":list_id" type="string" required=true >}} +Local ID of the list in the database. +{{< 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-query-parameters >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Return results older than this ID. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Return results newer than this ID. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than this ID. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="integer" required=false >}} +Maximum number of results to return. Defaults to 20.Return results older than this ID. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Statuses in this list will be returned. +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "103206791453397862", + "created_at": "2019-11-26T23:24:13.113Z", + ... + }, + ... +] +``` +{{< 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 >}} +{{< api-method method="get" host="" path="/api/v1/timelines/direct" title="\[DEPRECATED\] Direct timeline" >}} +{{< api-method-description >}} + +View statuses with a "direct" privacy, from your account or in your notifications. + +**Returns:** Array of Status\ +**OAuth:** User token + `read:statuses`\ +**Version history:**\ +x.x.x - added +- 2.6.0 - add `min_id`. deprecated in favor of conversations +- 3.0.0 - removed + +{{< 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="limit" type="string" required=false >}} +Maximum number of results to return. Defaults to 20. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Return results older than ID +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Return results newer than ID +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than ID +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Statuses with direct visibility, authored by you or mentioning you. Statuses are not grouped by conversation, but are simply returned in chronological order. +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "103206185588894565", + "created_at": "2019-11-26T20:50:15.866Z", + ... + "visibility": "direct", + ... + }, + ... +] +``` +{{< 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/timelines/conversations.md b/content/en/methods/timelines/conversations.md new file mode 100644 index 00000000..97024a14 --- /dev/null +++ b/content/en/methods/timelines/conversations.md @@ -0,0 +1,251 @@ +--- +title: conversations +description: >- + Direct conversations with other participants. (Currently, just threads + containing a post with "direct" visibility.) +menu: + docs: + weight: 10 + parent: methods-timelines +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/conversations" title="Show conversation" >}} +{{< api-method-description >}} + +**Returns:** Array of Conversation\ +**OAuth:** User token + `read:statuses`\ +**Version history:** + +- 2.6.0 - 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="limit" type="string" required=false >}} +Maximum number of results. Defaults to 20. Max 40. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Return results older than this ID. Use HTTP Link header to paginate. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Return results newer than this ID. Use HTTP Link header to paginate. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="min_id" type="string" required=false >}} +Return results immediately newer than this ID. Use HTTP Link header to paginate. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Truncated sample results of an API call with limit=2 +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "418450", + "unread": true, + "accounts": [ + { + "id": "482403", + "username": "amic", + "acct": "amic@nulled.red", + ... + } + ], + "last_status": { + "id": "103196583826321184", + "created_at": "2019-11-25T04:08:24.000Z", + "in_reply_to_id": "103196540587943467", + "in_reply_to_account_id": "14715", + ... + } + }, + { + "id": "418374", + "unread": false, + "accounts": [ + { + "id": "464472", + "username": "freon", + "acct": "freon@letsalllovela.in", + ... + } + ], + "last_status": { + "id": "103195253010396431", + "created_at": "2019-11-24T22:29:56.331Z", + "in_reply_to_id": "103195239650546339", + "in_reply_to_account_id": "14715", + ... + } + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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/conversations/:id" title="Remove conversation" >}} +{{< api-method-description >}} + +**Returns:** empty object\ +**OAuth:** User token + `write:conversations`\ +**Version history:** + +- 2.6.0 - 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 conversation in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=true >}} +{{< endapi-method-parameter >}} +{{< endapi-method-headers >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +An empty object will be returned. +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authentication header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +The conversation does not exist, or is not owned by you. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/conversations/:id/read" title="Mark as read" >}} +{{< api-method-description >}} + +**Returns:** Conversation\ +**OAuth:** User token + `write:conversations`\ +**Version history:** + +- 2.6.0 - added + +{{< endapi-method-description >}} +{{< api-method-spec >}} +{{< api-method-request >}} +{{< api-method-path-parameters >}} +{{< api-method-parameter name=":id" type="string" required=false >}} +ID of the conversation in the database +{{< endapi-method-parameter >}} +{{< endapi-method-path-parameters >}} +{{< api-method-headers >}} +{{< api-method-parameter name="Authorization" type="string" required=true >}} +{{< endapi-method-parameter >}} +{{< endapi-method-headers >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +The value of `unread` has been changed to false. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "418450", + "unread": false, + "accounts": [ + { + "id": "482403", + ... + } + ], + "last_status": { + "id": "103196583826321184", + ... + } +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +The conversation does not exist, or is not owned by you. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/timelines/lists.md b/content/en/methods/timelines/lists.md new file mode 100644 index 00000000..3fa24a30 --- /dev/null +++ b/content/en/methods/timelines/lists.md @@ -0,0 +1,578 @@ +--- +title: lists +description: >- + View and manage lists. See also: /api/v1/timelines/list/id for loading a list + timeline. +menu: + docs: + weight: 20 + parent: methods-timelines +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/lists" title="Show user's lists" >}} +{{< api-method-description >}} + +Fetch all lists that the user owns. + +**Returns:** Array of List\ +**OAuth:** User token + `read:lists`\ +**Version history:** + +- 2.1.0 - 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 >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +Use id as a parameter for related API calls. +{{< endapi-method-response-example-description >}} + + +```javascript +[ + { + "id": "12249", + "title": "Friends" + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="get" host="https://mastodon.example" path="/api/v1/lists/:id" title="Show a single list" >}} +{{< api-method-description >}} + +Fetch the list with the given ID. Used for verifying the title of a list. + +**Returns:** List\ +**OAuth:** User token + `read:lists`\ +**Version history:** + +- 2.1.0 - 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 list in the database +{{< 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 >}} + +The list 12249 exists and is owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "12249", + "title": "Friends" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +If the ID does not exist or is not owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/lists" title="Create a list" >}} +{{< api-method-description >}} + +Create a new list. + +**Returns:** List\ +**OAuth:** User token + `write:lists`\ +**Version history:** + +- 2.1.0 - 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-form-data-parameters >}} +{{< api-method-parameter name="title" type="string" required=true >}} +The title of the list to be created. +{{< 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 >}} + +A list was created successfully with title=test +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "13585", + "title": "test" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="put" host="https://mastodon.example" path="/api/v1/lists/:id" title="Update a list" >}} +{{< api-method-description >}} + +Change the title of a list. + +**Returns:** List\ +**OAuth:** User token + `write:lists`\ +**Version history:** + +- 2.1.0 - 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 list in the database +{{< 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="title" type="string" required=true >}} +The title of the list to be updated. +{{< 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 >}} + +The title of list 13585 was successfully updated to title=testing +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "id": "13585", + "title": "testing" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +If the title is blank +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Validation failed: Title can't be blank" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="delete" host="https://mastodon.example" path="/api/v1/lists/:id" title="Delete a list" >}} +{{< api-method-description >}} + +**Returns:** empty object\ +**OAuth:** User token + `write:lists`\ +**Version history:** + +- 2.1.0 - 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 list in the database +{{< 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 >}} + +An empty object will be returned if the list was successfully deleted +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +ID does not exist or is not owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + +## Accounts in a list + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/lists/:id/accounts" title="View accounts in list" >}} +{{< api-method-description >}} + +**Returns:** Array of Account\ +**OAuth:** User token + `read:lists`\ +**Version history:** + +- 2.1.0 - 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 list in the database +{{< 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-query-parameters >}} +{{< api-method-parameter name="max_id" type="string" required=false >}} +Internal parameter. Use HTTP Link header for pagination. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="since_id" type="string" required=false >}} +Internal parameter. Use HTTP Link header for pagination. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="limit" type="number" required=false >}} +Maximum number of results. Defaults to 40. Max 40. Set to 0 in order to get all accounts without pagination. Pagination is done with the HTTP Link header. +{{< 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 >}} + + +```javascript +[ + { + "id": "952529", + ... + }, + { + "id": "917388", + ... + }, + { + "id": "869022", + ... + }, + { + "id": "832844", + ... + }, + { + "id": "482403", + ... + } +] +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +The list ID does not exist or is not owned by you +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="post" host="https://mastodon.example" path="/api/v1/lists/:id/accounts" title="Add accounts to list" >}} +{{< api-method-description >}} + +Add accounts to the given list. Note that the user must be following these accounts. + +**Returns:** empty object\ +**OAuth:** User token + `write:lists`\ +**Version history:** + +- 2.1.0 - 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 list in the database +{{< 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="account_ids" type="array" required=true >}} +Array of account IDs to add to the list. +{{< 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 >}} + + +```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 >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +You are not following a given account ID, or you do not own the list ID, or list/account ID does not exist +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=422 >}} +{{< api-method-response-example-description >}} + +Account is already in list +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Validation failed: Account has already been taken" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} +{{< api-method method="delete" host="https://mastodon.example" path="/api/v1/lists/:id/accounts" title="Remove accounts from list" >}} +{{< api-method-description >}} + +Remove accounts from the given list. + +**Returns:** empty object\ +**OAuth:** User token + `write:lists`\ +**Version history:** + +- 2.1.0 - 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 list in the database +{{< 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="account_ids" type="array" required=true >}} +Array of account IDs to remove from the list. +{{< 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 >}} + +Account was successfully removed from the list, or it was already not in the list. +{{< endapi-method-response-example-description >}} + + +```javascript +{} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=404 >}} +{{< api-method-response-example-description >}} + +List ID is not owned by you or does not exist +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Record not found" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/timelines/markers.md b/content/en/methods/timelines/markers.md new file mode 100644 index 00000000..07b37bff --- /dev/null +++ b/content/en/methods/timelines/markers.md @@ -0,0 +1,146 @@ +--- +title: markers +description: Save and restore your position in timelines. +menu: + docs: + weight: 30 + parent: methods-timelines +--- + +{{< api-method method="get" host="https://mastodon.example" path="/api/v1/markers" title="Get saved timeline position" >}} +{{< api-method-description >}} + +**Returns:** Marker\ +**OAuth:** User token + `read:statuses`\ +**Version history:** + +- 3.0.0 - 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="timeline" type="array" required=true >}} +Array of markers to fetch. String enum anyOf `home`, `notifications`. If not provided, an empty object will be returned. +{{< endapi-method-parameter >}} +{{< endapi-method-query-parameters >}} +{{< endapi-method-request >}} +{{< api-method-response >}} +{{< api-method-response-example httpCode=200 >}} +{{< api-method-response-example-description >}} + +timeline\[\] = \["home", "notifications"\] +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "notifications": { + "last_read_id": "35098814", + "version": 361, + "updated_at": "2019-11-26T22:37:25.239Z" + }, + "home": { + "last_read_id": "103206604258487607", + "version": 468, + "updated_at": "2019-11-26T22:37:25.235Z" + } +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing 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="post" host="https://mastodon.example" path="/api/v1/markers" title="Save position in timeline" >}} +{{< api-method-description >}} + +**Returns:** Marker\ +**OAuth:** User token + `write:statuses`\ +**Version history:** + +- 3.0.0 - 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-form-data-parameters >}} +{{< api-method-parameter name="home\[last_read_id\]" type="string" required=false >}} +ID of the last status read in the home timeline. +{{< endapi-method-parameter >}} +{{< api-method-parameter name="notifications\[last_read_id\]" type="string" required=false >}} +ID of the last notification read. +{{< 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 >}} + +Calling this API with home\[last_read_id\] causes a marker to be created for the home timeline. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "home": { + "last_read_id": "103194548672408537", + "version": 462, + "updated_at": "2019-11-24T19:39:39.337Z" + } +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=401 >}} +{{< api-method-response-example-description >}} + +Invalid or missing Authorization header +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "The access token is invalid" +} +``` +{{< endapi-method-response-example >}} +{{< api-method-response-example httpCode=409 >}} +{{< api-method-response-example-description >}} + +If object is stale while being updated, an error will occur. +{{< endapi-method-response-example-description >}} + + +```javascript +{ + "error": "Conflict during update, please try again" +} +``` +{{< endapi-method-response-example >}} +{{< endapi-method-response >}} +{{< endapi-method-spec >}} +{{< endapi-method >}} + + diff --git a/content/en/methods/timelines/streaming.md b/content/en/methods/timelines/streaming.md new file mode 100644 index 00000000..50bdc00f --- /dev/null +++ b/content/en/methods/timelines/streaming.md @@ -0,0 +1,91 @@ +--- +title: streaming +description: >- + Subscribe to server-sent events for real-time updates via a long-lived HTTP + connection or via WebSocket. +menu: + docs: + weight: 40 + parent: methods-statuses +--- + +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/health + +Returns `OK` when streaming service is fine. Added in 2.5.0 + +#### 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: + +```text +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/status.md" >}}) | +| `notification` | A new notification has appeared | [Notification]({{< relref "../../entities/notification.md" >}}) | +| `delete` | A status has been deleted | ID of the deleted status | +| `filters_changed` | Keyword filters have been changed | | + +The payload is JSON-encoded. + +{{< hint style="info" >}} + +In case of `filters_changed` event, `payload` is not defined. +{{< /hint >}} + + diff --git a/content/en/spec/activitypub.md b/content/en/spec/activitypub.md new file mode 100644 index 00000000..0ba4c85e --- /dev/null +++ b/content/en/spec/activitypub.md @@ -0,0 +1,360 @@ +--- +title: ActivityPub +description: >- + A decentralized social networking protocol based upon the ActivityStreams 2.0 + data format and JSON-LD. +menu: + docs: + weight: 10 + parent: spec +--- + +{{< hint style="warning" >}} +Sample payloads will be added at a future date. +{{< /hint >}} + +## Status federation + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/activity.rb" caption="app/lib/activitypub/activity.rb" >}} + +### Supported activities for statuses + +* Create = transformed into a status and saved into database +* Delete = removes a status from the database +* Like = transformed into a favourite on a status +* Announce = transformed into a boost on a status +* Flag = transformed into a report to the moderation team. +* Update = only supported on polls. Used to refresh vote count. +* Undo = undo a previous Like or Announce. + +### Payloads + +The first-class Object types supported by Mastodon are `Note` and `Question`. + +* Notes are transformed into regular statuses. +* Questions are transformed into a poll status. + +Some other Object types are converted as best as possible. The transformer uses `content` if available, or `name` if not, in order to generate status text. The `url` will be appended. The `summary` property will be used as the CW text. + +* Article +* Page +* Image +* Audio +* Video +* Event + +## Profile federation + +### Supported activities for profiles + +* Follow = Indicate interest in receiving status updates from a profile. +* Accept/Reject = used to approve or deny Follow activities. Unlocked accounts will automatically reply with an Accept, while locked accounts can manually choose whether to approve or deny a follow request. +* Add/Remove = manage pinned posts and featured collections. +* Block = Signal to a remote server that they should hide your profile from that user. Not guaranteed. +* Flag = report user +* Update = refresh account details +* Move = migrate followers from one account to another. Requires alsoKnownAs to be set in both directions. +* Delete = remove an account from the database, as well as all of their statuses. +* Undo = undo a previous Follow, Accept Follow, or Block. + +### Properties used + +| Property | Interpretation | +| :--- | :--- | +| preferredUsername | Used for Webfinger lookup. Must be unique on the domain, and must correspond to a Webfinger `acct:` URI. | +| name | Used as profile display name. | +| summary | Used as profile bio. | +| type | Assumed to be Person. If type is Application or Service, it will be interpreted as a bot flag. | +| url | Used as profile link. | +| icon | Used as profile avatar. | +| image | Used as profile header. | +| manuallyApprovesFollowers | Will be shown as a locked account. | +| discoverable | Will be shown in the profile directory. See [Discoverability flag](activitypub.md#discoverable). | +| publicKey | Required for signatures. See [Public key](activitypub.md#public-key). | +| featured | Pinned posts. See [Featured collection](activitypub.md#featured). | +| attachment | Used for profile fields. See [Profile metadata](activitypub.md#profile-metadata) and [Identity proofs](activitypub.md#identityproof). | +| alsoKnownAs | Required for Move activity. | + +## HTML sanitization + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/lib/sanitize_config.rb" caption="app/lib/sanitize\_config.rb" >}} + + Mastodon sanitizes incoming HTML in order to not break assumptions for API client developers. Supported elements include `

`, ``, `
`, and ``. Unsupported elements will be converted to `

`.The sanitizer will keep classes if they begin with microformats prefixes or are semantic classes: + +* h-\* +* p-\* +* u-\* +* dt-\* +* e-\* +* mention +* hashtag +* ellipsis +* invisible + +## JSON-LD Namespacing + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/adapter.rb" caption="app/lib/activitypub/adapter.rb" >}} + +### Mastodon extensions \(`toot:`\) + +Contains definitions for Mastodon features. + +* toot:Emoji +* toot:IdentityProof +* toot:blurhash +* toot:focalPoint +* toot:featured +* toot:discoverable +* toot:votersCount + +### ActivityStreams extensions \(`as:`\) + +Contains ActivityStreams extended properties that have been proposed but not officially adopted yet. + +* as:Hashtag +* as:alsoKnownAs +* as:manuallyApprovesFollowers +* as:movedTo +* as:sensitive + +### W3ID Security Vocabulary \(`sec:`\) + +Contains properties used for HTTPS Signatures and Linked Data Signatures. Also used for identity proofs. See [Security](security.md) for more information. + +* sec:publicKey +* sec:publicKeyPem +* sec:owner +* sec:signature +* sec:signatureValue + +#### W3ID Identity + +Contains a collection of terms from various namespaces, used for Linked Data Signatures. + +* dc:creator +* dc:created +* sec:signature +* sec:signatureValue + +### schema.org extensions \(`schema:`\) + +Contains properties used for profile metadata. + +* schema:PropertyValue +* schema:value + +## Extensions + +### Public key + +Public keys are used for HTTPS Signatures and Linked Data Signatures. This is implemented using an extra property `publicKey` on actor objects. See [Security](security.md) for more information. Example: + +```javascript +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1" + ], + "id": "https://mastodon.social/users/Gargron", + "type": "Person", + "publicKey": { + "id": "https://mastodon.social/users/Gargron#main-key", + "owner": "https://mastodon.social/users/Gargron", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXc4vkECU2/CeuSo1wtn\nFoim94Ne1jBMYxTZ9wm2YTdJq1oiZKif06I2fOqDzY/4q/S9uccrE9Bkajv1dnkO\nVm31QjWlhVpSKynVxEWjVBO5Ienue8gND0xvHIuXf87o61poqjEoepvsQFElA5ym\novljWGSA/jpj7ozygUZhCXtaS2W5AD5tnBQUpcO0lhItYPYTjnmzcc4y2NbJV8hz\n2s2G8qKv8fyimE23gY1XrPJg+cRF+g4PqFXujjlJ7MihD9oqtLGxbu7o1cifTn3x\nBfIdPythWu5b4cujNsB3m3awJjVmx+MHQ9SugkSIYXV0Ina77cTNS0M2PYiH1PFR\nTwIDAQAB\n-----END PUBLIC KEY-----\n" + } +} +``` + +### Featured collection + +What is known in Mastodon as “pinned toots”, or statuses that are always featured at the top of people’s profiles, is implemented using an extra property `featured` on the actor object that points to a `Collection` of objects. Example: + +```javascript +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "toot": "http://joinmastodon.org/ns#", + "featured": { + "@id": "toot:featured", + "@type": "@id" + } + } + ], + + "id": "https://example.com/@alice", + "type": "Person", + "featured": "https://example.com/@alice/collections/featured" +} +``` + +### Custom emojis + +Mastodon supports arbitrary emojis, that is, small images uploaded by admins and invokable via shortcodes. For this, an `Emoji` type is used. These emojis are listed in the `tag` property just like `Mention` and `Hashtag` objects, since they are entities that affect how the text is rendered. Example: + +```javascript +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji" + } + ], + + "id": "https://example.com/@alice/hello-world", + "type": "Note", + "content": "Hello world :kappa:", + "tag": [ + { + "id": "https://example.com/emoji/123", + "type": "Emoji", + "name": ":kappa:", + "icon": { + "type": "Image", + "mediaType": "image/png", + "url": "https://example.com/files/kappa.png" + } + } + ] +} +``` + +### Focal points + +Mastodon supports setting a focal point on uploaded images, so that wherever that image is displayed, the focal point stays in view. This is implemented using an extra property `focalPoint` on `Image` objects. The property is simply an array of two floating points between -1.0 and 1.0, with 0,0 being the center of the image, the first value being x \(-1.0 is the left edge, +1.0 is the right edge\) and the second value being y \(-1.0 is the bottom edge, +1.0 is the top edge\). See [Focal points](../methods/statuses/media.md#focal-points) for more information. Example: + +```javascript +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "toot": "http://joinmastodon.org/ns#", + "focalPoint": { + "@container": "@list", + "@id": "toot:focalPoint" + } + } + ], + + "id": "https://example.com/@alice/hello-world", + "type": "Note", + "content": "A picture attached!", + "attachment": [ + { + "type": "Image", + "mediaType": "image/png", + "url": "https://example.com/files/cats.png", + "focalPoint": [ + -0.55, + 0.43 + ] + } + ] +} +``` + +### Blurhash + +Mastodon generates colorful preview thumbnails for attachments. This is implemented using an extra property `blurhash` on `Image` objects. The property is a string generated by the [BlurHash algorithm](https://blurha.sh). Example: + +```javascript +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "toot": "http://joinmastodon.org/ns#", + "blurhash": "toot:blurhash" + } + ], + + "id": "https://example.com/@alice/hello-world", + "type": "Note", + "content": "A picture attached!", + "attachment": [ + { + "type": "Image", + "mediaType": "image/png", + "url": "https://example.com/files/cats.png", + "blurhash": "UBL_:rOpGG-oBUNG,qRj2so|=eE1w^n4S5NH" + } + ] +} +``` + +### Profile metadata + +Mastodon supports arbitrary profile fields containing name-value pairs. This is implemented using the `attachment` property on actor objects, with objects in the array having a type of `PropertyValue` and a `value` property, both from the schema.org namespace. Example: + +```javascript +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "PropertyValue": "schema:PropertyValue", + "value": "schema:value" + } + ], + "id": "https://mastodon.social/users/Gargron", + "type": "Person", + "attachment": [ + { + "type": "PropertyValue", + "name": "Patreon", + "value": "https://www.patreon.com/mastodon" + }, + { + "type": "PropertyValue", + "name": "Homepage", + "value": "https://zeonfederated.com" + } + ] +} +``` + +### Identity proofs + +Mastodon supports integration with identity providers to prove that a profile is linked to a certain identity. This is implemented using the `attachment` property on actor objects, with objects in the array having a type of `IdentityProof` from the Mastodon namespace. The object also includes `signatureAlgorithm` and `signatureValue` from the W3ID Security Vocabulary namespace. Example: + +```javascript +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "toot": "http://joinmastodon.org/ns#", + "IdentityProof": "toot:IdentityProof" + } + ], + "id": "https://mastodon.social/users/Gargron", + "type": "Person", + "attachment": [ + { + "type": "IdentityProof", + "name": "gargron", + "signatureAlgorithm": "keybase", + "signatureValue": "5cfc20c7018f2beefb42a68836da59a792e55daa4d118498c9b1898de7e845690f" + } + ] +} +``` + +### Discoverability flag + +Mastodon allows users to opt-in or opt-out of discoverability features like the profile directory. This flag may also be used as an indicator of the user's preferences toward being included in external discovery services, such as search engines or other indexing tools. If you are implementing such a tool, it is recommended that you respect this property if it is present. This is implemented using an extra property `discoverable` on objects. Example: + +```javascript +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + { + "toot": "http://joinmastodon.org/ns#", + "discoverable": "toot:discoverable" + } + ], + "id": "https://mastodon.social/users/Gargron", + "type": "Person", + "discoverable": true +} +``` + diff --git a/content/en/spec/microformats.md b/content/en/spec/microformats.md new file mode 100644 index 00000000..7c4290a9 --- /dev/null +++ b/content/en/spec/microformats.md @@ -0,0 +1,98 @@ +--- +title: Microformats +description: An open data format using CSS classes to structure your already-existing HTML. +menu: + docs: + weight: 40 + parent: spec +--- + +## What are microformats? + +[Microformats 2.0](https://microformats.io/) is a standard used to embed metadata directly within an HTML document. Rather than needing to use an API for read-only purposes, a web page can simply be parsed for certain CSS classes in order to extract information that you have already fetched simply by viewing the page, rather than having to separately request that same information from an API. The use of microformats classes allows for semantic parsing of data within a given web page, and can be used to generate feeds, cards, or representations of that data. + +## Microformats classes + +All microformats classes use a prefix. The prefix indicates the type of the element, independent of hierarchy. These are the microformats classes as used in Mastodon's codebase. + +### Root elements \(`h-*`\) + +#### `h-feed` + +Represents a stream of entries. Attached to a profile's toots. Also attached to the parent thread within detailed status views. + +#### `h-entry` + +Represents episodic or date stamped online content. Attached to a status. + +#### `h-cite` + +Represents a reference to another online publication. Attached to a boost. Also attached to other statuses in the thread within detailed status views. + +#### `h-card` + +Represents a person or organization. Attached to the container of display name, username, and avatar. Also attached to mentions. + +### Plain-text properties \(`p-*`\) + +#### `p-author` + +Within `h-entry` or `h-cite`, represents the author of the entry, and is attached to the container of display name, username, and avatar. + +#### `p-name` + +Within `h-feed`, represents the title of the feed. Attached to `data` element with `value` attribute. +Within `h-entry` or `h-cite`, represents the title of the entry. Unused in Mastodon. +Within `h-card`, represents the plain-text name of a person or organization. Attached to display name. + +#### `p-in-reply-to` + +Within `h-entry` of a detailed status, represents the status that is the direct parent. + +#### `p-repost-of` + +Within h-entry of a detailed status, represents a post that is a reblog and also a direct parent. Currently unused, since reblogs cannot be replied to. + +#### `p-comment` + +Within `h-entry` of a detailed status, represents statuses that are direct children. + +### URL properties \(`u-*`\) + +#### `u-photo` + +Within `h-card`, represents the profile picture. Attached to the avatar image. + +#### `u-uid` + +Within `h-entry` or `h-cite`, represents a universally unique identifier. Attached to timestamp link. + +#### `u-url` + +Within `h-entry` or `h-cite`, represents the status permalink. Attached to timestamp link. +Within `h-card`, represents the profile permalink. Attached to display name link. + +### Datetime properties \(`dt-*`\) + +#### `dt-published` + +Within `h-entry` or `h-cite`, represents the date and time at which the status was published. Attached to `data` element with `value` attribute. + +### Element tree \(`e-*`\) + +#### `e-content` + +Within `h-entry` or `h-cite`, represents the content of the status. Attached to status content. + +## Additional classes + +These elements are attached by Mastodon for parsing metadata, but are not technically part of the Microformats vocabulary. + +#### `mention` + +Indicates that the link should be opened in-app with the associated mention data from the API. + +#### `hashtag` + +Indicates that the link should be opened in-app with the associated hashtag data from the API. + diff --git a/content/en/spec/oauth.md b/content/en/spec/oauth.md new file mode 100644 index 00000000..f8b57b47 --- /dev/null +++ b/content/en/spec/oauth.md @@ -0,0 +1,46 @@ +--- +title: OAuth +description: >- + An open standard for token-based authentication and authorization on the + Internet +menu: + docs: + weight: 50 + parent: spec +--- + +## What is OAuth? + +The Mastodon API has many methods that require authentication from a client or authorization from a user. This is accomplished with OAuth 2.0, an authorization framework described in [RFC 6749](https://tools.ietf.org/html/rfc6749) that allows third-party applications to obtain limited access to an HTTP service on behalf of a resource owner, through the use of a standardized authorization flow that generates a client access token to be used with HTTP requests. + +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 + +To obtain an OAuth token for a Mastodon website, 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](../methods/apps/#create-an-application) and then [proceed with normal OAuth 2]({{< relref "../methods/apps/oauth.md" >}}). + +## OAuth 2 endpoints implemented + +The following descriptions are taken from the [Doorkeeper documentation](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples). Mastodon uses Doorkeeper to implement OAuth 2. For more information on how to use these endpoints, see the [API documentation for OAuth.]({{< relref "../methods/apps/oauth.md" >}}) + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/config/initializers/doorkeeper.rb" caption="Doorkeeper config initializer" >}} + +### [GET /oauth/authorize](../methods/apps/oauth.md#authorize-a-user) + +Displays an authorization form to the user. If approved, it will create and return an authorization code, then redirect to the desired `redirect_uri`, or show the authorization code if `urn:ietf:wg:oauth:2.0:oob` was requested. + +### [POST /oauth/token](../methods/apps/oauth.md#obtain-a-token) + +Obtain an access token. This corresponds to the token endpoint, section 3.2 of the OAuth 2 RFC. + +### [POST /oauth/revoke](../methods/apps/oauth.md#revoke-token) + +Post here with client credentials to revoke an access token. This corresponds to the token endpoint, using the OAuth 2.0 Token Revocation RFC \(RFC 7009\). + +## Common gotchas + +* When registering an application using Mastodon's REST API, there is a `scopes` parameter. When interfacing with OAuth endpoints, you must use the `scope` parameter instead, and this parameter's value must be a subset of the `scopes` registered with the app. You cannot include anything that wasn't in the original set. +* When registering an application using Mastodon's REST API, there is a `redirect_uris` parameter. When interfacing with OAuth endpoints, you must use the `redirect_uri` parameter instead, and this parameter's value must be one of the `redirect_uris` registered with the app. + diff --git a/content/en/spec/security.md b/content/en/spec/security.md new file mode 100644 index 00000000..e2f68c46 --- /dev/null +++ b/content/en/spec/security.md @@ -0,0 +1,133 @@ +--- +title: Security +description: Public key cryptography and supported signature schemes over HTTP and JSON-LD. +menu: + docs: + weight: 30 + parent: spec +--- + +## HTTP Signatures + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/lib/request.rb" caption="app/lib/request.rb" >}} + +[HTTP Signatures](https://w3c-dvcg.github.io/http-signatures/) is a specification for signing HTTP messages by using a \`Signature:\` header with your HTTP request. Mastodon requires the use of HTTP Signatures in order to validate that any activity received was authored by the actor generating it. When secure mode is enabled, all GET requests require HTTP signatures as well. + +For any HTTP request incoming to Mastodon, the following header should be attached: + +```http +Signature: keyId="https://my-example.com/actor#main-key",headers="(request-target) host date",signature="Y2FiYW...IxNGRiZDk4ZA==" +``` + +The three parts of the `Signature:` header can be broken down like so: + +```http +Signature: +keyId="https://my-example.com/actor#main-key", +headers="(request-target) host date", +signature="Y2FiYW...IxNGRiZDk4ZA==" +``` + +The `keyId` should correspond to the actor and the key being used to generate the `signature`, whose value is equal to all parameters in `headers` concatenated together and signed by the key, then Base64-encoded. See [ActivityPub > Public key](activitypub.md#public-key) for more information on actor keys. An example key looks like this: + +```javascript +"publicKey": { + "id": "https://my-example.com/actor#main-key", + "owner": "https://my-example.com/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXc4vkECU2/CeuSo1wtn\nFoim94Ne1jBMYxTZ9wm2YTdJq1oiZKif06I2fOqDzY/4q/S9uccrE9Bkajv1dnkO\nVm31QjWlhVpSKynVxEWjVBO5Ienue8gND0xvHIuXf87o61poqjEoepvsQFElA5ym\novljWGSA/jpj7ozygUZhCXtaS2W5AD5tnBQUpcO0lhItYPYTjnmzcc4y2NbJV8hz\n2s2G8qKv8fyimE23gY1XrPJg+cRF+g4PqFXujjlJ7MihD9oqtLGxbu7o1cifTn3x\nBfIdPythWu5b4cujNsB3m3awJjVmx+MHQ9SugkSIYXV0Ina77cTNS0M2PYiH1PFR\nTwIDAQAB\n-----END PUBLIC KEY-----\n" + }, +``` + +See also: [https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/](https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/) + +### Creating HTTP signatures + +To create an HTTP signature, you will have to define which headers are being hashed and signed. For example, consider the following request being sent out: + +```http +GET /users/username/inbox HTTP/1.1 +Host: mastodon.example +Date: 18 Dec 2019 10:08:46 GMT +Accept: application/activity+json +``` + +The signature string is constructed using the values of the HTTP headers defined in `headers`, joined by newlines. Typically, you will want to include the request target, as well as the host and the date. Mastodon assumes `Date:` header if none are provided. For the above request, to generate a `Signature:` with `headers="(request-target) host date"` we would generate the following string: + +```text +(request-target): get /users/username/inbox +host: mastodon.example +date: 18 Dec 2019 10:08:46 GMT +``` + +Note that we don't care about the `Accept:` header because we won't be specifying it in `headers`. + +The signature string is then hashed with SHA256 and signed with the actor's public key. The resulting value is attached as `signature` within the Signature: header. The final request looks like this: + +```http +GET /users/username/inbox HTTP/1.1 +Host: mastodon.example +Date: 18 Dec 2019 10:08:46 GMT +Accept: application/activity+json +Signature: keyId="https://my-example.com/actor#main-key",headers="(request-target) host date",signature="Y2FiYW...IxNGRiZDk4ZA==" +``` + +This request is functionally equivalent to saying that `https://my-example.com/actor` is requesting `https://mastodon.example/users/username/inbox` and is proving that they sent this request by signing `(request-target)`, `Host:`, and `Date:` with their public key linked at `keyId`, resulting in the provided `signature`. + +### Verifying HTTP signatures + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/controllers/concerns/signature_verification.rb" caption="app/controllers/concerns/signature\_verification.rb" >}} + +Consider the following request: + +```http +GET /users/username/inbox HTTP/1.1 +Host: mastodon.example +Date: 18 Dec 2019 10:08:46 GMT +Accept: application/activity+json +Signature: keyId="https://my-example.com/actor#main-key",headers="(request-target) host date",signature="Y2FiYW...IxNGRiZDk4ZA==" +``` + +Mastodon verifies the signature using the following algorithm: + +* Split `Signature:` into its separate parameters. +* Construct the signature string from the value of `headers`. +* Fetch the `keyId` and resolve to an actor's `publicKey`. +* SHA256 hash the signature string and compare to the Base64-decoded `signature` as decrypted by `publicKey[publicKeyPem]`. +* Use the Date: header to check that the signed request was made within the past 12 hours. + +## Linked Data Signatures + +{{< caption-link url="https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/linked_data_signature.rb" caption="app/lib/activitypub/linked\_data\_signature.rb" >}} + +[Linked Data Signatures 1.0](https://w3c-dvcg.github.io/ld-signatures/) is a specification for attaching cryptographic signatures to JSON-LD documents. LD Signatures are not used widely within Mastodon, but they are used in the following situations: + +* When running a [self-destruct](../admin/tootctl.md#tootctl-self-destruct) sequence to send Delete activities to all known peers, the payload will use LD Signatures because HTTP Signatures will not be available. Receiving servers will process the signature by validating it against the locally cached actor key, since the HTTP server will no longer be hosting old actor information. +* When accepting activities from a relay. Public activities can optionally be sent to a relay with LD Signatures, and any server subscribing to a relay does not have to manually refetch the activity from the origin. This prevents having potentially infinite servers attempt to load the status from your instance. + +### Creating LD signatures + +To create a signature, Mastodon uses the keypair attached to an actor at `https://mastodon.example/users/username#main-key`. It then creates an SHA256 hash of the document, signs it with the keypair, and Base64-strict-encodes the resulting output to derive a `signatureValue`. The following hash is merged into the JSON-LD document: + +```javascript +"signature": { + "type": "RsaSignature2017", + "creator": "https://mastodon.example/users/username#main-key", + "created": "2019-12-08T03:48:33.901Z", + "signatureValue": "s69F3mfddd99dGjmvjdjjs81e12jn121Gkm1" +} +``` + +{{< hint style="warning" >}} +Mastodon's current implementation of LD Signatures is somewhat outdated due to a change in the JSON-LD @context between the drafting stage and finalization stage of the specification. Mastodon expects a `type` of `RsaSignature2017` while the current specification instead defines `RsaSignature2018` via the namespace `https://w3id.org/security/v2`. +{{< /hint >}} + +### Verifying LD signatures + +To verify a signature, Mastodon uses the following algorithm: + +* Make sure that a `signature` exists and is a hash. +* Make sure that `signature[type]` is `RsaSignature2017`. +* Fetch the `signature[creator]` URI. Make sure the creator exists. +* Strip `type`, `id`, and `signatureValue` from the `signature`, leaving only `signature[creator]` and `signature[created]`. +* Base64-decode the `signatureValue` and verify it against the public key in `signature[creator]`. + diff --git a/content/en/spec/webfinger.md b/content/en/spec/webfinger.md new file mode 100644 index 00000000..4c335d68 --- /dev/null +++ b/content/en/spec/webfinger.md @@ -0,0 +1,75 @@ +--- +title: WebFinger +description: Translate `user@domain` mentions to actor profile URIs. +menu: + docs: + weight: 20 + parent: spec +--- + +## What is WebFinger, and why is it used? + +On Mastodon, user profiles can be hosted either locally on the same website as yours, or remotely on a completely different website. The same username may be used on a different domain. Therefore, a Mastodon user's full mention consists of both the username and the domain, in the form `@username@domain`. In practical terms, `@user@example.com` is not the same as `@user@example.org`. If the domain is not included, Mastodon will try to find a local user named `@username`. However, in order to deliver to someone over ActivityPub, the `@username@domain` mention is not enough -- **mentions must be translated to an HTTPS URI first**, so that the remote actor's inbox and outbox can be found. + +Enter WebFinger. WebFinger as described in [RFC 7033](https://tools.ietf.org/html/rfc7033) is a spec that defines **a method for resolving links to a resource**, given only a URI on a particular server. This allows anyone to look up where a resource is located without having to know its exact location beforehand; for example, by email or phone number. This lookup is directed at the endpoint `/.well-known/webfinger`, and a `resource` query parameter is passed along with the lookup. The resource URI used with Mastodon is the `acct:` URI as described in [RFC 7565](https://tools.ietf.org/html/rfc7565), with the username of a profile that is hosted on a particular domain. + +{{< hint style="danger" >}} +**Because Mastodon heavily relies on mentions for addressing other profiles, WebFinger is required for fully interoperating with Mastodon.** Users can generally load profiles by searching for the direct HTTPS URI if they know it, or for the `username@domain` address, but Mastodon's internal logic depends almost completely on `acct`: URIs or `username@domain` representations. Searching for any objects or profiles from an ActivityPub implementation without WebFinger will fail because the author cannot be converted to a user in the local database. +{{< /hint >}} + +## Sample WebFinger flow + +Suppose we want to lookup the user `@Gargron` hosted on the `mastodon.social` website. + +Simply make a request to that domain's `/.well-known/webfinger` endpoint, with the `resource` query parameter set to an `acct:` URI. + +{{< code title="https://mastodon.social/.well-known/webfinger?resource=acct:gargron@mastodon.social" >}} +```javascript +{ + "subject": "acct:Gargron@mastodon.social", + "aliases": [ + "https://mastodon.social/@Gargron", + "https://mastodon.social/users/Gargron" + ], + "links": [ + { + "rel": "http://webfinger.net/rel/profile-page", + "type": "text/html", + "href": "https://mastodon.social/@Gargron" + }, + { + "rel": "self", + "type": "application/activity+json", + "href": "https://mastodon.social/users/Gargron" + }, + { + "rel": "http://ostatus.org/schema/1.0/subscribe", + "template": "https://mastodon.social/authorize_interaction?uri={uri}" + } + ] +} +``` +{{< /code >}} + +You can parse this JSON response to find a link with your desired type. For ActivityPub `id`, we are interested in finding `application/activity+json` specifically. + +This way, we have translated `@Gargron@mastodon.social` to `https://mastodon.social/users/Gargron` and we can now interact over ActivityPub by referring to this URI as `id` where appropriate. + +{{< code title="Sample activity" >}} +```javascript +{ +"id": "https://social.example/activities/1", +"type": "Create", +"actor": "https://social.example/actors/1", +"object": { + "id": "https://social.example/objects/1", + "type": "Note", + "content": "Hello, Gargron!" +}, +"to": "https://mastodon.social/users/Gargron" +} +``` +{{< /code >}} + +Note in the above example that `social.example` does not use the same URI structure as Mastodon. Thus, we cannot simply guess the actor `id` given only the username and domain. However, if `social.example` supports WebFinger, then we can get this `id`simply by requesting `https://social.example/.well-known/webfinger?resource=acct:username@social.example`and parsing the response for a link with the `application/activity+json` type. + diff --git a/content/en/usage/basics.md b/content/en/usage/basics.md deleted file mode 100644 index 64f9ed31..00000000 --- a/content/en/usage/basics.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Basics -description: Overview of Mastodon's basic functionality -menu: - docs: - parent: usage - weight: 1 ---- -## Sign up - -You have to choose a server to sign up on, like you would choose an e-mail provider, or a World of Warcraft realm for your new character. The server will be hosting your account and your home feed. - -You can [browse a list of servers by categories and languages on joinmastodon.org](https://joinmastodon.org/#getting-started). - -## Edit profile -### Picture, name and bio - -- You can upload a profile picture -- You can upload a header image for your profile -- You can set a display name different to your username -- You can write about yourself in the bio -- You can mention people and use hashtags and custom emoji in your bio - -### Profile metadata - -Profile metadata is a way to add extra information to your profile that is easy to skim. You have 4 rows where you can define the label and the value. For example: - -|Label|Content| -|-----|-------| -|Age|25| -|Country|Germany| -|Pronouns|he/him| - -It's completely up to you what you put there. The content can contain mentions, hashtags, custom emojis and links. - -### Link verification - -If you put a link in your profile metadata, Mastodon checks if the linked page links back to your Mastodon profile. If so, you get a verification checkmark next to that link, since you are confirmed as the owner. - -Behind the scenes, Mastodon checks for the `rel="me"` attribute on the link back. Likewise, Mastodon puts `rel="me"` on the links within profile metadata. - -## Posting -### Text - -- You can use up to 500 characters -- You can mention other people like `@alice` or `@alice@example.com` -- When mentioning other people, the domain part of their username is not counted -- If you post links, they must begin with `http://` or `https://` -- When posting links, all links are counted as 23 characters, no matter how long -- You can use hashtags like `#example` so others can find your post by that tag -- You can add a content warning to your post -- The content warning is plain text. It does not support mentions, hashtags or links - -### Media - -- You can upload PNG and JPG images -- Uploaded GIFs are converted to soundless MP4s like on Imgur/Gfycat (GIFV) -- You can also directly upload soundless MP4s and WebMs (GIFV) -- You can upload videos in the MP4, WebM or MOV format -- Upload limit for images is 8 MB -- Upload limit for videos is 40 MB -- Images with a surface area larger than 1280² pixels are downsized -- All media in a post can be hidden behind a spoiler - -### Custom emoji - -- Each server offers a set of custom emoji you can use, like on Discord -- You can use an emoji using its shortcode like `:thounking:` diff --git a/content/en/usage/decentralization.md b/content/en/usage/decentralization.md deleted file mode 100644 index 89c150dd..00000000 --- a/content/en/usage/decentralization.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Decentralization -description: How Mastodon is decentralized and what it means in practical terms -menu: - docs: - parent: usage - weight: 2 ---- - -Mastodon is a **federated** social network. - -## What is federation? - -**Federation** is a form of decentralization. Instead of a single central node that all people use, there are multiple nodes, that any number of people can use. - -|Grade of centralization|Examples| -|:---------------------:|--------| -|Centralized|Twitter, Facebook, Instagram| -|Federated|E-mail, XMPP| -|Distributed|BitTorrent, IPFS, Scuttlebutt| - -A Mastodon server can operate alone. Just like a traditional website, people sign up on it, post messages, upload pictures and talk to each other. *Unlike* a traditional website, Mastodon servers can interoperate, letting their users communicate with each other, just like you can send an e-mail from your GMail address to someone from Outlook. - -

- -

Left to right: Centralized, Federated, Distributed

-
- -In practical terms: Imagine if you could follow an Instagram user from your Twitter account and comment on their photos without leaving your account. If Twitter and Instagram were federated services, that would be possible. - -## The fediverse - -Mastodon uses a standardized, open protocol to implement federation. It is called ActivityPub. Any software that likewise implements federation via ActivityPub can seamlessly communicate with Mastodon, just like Mastodon servers communicate with one another. - -The **fediverse** ("federated universe") is the name for all servers that can communicate with each other. That includes all Mastodon servers, but also other implementations: - -- Misskey -- Pleroma -- PeerTube -- Plume -- and many more - -The fediverse does not have its own brand, so you will more often hear "follow me on Mastodon" than "follow me on the fediverse", but technically the latter is more correct. - -## Practical implications -### Addressing people - -Mastodon usernames actually consist of two parts: - -- The local username, e.g. `alice` -- And the domain of the server, e.g. `example.com` - -Just like an e-mail address. For convenience sake, Mastodon allows you to skip the second part when addressing people on the same server as you, but you have to keep in mind when sharing your username with other people, you need to include the domain or they won't be able to find you as easily. - -|{{< no >}}|{{< yes >}}| -|:--------:|:---------:| -|I'm @alice on Mastodon!|I'm @alice@example.com on Mastodon!| - -The search form in Mastodon will find people either with the above address form, or the link to the person's profile, so you can share that instead if you prefer. - -### Following people - -As long as you encounter a person within your app's user interface, e.g. the web interface on your home server, or your mobile app, you can just click "follow" and you won't notice a difference if that person is on your server or not. - -However if you come across someone's public profile hosted on a different server, there's an obstacle: That server sees you as just another anonymous visitor. - -So when you click "follow", a dialog will pop up asking you to enter your own full username (with the domain part, most importantly). This way, the dialog actually sends you back to your home server, where you are logged in and can really do stuff. - -You will also notice that dialog when clicking on "reply", "boost" or "favourite" on public pages of other servers. - -### Browsing content - -To allow you to discover potentially interesting content, Mastodon provides a way to browse all public posts. Well, there is no global shared state between all servers, so there is no way to browse *all* public posts. When you browse the **federated timeline**, you see all public posts that the server you are on knows about. There are various ways your server may discover posts, but the bulk of them will be from people that other users on your server follow. - -There is a way to filter the federated timeline to view only public posts created on your server: The **local timeline**. Mind that "local" here refers to the server, not to a geographical location. - -### Funding and monetization - -All Mastodon servers are operated by different people or organizations completely independently. Mastodon does not implement any monetization strategies in the software. - -Some server operators choose to offer paid accounts, some server operators are companies who can utilize their existing infrastructure, and most server operators rely on crowdfunding from their users via Patreon and similar services. So if you want to support the server hosting your account, check if it offers a way to donate. - -Mastodon development is likewise crowdfunded via Patreon. No venture capital is involved. - -### Impersonation and verification - -The same username *can* be registered on different servers, there is no way to claim all of them ahead of time. Just like with e-mail, you should not expect `alice@hotmail.com` to be the same person as `alice@gmail.com`. - -Because Mastodon can be self-hosted, there is no better way to verify your identity than to host Mastodon on your own domain, which people already trust. - -Document-based verification and blue ticks are not possible without a central authority. However, Mastodon can cross-reference the links you put on your profile to prove that you are the real owner of those links. In case one of those links is your personal homepage that is known and trusted, it can serve as the next-best-thing to identity verification. diff --git a/content/en/usage/privacy.md b/content/en/usage/privacy.md deleted file mode 100644 index bc535069..00000000 --- a/content/en/usage/privacy.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Privacy -overview: Overview of privacy-related features on Mastodon and their implications -menu: - docs: - parent: usage - weight: 3 ---- - -## Publishing levels - -|Level|Public timelines|Permalink|Profile view|Home feeds| -|-----|:--------------:|:-------:|:----------:|:--------:| -|Public|{{< yes >}}|{{< yes >}}|{{< yes >}}|{{< yes >}}| -|Unlisted|{{< no >}}|{{< yes >}}|{{< yes >}}|{{< yes >}}| -|Followers-only|{{< no >}}|{{< no >}}|{{< no >}}|{{< yes >}}| -|Direct|{{< no >}}|{{< no >}}|{{< no >}}|{{< no >}}| - -No matter which level, every mentioned user can see the message in their notifications. - -**Do not share dangerous and sensitive information over direct messages**. Mastodon is not an encrypted messaging app like Signal or Wire, the database administrators of the sender's and recipient's servers have access to the text. Use them with the same caution as you would use forum PMs, Discord PMs and Twitter DMs. - -## Account locking - -To effectively publish private (followers-only) posts, you must lock your account--otherwise, anyone could follow you to view older posts. Locking your account on Mastodon does one thing: Adds an authorization step to the process of following you. - -Once locked, before someone can become your follower, you will receive a follow request, which you can either accept or reject. - -Please mind that post privacy on Mastodon is per-post, rather than account-wide, and as such there is no way to instantly make past public posts private. - -## Blocking and muting -### Hiding boosts - -If you hide boosts from someone, you won't see their boosts in your home feed. - -### Muting - -When muting, you have the option to mute notifications from them or not. Muting without muting notifications hides the user from your view: - -- You won't see the user in your home feed -- You won't see other people boosting the user -- You won't see other people mentioning the user -- You won't see the user in public timelines - -If you choose to also mute notifications from them, you will additionally not see notifications from that user. - -The user has no way of knowing they have been muted. - -### Blocking - -Blocking hides a user from your view: - -- You won't see the user in your home feed -- You won't see other people boosting the user -- You won't see other people mentioning the user -- You won't see the user in public timelines -- You won't see notifications from that user - -Additionally, on the blocked user's side: - -- The user is forced to unfollow you -- The user cannot follow you -- The user won't see other people's boosts of you -- The user won't see you in public timelines - -If you and the blocked user are on the same server, the blocked user will not be able to view your posts on your profile while logged in. - -### Hiding an entire server - -If you hide an entire server: - -- You will not see posts from that server on the public timelines -- You won't see other people's boosts of that server in your home feed -- You won't see notifications from that server -- You will lose any followers that you might have had on that server diff --git a/content/en/user/contacts.md b/content/en/user/contacts.md new file mode 100644 index 00000000..a5f9d3bd --- /dev/null +++ b/content/en/user/contacts.md @@ -0,0 +1,45 @@ +--- +title: More settings +description: 'Invite new users, sort through your contacts, and secure your account.' +menu: + docs: + weight: 80 + parent: user +--- + +## Generating invites + +{{< figure src="/assets/image%20%2862%29.png" caption="Invite people from your account's settings" >}} + +Invite links can be generated and shared with other people, and some servers require invites in order to register for an account. When generating an invite link, you can set the max uses to limit how many times a certain link is used, or how long it has been active. Invite links can be deactivated at any time. + +## Follows and followers + +{{< figure src="/assets/image%20%2849%29.png" caption="Mutuals who have not moved their account, sorted by last activity" >}} + +Within settings, you can find a relationship manager that lets you filter and sort through the profiles that you are connected to, based on different criteria: + +* **Relationship:** whether a profile is following you, followed by you, or mutually following each other. +* **Account status:** whether a profile is currently marked as redirected or not. +* **Account activity:** whether a profile has posted in the past month or not. + +You can select certain users to unfollow, or to remove from your followers, by checking the boxes and clicking the corresponding button in the table header. + +## Account settings + +From the account settings, you can change your email address, set a new password, revoke active sessions or authorized apps, and enable two-factor authentication. + +## Identity proofs + +[Link verification](profile.md#link-verification) of profile metadata fields is one way to prove your identity by using rel=me links, but Mastodon also supports a more generalized proof provider subsystem. Currently, the only supported identity provider for this subsystem is Keybase. + +### Keybase identity verification + +{{< figure src="/assets/image%20%2860%29.png" caption="An identity proof on a profile" >}} + +First, sign up for Keybase and generate or upload a GPG public key to your Keybase account. Next, go to "prove more identities". Find your instance if it is available, and if not, contact Keybase for help. Select your Mastodon domain and enter your username. You will be able to prove your identity by authorizing with your Mastodon account and posting a proof message. Once you do this, the identity proof will be established, and your profile will show Keybase as a proven identity. + +{{< hint style="danger" >}} +**Keybase verification is irreversible.** Keybase uses an immutable signature chain for its identity proofs, so once you prove your identity on Keybase, you cannot remove it. You can only revoke your proof by signing a revocation message with your associated private key. +{{< /hint >}} + diff --git a/content/en/user/discoverability.md b/content/en/user/discoverability.md new file mode 100644 index 00000000..a0ddb4d1 --- /dev/null +++ b/content/en/user/discoverability.md @@ -0,0 +1,39 @@ +--- +title: Promoting yourself and others +description: 'Give visibility to hashtags, profiles, and posts.' +menu: + docs: + weight: 60 + parent: user +--- + +## Featured links on your profile + +### Featured hashtags + +{{< figure src="/assets/image%20%2858%29.png" caption="A featured hashtag showing last usage date and total usage." >}} + +You can choose to feature certain hashtags that you use often. Go to Settings > Profile > Featured hashtags to manage which hashtags you are currently featuring. Once featured, a link to the hashtag will be shown on your profile, with the date of the last time it was used in a status, as well as the total number of statuses in which it was used. + +### Featured profiles + +{{< figure src="/assets/image%20%2833%29.png" caption="Four randomly-selected featured profiles." >}} + +You can choose to feature profiles of people that you are following. Go to that person's profile dropdown menu and click "Feature on profile". When you feature a profile, a link to their profile will appear on your profile, under a section titled "your choices". Up to 4 profiles will be shown at a time, and these profiles are selected randomly from your pool of featured profiles every time the page is loaded. + +## Pinned posts + +{{< figure src="/assets/image%20%2837%29.png" caption="A pinned toot by mastodon.social/@gargron" >}} + +You can choose to feature up to 5 of your own public posts at the top of your profile. Go to the status dropdown menu and click "Pin on profile". When you pin a toot, it will appear at the top of your "toots" tab, before all other chronological status updates. + +## Profile directory + +{{< figure src="/assets/image%20%2831%29.png" caption="Profile directory as seen from mastodon.social" >}} + +The profile directory shows all accounts that have opted into being shown in the directory, and can be used to quickly find profiles that you may be interested in following. + +The profile directory can be sorted either by recent activity \(the most recently published status\), or by new arrivals \(the most recently created accounts\). The directory can also be filtered to show only local accounts, or to show all known accounts that your website is aware of. + +Profiles appear as cards that include a user's display name, address, account bio, and some brief stats such as how many toots they've published, how many followers they have, and the time of their last published status. + diff --git a/content/en/user/external.md b/content/en/user/external.md new file mode 100644 index 00000000..1ca9f573 --- /dev/null +++ b/content/en/user/external.md @@ -0,0 +1,21 @@ +--- +title: Using Mastodon externally +description: You can browse and interact on Mastodon from external apps or websites. +menu: + docs: + weight: 90 + parent: user +--- + +## Remote interactions on another Mastodon site + +{{< figure src="/assets/image%20%2863%29.png" caption="An example of a post's public permalink on a Mastodon site." >}} + +When you are browsing a remote site powered by Mastodon, clicking on any of the interaction buttons will load a dialog that will redirect you to your local site. + +{{< figure src="/assets/image%20%288%29.png" caption="A remote interaction dialog for replying to a toot." >}} + +## Signing into a client app + +You can use your Mastodon account to sign into any app that implements the Mastodon API. A list of such apps can be found at [https://joinmastodon.org/apps](https://joinmastodon.org/apps). + diff --git a/content/en/user/moderating.md b/content/en/user/moderating.md new file mode 100644 index 00000000..52761aff --- /dev/null +++ b/content/en/user/moderating.md @@ -0,0 +1,107 @@ +--- +title: Dealing with unwanted content +description: 'Control what you see, for a more comfortable social media experience.' +menu: + docs: + weight: 50 + parent: user +--- + +## Filtering posts + +It is possible to filter statuses for specific keywords and phrases so that they can be hidden automatically. + +{{< figure src="/assets/image%20%2848%29.png" caption="A sample of active filters for various keywords in different contexts." >}} + +To create or manage your filters, go to Settings > Filters. The "Add new filter" button will let you create a new filter, and existing filters can be edited or deleted. Your existing filters will be summarized in a table. + +{{< figure src="/assets/image%20%2814%29.png" caption="Filters can have an expiry date, specific contexts, server-side drop, and use word boundaries." >}} + +Filters have the following settings: + +### Keyword or phrase + +This is the string that will be matched. The keyword will be searched for in any status's content, including CW, media descriptions, and poll options. + +### Expire after + +Optionally only apply the filter for a limited amount of time. Expired filters are not automatically deleted, but can be reactivated by setting a new expiry date \(or changing it back to "never" expire\). + +### Filter contexts + +Choose where the filter will be applied: + +* Home timeline = matching statuses will be removed from your home feed +* Notifications = matching notifications will not be shown +* Public timelines = matching statuses will not appear in local/federated timelines +* Conversations = matching statuses will be hidden in threads and detailed views + +### Drop instead of hide + +Filtering is usually done client-side, so that disabling a filter will cause filtered statuses to be visible again. However, if you enable "drop instead of hide", any matching statuses will be disappear completely and will never be delivered to your home or notifications. + +### Whole word + +Filters normally apply to any status that contains the included characters, regardless of whether they are in the middle of a word. Enabling "whole word" will only apply the filter if the keyword is surrounded by spaces or other non-alphanumeric characters. + +## User-level actions + +{{< figure src="/assets/image%20%2824%29.png" caption="The user dropdown menu offers various actions." >}} + +### Hiding boosts + +If you hide boosts from someone, you won’t see their boosts in your home feed. This option only appears on users who you are currently following. + +### Muting + +{{< figure src="/assets/image%20%2852%29.png" caption="Sample of muted accounts." >}} + +When muting, you have the option to mute notifications from them or not. Muting without muting notifications hides the user from your view: + +* You won’t see the user in your home feed +* You won’t see other people boosting the user +* You won’t see other people mentioning the user +* You won’t see the user in public timelines + +If you choose to also mute notifications from them, you will additionally not see notifications from that user. + +The user has no way of knowing they have been muted. + +### Blocking + +{{< figure src="/assets/image%20%2836%29.png" caption="Sample of blocked accounts." >}} + +Blocking hides a user from your view: + +* You won’t see the user in your home feed +* You won’t see other people boosting the user +* You won’t see other people mentioning the user +* You won’t see the user in public timelines +* You won’t see notifications from that user + +Additionally, on the blocked user’s side: + +* The user is forced to unfollow you +* The user cannot follow you +* The user won’t see other people’s boosts of you +* The user won’t see you in public timelines + +If you and the blocked user are on the same server, the blocked user will not be able to view your posts on your profile while logged in. + +### Hiding an entire server + +![](/assets/image%20%2861%29.png) + +If you hide an entire server: + +* You will not see posts from that server on the public timelines +* You won’t see other people’s boosts of that server in your home feed +* You won’t see notifications from that server +* You will lose any followers that you might have had on that server + +## Reporting problematic content to moderators + +{{< figure src="/assets/image%20%283%29.png" caption="The report modal allows selecting example statuses, adding a note, and forwarding reports." >}} + +If you see a status or user that is violating the rules of your website, you can report that user to your site's moderators. Clicking the "report" option on the user dropdown or status dropdown will open the report modal. Here, you can \(and should\) add a note about why you are reporting this account. You can attach certain problematic statuses for additional context on why you are reporting the account, and if their conduct is violating the rules of the remote website, you can also choose to forward the report to their site's moderators. + diff --git a/content/en/user/moving.md b/content/en/user/moving.md new file mode 100644 index 00000000..88211162 --- /dev/null +++ b/content/en/user/moving.md @@ -0,0 +1,44 @@ +--- +title: Moving or leaving accounts +menu: + docs: + weight: 100 + parent: user +--- + +## Exporting your information + +{{< figure src="/assets/image%20%2835%29.png" caption="The data export page in settings" >}} + +At any time you want, you can go to Settings > Export and download a CSV file for your current followed accounts, your currently created lists, your currently blocked accounts, your currently muted accounts, and your currently blocked domains. Your following, blocking, muting, and domain-blocking lists can be imported at Settings > Import, where they can either be merged or overwritten. + +Requesting an archive of your toots and media can be done once every 7 days, and can be downloaded in ActivityPub JSON format. Mastodon currently does not support importing toots or media due to technical limitations, but your archive can be viewed by any software that understands how to parse ActivityPub documents. + +## Redirecting or moving your profile + +From the bottom of Settings > Account, you can find options related to account redirection or migration. + +### Profile redirect + +{{< figure src="/assets/image%20%2853%29.png" caption="Profile redirect form" >}} + +Redirecting your account disables posting from that account and displays a "profile moved" notice indicating your new account. Anyone viewing your profile can see this notice and will know to follow you at your new account. Following redirected accounts is not possible. The redirect can be canceled at any time. + +### Profile move + +{{< figure src="/assets/image%20%2847%29.png" caption="Profile move form" >}} + +Moving your account is the same as redirecting your account, but it will also irreversibly force everyone to unfollow your current account and follow your new account, if their software supports the Move activity. Your toots will not be moved, due to technical limitations. There is also a very heavy cooldown period in which you cannot migrate again, so be very careful before using this option! + +### Account aliases + +{{< figure src="/assets/image%20%2840%29.png" caption="Alias management screen" >}} + +Profile moves can only be initiated when your two accounts have been aliased. Account aliases are currently not used for anything other than profile moves, where you will need to set your old account as an alias of your new account before initiating the move. Setting aliases is harmless and reversible on its own. + +## Deleting your account + +{{< figure src="/assets/image%20%2816%29.png" caption="Account deletion form" >}} + +From the bottom of Settings > Account, you can find the form to delete your account. Deleting your account is irreversible, and will cause both your profile and username to become forever unusable. + diff --git a/content/en/user/network.md b/content/en/user/network.md new file mode 100644 index 00000000..ae4c88b8 --- /dev/null +++ b/content/en/user/network.md @@ -0,0 +1,89 @@ +--- +title: Using the network features +description: Follow and talk to anyone from any server. +menu: + docs: + weight: 40 + parent: user +--- + +## Browsing content through public timelines + +{{< figure src="/assets/image%20%2830%29.png" caption="Posts within a public timeline" >}} + +To allow you to discover potentially interesting content, Mastodon provides a way to browse all public posts. Well, there is no global shared state between all servers, so there is no way to browse _all_ public posts. When you browse the **federated timeline**, you see all public posts that the server you are on knows about. There are various ways your server may discover posts, but the bulk of them will be from people that other users on your server follow. + +There is a way to filter the federated timeline to view only public posts created on your server: The **local timeline**. Mind that “local” here refers to the server, not to a geographical location. + +## Interacting with people's posts + +{{< figure src="/assets/image%20%2821%29.png" caption="An expanded view can be loaded by clicking a status in the timeline." >}} + +You can perform quick actions on a post directly from the timeline, or you can click on the post to load an expanded view that shows extra information, such as a full timestamp, interaction counts, and threaded replies, if any. The following actions can be performed on a post: + +* **Reply** to a post by clicking the arrow icon. Your toot will show up in the thread below the post you are replying to. +* **Boost** a post by clicking the cycled-arrow icon. The post will be reshared on your profile. +* **Favourite** a post by clicking the star icon. The post will be added to your favourites list, and a favourite notification will be delivered to its author. +* **Bookmark** a post by clicking the ribbon icon. The post will be privately added to your bookmarks list without generating a notification. +* Access a **menu** of additional options by clicking the ellipsis icon. + +## Notifications + +{{< figure src="/assets/image%20%2850%29.png" caption="Notifications column" >}} + +When other people interact with you or your posts, you will receive a notification depending on the type of the event. Your notifications column allows you to view all notifications in the same stream, or to filter for specific types of notifications: + +* **Mentions:** received when someone has mentioned you in a post. +* **Favourites:** received when someone has favourited one of your posts. +* **Boosts:** received when someone has boosted one of your posts. +* **Polls:** Received when a poll that you have voted in or created has ended. +* **Follows:** Received when someone has followed your profile. + +## Following profiles + +![](/assets/image%20%2811%29.png) + +As long as you encounter a person within your app’s user interface, e.g. the web interface on your home server, or your mobile app, you can just click “follow” and you won’t notice a difference if that person is on your server or not. + +However if you come across someone’s public profile hosted on a different server, there’s an obstacle: That server sees you as just another anonymous visitor. Not to worry! You can simply copy the URL of that profile, or of one of their posts, and then paste that URL into the search function. + +If you are visiting a public page on another Mastodon site, see [Using Mastodon outside of your site](external.md#remote-interactions-on-another-mastodon-site). + +## Search + +{{< figure src="/assets/image%20%2819%29.png" caption="The search function can be accessed from the sidebar." >}} + +Mastodon's basic search allows logged-in users to find toots containing a specific hashtag, or to load a user or status directly if they know the URL or address. Searching for a term will show profiles whose username or display name contains that term, as well as hashtags that match or contain that term. + +{{< figure src="/assets/image%20%2839%29.png" caption="An example of a toot being loaded directly by its URL." >}} + +{{< figure src="/assets/image%20%2823%29.png" caption="An example of accounts returned when searching for "cats"." >}} + +{{< figure src="/assets/image%20%2827%29.png" caption="An example of hashtags returned when searching for "cats"." >}} + +Admins may optionally install full-text search. Mastodon’s full-text search allows logged-in users to find results from their own toots, their favourites, and their mentions. It deliberately does not allow searching for arbitrary strings in the entire database, in order to reduce the risk of abuse by people searching for controversial terms to find people to dogpile. + +The following operators are supported: + +* **"exact phrases"** will try to find the term inside the quote marks. This allows looking only for direct matches, such as `"look at my cluckers"` to find posts explicitly telling you to look at someone's cluckers. +* **-exclude** will exclude the term prepended by a minus sign. This allows filtering out certain terms, such as `animals -cats` to find posts about animals without posts about cats. +* **+include** will include the term after the plus sign. This allows searching for multiple terms that must be included, such as `cat +dog` to find posts about both cats and dogs. + +## Direct conversations + +{{< figure src="/assets/image%20%2812%29.png" caption="A list of conversations containing direct messages." >}} + +In Mastodon, direct messages are simply toots that have the "direct" visibility selected. Visibility can be selected per-post, which allows changing the privacy level later in a thread. The direct messages column currently shows a list of all conversations containing a direct post. Clicking on a conversation will load the associated thread. + +{{< figure src="/assets/image%20%2857%29.png" caption="A direct message in a thread." >}} + +## List timelines + +Lists are subsets of your home timeline. You can create a list, give it a name, and add users that you follow to that list. + +![](/assets/image%20%2828%29.png) + +Opening a list will load that list's timeline. List timelines contain only posts by members of that list, as well as replies to you or to other members of the list. + +{{< figure src="/assets/image%20%285%29.png" caption="A list timeline" >}} + diff --git a/content/en/user/posting.md b/content/en/user/posting.md new file mode 100644 index 00000000..b54e0500 --- /dev/null +++ b/content/en/user/posting.md @@ -0,0 +1,134 @@ +--- +title: Posting toots +description: Sharing your thoughts has never been more convenient. +menu: + docs: + weight: 30 + parent: user +--- + +{{< figure src="/assets/image%20%2859%29.png" caption="Compose form with CW enabled" >}} + +## Text + +The main body of each status update can be composed using the text field. The default character limit is 500 characters. + +### Links + +{{< figure src="/assets/image%20%287%29.png" caption="Links must start with http\(s\):// and are counted as 23 characters regardless of length." >}} + +If you include links in your post, they must begin with `http://` or `https://`. All links are counted as 23 characters, no matter how long they actually are, so there is no need to use a link shortener to save characters. In fact, using a link shortener is actively discouraged. + +### Mentions + +{{< figure src="/assets/image%20%2820%29.png" caption="Suggested mentions for both local and remote users." >}} + +You can mention users by typing out their full address, e.g. `@alice@example.com`. Note that any usage of`@word` will be interpreted as mentioning the local user with the username `word`, if that user exists. Only the username part will count against your character limit -- the domain is not counted. + +### Hashtags + +{{< figure src="/assets/image%20%2825%29.png" caption="Hashtags are autosuggested by usage frequency." >}} + +You can use a `#hashtag` to make your post discoverable to anyone searching for that hashtag. Hashtags can contain alphanumeric characters and underscores, but cannot contain numbers only. + +### Custom emoji + +{{< figure src="/assets/image%20%2838%29.png" caption="An array of custom emoji are available in the selector." >}} + +Each server offers a set of custom emoji you can use, like on Discord. You can use an emoji using its shortcode like `:thounking:`, or by clicking the emoji face in the compose box and browsing through the "Custom" category. You can also browse through and search for standard unicode emoji. + +## Attachments + +You can attach either files or a poll to your status. + +### Files + +{{< figure src="/assets/image%20%2844%29.png" caption="Thumbnail for attached media, with options to delete, edit, or mark as sensitive" >}} + +Click the paper clip to attach a file to your post. You can attach the following: + +* **Images** \(PNG, JPG, GIF\) **up to 8MB**. Images will be downscaled to 1.6 megapixels \(enough for a 1280x1280 image\). Up to 4 images can be attached. + * **Animated GIFs** are converted to soundless MP4s like on Imgur/Gfycat \(**GIFV**\). You can also upload soundless MP4 and WebM, which will be handled the same way. +* **Videos** \(MP4, M4V, MOV, WebM\) **up to 40MB**. Video will be transcoded to H.264 MP4 with a maximum bitrate of 1300kbps and framerate of 60fps. +* **Audio** \(MP3, OGG, WAV, FLAC, OPUS, AAC, M4A, 3GP\) **up to 40MB**. Audio will be transcoded to MP3 using V2 VBR \(roughly 192kbps\). + +#### Editing media + +{{< figure src="/assets/image%20%2826%29.png" caption="Edit media to add a media description or choose a focal point for the preview thumbnail." >}} + +By clicking the "Edit" link on the attachment thumbnail, you can load a modal which will allow adding a media description or changing the focal point. Although optional, it is a good idea to add media descriptions that briefly describe what is in contained in the media. These descriptions will be shown when the media fails to load for any reason, or when accessed by screen readers and other assistive technology. Setting the focal point is also optional, but can make preview thumbnails looks better when they are not shown in a 16:9 aspect ratio. + +### Polls + +{{< figure src="/assets/image%20%2841%29.png" caption="A poll with 2 one-of choices, expiring in 1 day" >}} + +Click the bar graph icon to attach a poll to your post. + +* You can add up to 4 choices. Each choice can be up to 25 characters. +* Polls default to one-of / single-choice. Click on the radio button to switch your poll to any-of / multiple-choice checkboxes. +* Polls can be set to expire in 5 minutes, 30 minutes, 1 hour, 6 hours, 1 day, 3 days, or 7 days. + +## Publishing levels + +| Level | Public timelines | Permalink | Profile view | Home feeds | +| :--- | :--- | :--- | :--- | :--- | +| Public | Yes | Yes | Yes | Yes | +| Unlisted | No | Yes | Yes | Yes | +| Followers-only | No | Logged in on the same site | In-app or logged in | Yes | +| Direct | No | Logged in and mentioned | In-app or logged in | No | + +Posts can be published with four different privacy levels: + +### Public + +The default option. + +* Anyone can see your post at the permalink without logging in. +* Your post will appear in-app in the public timelines. +* Your followers will receive the post in their home feeds, and anyone mentioned will receive the post in notifications. +* Your post can be boosted into other home feeds. + +### Unlisted + +Exactly the same as public, but with the following difference: + +* Your post will not appear in Mastodon's public timelines. + +### Followers-only + +A more limited delivery option. + +* Seeing your post at the permalink requires being logged in on the same website as someone who follows you or was mentioned. +* Your post will not appear in-app except to followers browsing your profile, and to anyone mentioned. +* Your followers will receive the post in their home feeds, and anyone mentioned will receive the post in notifications. +* Your post cannot be boosted, except by yourself. + +{{< hint style="warning" >}} +To effectively publish private \(followers-only\) posts, you must **lock your account**–otherwise, anyone could follow you to view older posts. +{{< /hint >}} + +{{< hint style="danger" >}} +Please mind that post privacy on Mastodon is per-post, rather than account-wide, and as such **there is no way to make past public posts private.** +{{< /hint >}} + +### Direct + +Send your post only to mentioned users. + +* Seeing your post at the permalink requires being logged in on the same website as someone who was mentioned. +* Your post will not appear in-app except to anyone mentioned. +* Anyone mentioned will receive the post in notifications. It will not appear in the home timeline. +* Your post cannot be boosted. + +{{< hint style="warning" >}} +**Do not share dangerous and sensitive information over direct messages**. Mastodon is not an encrypted messaging app like Signal or Wire, the database administrators of the sender’s and recipient’s servers have access to the text. Use them with the same caution as you would use forum PMs, Discord PMs and Twitter DMs. +{{< /hint >}} + +## Content warnings and sensitive content + +{{< figure src="/assets/image.png" caption="A status with a CW that is marked as sensitive content." >}} + +One feature that Mastodon provides that you may not have seen on other social networks is the option to attach a content warning to your posts. When a content warning is included, the status content will be collapsed by default, and only the CW will be shown, similarly to an email subject line or a "read more" break. This can be used to add a summary or subject for your post, to collapse long posts, or to otherwise provide context or setup for the body of the post. + +When media is attached, a checkbox appears to allow you to "mark media as sensitive". This hides the full media behind a blurred thumbnail by default. Adding a CW to a post automatically marks the post as sensitive as well. + diff --git a/content/en/user/preferences.md b/content/en/user/preferences.md new file mode 100644 index 00000000..a57d7458 --- /dev/null +++ b/content/en/user/preferences.md @@ -0,0 +1,89 @@ +--- +title: Set your preferences +description: Customize things just the way you like them. +menu: + docs: + weight: 70 + parent: user +--- + +## Customizing the user interface + +### Choose a theme + +Mastodon defaults to a dark theme, but a light or high-contrast theme can be selected. + +{{< figure src="/assets/image%20%2834%29.png" caption="Mastodon light theme" >}} + +### Choose your layout + +Mastodon defaults to a simple, one-column layout with a compose box on the left and a column switcher on the right. You can choose to enable the advanced web interface, which allows you view and pin multiple columns at the same time. + +{{< figure src="/assets/image%20%2832%29.png" caption="The advanced web interface" >}} + +In either interface, updates will load automatically as new posts are available. You can enable Slow Mode to instead show a banner at the top of the column indicating the number of new items available, which will be loaded only when you click the banner. + +For accessibility reasons, the auto-play of animated GIFs is disabled by default. You can enable animated GIFs if you want to see animations. You can also reduce motion of animations throughout the UI. + +Trending hashtags can be shown or hidden below the getting started column in the advanced UI, or below the column switcher in the simple UI \(only when there is enough space to display them\). + +### Confirmation dialogs + +You can choose to require confirmation before performing certain actions. Currently, confirmations can be set before performing the following actions: + +* Unfollow +* Boost +* Delete + +### Sensitive content + +By default, any media marked as sensitive is hidden behind a click-through overlay. You can also choose to always show/hide media behind this overlay, regardless of whether it is marked as sensitive. + +Hidden and unloaded media uses a colorful gradient provided by the BlurHash algorithm, which uses the colors of the image but blurs the details. These gradients can be disabled. + +{{< figure src="/assets/image%20%286%29.png" caption="An example blurhash thumbnail" >}} + +Posts with content warnings are collapsed by default, but you can choose to always expand the warnings so that the full post is displayed. + +## Controlling your notifications + +### Sending emails + +You can choose to receive email notifications according to the type of notification you receive within Mastodon. The following notification types are available to enable: + +* Follows +* Follow requests +* Boosts +* Favourites +* Mentions + +You can also enable digest emails, which will provide you with an overview of notifications received during periods of long inactivity. + +### Hiding certain notifications + +You can choose to not receive notifications from people you don't follow, or from people who don't follow you. This will cause replies, favourites, boosts, and other interactions to not be shown to you. + +You can also choose to not receive notifications when you receive a direct message from people you don't follow. + +## Miscellaneous options + +If you opt out of search engine indexing, a `noindex` flag will be added to your public profile and status pages. + +You can choose to hide your network, which will make your following and follower lists private to you only. + +{{< figure src="/assets/image%20%284%29.png" caption="A profile that has opted to hide its network" >}} + +If you want to see posts that are boosted multiple times be reinserted into your feed at the top, you can disable boost grouping in timelines. + +### Posting defaults + +Posts default to public privacy. You can choose to default new posts as unlisted or followers-only instead. For an explanation of post privacy levels, see [Posting to your Mastodon profile > Publishing levels](posting.md#publishing-levels). + +By default, the language of your posts is automatically detected, but this detection is imprecise and may not be accurate. If you primarily or exclusively post in a certain language, it is a good idea to set that language here. + +If you often post sensitive media, you can choose to always mark your media as sensitive. + +### Filtering languages on public timelines + +You can choose to only show posts in certain detected languages while browsing the public timelines. However, note that language detection can be very imprecise, so you may still see some posts in a disabled language, or miss some posts from enabled languages. + diff --git a/content/en/user/profile.md b/content/en/user/profile.md new file mode 100644 index 00000000..f76520cc --- /dev/null +++ b/content/en/user/profile.md @@ -0,0 +1,77 @@ +--- +title: Setting up your profile +description: Get started with your new account. +menu: + docs: + weight: 20 + parent: user +--- + +## Your appearance + +{{< figure src="/assets/image%20%2829%29.png" caption="Profile cards showing display name, avatar, and header" >}} + +You can change how your profile appears to others by navigating to Settings > Profile > Appearance. + +### Display name + +Your display name is shown to other users before your address. You can set a display name up to 30 characters by default. + +### Bio + +Your bio is a short description of yourself that is displayed as a note on your profile. You can set a bio of up to 500 characters by default. + +### Avatar + +Your avatar is an icon that is displayed next to your posts and is part of your visual identity. You can upload an avatar as a PNG, GIF, or JPG image up to 2MB in size. This image will be downscaled to 400x400. + +### Header + +Your header is a banner image shown at the top of your profile, as well as in profile cards used in follow lists and account directories. You can upload a header as a PNG, GIF, or JPG image up to 2MB in size. This image will be downscaled to 1500x500. + +## Profile flags + +You can set certain flags on your profile to let others know how you use Mastodon. + +![](/assets/image%20%281%29.png) + +### Locked account + +By locking your account, two things will happen: + +* New followers will not be automatically accepted, but will instead require you to manually approve them. +* A lock icon will be shown to others, to let them know that their follow will not be immediately accepted. + +### Bot account + +Enabling the bot flag will add a bot icon to your profile. This icon will let others know that your profile may perform automated actions, or might not be monitored by a human. Other software may choose to treat bot profiles differently, but Mastodon currently treats the bot flag as a visual indication only. + +### Profile directory + +Opting in to be listed on the profile directory will make your profile discoverable through a feature that allows browsing through profiles. + +## Profile metadata + +Profile metadata is a way to add extra information to your profile that is easy to skim. You have 4 rows where you can define the label and the value. For example: + +| Label | Content | +| :--- | :--- | +| Age | 25 | +| Country | Germany | +| Pronouns | he/him | +| Website | https://example.com | + +It’s completely up to you what you put there. The content can contain mentions, hashtags, custom emojis and links. + +### Link verification + +Document-based verification and blue ticks are not possible without a central authority. However, Mastodon can cross-reference the links you put on your profile to prove that you are the real owner of those links. In case one of those links is your personal homepage that is known and trusted, it can serve as the next-best-thing to identity verification. + +If you put a link in your profile metadata, Mastodon checks if the linked page links back to your Mastodon profile. If so, you get a verification checkmark next to that link, since you are confirmed as the owner. + +Behind the scenes, Mastodon checks for the `rel="me"` attribute on the link back. Likewise, Mastodon puts `rel="me"` on the links within profile metadata. + +{{< hint style="info" >}} +Because Mastodon can be self-hosted, there is no better way to verify your identity than to host Mastodon on your own domain, which people already trust. +{{< /hint >}} + diff --git a/content/en/user/signup.md b/content/en/user/signup.md new file mode 100644 index 00000000..ede772b8 --- /dev/null +++ b/content/en/user/signup.md @@ -0,0 +1,58 @@ +--- +title: Signing up for an account +description: Find your perfect community. +menu: + docs: + weight: 10 + parent: user +--- + +## Choosing a website + +You have to choose a website to sign up on, like you would choose an e-mail provider, or a World of Warcraft realm for your new character. The website will be your service provider, hosting your account, your profile, and your home feed. + +{{< hint style="info" >}} +You can [browse a list of servers by categories and languages on joinmastodon.org](https://joinmastodon.org/#getting-started). +{{< /hint >}} + +### Understanding a website's policies + +Before you sign up for a service, it is important to understand its policies and terms of use. A Mastodon website will usually have its policies listed on the `/about/more` page, which can be found by clicking "learn more" on the landing page while not logged in to that website. + +### Signup modes + +Mastodon allows website administrators to set one of three different signup modes: open signups, invites, and approval mode. + +#### Open signup + +Some websites may allow you to register immediately -- simply fill out the registration with your username, email address, and password, and you can start using your account. + +#### Server invites + +Some websites disable the registration form, and instead require invite links to be generated and shared in order to allow people to register. + +#### Approval-based registration + +Some websites allow you to fill out a registration form, but with an additional form entry for mentioning why you want to join that website. Once you submit the form, your account must be approved by a moderator before you can start using it. + +## Your username and your domain + +Mastodon usernames actually consist of two parts: + +* The local username, e.g. `alice` +* And the domain of the website, e.g. `example.com` + +Just like an e-mail address. For convenience sake, Mastodon allows you to skip the second part when addressing people on the same server as you, but you have to keep in mind when sharing your username with other people, you need to include the domain or they won’t be able to find you as easily. + +| | | +| :--- | :--- | +| I’m @alice on Mastodon! | Wrong | +| I’m @alice@example.com on Mastodon! | Correct | +| I'm https://example.com/@alice on Mastodon! | Correct | + +The search form in Mastodon will find people either with the above address form, or the link to the person’s profile, so you can share that instead if you prefer. + +The same username _can_ be registered on different servers -- there is no way to claim all of them ahead of time. Just like with e-mail, you should not expect `alice@outlook.com` to be the same person as `alice@gmail.com` or `alice@yahoo.com`. + + + diff --git a/content/fr/_index.md b/content/fr/_index.md deleted file mode 100644 index e850fd45..00000000 --- a/content/fr/_index.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Documentation de Mastodon ---- - -Bienvenue dans la documentation de Mastodon ! - -
- {{< youtube "IPSbNdBmWKE" >}} -
- -**Choisissez ce que vous voulez voir aujourd'hui :** - -- [Apprendre à se servir de Mastodon]({{< relref "usage/basics.md" >}}) -- [Apprendre à installer Mastodon]({{< relref "administration/installation.md" >}}) -- [Apprendre à coder une application pour Mastodon]({{< relref "api/guidelines.md" >}}) diff --git a/content/fr/administration/configuration.md b/content/fr/administration/configuration.md deleted file mode 100644 index a8d3ad1c..00000000 --- a/content/fr/administration/configuration.md +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: Configuration -description: Vue d'ensemble des options de configuration de Mastodon -menu: - docs: - parent: administration - weight: 2 ---- - -Mastodon utilise des variables d'environnement pour sa configuration. - -Par commodité, Mastodon lit ces variables depuis un fichier texte nommé `.env.production` dans le dossier contenant Mastodon, mais elles peuvent toujours être outrepassées par un processus. Par exemple, les fichiers de service systemd peuvent lire des variables d'environnement depuis un `EnvironmentFile` ou des variables définies avec `Environment` dans le fichier de service directement, pour que vous puissiez avoir plusieurs configurations pour des services spécifiques. Ces variables peuvent aussi être définies quand Mastodon est exécuté depuis la ligne de commande. - -## Basique -### Fédération - -- `LOCAL_DOMAIN` -- `WEB_DOMAIN` -- `ALTERNATE_DOMAINS` - -### Secrets - -- `SECRET_KEY_BASE` -- `OTP_SECRET` -- `VAPID_PRIVATE_KEY` -- `VAPID_PUBLIC_KEY` - -### Déploiement - -- `RAILS_ENV` -- `RAILS_SERVE_STATIC_FILES` -- `RAILS_LOG_LEVEL` -- `TRUSTED_PROXY_IP` -- `SOCKET` -- `PORT` -- `NODE_ENV` -- `BIND` - -### Options pour l'aménagement des ressources - -- `WEB_CONCURRENCY` -- `MAX_THREADS` -- `PREPARED_STATEMENTS` -- `STREAMING_API_BASE_URL` -- `STREAMING_CLUSTER_NUM` - -## Connexion aux bases de données -### PostgreSQL - -- `DB_HOST` -- `DB_USER` -- `DB_NAME` -- `DB_PASS` -- `DB_PORT` -- `DATABASE_URL` - -### Redis - -- `REDIS_HOST` -- `REDIS_PORT` -- `REDIS_URL` -- `REDIS_NAMESPACE` -- `CACHE_REDIS_HOST` -- `CACHE_REDIS_PORT` -- `CACHE_REDIS_URL` -- `CACHE_REDIS_NAMESPACE` - -### ElasticSearch - -- `ES_ENABLED` -- `ES_HOST` -- `ES_PORT` -- `ES_PREFIX` - -### StatsD - -- `STATSD_ADDR` -- `STATSD_NAMESPACE` - -## Limites - -- `SINGLE_USER_MODE` -- `EMAIL_DOMAIN_WHITELIST` -- `DEFAULT_LOCALE` -- `MAX_SESSION_ACTIVATIONS` -- `USER_ACTIVE_DAYS` - -## E-mail - -- `SMTP_SERVER` -- `SMTP_PORT` -- `SMTP_LOGIN` -- `SMTP_PASSWORD` -- `SMTP_FROM_ADDRESS` -- `SMTP_DOMAIN` -- `SMTP_DELIVERY_METHOD` -- `SMTP_AUTH_METHOD` -- `SMTP_CA_FILE` -- `SMTP_OPENSSL_VERIFY_MODE` -- `SMTP_ENABLE_STARTTLS_AUTO` -- `SMTP_TLS` - -## Stockage distant des fichiers - -- `CDN_HOST` -- `S3_ALIAS_HOST` - -### Stockage local des fichiers - -- `PAPERCLIP_ROOT_PATH` -- `PAPERCLIP_ROOT_URL` - -### Amazon S3 et compatibles - -- `S3_ENABLED` -- `S3_BUCKET` -- `AWS_ACCESS_KEY_ID` -- `AWS_SECRET_ACCESS_KEY` -- `S3_REGION` -- `S3_PROTOCOL` -- `S3_HOSTNAME` -- `S3_ENDPOINT` -- `S3_SIGNATURE_VERSION` - -### Swift - -- `SWIFT_ENABLED` -- `SWIFT_USERNAME` -- `SWIFT_TENANT` -- `SWIFT_PASSWORD` -- `SWIFT_PROJECT_ID` -- `SWIFT_AUTH_URL` -- `SWIFT_CONTAINER` -- `SWIFT_OBJECT_URL` -- `SWIFT_REGION` -- `SWIFT_DOMAIN_NAME` -- `SWIFT_CACHE_TTL` - -## Authentification externe - -- `OAUTH_REDIRECT_AT_SIGN_IN` - -### LDAP - -- `LDAP_ENABLED` -- `LDAP_HOST` -- `LDAP_PORT` -- `LDAP_METHOD` -- `LDAP_BASE` -- `LDAP_BIND_DN` -- `LDAP_PASSWORD` -- `LDAP_UID` -- `LDAP_SEARCH_FILTER` - -### PAM - -- `PAM_ENABLED` -- `PAM_EMAIL_DOMAIN` -- `PAM_DEFAULT_SERVICE` -- `PAM_CONTROLLED_SERVICE` - -### CAS - -- `CAS_ENABLED` -- `CAS_URL` -- `CAS_HOST` -- `CAS_PORT` -- `CAS_SSL` -- `CAS_VALIDATE_URL` -- `CAS_CALLBACK_URL` -- `CAS_LOGOUT_URL` -- `CAS_LOGIN_URL` -- `CAS_UID_FIELD` -- `CAS_CA_PATH` -- `CAS_DISABLE_SSL_VERIFICATION` -- `CAS_UID_KEY` -- `CAS_NAME_KEY` -- `CAS_EMAIL_KEY` -- `CAS_NICKNAME_KEY` -- `CAS_FIRST_NAME_KEY` -- `CAS_LAST_NAME_KEY` -- `CAS_LOCATION_KEY` -- `CAS_IMAGE_KEY` -- `CAS_PHONE_KEY` - -### SAML - -- `SAML_ENABLED` -- `SAML_ACS_URL` -- `SAML_ISSUER` -- `SAML_IDP_SSO_TARGET_URL` -- `SAML_IDP_CERT` -- `SAML_IDP_CERT_FINGERPRINT` -- `SAML_NAME_IDENTIFIER_FORMAT` -- `SAML_CERT` -- `SAML_PRIVATE_KEY` -- `SAML_SECURITY_WANT_ASSERTION_SIGNED` -- `SAML_SECURITY_WANT_ASSERTION_ENCRYPTED` -- `SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED` -- `SAML_ATTRIBUTES_STATEMENTS_UID` -- `SAML_ATTRIBUTES_STATEMENTS_EMAIL` -- `SAML_ATTRIBUTES_STATEMENTS_FULL_NAME` -- `SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME` -- `SAML_ATTRIBUTES_STATEMENTS_LAST_NAME` -- `SAML_UID_ATTRIBUTE` -- `SAML_ATTRIBUTES_STATEMENTS_VERIFIED` -- `SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL` - -## Services cachés (Tor) - -- `http_proxy` -- `ALLOW_ACCESS_TO_HIDDEN_SERVICE` - -## Autres - -- `SKIP_POST_DEPLOYMENT_MIGRATIONS` diff --git a/content/fr/administration/installation.md b/content/fr/administration/installation.md deleted file mode 100644 index 4c8fe46b..00000000 --- a/content/fr/administration/installation.md +++ /dev/null @@ -1,339 +0,0 @@ ---- -title: Installation -description: Comment installer Mastodon sur un serveur Ubuntu 18.04 -menu: - docs: - parent: administration - weight: 1 ---- - - - -## Configuration basique du serveur (facultatif) - -Si vous configurez une nouvelle machine, il est recommandé de la sécuriser en premier lieu. En supposant que vous utilisez **Ubuntu 18.04** : - -### Refuser les connections SSH par mot de passe (clés uniquement) - -Assurez-vous tout d'abord que vous actuellement connecté à votre serveur en utilisant une clé SSH et non avec un mot de passe, sinon vous serez bloqué. La plupart des hébergeurs supportent l'envoi d'une clé SSH publique et configurent automatiquement la connexion à l'utilisateur root sur votre nouveau serveur via votre clé. - -Ouvrez `/etc/ssh/sshd_config` et cherchez `PasswordAuthentication`. Assurez-vous que la ligne n'est pas commentée et qu'elle est réglée sur `no`. Si vous avez apporté des modifications au fichier, redémarrez sshd : - -```sh -systemctl restart ssh -``` - -### Mettre à jour le système - -```sh -apt update && apt upgrade -y -``` - -### Installer fail2ban pour bloquer les tentatives de connexion répétées - -```sh -apt install fail2ban -``` - -Ouvrez `/etc/fail2ban/jail.local` et copiez-collez ceci à l'intérieur : - -```ini -[DEFAULT] -destemail = votre@adresse_mail.ici -sendername = Fail2Ban - -[sshd] -enabled = true -port = 22 - -[sshd-ddos] -enabled = true -port = 22 -``` - -Enfin, redémarrez fail2ban : - -```sh -systemctl restart fail2ban -``` - -### Installer un pare-feu et mettre uniquement sur liste blanche les ports SSH, HTTP et HTTPS - -D'abord, installez iptables-persistent. Durant l'installation, il vous sera demandé si vous voulez conserver les directives actuelles--refusez. - -```sh -apt install -y iptables-persistent -``` - -Ouvrez `/etc/iptables/rules.v4` et copiez-collez ceci à l'intérieur : - -``` -*filter - -# Autoriser tout trafic sur la boucle locale (lo0) et refuser tout trafic vers 127/8 qui n'utilise pas lo0 --A INPUT -i lo -j ACCEPT --A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT - -# Autoriser toutes les connexions entrantes établies --A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT - -# Autoriser tout le trafic sortan - vous pouvez modifier cette ligne pour n'autoriser qu'un certain type de trafic --A OUTPUT -j ACCEPT - -# Autoriser les connexions HTTP et HTTPS de n'importe où (via les ports habituels pour les sites web et SSL) --A INPUT -p tcp --dport 80 -j ACCEPT --A INPUT -p tcp --dport 443 -j ACCEPT - -# Autoriser les connexions SSH -# Le nombre juste après -dport doit être le même que celui défini dans sshd_config --A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT - -# Autoriser le ping --A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT - -# Enregistrer les accès refusés par iptables --A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 - -# Rejeter toutes les autres connexions entrantes - par défaut, refuser tout ce qui n'est pas défini explicitement par la directive ALLOW --A INPUT -j REJECT --A FORWARD -j REJECT - -COMMIT -``` - -Avec iptables-persistent, cette configuration sera chargée à chaque redémarrage. Mais puisque nous n'allons pas redémarrer tout de suite, nous devons la charger manuellement pour cette fois : - -```sh -iptables-restore < /etc/iptables/rules.v4 -``` - -## Pré-requis - -- Une machine exécutant **Ubuntu 18.04** sur laquelle vous avez un accès root -- Un **nom de domaine** (ou un sous-domaine) pour l'instance Mastodon, ex. `exemple.com` -- Un service d'envoi de courriel ou autre **serveur SMTP** - -Vous exécuterez les commandes suivantes en tant qu'utilisateur root sur le serveur. Si vous n'êtes pas encore root, identifiez-vous : - -```sh -sudo -i -``` - -### Dépôts de paquets système - -Assurez-vous que curl est installé : - -```sh -apt install -y curl -``` - -#### Node.js - -```sh -curl -sL https://deb.nodesource.com/setup_8.x | bash - -``` - -#### Yarn - -```sh -curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -``` - -### Paquets système - -```sh -apt update -apt install -y \ - imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \ - g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \ - bison build-essential libssl-dev libyaml-dev libreadline6-dev \ - zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev \ - nginx redis-server redis-tools postgresql postgresql-contrib \ - certbot yarn libidn11-dev libicu-dev libjemalloc-dev -``` - -### Installation de Ruby - -Nous utiliserons rbenv pour gérer les différentes versions de Ruby, car c'est plus facile pour récupérer les bonnes versions et se mettre à jour quand une nouvelle version est publiée. rbenv doit être installé pour qu'un seul utilisateur, nous devons donc créer le compte utilisateur que Mastodon utilisera par la suite : - -```sh -adduser --disabled-login mastodon -``` - -Nous pouvons ensuite nous identifier : - -```sh -su - mastodon -``` - -Et procéder à l'installation de rbenv et rbenv-build: - -```sh -git clone https://github.com/rbenv/rbenv.git ~/.rbenv -cd ~/.rbenv && src/configure && make -C src -echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc -echo 'eval "$(rbenv init -)"' >> ~/.bashrc -exec bash -git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build -``` - -Une fois ceci fait, nous pouvons installer la bonne version de Ruby : - -```sh -RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.6.1 -rbenv global 2.6.1 -``` - -La version de gem fournie par défaut avec ruby_2.6.1 est incompatible avec la dernière version de bundler, nous devons donc mettre à jour gem : - -``` -gem update --system -``` - -Nous aurons aussi besoin d'installer bundler : - -```sh -gem install bundler --no-document -``` - -Retournez sur root : - -```sh -exit -``` - -## Configuration -### Mettre en place PostgreSQL -#### Configurer pour des performances optimales (facultatif) - -Pour obtenir des performances optimales, vous pourriez utiliser [pgTune](https://pgtune.leopard.in.ua/#/) afin de générer une configuration adéquate et modifier les valeurs si nécessaire dans `/etc/postgresql/9.6/main/postgresql.conf` avant de redémarrer PostgreSQL avec `systemctl restart postgresql` - -#### Créer un utilisateur - -Vous devez créer un utilisateur PostgreSQL que Mastodon pourra utiliser. Il est plus facile de partir sur une authentification "ident" dans une configuration basique, c-à-d que l'utilisateur PostgreSQL n'a pas un mot de passe différent et peut être utilisé par l'utilisateur Linux portant le même nom. - -Accédez à l'interface PostgreSQL : - -```sh -sudo -u postgres psql -``` - -Là, exécutez ceci : - -``` -CREATE USER mastodon CREATEDB; -\q -``` - -C'est fait ! - -### Mettre en place Mastodon - -C'est le moment de télécharger le code source de Mastodon. Connectez-vous à l'utilisateur mastodon : - -```sh -su - mastodon -``` - -#### Récupérer le code - -Utilisez git pour télécharger la dernière version stable de Mastodon : - -```sh -git clone https://github.com/tootsuite/mastodon.git live && cd live -git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1) -``` - -#### Installer les dernières dépendances - -Maintenant, installez les dépendances Ruby et JavaScript : - -```sh -bundle install \ - -j$(getconf _NPROCESSORS_ONLN) \ - --deployment --without development test -yarn install --pure-lockfile -``` - -#### Générer un fichier de configuration - -Lancez l'assistant de configuration interactif : - -```sh -RAILS_ENV=production bundle exec rake mastodon:setup -``` - -L'assistant va : - -- Créer un fichier de configuration -- Compiler les ressources web -- Créer la base de données - -Le fichier de configuration est enregistré sous le nom de `.env.production`. Vous pouvez le relire et le modifier à votre guise. Référez-vous à la [page de documentation]({{< relref "configuration.md" >}}) à ce sujet. - -Nous en avons fini avec l'utilisateur mastodon, pour l'heure, passez à nouveau sur root : - -```sh -exit -``` - -### Mettre en place nginx - -Copiez le modèle de configuration pour nginx depuis le dossier contenant Mastodon : - -```sh -cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon -ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon -``` - -Modifiez `/etc/nginx/sites-available/mastodon` pour remplacer `example.com` par votre propre nom de domaine, et apportez les autres modifications que vous auriez à faire. - -Rechargez nginx pour que les modifications soient prises en compte : - -```sh -systemctl reload nginx -``` - -### Obtenir un certificat SSL - -Nous utiliserons Let's Encrypt pour obtenir un certificat SSL gratuitement : - -```sh -certbot certonly --webroot -d example.com -w /home/mastodon/live/public/ -``` - -Modifiez `/etc/nginx/sites-available/mastodon` pour dé-commenter et adapter à votre cas les lignes `ssl_certificate` et `ssl_certificate_key`. - -Enfin, rechargez nginx pour que les modifications soient prises en compte : - -```sh -systemctl reload nginx -``` - -Vous devriez pouvoir désormais visiter votre domaine dans un navigateur web et voir l'éléphant frappant l'ordinateur avec un message d'erreur. C'est parce que nous n'avons pas encore démarré le processus Mastodon. - -### Mettre en place les services systemd - -Copiez les modèles de fichiers service systemd depuis le dossier contenant Mastodon : - -```sh -cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/ -``` - -Ouvrez les fichiers et assurez-vous que le nom d'utilisateur et les chemins d'accès sont corrects : - -- `/etc/systemd/system/mastodon-web.service` -- `/etc/systemd/system/mastodon-sidekiq.service` -- `/etc/systemd/system/mastodon-streaming.service` - -Enfin, démarrez et activez les nouveaux services systemd : - -```sh -systemctl start mastodon-web mastodon-sidekiq mastodon-streaming -systemctl enable mastodon-* -``` - -Ils démarreront automatiquement à chaque redémarrage de la machine. - -**Hourra ! C'est enfin fini. Vous pouvez accéder à votre instance depuis votre navigateur !** diff --git a/content/fr/administration/migrating.md b/content/fr/administration/migrating.md deleted file mode 100644 index 948ab1e2..00000000 --- a/content/fr/administration/migrating.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: Migration de serveur -description: Comment migrer une instance Mastodon sur un nouveau serveur -menu: - docs: - parent: administration - weight: 6 ---- - -Parfois, pour des raisons diverses, vous avez besoin de migrer votre instance Mastodon d'un serveur à un autre. Heureusement, ce n'est pas une opération trop complexe, même si ça peut résulter en un petit temps où l'instance n'est pas utilisable. - -**Note :** ce guide a été écrit avec l'utilisation d'Ubuntu Server en tête ; certaines opérations peuvent différer si vous utilisez un autre système d'exploitation. - -Étapes basiques ----- - -1. Créez une nouvelle instance Mastodon en utilisant le [guide d'installation](/administration/installation/) (mais n'exécutez pas `mastodon:setup`). -2. Arrêtez Mastodon sur l'ancien serveur (par ex. `systemctl stop 'mastodon-*.service'`). -3. Sauvegardez et chargez la base de données PostgreSQL en suivant les instructions plus bas. -4. Copier les fichiers du dossier `system/` en suivant les instructions plus bas. (Note : si vous utilisez S3, vous pouvez passer cette étape.) -5. Copiez le fichier `.env.production`. -6. Exécutez `RAILS_ENV=production ./bin/tootctl feeds build` pour reconstruire les timelines personnelles de chaque utilisateur·ice. -7. Démarrez Mastodon sur le nouveau serveur. -8. Mettez à jour la zone DNS pour qu'elle pointe sur le nouveau serveur. -9. Mettez à jour ou copiez votre configuration Nginx, ré-exécutez LetsEncrypt si nécessaire. -10. Profitez de votre nouveau serveur ! - -Étapes détaillées ----- - -### Quelles données doivent être migrées - -Prioritairement, vous devez copier ceci : - -- Le dossier `~/live/public/system`, qui contient les photos et vidéos téléversées par les utilisateur·ice·s (si vous utilisez S3, vous n'avez pas à le faire) -- La base de données PostgreSQL (en utilisant [pg\_dump](https://www.postgresql.org/docs/9.1/static/backup-dump.html)) -- Le fichier `~/live/.env.production`, qui contient la configuration de l'instance et ses variables secrètes - -Moins important, vous voudrez probablement copier ces fichiers pour plus de commodité : - -- La configuration nginx (sous `/etc/nginx/sites-available/default`) -- Les fichiers de services systemd (`/etc/systemd/system/mastodon-*.service`), qui peuvent contenir des modifications spécifiques à votre instance -- La configuration PgBouncer dans `/etc/pgbouncer` (si vous l'utilisez) - -### Sauvegarder et charger PostgreSQL - -Au lieu d'exécuter `mastodon:setup`, on va créer une base de données PostgreSQL vide -en utilisant la base de données `template0` (qui est utile quand on restaure une sauvegarde PostgreSQL, -[comme détaillé dans la documentation de pg\_dump](https://www.postgresql.org/docs/9.1/static/backup-dump.html#BACKUP-DUMP-RESTORE)). - -Exécutez ceci en tant qu'utilisateur `mastodon` sur l'ancien serveur : - -```bash -pg_dump -Fc mastodon_production -f backup.dump -``` - -Copiez le fichier `backup.dump` sur le nouveau serveur, en utilisant `rsync` ou `scp`. Puis, sur le nouveau serveur, -créez une base de données vide en tant qu'utilisateur `mastodon` : - -```bash -createdb -T template0 mastodon_production -``` - -Et importez-la : - -```bash -pg_restore -U mastodon -n public --no-owner --role=mastodon \ - -d mastodon_production backup.dump -``` - -(Notez que si le nom d'utilisateur sur le nouveau serveur n'est pas `mastodon`, vous devriez changer les valeurs de -`-U` AND `--role` dans la commande juste au-dessus. C'est pas grave si le nom d'utilisateur est différent entre les deux serveurs.) - -### Copier les fichiers - -Cela va sûrement prendre du temps, et vous voudrez sûrement éviter de recopier des fichiers inutilement, utiliser `rsync` est donc recommandé. -Sur l'ancien serveur, en tant qu'utilisateur `mastodon`, faites : - -```bash -rsync -avz ~/live/public/system/ mastodon@exemple.fr:~/live/public/system/ -``` - -Vous répèterez l'opération si jamais les fichiers sur l'ancien serveur devaient changer. - -Vous devriez copier le fichier `.env.production`, qui contient des secrets nécessaires à l'instance. - -Optionnellement, vous pouvez copier les fichiers de configuration nginx, systemd, et pgbouncer, ou les réécrire de zéro. - -### Durant la migration - -Vous pouvez modifier le fichier `~/live/public/500.html` sur l'ancien serveur si vous voulez afficher un joli message d'erreur et permettre de faire savoir aux utilisateur·ice·s qu'une migration est en cours. - -Vous voudrez probablement modifier le TTL DNS pour quelque chose de plus petit (30 à 60 minutes) un jour à l'avance, la propagation DNS se fera ainsi plus rapidement quand vous aurez indiqué la nouvelle adresse IP. - -### Après la migration - -Vous pouvez aller sur [whatsmydns.net](http://whatsmydns.net/) pour voir la progression de la propagation DNS. -Pour ne pas attendre, vous pouvez toujours modifier votre propre fichier `/etc/hosts` pour pointer vers votre nouveau serveur et donc commencer à vous amuser avec avant les autres. diff --git a/content/fr/administration/optional-features.md b/content/fr/administration/optional-features.md deleted file mode 100644 index c2bc4ac6..00000000 --- a/content/fr/administration/optional-features.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: Fonctionnalités facultatives -description: Comment activer les fonctionnalités facultatives de Mastodon -menu: - docs: - parent: administration - weight: 5 ---- - -## Recherche plein-texte - -Mastodon supporte la recherche plein-texte quand ElasticSearch est disponible. La recherche plein-texte permet aux utilisateur·ice·s connecté·e·s de chercher dans leurs propres pouets, favoris et mentions. Cependant, la recherche plein-texte empêche délibérément de chercher arbitrairement dans toute la base de données. - -### Installer ElasticSearch - -ElasticSearch requiert un environnement java. Si vous n'avez pas Java d'installé, faites-le maintenant. En supposant que vous êtes connecté en `root` : - - apt install openjdk-8-jre-headless - -Ajoutez le dépôt logiciel officiel d'ElasticSearch : - - wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add - - echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | tee -a /etc/apt/sources.list.d/elastic-6.x.list - apt update - -Vous pouvez désormais installer ElasticSearch: - - apt install elasticsearch - -> **Avertissement de sécurité :** Par défaut, ElasticSearch est supposé se connecter à localhost uniquement, c-à-d être inaccessible depuis le réseau. Vous pouvez vérifier à quelle adresse ElasticSearch se connecte en regardant `network.host` dans le fichier `/etc/elasticsearch/elasticsearch.yml`. Considérez le fait que quiconque pouvant accéder à ElasticSearch sera en mesure de lire et de modifier n'importe quelle donnée à l'intérieur, puisqu'il n'y a pas de système d'authentification. C'est donc très important d'assurer la sécurité de la connexion. Avoir un pare-feu qui n'autorise que les ports 22, 80, et 443 est conseillé, comme expliqué dans [les instructions d'installation]({{< relref "installation.md" >}}). Si vous avez une instance répartie sur plusieurs serveurs, vous devez savoir comment sécuriser son trafic interne. - -Pour démarrer ElasticSearch: - - systemctl enable elasticsearch - systemctl start elasticsearch - -### Configurer Mastodon - -Modifiez `.env.production` pour ajouter les variables suivantes : - -```bash -ES_ENABLED=true -ES_HOST=localhost -ES_PORT=9200 -``` - -Si vous avez plusieurs instances Mastodon sur la même machine et que vous prévoyez d'utiliser la même installation d'ElasticSearch pour chacune d'entre elles, assurez-vous que chaque instance a un `REDIS_NAMESPACE` unique dans leur fichier de configuration, afin de différencier les index. Si vous avez besoin de passer outre le préfixe d'un index ElasticSearch, vous pouvez directement définir `ES_PREFIX`. - -Après avoir sauvegardé le nouveau fichier de configuration, créez l'index dans ElasticSearch avec : - - RAILS_ENV=production bundle exec rake chewy:upgrade - -Puis, redémarrez les processus Mastodon pour que la nouvelle configuration soit prise en compte : - - systemctl restart mastodon-sidekiq - systemctl reload mastodon-web - -Désormais, les nouveaux messages seront inscrits dans l'index ElasticSearch. La dernière étape est d'importer également toutes les anciennes données. Cela peut prendre du temps : - - RAILS_ENV=production bundle exec rake chewy:sync - -## Services cachés (Tor) - -Mastodon peut être accédé via Tor à l'aide d'un service caché. Cela vous donnera une addresse .onion qui ne peut être utilisée qu'en se connectant au réseau Tor. - -### Installer Tor - -Tout d'abord, le dépôt logiciel de Tor pour Debian doit être ajouté à apt. - -``` -deb https://deb.torproject.org/torproject.org stretch main -deb-src https://deb.torproject.org/torproject.org stretch main -``` - -Puis, ajoutez la clé GPG. - -```bash -curl https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --import -``` - -Enfin, installez les paquets nécessaires. - -```bash -apt install tor deb.torproject.org-keyring -``` - -### Configurer Tor - -Modifiez le fichier `/etc/tor/torrc` et ajoutez la configuration suivante. - -```bash -HiddenServiceDir /var/lib/tor/mastodon/ -HiddenServiceVersion 3 -HiddenServicePort 80 127.0.0.1:80 -``` - -Redémarrez tor. - -```bash -sudo service tor restart -``` - -Vous pouvez désormais récupérer votre adresse .onion dans le fichier `/var/lib/tor/mastodon/hostname`. Cela ne fonctionne _que_ si vous servez Mastodon à travers le port 80 et _que_ s'il s'agit du seul site que vous avez sur votre serveur. - -### Configurer un serveur web multi-sites - -Si vous avez plusieurs sites sur votre serveur web, vous devrez indiquer à votre serveur web comment servir l'adresse .onion. Dans le fichier de configuration du serveur web pour Mastodon, ajoutez une entrée additionnelle. Par exemple pour Nginx : - -```bash -server { - … - server_name mastodon.myhosting.com qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7.onion - … -} -``` - -### Servir le service caché Tor via HTTP - -Même s'il est tentant de servir votre Mastodon "caché" via HTTPS, ce n'est pas une bonne idée. Lisez [cet article de blog](https://blog.torproject.org/facebook-hidden-services-and-https-certs) du Tor Project pour savoir pourquoi les certificats SSL ne changent rien ici. Puisque vous ne pouvez pas obtenir de certificat SSL pour un .onion, vous seriez submergé d'erreurs de certificat quand vous utiliseriez votre instance Mastodon. - -La solution est de servir votre instance Mastodon via HTTP, mais uniquement pour Tor. - -Prenez pour exemple cette configuration Nginx. - -``` -server { - listen 80; - server_name mastodon.myhosting.com; - return 301 https://$host$request_uri; -} - -server { - listen 443 ssl http2; - server_name mastodon.myhomsting.com; - … -} -``` - -Ajoutez une nouvelle entrée `server` qui recopie celle ayant SSL (sans pour autant recopier les lignes concernant SSL), mais qui définit l'utilisation du port 80 avec votre adresse .onion. - -``` -server { - listen 80; - server_name mastodon.myhosting.com; - return 301 https://$host$request_uri; -} - -server { - listen 80; - server_name qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7.onion; - … -} - -server { - listen 443 ssl http2; - server_name mastodon.myhosting.com; - … -} -``` - -Redémarrez le serveur web. - -```bash -service nginx restart -``` - -Vous pouvez également lire cette [réponse sur Server Fault](https://serverfault.com/a/373661) (en anglais) pour une solution plus [DRY](https://fr.wikipedia.org/wiki/Ne_vous_r%C3%A9p%C3%A9tez_pas). - -## Connexion via LDAP/PAM/CAS/SAML - -Bientôt. - diff --git a/content/fr/administration/post-installation.md b/content/fr/administration/post-installation.md deleted file mode 100644 index 52471cff..00000000 --- a/content/fr/administration/post-installation.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: Opérations post-installation -description: Que faire après que l'installation de Mastodon soit terminée -menu: - docs: - parent: administration - weight: 3 ---- - -## Utiliser l'interface en ligne de commande - -L'interface en ligne de commande de Mastodon réside dans un fichier exécutable nommé `tootctl`, dans le répertoire `bin`, à l'intérieur du dossier contenant Mastodon. Vous devez obligatoirement spécifier dans quel mode vous avez l'intention de l'invoquer, en spécifiant la variable d'environnement `RAILS_ENV`. Vous devez utiliser `RAILS_ENV=production`, sauf si vous êtes un·e développeur·euse qui travaillerait sur sa propre machine. Si vous êtes sûr·e que vous n'utiliserez pas d'autre mode que `production` (les autres étant `development`, `test`, ou `staging`), vous pouvez ajouter cette variable dans le fichier `.bashrc` pour plus de commodité : - -```bash -echo "export RAILS_ENV=production" >> ~/.bashrc -``` - -Si vous faites ainsi, vous n'aurez pas à spécifier la variable à chaque fois. Sinon, les invocations de `tootctl` se passent généralement ainsi, en supposant que le code source de Mastodon réside dans `/home/mastodon/live` : - -```bash -cd /home/mastodon/live -RAILS_ENV=production bin/tootctl help -``` - -## Créer un compte administrateur -### Dans le navigateur - -Après avoir s'être inscrit·e depuis le navigateur, vous devrez user de la ligne de commande pour donner à votre compte fraîchement créé les privilèges administrateur. En supposant que votre nom d'utilisateur est `alice` : - -```bash -RAILS_ENV=production bin/tootctl accounts modify alice --role admin -``` - -### Depuis la ligne de commande - -Vous pouvez créer un nouveau compte à partir de la ligne de commande. - -```bash -RAILS_ENV=production bin/tootctl accounts create \ - alice \ - --email alice@exemple.fr \ - --confirmed \ - --role admin -``` - -Un mot de passé généré aléatoirement s'affichera dans le terminal. - -## Remplir les infos de l'instance - -Après vous être connecté, allez dans les paramètres, sur la page **Paramètres du site**, dans l'onglet Administration. Bien que techniquement il n'y ait pas d'obligation de fournir d'informations, c'est une tâche considérée comme cruciale quand il s'agit d'une instance dédiée à recevoir du monde dessus. - -|Paramètre|Signification| -|-------|-------| -|Nom d'utilisateur·ice|Votre nom d'utilisateur·ice pour que les gens sachent à qui appartient l'instance| -|Adresse courriel publique|Une adresse mail pour que les gens ne pouvant se connecter, ou les gens qui voudraient se créer un compte, puissent vous contacter| -|Description de l'instance|Pourquoi avez-vous créé cette instance ? À qui est-elle destinée ? Qu'est-ce qui la rend différente ? | -|Description étendue de l'instance|Vous pouvez mettre toutes sortes d'information dedans, mais mettre un **code de conduite** est recommandé. | - -Une fois fini, appuyez sur "Enregistrer les modifications". - -## Mettre en place des sauvegardes régulières (facultatif, mais pas vraiment non plus) - -Pour toute utilisation en conditions réelles, vous devriez vous assurer de faire des sauvegardes régulières de votre instance Mastodon. - -### Vue d'ensemble - -Voici les choses qui doivent être sauvegardées par ordre d'importance : - -1. La base de données PostgreSQL -2. Les secrets du fichier `.env.production` ou son équivalent -3. Les fichiers téléversés par les utilisateur·ice·s -4. La base de données Redis - -### Types de défaillances - -Il y a deux types de défaillances que les gens vont essayer d'éviter : la défaillance du matériel, comme la corruption des données sur le disque dur ; et l'erreur humaine et logicielle, comme une suppression involontaire des données. Dans cette documentation, on ne parlera que du premier type. - -Une base de données PostgreSQL effacée ou perdue, et c'est le game over. Mastodon stocke toutes les données les plus importantes dans la base de données PostgreSQL. Si la base de données disparaît, tous les comptes, posts et abonné·e·s de votre instance disparaîtront avec. - -Si vous perdez les secrets de configuration, certaines fonctionnalités de Mastodon cesseront de fonctionner, vos utilisateur·ice·s seront déconnectés, la double authentification (2FA) sera indisponible, les notifications push ne seront plus délivrées. - -Si vous perdez les fichiers téléversés par les utilisateur·ice·s, vous perdrez les photos de profil, bannières et photos rattachés aux posts, mais Mastodon continuera de fonctionner. - -Perdre la base de données Redis est presque inoffensif : les seules données irrécupérables seront le contenu des queues Sidekiq et les retentatives planifiées de tâches qui ont échouées. Les timelines personnelles et celles des listes sont stockées dans Redis, mais elles peuvent être refaites avec `tootctl`. - -Les meilleures sauvegardes sont celles qui sont "hors-site", c-à-d des sauvegardes qui ne sont pas sur la même machine que celle où se trouve Mastodon. Si le serveur que vous utilisez prend feu et que le disque dur explose, les sauvegardes qui sont dessus ne seront pas d'une grande aide. - -### Sauvegarder les secrets - -Les secrets sont les plus simples à sauvegarder, puisqu'ils ne changent jamais. Vous n'avez qu'à sauvegarder `.env.production` dans un endroit sûr. - -### Sauvegarder PostgreSQL - -PostgreSQL encoure le risque d'avoir des données corrompues à cause d'une coupure de courant, un disque dur défectueux, et des schémas de migrations bâclés. Pour cette raison, faire une sauvegarde de temps en temps avec `pg_dump` ou `pg_dumpall` est recommandé. - -Pour des configurations nécessitant une haute disponibilité, il est possible de répliquer la base de données afin d'avoir un deuxième serveur PostgreSQL avec des données constamment à jour, prêt à être utilisé si le premier est indisponible. - -### Sauvegarder les fichiers téléversés par les utilisateur·ice·s - -Si vous utilisez un fournisseur de stockage externe comme Amazon S3, Google Cloud ou Wasabi, vous n'avez pas besoin de vous inquiétez pour les sauvegardes. Ces entreprises sont responsables des défaillances matérielles. - -Si vous stockez localement les fichiers, c'est à vous de faire des copies du volumineux dossier `public/system`, où les fichiers téléversés sont stockés par défaut. - -### Sauvegarder Redis - -Sauvegarder Redis est simple. Redis écrit régulièrement dans `/var/lib/redis/dump.rdb`, qui est le seul fichier que vous avez à récupérer. diff --git a/content/fr/administration/scaling-up.md b/content/fr/administration/scaling-up.md deleted file mode 100644 index d058c86a..00000000 --- a/content/fr/administration/scaling-up.md +++ /dev/null @@ -1,265 +0,0 @@ ---- -title: Amélioration des performances -description: Comment améliorer Mastodon de manière horizontale pour gérer plus de requêtes -menu: - docs: - parent: administration - weight: 4 ---- - -## Gérer la simultanéité des processus - -Mastodon possède trois types de processus : - -- Web (Puma) -- API de streaming -- Tâches de fond (Sidekiq) - -### Web (Puma) - -Le processus web sert les requêtes HTTP à durée de vie courte sur la majorité de l'application. Les variables d'environnement suivantes contrôlent ce processus : - -- `WEB_CONCURRENCY` définit le nombre de processus créés -- `MAX_THREADS` définit le nombre de threads par processus - -Les threads se partagent la mémoire RAM du processus parent. Les processus se réservent de la mémoire RAM, même s'ils peuvent en partager entre eux via le copy-on-write. Un plus grand nombre de threads va faire monter votre processeur à 100% d'utilisation plus rapidement, un plus grand nombre de processus va remplir votre RAM plus rapidement. - -Ces valeurs agissent sur le nombre de requêtes HTTP qui pourront être traitées simultanément. - -En termes de rendement, avoir plus de processus est mieux qu'avoir plus de threads. - -### API de streaming - -L'API de streaming gère les connexions HTTP et WebSocket à durée de vie longue, à travers lesquelles les clients reçoivent en temps réel les mises à jour de statuts. Les variables d'environnement suivantes contrôlent ce processus : - -- `STREAMING_CLUSTER_NUM` définit le nombre de processus créés -- `STREAMING_API_BASE_URL` définit l'URL de l'API de streaming - -Un seul processus peut gérer un nombre considérable de connexions. L'API de streaming peut être hébergée sur un sous-domaine différent si vous le voulez, par exemple pour gagner du temps lorsque nginx relaie les connexions. - -### Tâches de fond (Sidekiq) - -Beaucoup de tâches dans Mastodon sont reléguées à l'arrière-plan afin de s'assurer que les requêtes HTTP soient rapidement traitées, et pour empêcher que des requêtes HTTP abandonnées n'affectent l'exécution de ces tâches. Sidekiq est un processus unique, avec un nombre définissable de threads. - -#### Nombre de threads - -Tandis que le nombre de threads dans le processus Web a un impact sur la réactivité de l'instance Mastodon pour l'utilisateur·ice final·e, le nombre de threads alloués aux tâches de fond a un impact sur la rapidité à laquelle les posts seront envoyés de l'instance aux autres, sur le temps qu'il faudra pour qu'un courriel soit expédié, etc. - -Le nombre de threads n'est pas défini par une variable d'environnement ici, mais par un argument lors de l'invocation de Sidekiq, par exemple : - -```sh -bundle exec sidekiq -c 15 -``` - -ferait démarrer le processus sidekiq avec 15 threads. Gardez à l'esprit que chaque thread doit être en mesure de se connecter à la base de données PostgreSQL, ce qui signifie que le pool de connexions à la base de données doit être suffisamment large pour supporter tous les threads. La taille de ce pool est définie avec l'environnement de variable `DB_POOL` et doit être au moins égale au nombre de threads. - -#### Queues - -Sidekiq utilise différentes queues pour les tâches d'importance variable, où l'importance est définie par l'impact sur l'expérience utilisateur qu’aurait une queue dysfonctionnelle, par ordre décroissant. - -|Queue|Importance| -|:---:|------------| -|`default`|Toutes les tâches qui affectent les utilisateur·ice·s de l'instance| -|`push`|La délivrance de contenus aux autres instances| -|`mailers`|L'envoi des courriels| -|`pull`|La récupération de contenus depuis d'autres instances| - -Les queues par défaut et leurs priorités sont stockées dans `config/sidekiq.yml`, mais elles peuvent être outrepassées lors de l'invocation de Sidekiq via la ligne de commandes, par exemple : - -```sh -bundle exec sidekiq -q default -``` - -n'exécutera que la queue `default`. - -Sidekiq travaille d'une certaine façon avec les queues, il vérifie d'abord s'il y a des tâches à effectuer dans la première queue, et s'il n'y en a pas, il vérifie dans la queue suivante. Cela signifie que, si la première queue est pleine à craquer, les autres queues devront patienter. - -En guise de solution, il est possible de démarrer plusieurs processus Sidekiq pour assurer une vraie exécution parallèle des queues, par exemple en créant plusieurs services systemd pour Sidekiq avec différents arguments. - -## Mise en commun des transactions avec PgBouncer -### Pourquoi vous avez potentiellement besoin de PgBouncer - -Si vous commencez à manquer de connexions vers PostgreSQL (la valeur par défaut étant de 100 connexions), alors vous pourriez trouver en PgBouncer une bonne solution. Cette section détaille des pièges récurrents ainsi que des exemples de configurations optimales pour Mastodon. - -Notez que vous pouvez aller voir "PgHero" dans la partie administration de votre instance pour savoir combien de connexions à PostgreSQL sont actuellement utilisées. Habituellement, Mastodon utilise autant de connexions qu'il y a de threads dans Puma, Sidekiq et l'API de streaming réunis. - -### Installer PgBouncer - -Sur Debian et Ubuntu: - - sudo apt install pgbouncer - -### Configurer PgBouncer -#### Définir un mot de passe - -Tout d'abord, si l'utilisateur `mastodon` dans PostgreSQL n'a pas de mot de passe, vous devrez en définir un. - -Voilà comment vous pourriez redéfinir le mot de passe : - - psql -p 5432 -U mastodon mastodon_production -w - -Puis (évidemment, utilisez un autre mot de passe que le mot "password") : - - ALTER USER mastodon WITH PASSWORD 'password'; - -Puis faites `\q` pour quitter. - -#### Configurer userlist.txt - -Modifiez `/etc/pgbouncer/userlist.txt` - -Du moment que vous spécifiez un utilisateur et un mot de passe dans pgbouncer.ini plus tard, les valeurs dans userlist.txt n'ont *pas* besoin de correspondre à de vrais utilisateurs dans PostgreSQL. Vous pouvez définir arbitrairement des utilisateurs et leurs mots de passe, mais vous pouvez aussi réutiliser les "vrais" identifiants pour plus de simplicité. Ajoutez l'utilisateur `mastodon` dans le fichier `userlist.txt` : - - "mastodon" "md5d75bb2be2d7086c6148944261a00f605" - -On utilise ici le schéma MD5, où le mot de passe est juste la somme MD5 de `mot de passe + utilisateur` avec le préfixe `md5`. Par exemple, pour générer le hash avec l'utilisateur `mastodon` et le mot de passe `password`, vous pouvez faire : - -```bash -# Ubuntu, Debian, etc. -echo -n "passwordmastodon" | md5sum -# macOS, OpenBSD, etc. -md5 -s "passwordmastodon" -``` - -Et vous n'avez plus qu'à ajouter `md5` au début de la ligne. - -Vous voudrez aussi créer un administrateur `pgbouncer` afin de vous connecter à la base de données administrateur PgBouncer. Voici un exemple de fichier `userlist.txt` : - -``` -"mastodon" "md5d75bb2be2d7086c6148944261a00f605" -"pgbouncer" "md5a45753afaca0db833a6f7c7b2864b9d9" -``` - -Dans les deux cas le mot de passe est `password`. - -#### Configurer pgbouncer.ini - -Modifiez `/etc/pgbouncer/pgbouncer.ini` - -Ajoutez une ligne en dessous de `[databases]` qui liste les bases de données PostgreSQL auxquelles vous voulez vous connecter. PgBouncer utilisera ici le même utilisateur/mot de passe et le même nom de base de données pour se connecter à PostgreSQL : - -```ini -[databases] -mastodon_production = host=127.0.0.1 port=5432 dbname=mastodon_production user=mastodon password=password -``` - -Les variables `listen_addr` et `listen_port` indiquent à PgBouncer sur quelle adresse/port accepter les connexions. Ces valeurs par défaut sont convenables. - -```ini -listen_addr = 127.0.0.1 -listen_port = 6432 -``` - -Mettez `md5` comme valeur pour `auth_type` (en supposant que vous utilisez le format MD5 dans `userlist.txt`) : - -```ini -auth_type = md5 -``` - -Assurez-vous que l'utilisateur `pgbouncer` est un administrateur : - -```ini -admin_users = pgbouncer -``` - -**Ce qui suit est très important !** Le mode par défaut du pool de connexions est "par session", tandis que Mastodon utilise le mode "par transaction". Autrement dit, une connexion PostgreSQL est initiée quand une transaction est créée, et se ferme quand la transaction est terminée. Vous voudrez donc changez la valeur de la variable `pool_mode` de `session` à `transaction` : - -```ini -pool_mode = transaction -``` - -Ensuite, `max_client_conn` définit combien de connexions PgBouncer lui-même va accepter, et `default_pool_size` pose une limite sur le nombre de connexions à PostgreSQL qui pourront être initiées. (Dans PgHero, le nombre de connexions affichées correspondra à `default_pool_size` parce qu'il ignore la présence de PgBouncer.) - -Les valeurs par défaut sont bonnes pour débuter, vous pourrez toujours les augmenter plus tard : - -```ini -max_client_conn = 100 -default_pool_size = 20 -``` - -N'oubliez pas de recharger ou redémarrer PgBouncer après avoir sauvegardé vos modifications : - - sudo systemctl reload pgbouncer - -#### Vérifier que tout fonctionne - -Vous devriez être en mesure de vous connecter à PgBouncer de la même manière qu'avec PostgreSQL : - - psql -p 6432 -U mastodon mastodon_production - -Et utiliser votre mot de passe pour vous connecter. - -Vous pouvez aussi regarder les logs de PgBouncer ainsi : - - tail -f /var/log/postgresql/pgbouncer.log - -#### Configurer Mastodon afin qu'il puisse communiquer avec PgBouncer - -Dans le fichier `.env.production`, assurez-vous que la variable suivante est définie ainsi : - -```bash -PREPARED_STATEMENTS=false -``` - -Vu qu'on fait une mise en commun des transactions, on ne peut pas utiliser des déclarations prédéfinies. - -Ensuite, configurez Mastodon pour qu'il utilise le port 6432 (PgBouncer) au lieu du port 5432 (PostgreSQL) et vous devriez pouvoir utiliser votre instance par la suite : - -```bash -DB_HOST=localhost -DB_USER=mastodon -DB_NAME=mastodon_production -DB_PASS=password -DB_PORT=6432 -``` - -> **Hop hop hop !** Vous ne pouvez pas utiliser PgBouncer pour effectuer les tâches `db:migrate`. Mais il est facile de contourner le problème. Si PostgreSQL et PgBouncer sont sur la même machine, il suffit de définir `DB_PORT=5432` en plus de `RAILS_ENV=production` quand vous invoquez la tâche. Par exemple : `RAILS_ENV=production DB_PORT=5432 bundle exec rails db:migrate` (vous pouvez aussi définir `DB_HOST` si l'un des deux services n'est pas sur la même machine, etc.) - -#### Administrer PgBouncer - -La façon la plus simple de redémarrer PgBouncer est de faire ainsi : - - sudo systemctl restart pgbouncer - -Mais si vous avez créé un utilisateur avec les droits administrateurs dans PgBouncer, vous pouvez aussi vous connecter en tant qu'administrateur : - - psql -p 6432 -U pgbouncer pgbouncer - -Puis faire : - - RELOAD; - -Et enfin quitter en faisant `\q`. - -## Un Redis séparé pour le cache - -Redis est largement utilisé à travers l'application, mais certaines utilisations de Redis sont plus importantes que d'autres. Les timelines personnelles et des listes, les queues Sidekiq ainsi que l'API de streaming sont fournies par Redis et ce sont des données importantes que vous ne voudriez pas perdre (même si cette perte peut être surmontée, contrairement à celle de la base de données PostgreSQL – ne la perdez jamais !). Cependant, Redis est aussi utilisé pour le cache volatile. Si vous en êtes arrivés au stade dans l'amélioration des performances où vous avez peur que Redis ne puisse tout gérer, vous pouvez utiliser une autre base de données Redis pour le cache. Dans l'environnement d'exécution, vous pouvez spécifier la variable `CACHE_REDIS_URL` ou des variables plus restreintes comme `CACHE_REDIS_HOST`, `CACHE_REDIS_PORT`, etc. Les variables non définies auront les valeurs par défaut, celles utilisées s'il n'y avait pas de deuxième cache. - -Si vous voulez configurer la base de données Redis, vous pouvez vous débarrasser de l'écriture en arrière-plan des données sur le disque, puisque ce n'est pas très important si les données sont perdues au redémarrage, et vous pourrez ainsi économiser des accès lecture/écriture sur le disque. Vous pouvez également ajouter une limite d'utilisation de mémoire et une règle de suppression de données obsolètes, mais pour ça, il faudra lire cette page (en anglais) : [Using Redis as an LRU cache](https://redis.io/topics/lru-cache) - -## Réplication des données - -Pour réduire la charge sur votre serveur PostgreSQL, vous pourriez mettre en place une réplication des données (read replica). [Lisez ce guide pour voir un exemple](https://cloud.google.com/community/tutorials/setting-up-postgres-hot-standby). Vous pouvez utiliser la réplication dans Mastodon de différentes manières : - -- L'API de streaming ne génère pas d'écritures sur le disque, vous pouvez donc connecter l'API directement au serveur répliquant. Mais puisque l'API n’interroge pas souvent la base de données, l'impact sur les performances sera moindre. -- Utiliser Makara dans les processus Web et Sidekiq, ainsi les écritures iront sur le serveur principal tandis que les lectures iront sur le serveur répliquant. Voyons cela plus en détail. - -Vous aurez à modifier le fichier `config/database.yml` et remplacer la section `production` ainsi : - -```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 -``` - -Assurez-vous que les URL pointent au bon endroit. Vous pouvez ajouter plusieurs serveurs pour répliquer les données. Vous pouvez avoir PgBouncer installé sur le serveur hébergeant Mastodon, avec une configuration connectant PgBouncer à deux serveurs PostgreSQL différents en fonction du nom de la base de données appelée, par exemple "mastodon" irait sur le serveur principal et "mastodon_replica" irait sur le répliquant. Dans le fichier ci-dessus, les deux URL pointeraient sur PgBouncer avec le même utilisateur, le même mot de passe, le même hôte et port, mais avec un nom de base de données différent. Les possibilités sont infinies ! Pour plus d'informations sur Makara, [consultez leur documentation](https://github.com/taskrabbit/makara#databaseyml). diff --git a/content/fr/administration/troubleshooting.md b/content/fr/administration/troubleshooting.md deleted file mode 100644 index 8243f0c9..00000000 --- a/content/fr/administration/troubleshooting.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Résolution de problèmes -description: Comment trouver ce qui ne va pas avec votre instance Mastodon -menu: - docs: - parent: administration - weight: 99 ---- - -**Je vois une page d'erreur qui dit que quelque chose ne s'est pas bien passé. Comment je fais pour savoir ce qui ne va pas ?** - -Tous les messages d'erreur avec des stack traces sont inscrits dans le log système. Si vous utilisez systemd, les logs de chaque service systemd peuvent être lus avec `journalctl -u mastodon-web` (remplacez avec le nom du service désiré). Si vous utilisez Docker, c'est à peu près pareil : `docker logs mastodon_web_1` (remplacez avec le nom du conteneur désiré). - -Le détail des erreurs côté serveur n'est *jamais* donné au public, puisqu'il peut révéler comment votre instance est configurée et cela peut donner aux attaquants des indices pour s'infiltrer dans le système ou mieux en abuser. - -Chaque réponse du serveur web Mastodon est accompagné d'un header avec un identifiant de requête unique, qui apparaît dans les logs. En inspectant les headers de la page d'erreur, vous pourrez facilement retrouver la stack trace correspondante dans les logs. - -**Après avoir mis à jour vers une version supérieure, quelques pages s'affichent bizarrement. Pourquoi ?** - -Vérifier que vous avez exécuté `RAILS_ENV=production bin/rails assets:precompile` après la mise à jour, et redémarré le processus web de Mastodon, puisqu'il semble que le processus envoie encore des feuilles de style et des scripts périmés. Il se peut aussi que la précompilation ait échouée à cause d'un manque de mémoire RAM, webpack prenant malheureusement beaucoup trop de mémoire. Si c'est le cas, assurez-vous d'avoir un espace swap de disponible. Sinon, il est possible de pré-compiler les ressources web sur une autre machine, et de les copier ensuite dans le dossier `public/packs`. - -**Après avoir mis à jour vers une version supérieure, certaines requêtes échouent et les logs montrent des messages d'erreurs à propos de colonnes ou tables manquantes. Pourquoi ?** - -Vérifiez que vous avez exécuté `RAILS_ENV=production bin/rails db:migrate` après la mise à jour, puisqu'il semble que votre Mastodon essaye d'accéder à un schéma de base de données plus ancien ou plus récent que prévu. Si vous utilisez PgBouncer, assurez-vous que cette commande le connecte directement à PostgreSQL, puisque PgBouncer ne supporte pas vraiment les verrouillages de tables qui sont utilisés lors des mises à jour. - -**J'essaye d'exécuter une commande `tootctl` ou `rake`/`rails`, mais tout ce que j'obtiens est une erreur à propos de constantes non initialisées. Qu'est-ce qui ne va pas ?** - -Vérifiez que vous avez mis `RAILS_ENV=production` avant le début de votre commande. Par défaut, Mastodon s'exécute dans un environnement supposé être de développement, donc il essaye de charger des gemmes Ruby liées au développement. Cependant, dans un environnement de production, on évite d'installer ces gems Ruby, et c'est de là que vient l'erreur. diff --git a/content/fr/administration/upgrading.md b/content/fr/administration/upgrading.md deleted file mode 100644 index d92b0e84..00000000 --- a/content/fr/administration/upgrading.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Mettre à jour son instance -description: Comment mettre à jour Mastodon vers une version plus récente -menu: - docs: - parent: administration - weight: 5 ---- - -Quand une nouvelle version de Mastodon est publiée, elle apparaît sur la [page des versions sur GitHub](https://github.com/tootsuite/mastodon/releases). Notez toutefois qu'exécuter du code de la branche `master` (et donc pas prêt pour le grand public) est dans la plupart des cas non recommandé. - -Les versions de Mastodon correspondent aux étiquettes git. Tout d'abord, connectez-vous avec l'utilisateur `mastodon` : - -```sh -su - mastodon -``` - -Allez à la racine du répertoire contenant Mastodon : - -```sh -cd /home/mastodon/live -``` - -Téléchargez le code de la dernière version, en supposant ici que la dernière version se nomme `v2.5.0` : - -```sh -git fetch --tags -git checkout v2.5.0 -``` - -La page des versions contient une liste des modifications et nouveautés apportées par une version, et en dessous, les instructions pour réaliser la mise à jour (en anglais). Si la dernière version nécessite par exemple de recompiler les ressources web, vous exécuteriez cette commande : - -```sh -RAILS_ENV=production bundle exec rails assets:precompile -``` - -Après avoir exécuté toutes les instructions spécifiques à la dernière version, il ne reste plus qu'à redémarrer Mastodon. *Habituellement*, l'API de streaming n'est pas mise à jour et ne nécessite pas de redémarrage. La redémarrer pourrait causer une charge inhabituellement haute sur le serveur, il est donc conseillé d'éviter de le faire le plus possible. - -Déconnectez-vous pour retourner à l'utilisateur root : - -```sh -exit -``` - -Vous devriez redémarrer Sidekiq : - -```sh -systemctl restart mastodon-sidekiq -``` - -Et vous devriez recharger le processus web pour éviter une période d'indisponibilité de l'instance : - -```sh -systemctl reload mastodon-web -``` - -**C'est tout !** Vous utilisez désormais la dernière version de Mastodon. diff --git a/content/fr/api/authentication.md b/content/fr/api/authentication.md deleted file mode 100644 index ee65649d..00000000 --- a/content/fr/api/authentication.md +++ /dev/null @@ -1,48 +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 - -## OAuth 2 endpoints - -The following descriptions are taken from the [Doorkeeper documentation](https://github.com/doorkeeper-gem/doorkeeper/wiki/API-endpoint-descriptions-and-examples). Mastodon uses Doorkeeper to implement OAuth 2. - -### GET /oauth/authorize - -Redirect here with `response_type=code`, `client_id`, `client_secret`, `redirect_uri`, `scope`. Displays an authorization form to the user. If approved, it will create and return an authorization code, then redirect to the desired `redirect_uri`, or show the authorization code if `urn:ietf:wg:oauth:2.0:oob` was requested. - -### POST /oauth/token - -Post here with `authorization_code` for authorization code grant type or `username` and `password` for password grant type. Returns an access token. This corresponds to the token endpoint, section 3.2 of the OAuth 2 RFC. - -### POST /oauth/revoke - -Post here with client credentials (in basic auth or in params `client_id` and `client_secret`) to revoke an access token. This corresponds to the token endpoint, using the OAuth 2.0 Token Revocation RFC (RFC 7009). - -## Example authorization code flow - -1. Get `client_id` and `client_secret` from your local cache. If you don't have the two, you need to [register the application]({{< relref "api/rest/apps.md#post-api-v1-apps" >}}). Store `client_id` and `client_secret` in your local cache for next time. We actually don't need the `id` returned from this call. -1. Tell the user to visit `/oauth/authorize` with parameters `scope`, `response_type=code`, `redirect_uri`, and your `client_id`. The user clicks on the URL and gets shown a page asking them to authorize your app for the scopes you requested. If the user clicks on the right button, they are redirected back to your `redirect_uri` with a `code` param in the query string. That is the authorization code. -1. Send a POST request to `/oauth/token` with the parameters `client_id`, `client_secret`, `grant_type=authorization_code`, `code`, `redirect_uri`. Save the `access_token` you get back in your local cache. Note that an authorization code can only be used once. If it has been used already, you need to repeat step two to get a new one. - -Once you have the access token, add the HTTP header `Authorization: Bearer ...` to any API call. - -## Common gotchas - -- The OAuth param name is `scope`, but when registering the application using Mastodon's REST API, the param name is `scopes`. The OAuth param can be a subset of the scopes you registered initially, but cannot include anything that wasn't in the original set. -- The OAuth param name is `redirect_uri`, but when registering the application using Mastodon's REST API, the param name is `redirect_uris`. The latter can actually consist of multiple allowed URIs, separated by newlines. -- The `redirect_uri` in all OAuth requests must either be the same as the one registered with the application, or one of them, if you registered multiple URIs separated by newlines with the application. \ No newline at end of file diff --git a/content/fr/api/entities.md b/content/fr/api/entities.md deleted file mode 100644 index e4e8df2e..00000000 --- a/content/fr/api/entities.md +++ /dev/null @@ -1,379 +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 string representations of integers. - - IDs can be sorted first by size, and then lexically, to produce a chronological ordering of resources. -- 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| - -### Token - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `access_token` | String |{{< no >}}|0.1.0| -| `token_type` | String |{{< no >}}|0.1.0| -| `scope` | String |{{< no >}}|0.1.0| -| `created_at` | Number |{{< no >}}|0.1.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 (ISO 639, Part 1-5) |{{< 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` - -## Poll - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `id` | String |{{< no >}}|2.8.0| -| `expires_at` | String (Datetime) |{{< yes >}}|2.8.0| -| `expired` | Boolean |{{< no >}}|2.8.0| -| `multiple` | Boolean |{{< no >}}|2.8.0| -| `votes_count` | Number |{{< no >}}|2.8.0| -| `options` | Array of [Poll option](#poll-option) |{{< no >}}|2.8.0| -| `voted` | Boolean |{{< yes >}}|2.8.0| - -### Poll option - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `title` | String |{{< no >}}|2.8.0| -| `votes_count` | Number |{{< yes >}}|2.8.0| - -## 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| -| `card` | [Card](#card) |{{< yes >}}|2.6.0| -| `poll` | [Poll](#poll) |{{< yes >}}|2.8.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` - -## ScheduledStatus - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `id` | String |{{< no >}}|2.7.0| -| `scheduled_at` | String (Datetime) |{{< no >}}|2.7.0| -| `params` | Array of [Hash](#statusparams) |{{< no >}}|2.7.0| -| `media_attachments` | Array of [Attachment](#attachment) |{{< no >}}|2.7.0| - -### StatusParams - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `text` | String |{{< no >}}|2.7.0| -| `in_reply_to_id` | String |{{< yes >}}|2.7.0| -| `media_ids` | Array of String |{{< yes >}}|2.7.0| -| `sensitive` | Boolean |{{< yes >}}|2.7.0| -| `spoiler_text` | String |{{< yes >}}|2.7.0| -| `visibility` | [String (Enum)](#visibility) |{{< no >}}|2.7.0| -| `scheduled_at` | String (Datetime) |{{< yes >}}|2.7.0| -| `application_id` | String |{{< no >}}|2.7.0| - -## 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| - -### Conversation - -|Attribute|Type|Nullable|Added in| -|---------|-----------|:------:|:------:| -| `id` | String |{{< no >}}|2.6.0| -| `accounts` | Array of [Account](#account) |{{< no >}}|2.6.0| -| `last_status` | [Status](#status) |{{< yes >}}|2.6.0| -| `unread` | Boolean |{{< no >}}|2.6.0| diff --git a/content/fr/api/guidelines.md b/content/fr/api/guidelines.md deleted file mode 100644 index b9ef1ec2..00000000 --- a/content/fr/api/guidelines.md +++ /dev/null @@ -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: `

`, `
`, ``, `` - -### Mentions and hashtags - -Mentions and hashtags are `` 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 - - - example.com/page - - -``` - -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. diff --git a/content/fr/api/libraries.md b/content/fr/api/libraries.md deleted file mode 100644 index aca2a99e..00000000 --- a/content/fr/api/libraries.md +++ /dev/null @@ -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) diff --git a/content/fr/api/parameters.md b/content/fr/api/parameters.md deleted file mode 100644 index b1054e92..00000000 --- a/content/fr/api/parameters.md +++ /dev/null @@ -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. diff --git a/content/fr/api/permissions.md b/content/fr/api/permissions.md deleted file mode 100644 index 01770a07..00000000 --- a/content/fr/api/permissions.md +++ /dev/null @@ -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. diff --git a/content/fr/api/push.md b/content/fr/api/push.md deleted file mode 100644 index bc763643..00000000 --- a/content/fr/api/push.md +++ /dev/null @@ -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" >}}). diff --git a/content/fr/api/rest/accounts.md b/content/fr/api/rest/accounts.md deleted file mode 100644 index 9ff50292..00000000 --- a/content/fr/api/rest/accounts.md +++ /dev/null @@ -1,203 +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" >}} - -## POST /api/v1/accounts - -Returns [Token]({{< relref "entities.md#token" >}}) - -The method is available to apps with a token obtained via the client credentials grant. It creates a user and account records, as well as an access token for the app that initiated the request. The user is unconfirmed, and an e-mail is sent as usual. - -The method returns the access token, which the app should save for later. The REST API is not available to users with unconfirmed accounts, so the app must be smart to wait for the user to click a link in their e-mail inbox. - -The method is rate-limited by IP to 5 requests per 30 minutes. - -### Resource information - -{{< api_method_info auth="Yes" user="No" scope="write write:accounts" version="2.7.0" >}} - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `username` | User name | Required | -| `email` | E-mail address | Required | -| `password` | Password text | Required | -| `agreement` | Agreement to local rules, terms of use, privacy policy (Bool) | Required | -| `locale` | The language of the e-mail to be sent first | Required | - -The `agreement` parameter must be set to true after presenting the local rules, terms of use, privacy policy for the user and obtaining consent. - -## 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|Added in| -|----|-----------|:------:|:-----:|:------:| -| `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 | | | -| `exclude_reblogs` | Skip statuses that are reblogs of other statuses | Optional | false | 2.7.0 | - -### 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 | diff --git a/content/fr/api/rest/apps.md b/content/fr/api/rest/apps.md deleted file mode 100644 index d35ea028..00000000 --- a/content/fr/api/rest/apps.md +++ /dev/null @@ -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="2.0.0" >}} diff --git a/content/fr/api/rest/blocks.md b/content/fr/api/rest/blocks.md deleted file mode 100644 index bcc455e7..00000000 --- a/content/fr/api/rest/blocks.md +++ /dev/null @@ -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" >}} diff --git a/content/fr/api/rest/custom-emojis.md b/content/fr/api/rest/custom-emojis.md deleted file mode 100644 index 00d412c1..00000000 --- a/content/fr/api/rest/custom-emojis.md +++ /dev/null @@ -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="2.0.0" >}} diff --git a/content/fr/api/rest/domain-blocks.md b/content/fr/api/rest/domain-blocks.md deleted file mode 100644 index 051dc6f8..00000000 --- a/content/fr/api/rest/domain-blocks.md +++ /dev/null @@ -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="1.4.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="1.4.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="1.4.0" >}} - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `domain` | Domain to unblock| Required | diff --git a/content/fr/api/rest/endorsements.md b/content/fr/api/rest/endorsements.md deleted file mode 100644 index 6f317e0b..00000000 --- a/content/fr/api/rest/endorsements.md +++ /dev/null @@ -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="2.5.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="2.5.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="2.5.0" >}} diff --git a/content/fr/api/rest/favourites.md b/content/fr/api/rest/favourites.md deleted file mode 100644 index fa4e15c2..00000000 --- a/content/fr/api/rest/favourites.md +++ /dev/null @@ -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" >}}) diff --git a/content/fr/api/rest/filters.md b/content/fr/api/rest/filters.md deleted file mode 100644 index 93f53706..00000000 --- a/content/fr/api/rest/filters.md +++ /dev/null @@ -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="2.4.3" >}} - -## 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="2.4.3" >}} - -### 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="2.4.3" >}} - -## 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="2.4.3" >}} - -### 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="2.4.3" >}} diff --git a/content/fr/api/rest/follow-requests.md b/content/fr/api/rest/follow-requests.md deleted file mode 100644 index 161df7d1..00000000 --- a/content/fr/api/rest/follow-requests.md +++ /dev/null @@ -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" >}} diff --git a/content/fr/api/rest/follow-suggestions.md b/content/fr/api/rest/follow-suggestions.md deleted file mode 100644 index 31479526..00000000 --- a/content/fr/api/rest/follow-suggestions.md +++ /dev/null @@ -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="2.4.3" >}} - -## DELETE /api/v1/suggestions/:account_id - -Remove account from suggestions. - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="read" version="2.4.3" >}} diff --git a/content/fr/api/rest/instances.md b/content/fr/api/rest/instances.md deleted file mode 100644 index d8355481..00000000 --- a/content/fr/api/rest/instances.md +++ /dev/null @@ -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" >}} diff --git a/content/fr/api/rest/lists.md b/content/fr/api/rest/lists.md deleted file mode 100644 index a4ffcce3..00000000 --- a/content/fr/api/rest/lists.md +++ /dev/null @@ -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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.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="2.1.0" >}} - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `account_ids` | Array of account IDs | Required | diff --git a/content/fr/api/rest/media.md b/content/fr/api/rest/media.md deleted file mode 100644 index 7c4a3c4e..00000000 --- a/content/fr/api/rest/media.md +++ /dev/null @@ -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). diff --git a/content/fr/api/rest/mutes.md b/content/fr/api/rest/mutes.md deleted file mode 100644 index 375c16af..00000000 --- a/content/fr/api/rest/mutes.md +++ /dev/null @@ -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="1.4.2" >}} - -## 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="1.4.2" >}} diff --git a/content/fr/api/rest/notifications.md b/content/fr/api/rest/notifications.md deleted file mode 100644 index bf9e6109..00000000 --- a/content/fr/api/rest/notifications.md +++ /dev/null @@ -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="2.4.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="2.4.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="2.4.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="2.4.0" >}} diff --git a/content/fr/api/rest/polls.md b/content/fr/api/rest/polls.md deleted file mode 100644 index 060cc363..00000000 --- a/content/fr/api/rest/polls.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Polls -menu: - docs: - parent: rest-api - weight: 10 ---- - -## GET /api/v1/polls/:id - -Returns [Poll]({{< relref "entities.md#poll" >}}) - -### Resource information - -{{< api_method_info auth="No" user="No" scope="read read:statuses" version="2.8.0" >}} - -## POST /api/v1/polls/:id/votes - -Vote on a poll. - -Returns [Poll]({{< relref "entities.md#poll" >}}) - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `choices` | Array of choice indices | Required | - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="2.8.0" >}} \ No newline at end of file diff --git a/content/fr/api/rest/reports.md b/content/fr/api/rest/reports.md deleted file mode 100644 index 5fc209fb..00000000 --- a/content/fr/api/rest/reports.md +++ /dev/null @@ -1,24 +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="1.1.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 | -| `forward` | Whether to forward to the remote admin (in case of a remote account) | Optional | diff --git a/content/fr/api/rest/scheduled-statuses.md b/content/fr/api/rest/scheduled-statuses.md deleted file mode 100644 index 07bcfffa..00000000 --- a/content/fr/api/rest/scheduled-statuses.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Scheduled Statuses -menu: - docs: - parent: rest-api - weight: 10 ---- - -## GET /api/v1/scheduled_statuses - -Get scheduled statuses. - -Returns array of [ScheduledStatus]({{< relref "entities.md#scheduledstatus" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="read read:statuses" version="2.7.0" >}} - -## GET /api/v1/scheduled_statuses/:id - -Get scheduled status. - -Returns [ScheduledStatus]({{< relref "entities.md#scheduledstatus" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="read read:statuses" version="2.7.0" >}} - -## PUT /api/v1/scheduled_statuses/:id - -Update Scheduled status. Only `scheduled_at` can be changed. To change the content, delete it and post a new status. - -Returns [ScheduledStatus]({{< relref "entities.md#scheduledstatus" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="2.7.0" >}} - -### Parameters - -|Name|Description|Required| -|----|-----------|:------:| -| `scheduled_at` | Timestamp string to schedule posting of status (ISO 8601) | Optional | - -## DELETE /api/v1/scheduled_statuses/:id - -Remove Scheduled status. - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="2.7.0" >}} diff --git a/content/fr/api/rest/search.md b/content/fr/api/rest/search.md deleted file mode 100644 index 78d7720f..00000000 --- a/content/fr/api/rest/search.md +++ /dev/null @@ -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="2.4.1" >}} - -### Parameters - -|Name|Description|Required|Default| -|----|-----------|:------:|:-----:| -| `q` | The search query | Required || -| `resolve` | Attempt WebFinger look-up | Optional |false| diff --git a/content/fr/api/rest/statuses.md b/content/fr/api/rest/statuses.md deleted file mode 100644 index d32a8a3b..00000000 --- a/content/fr/api/rest/statuses.md +++ /dev/null @@ -1,177 +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" >}}) - -When `scheduled_at` option is present, -Returns [ScheduledStatus]({{< relref "entities.md#scheduledstatus" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="write write:statuses" version="0.0.0" >}} - -### Parameters - -|Name|Description|Required|Added in| -|----|-----------|:------:|:------:| -| `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\* | -| `poll` | Nested parameters to attach a poll to the status | Optional\* |2.8.0| -| `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 | -| `scheduled_at` | Timestamp string to schedule posting of status (ISO 8601) | Optional |2.7.0| -| `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. Polls require a `status` and cannot be combined with `media_ids`. - -Poll parameters: - -|Name|Description|Required| -|----|-----------|:------:| -| `poll[options]` | Array of poll answer strings | Required | -| `poll[expires_in]` | Duration the poll should be open for in seconds | Required | -| `poll[multiple]` | Whether multiple choices should be allowed | Optional | -| `poll[hide_totals]` | Whether to hide totals until the poll ends | Optional | - -### 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 for more on idempotency and idempotency keys. - -### Scheduled status - -Allows users to schedule a toot (with media attachments) to be published at a certain future date. - -The scheduled date must be at least 5 minutes into the future. At most, 300 toots can be scheduled at the same time. Only 50 toots can be scheduled for any given day. - -When `scheduled_at` option is present, instead of creating a status, we only run status validation, and if it passes, we create an entry in scheduled_statuses which encodes the status attributes. Every 5 minutes, a scheduler iterates over the scheduled_statuses table to fetch the ones due in the next 5 minutes, and push them into a more precise Sidekiq queue. In Sidekiq, the individual statuses are created, with media attachments being unassigned from the scheduled status and assigned to the real one. - -This option was added since v2.7.0. - -## 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" >}} - -## 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="1.6.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="1.6.0" >}} diff --git a/content/fr/api/rest/timelines.md b/content/fr/api/rest/timelines.md deleted file mode 100644 index 54257953..00000000 --- a/content/fr/api/rest/timelines.md +++ /dev/null @@ -1,123 +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 | - - -## GET /api/v1/conversations - -Conversations for an account - -Returns array of [Conversation]({{< relref "entities.md#conversation" >}}) - -### Resource information - -{{< api_method_info auth="Yes" user="Yes" scope="read read:statuses" version="2.6.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="2.1.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 >}} diff --git a/content/fr/api/streaming.md b/content/fr/api/streaming.md deleted file mode 100644 index 8faaa3d2..00000000 --- a/content/fr/api/streaming.md +++ /dev/null @@ -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. diff --git a/content/fr/development/activitypub.md b/content/fr/development/activitypub.md deleted file mode 100644 index f7e17e51..00000000 --- a/content/fr/development/activitypub.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Conformité avec ActivityPub -description: Quels objets et propriétés de la spécification ActivityPub sont supportés par Mastodon -menu: - docs: - parent: development - weight: 5 ---- - -## Les API - -- Mastodon supporte la partie serveur-à-serveur de la [spécification ActivityPub](https://www.w3.org/TR/activitypub/). -- Il implémente la [spécification des signatures HTTP](https://tools.ietf.org/html/draft-cavage-http-signatures-10) pour l'authentification des messages reçus. -- Mastodon supporte aussi [les signatures de Données Liées (Linked Data Signatures)](https://w3c-dvcg.github.io/ld-signatures/) pour les payloads transférés. - -## Restrictions - -- Tous les identifiants d'objets doivent utiliser `https://` comme protocole. -- Les instances doivent fournir un point d'entrée [WebFinger](https://tools.ietf.org/html/rfc7033) pour transformer les noms d'utilisateur·ice·s en acteurs. -- Les activités attribuées à un acteur doivent avoir un identifiant sur le même hôte que l'acteur. - -## Activités - -|Activité supportée|Objets supportés| -|------------------|-----------------| -|`Accept`|`Follow`| -|`Add`|`Note`| -|`Announce`|`Object`| -|`Block`|`Object`| -|`Create`|`Note`, `Article`, `Image`, `Video`, `Page`| -|`Delete`|`Object`| -|`Flag`|`Object`| -|`Follow`|`Object`| -|`Like`|`Object`| -|`Move`|`Object`| -|`Reject`|`Follow`| -|`Remove`|`Note`| -|`Undo`|`Accept`, `Announce`, `Block`, `Follow`, `Like`| -|`Update`|`Object`| - -En ce qui concerne l'activité `Create`, seul l'objet `Note` est un objet de première classe dans Mastodon, puisque Mastodon est un service de microblogage. Pour les autres types d'objets supportés, Mastodon en crée une représentation sous la forme d'un pouet, par exemple, un `Article` ou `Page` devient un pouet avec le `name` et `url` de l'objet original, ce qui incitera les utilisateur·ice·s à aller sur l'URL originale pour lire l'article. Pour les objets `Image` et `Video`, le `name` est également utilisé pour remplir le contenu du pouet, avec le fichier original joint au pouet. - -L'activité `Flag` permet de signaler un contenu d'une autre instance, et son `object` peut être soit un ou plusieurs acteurs, soit un ou plusieurs objets attribués à plusieurs acteurs. Les activités `Add` et `Remove` ne fonctionnent qu'avec les [collections mises en avant](#featured-collection). L'activité `Delete` peut être utilisé pour supprimer toutes les données locales de l'expéditeur·ice quand l'`object` de l'activité est l'expéditeur·ice. L'activité `Update` n'est utilisée que pour mettre à jour le profil de l'expéditeur·ice. De la même manière, l'activité `Move` autorise la migration des abonné·e·s de l'expéditeur·ice (`object`) à un autre acteur (`target`), mais seulement si cet acteur référence l'expéditeur·ice dans la propriété `alsoKnownAs`. - -## Extensions -### Collection mise en avant - -Ce qui est connu dans Mastodon comme des "toots épinglés", ou des statuts qui sont toujours affichés en haut des profils, est implémenté en utilisant une propriété supplémentaire nommée `featured` et associée à l'acteur de l'objet, cette propriété pointe vers une `Collection` d'objets. Par exemple : - -```json -{ - "@context": [ - "https://www.w3.org/ns/activitystreams", - - { - "toot": "http://joinmastodon.org/ns#", - "featured": { - "@id": "toot:featured", - "@type": "@id" - } - } - ], - - "id": "https://exemple.fr/@alice", - "type": "Person", - "featured": "https://exemple.fr/@alice/collections/featured" -} -``` - -### Émojis personnalisés - -Mastodon supporte les émojis personnalisés, de petites images téléversées par les administrateur·ice·s et invocables par des codes courts (:Kappa: par exemple). Pour ça, un type `Emoji` est utilisé. Ces émojis personnalisés sont listés dans la propriété `tag` comme les objets `Mention` et `Hashtag`, puisque ce sont des entités qui affectent la manière dont sera rendue le texte. Par exemple : - -```json -{ - "@context": [ - "https://www.w3.org/ns/activitystreams", - - { - "toot": "http://joinmastodon.org/ns#", - "Emoji": "toot:Emoji" - } - ], - - "id": "https://exemple.fr/@alice/hello-world", - "type": "Note", - "content": "Hello world :Kappa:", - "tag": [ - { - "id": "https://exemple.fr/emoji/123", - "type": "Emoji", - "name": ":Kappa:", - "icon": { - "type": "Image", - "mediaType": "image/png", - "url": "https://exemple.fr/files/kappa.png" - } - } - ] -} -``` - -### Points de focale - -Mastodon supporte la définition d'un point de focale sur les images téléversées, pour que peu importe où l'image est affichée, le point de focale reste le même. Cette fonctionnalité est implémentée en utilisant une propriété supplémentaire nommée `focalPoint` sur les objets `Image`. La propriété consiste en un tableau de deux nombres flottants entre 0 et 1. Par exemple : - -```json -{ - "@context": [ - "https://www.w3.org/ns/activitystreams", - - { - "toot": "http://joinmastodon.org/ns#", - "focalPoint": { - "@container": "@list", - "@id": "toot:focalPoint" - } - } - ], - - "id": "https://exemple.fr/@alice/hello-world", - "type": "Note", - "content": "Une image est jointe à ce toot !", - "attachment": [ - { - "type": "Image", - "mediaType": "image/png", - "url": "https://exemple.fr/files/cats.png", - "focalPoint": [ - 0.55, - 0.43 - ] - } - ] -} -``` diff --git a/content/fr/development/overview.md b/content/fr/development/overview.md deleted file mode 100644 index 480ee65c..00000000 --- a/content/fr/development/overview.md +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Vue d'ensemble -description: Comment mettre en place un environnement de développement pour Mastodon -menu: - docs: - parent: development - weight: 1 ---- - -Mastodon est une application **Ruby on Rails** avec un front-end **React.js**. Il suit les standards utilisées par ces frameworks, si vous êtes déjà familier·ère avec Rails ou React.js, vous n'aurez pas de mauvaises surprises. - -Le meilleur moyen de faire fonctionner Mastodon dans un environnement de développement est d'installer toutes les dépendances sur votre système, au lieu d'utiliser Docker ou Vagrant. Vous aurez besoin de Ruby, Node.js, PostgreSQL et Redis, ce qui est un set de dépendances relativement standard pour les applications Rails. - -## Environnements - -Un "environnement" est un set de valeurs de configuration destinés à un usage spécifique. Ces environnements sont : `development`, dans lequel vous modifiez du code ; `test`, dans lequel vous exécutez la suite automatisée de tests ; `staging`, qui permet de simuler en conditions quasi réelles ce qui serait utilisé par les utilisateur·ice·s ; et `production`, qui est destiné à être utilisé par le grand public. Mastodon fournit des configurations pour `development`, `test` et `production`. - -La valeur par défaut de la variable `RAILS_ENV` est `development`, vous n'avez donc rien à faire pour exécuter Mastodon en mode développement. En fait, la configuration de Mastodon a des valeurs par défaut adaptées pour l'environnement de développement, vous n'avez donc pas besoin d'un fichier `.env` sauf si vous voulez customiser certaines choses. Voici les différences entre un environnement de développement et un environnement de production : - -- Le code Ruby se recharge de lui-même quand vous le modifiez, ce qui signifie que vous n'avez pas besoin de redémarrer le serveur Rails pour voir vos changements -- Toutes les erreurs montrent les stack traces dans le navigateur, à la place d'une page d'erreur générique -- Webpack fonctionne sans interruption et recompile les ressources JS et CSS quand vous modifiez n'importe quel fichier front-end, et les pages se rechargent automatiquement -- La mise en cache est désactivée par défaut -- Un compte administrateur avec comme identifiant `admin@localhost:3000` et le mot de passe `mastodonadmin` est créé automatiquement durant l'exécution de la tâche `db:seed` - -Il est à noter que la configuration Docker fournie avec Mastodon est optimisée pour l'environnement de production, et que c'est donc très déconseillé pour une utilisation dans le but de faire du développement. La configuration Vagrant, en revanche, est faite spécialement pour le développement et non pour un usage en production. - -## Mise en place - -Après avoir cloné le projet et vous être placé dans le répertoire fraîchement créé, exécutez `bundle install` puis `yarn install`. - -Dans l'environnement de développement, Mastodon se connectera à PostgreSQL sous le nom de l'utilisateur Linux actuellement utilisé en employant la méthode `ident`, qui fonctionne directement dans la plupart des cas. La seule commande que vous avez à exécuter est `rails db:setup` qui va créer les bases de données `mastodon_development` et `mastodon_test`, charger le schéma associé, puis créer les données de bases pour `mastodon_development` qui sont définies dans le fichier `db/seed.rb`. Les seules données de bases sont le compte administrateur avec les identifiants `admin@localhost:3000` / `mastodonadmin`. - -> Gardez à l'esprit que par défaut, Mastodon sera accessible depuis le port 3000. Si vous choisissez un port différent, le compte administrateur généré utilisera ce nombre. - -## Exécution - -Il y a plusieurs processus qui doivent être démarrés pour profiter de toutes les fonctionnalités de Mastodon, mais on peut décider de ne pas en démarrer certains au cas par cas. Pour les démarrer tous en une seule commande, vous pouvez installer Foreman avec `gem install foreman --no-document` puis utiliser : - - foreman start - -dans le répertoire contenant Mastodon. Cela va démarrer les processus inscrits dans le fichier `Procfile.dev`, ce qui vous donnera : un serveur Rails, un serveur Webpack, l'API de streaming, et Sidekiq. Bien sûr, vous pouvez démarrer n'importe lequel de ces processus indépendamment en fonction de vos besoins. - -## Tests - -|Commande|Description| -|-------|-----------| -|`rspec`|Exécute la suite de tests Ruby| -|`yarn run test`|Exécute la suite de tests JavaScript| -|`rubocop`|Vérifie si le code Ruby est en conformité avec notre style de programmation| - -## Les bibliothèques logicielles les plus utilisées - -La connaissance et la compréhension de ces bibliothèques simplifiera le travail sur le code source de Mastodon. - -### Ruby - -- `haml`, un langage pour créer des templates -- `devise`, pour l'authentification -- `doorkeeper`, qui agit comme un fournisseur OAuth 2 -- `paperclip`, pour l'envoi de fichiers et de pièces jointes -- `sidekiq`, pour les tâches de fond - -### JavaScript - -- `immutable`, pour les structures de données immuables -- `react`, pour effectuer le rendu de l'application web dynamique -- `react-redux`, pour gérer l'état de React -- `react-router-dom`, pour la navigation dans React -- `react-intl`, pour les traductions dans React - -## Structure du code - -Ce qui suit n'a pas vocation à faire autorité ou à être exhaustif, mais plus à être une aide pour vous aider à vous retrouver dans l'application. - -### Ruby - -|Chemin |Description| -|----|-----------| -|`app/controllers`|Code qui relie les opérations aux templates| -|`app/helpers`|Code qui peut être récupéré depuis les vues, c-à-d les opérations banales| -|`app/lib`|Code qui ne rentre pas dans les autres catégories| -|`app/models`|Code qui représente des entités de données| -|`app/serializers`|Code qui génère du JSON à partir de modèles| -|`app/services`|Opérations complexes qui impliquent plusieurs modèles| -|`app/views`|Les templates pour générer des fichiers HTML ou autre| -|`app/workers`|Code qui s'exécute en dehors du cycle "requête-réponse"| -|`spec`|Les suites automatisées de tests| - -### JavaScript - -|Chemin|Description| -|----|-----------| -|`app/javascript/mastodon`|Code pour l'application React.js multi-colonnes | -|`app/javascript/packs`|Code pour les pages non-React.js| - -### CSS et autres ressources - -|Chemin|Description| -|----|-----------| -|`app/javascript/images`|Images| -|`app/javascript/styles`|Code qui se transforme en CSS via Sass| - -### Traductions - -|Chemin|Description| -|----|-----------| -|`config/locales`|Fichiers de traductions côté serveur au format YML| -|`app/javascript/mastodon/locales`|Fichiers de traductions côté client au format JSON| - -## Maintenance des traductions - -Tous les fichiers de traduction sont normalisés pour assurer un formatage et un ordre des valeurs constant, ce qui minimise les différences dans Git. - -|Commande|Description| -|-------|-----------| -|`i18n-tasks normalize`|Normalise les traductions côté serveur| -|`yarn run manage:translations`|Normalise les traductions côté client| diff --git a/content/fr/usage/basics.md b/content/fr/usage/basics.md deleted file mode 100644 index 2ed383d6..00000000 --- a/content/fr/usage/basics.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Les bases -description: Aperçu des fonctions de base de Mastodon -menu: - docs: - parent: usage - weight: 1 ---- -## Inscription - -Vous devez choisir une instance sur laquelle s'inscrire, comme vous choisiriez un fournisseur d'adresse e-mail ou un royaume pour votre personnage dans World of Warcraft. L'instance hébergera votre compte et votre timeline. - -Vous pouvez [parcourir une liste d'instance par catégorie et langue sur joinmastodon.org](https://joinmastodon.org/#getting-started). - -## Modifier son profil -### Image, nom et biographie - -- Vous pouvez téléverser une photo de profil -- Vous pouvez téléverser une bannière pour votre profil -- Vous pouvez définir un nom d'usage différent de votre nom d'utilisateur -- Vous pouvez vous présenter dans votre biographie -- Vous pouvez mentionner des gens et utiliser des hashtags ainsi que des émojis personnalisés dans votre biographie - -### Les méta-données du profil - -Les méta-données du profil sont un moyen d'ajouter des infos supplémentaires sur votre profil qui sera plus facile à lire. Vous disposez de 4 rangées dans lesquelles vous pouvez définir une étiquette et sa valeur. Par exemple : - -|Étiquette|Valeur| -|-----|-------| -|Âge|25| -|Pays|Allemagne| -|Pronoms|il/lui| - -C'est vous qui décidez de ce que vous mettez dedans. Les étiquettes et les valeurs peuvent contenir des @mentions, des #hashtags, des émojis personnalisés et des liens. - -### Vérification de lien - -Si vous mettez un lien dans les méta-données de votre profil, Mastodon vérifiera si le lien contient une indication renvoyant à votre profil Mastodon. Si c'est le cas, vous obtiendrez une coche à côté du lien, puisque vous avez prouvé que le lien vous appartient. - -En coulisses, Mastodon cherche l'attribut `rel="me"` dans la page. Mastodon met également `rel="me"` dans les liens affichés dans les méta-données de profil. - -## Envoyer un post -### Texte - -- Vous disposez de 500 caractères -- Vous pouvez mentionner d'autres personnes comme `@alice` ou `@alice@exemple.fr` -- Quand vous mentionnez d'autres personnes, la partie `exemple.fr` du nom d'utilisateur n'est pas affichée dans le message final -- Si vous postez des liens, ils doivent commencer par `http://` ou `https://` -- Quand vous postez un ou plusieurs lien(s), ils compteront tous pour 23 caractères, peu importe la longueur du lien -- Vous pouvez utiliser des hashtags comme `#exemple` pour que les autres puissent trouver votre post via ce tag -- Vous pouvez ajouter un avertissement de contenu à votre post -- L'avertissement de contenu est en texte basique. Il ne peut contenir de mentions, de hashtags ou de liens. - -### Médias - -- Vous pouvez téléverser des images au format PNG et JPG -- Les GIFs téléversés sont convertis en vidéos sans son au format MP4, comme sur Imgur/Gfycat (GIFV) -- Vous pouvez également téléverser directement des MP4 ou WebM sans son (GIFV) -- Vous pouvez téléverser des vidéos au format MP4, WebM ou MOV -- La taille limite des images téléversées est de 8 Mo -- La taille limite des vidéos téléversées est de 40 Mo -- Les images plus grandes que 1280x1280 pixels sont rétrécies -- Tous les médias d'un post peuvent être cachés derrière un spoiler - -### Émojis personnalisés - -- Chaque serveur offre un set d’émojis personnalisés à utiliser, comme sur Discord -- Vous pouvez utiliser un émoji en appelant son code, comme `:thounking:` diff --git a/content/fr/usage/decentralization.md b/content/fr/usage/decentralization.md deleted file mode 100644 index 45113410..00000000 --- a/content/fr/usage/decentralization.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Décentralisation -description: Comment Mastodon est décentralisé et ce que ça veut dire concrètement -menu: - docs: - parent: usage - weight: 2 ---- - -Mastodon est un réseau social **fédéré**. - -## Qu'est-ce que la fédération ? - -La **fédération** est une forme de décentralisation. Au lieu d'avoir un nœud de connexion unique que tout le monde utiliserait, il y en a plusieurs, que n'importe qui peut utiliser. - -|Degrés de centralisation|Exemples| -|:---------------------:|--------| -|Centralisé|Twitter, Facebook, Instagram| -|Fédéré|E-mail, XMPP| -|Distribué|BitTorrent, IPFS, Scuttlebutt| - -Une instance Mastodon peut opérer seule. Comme un site web traditionnel, les gens s'inscrivent dessus, postent des messages, envoient des photos et se parlent entre eux. *Contrairement* à un site web traditionnel, les instances Mastodon peuvent opérer entre elles, laissant leurs utilisateur·ice·s communiquer ensemble, comme vous enverriez un mail depuis votre adresse GMail à quelqu'un utilisant une adresse Outlook. - -

- -

De gauche à droite : Centralisé, Fédéré, Distribué

-
- -Concrètement : Imaginez si vous pouviez suivre quelqu'un sur Instagram depuis votre compte Twitter et commenter ses photos sans changer de compte ou d'application. Si Twitter et Instagram étaient des services fédérés, ce serait possible. - -## Le Fediverse - -Mastodon utilise un protocole ouvert et standardisé pour la fédération. Il se nomme ActivityPub. N'importe quel logiciel qui utilise également ActivityPub pour la fédération peut communiquer sans problèmes avec Mastodon, comme n'importe quelle instance Mastodon peut communiquer avec une autre. - -Le **Fediverse** ("federated universe", univers fédéré) est le nom qu'on donne à l'ensemble des instances qui peuvent communiquer entre elles. Ça inclut toutes les instances Mastodon, mais également d'autres logiciels : - -- Misskey -- Pleroma -- PeerTube -- Plume -- et plein d'autres encore - -Le Fediverse n'a pas de logiciel spécifique associé, vous entendrez donc plus souvent "suivez-moi sur Mastodon" que "suivez-moi sur le Fediverse", bien que le deuxième soit techniquement plus approprié. - -## Implications concrètes -### S'adresser à des gens - -Les noms d'utilisateur sur Mastodon sont en deux parties : - -- Le nom d'utilisateur local, ex. `alice` -- Et le nom de domaine de l'instance, ex. `exemple.fr` - -Comme une adresse e-mail. Par commodité, Mastodon vous permet de zapper la deuxième partie du nom d'utilisateur quand vous vous adressez à des gens sur la même instance que vous, mais rappelez-vous que si vous partagez votre nom d'utilisateur à d'autres personnes, vous devrez donner le nom complet ou sinon elles auront du mal à vous trouver. - -|{{< no >}}|{{< yes >}}| -|:--------:|:---------:| -|Je suis @alice sur Mastodon !|Je suis @alice@exemple.fr sur Mastodon !| - -La barre de recherche dans Mastodon peut trouver des gens soit sous la forme `@nom@domaine.tld`, soit sous la forme d'un lien (`https://exemple.fr/@nom`), vous pouvez donc partager sous la forme qui vous convient le mieux. - -### Suivre des gens - -Tant que vous rencontrez quelqu'un via l'interface utilisateur de l'application, ex. l'interface web de votre instance, ou votre application mobile, vous avez juste à cliquer sur le bouton "Suivre" et vous ne verrez aucune différence si la personne est sur votre instance ou non. - -Par contre, si vous arrivez sur la page publique d'une personne sur une autre instance, il y a un problème : l'instance vous voit comme un·e simple inconnu·e. - -Quand vous cliquez sur "Suivre", une fenêtre va apparaître, vous demandant d'entrer votre nom d'utilisateur complet (avec la partie du nom de domaine, la plus importante). Ainsi, la fenêtre vous renverra sur votre instance et vous permettra de suivre la personne. - -Vous verrez aussi cette fenêtre quand vous cliquez sur "Répondre", "Boost" ou "Mettre en favori" sur les pages publiques d'autres instances. - -### Parcourir le contenu - -Afin de vous permettre de découvrir du contenu potentiellement intéressant, Mastodon fournit un moyen de parcourir tous les posts publics. Enfin, il n'y pas pas d'accord global de partage du contenu entre toutes les instances, donc il n'y a pas vraiment de moyen de parcourir *tous* les posts publics. Quand vous parcourez la **timeline fédérée**, vous voyez tous les posts publics que l'instance sur laquelle vous êtes connaît. Il y a différentes façons de faire découvrir à votre instance des posts, mais la manière la plus simple est de suivre des gens d'autres instances. - -Il y a un moyen de filtrer la timeline fédérée afin de ne voir que les posts publics faits à partir de votre instance : la **timeline locale**. Note que "locale" se réfère à l'instance, pas à une position géographique. - -### Financement et monétisation - -Toutes les instances Mastodon sont gérées par des personnes ou des organisations complètement différentes et indépendantes. Mastodon n'offre aucune solution de monétisation dans le logiciel. - -Quelques administrateur·ice·s d'instances choisissent de fournir des comptes contre de l'argent. D'autres travaillent dans des entreprises ou des organismes du service public qui utilisent leur infrastructure déjà existante pour héberger leur instance. La plupart des administrateur·ice·s d'instances s'en réfèrent au crowdfunding via Patreon ou autre pour payer les frais de service. Si vous voulez soutenir l'instance qui héberge votre compte, cherchez s'il est fait mention d'un moyen de financer l'instance. - -Le développement de Mastodon est financé par crowdfunding via Patreon. Aucun capital-risque n'est impliqué. - -### Usurpation d'identité et vérification - -Le même nom d'utilisateur *peut* être utilisé sur différentes instances, il n'y a aucun moyen de réclamer la propriété de chaque nom à l'avance. Comme avec les mails, vous ne devriez pas vous attendre à ce que `alice@hotmail.com` soit la même Alice que `alice@gmail.com`. - -Puisque Mastodon peut être auto-hébergé, il n'y a de meilleur moyen de prouver son identité qu'en ayant une instance sur un nom de domaine vous appartenant, les gens y faisant déjà confiance. - -La vérification d'identité via des documents et l'apposition d'une coche bleue à côté de son nom ne sont pas possible sans une autorité centralisée. Par contre, Mastodon peut croiser les liens que vous mettez sur votre profil pour prouver que vous détenez la propriété de ces liens. Si l'un de ces liens est votre page web personnelle qui est connue et donc de confiance, cela peut servir comme une alternative à la vérification d'identité. diff --git a/content/fr/usage/moderation.md b/content/fr/usage/moderation.md deleted file mode 100644 index 79c93c01..00000000 --- a/content/fr/usage/moderation.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Modération -description: Aperçu des outils de modération de Mastodon -menu: - docs: - parent: usage - weight: 4 ---- -## Modération individuelle - -La modération dans Mastodon se fait toujours localement, c-à-d que les actions ne se verront que depuis l'instance où elles ont été prises. Un·e administrateur·ice ou modérateur·ice d'une instance ne peut s'en prendre à une personne d'une autre instance, ses actions n'ont de conséquences que sur la copie locale sur leur propre instance. - -### Désactiver la connexion - -Un compte Mastodon peut être désactivé. Cela empêche l'utilisateur·ice de faire quoi que ce soit avec son compte, mais tout ce qui a été posté reste là. Cette restriction est réversible, le compte peut être réactivé à tout moment. Cette restriction n'est disponible que pour les utilisateur·ice·s de votre instance. - -### Silence - -Un silence (masquage) sur Mastodon est comparable au sandbox en informatique. Un compte silencé n'apparaît pas aux personnes qui ne le suivaient pas auparavant. Le contenu est toujours là, et il peut toujours être trouvé en le cherchant, quand on clique sur la @mention ou quand on cherche dans sa propre liste d'abonnements, mais il est invisible pour les autres. - -À ce stade, le silence n'affecte pas la fédération. Un compte localement silencé n'est *pas* silencé automatiquement sur les autres instances. - -Cette restriction est réversible, le compte peut être dé-silencé à tout moment. - -### Suspension - -Une suspension sur Mastodon est synonyme de suppression. Le compte n'apparaît plus quand on le cherche, la page de profil disparaît, tous les posts, téléversements, liste d'abonnements et d'abonné·e·s, et toutes les autres données sont supprimées. Cette restriction est **irréversible**. Bien que le compte puisse être dé-suspendu, permettant ainsi à l'utilisateur·ice d'en regagner l'accès, les anciennes données sont définitivement effacées. - -## Modération globale d'une instance - -La modération individuelle d'un grand nombre de personnes d'une instance ayant une mauvaise attitude pouvant être épuisant, il est possible de modérer préventivement tous les utilisateur·ice·s de cette instance en utilisant un **blocage de domaine**, qui se décline en plusieurs degrés de sévérité. - -### Rejet des médias - -Quand cette option est activée, aucun fichier de cette instance sera accepté localement. Cela comprend les photos de profil, les bannières, les émojis personnalisés et les médias rattachés aux posts. - -### Masquage - -Applique un masquage sur tous les comptes passés et futurs de cette instance. - -### Suspendre - -Applique une suspension à tous les comptes passés et futurs de cette instance. Aucun contenu de cette instance sera stocké localement, à part les noms d'utilisateur. - -## Mesures anti-spam - -Il y a quelques mesures de base qui limitent le spam sur Mastodon : - -- L'inscription requiert la confirmation de son adresse mail -- Le nombre d'inscriptions via la même adresse IP est limité - -Toutefois, les spammeurs et spammeuses déterminé·e·s arriveront à passer outre ces mesures. Vous pouvez alors user du **blacklisting de domaines courriel**. Durant l'inscription, Mastodon cherche un enregistrement A ou MX dans le nom de domaine utilisé par l'adresse mail, c-à-d l'adresse IP du serveur mail, et vérifie si cette adresse n'est pas dans une blacklist générée dynamiquement. - -### Blocage de serveur de courriel - -Les spammeur·euse·s vont souvent utiliser plusieurs domaines de courriel pour que ça donne l'impression qu'iels utilisent plein de serveurs différents et qu'il serait donc plus difficile de tous les bloquer. Cependant, l'expérience montre que la plupart du temps tous ces domaines renvoient à la même adresse IP. Si vous voyez plein de spammeur·euse·s s'inscrire en même temps, vous pouvez vérifier si c'est le cas ici, soit en utilisant un service de recherche DNS en ligne, ou en utilisant l'utilitaire `dig` sur Linux, par exemple `dig 1.2.3.4` retournera tous les enregistrements DNS pour cette adresse IP. Si l'IP est la même pour tous les domaines mail, vous pouvez l'ajouter dans la blacklist de domaines de courriels. - -### Blocage d'adresse IP - -Il n'est pas possible de bloquer les visiteurs sur la base de leur adresse IP dans Mastodon en soi, et ce n'est pas une stratégie infaillible. Les adresses IP sont parfois partagées par différentes personnes (entreprise, école…) et peuvent parfois changer de propriétaire. Mais il est possible de bloquer des visiteurs sur la base de leur adresse IP dans Linux en utilisant un pare-feu. Voici un exemple avec `iptables` et `ipset` : - -```bash -# Installez ipset -sudo apt install ipset -# Créez une blacklist nommée "spambots" -sudo ipset create spambots nethash -# Ajoutez 1.2.3.4 à la blacklist -sudo ipset add spambots 1.2.3.4 -# Ajoutez une règle de pare-feu basée sur la blacklist -sudo iptables -I INPUT 1 -m set --match-set spambots src -j DROP -``` - -Prenez garde à ne pas vous interdire de connexion à votre serveur. diff --git a/content/fr/usage/privacy.md b/content/fr/usage/privacy.md deleted file mode 100644 index b7141d6a..00000000 --- a/content/fr/usage/privacy.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Vie privée -description: Aperçu des fonctionnalités de Mastodon en rapport à la vie privée et leurs implications -menu: - docs: - parent: usage - weight: 3 ---- - -## Niveaux de publication - -|Niveau|Timelines publiques|Permalien|Page de profil public|Timeline personnelle| -|-----|:--------------:|:-------:|:----------:|:--------:| -|Public|{{< yes >}}|{{< yes >}}|{{< yes >}}|{{< yes >}}| -|Non-listé|{{< no >}}|{{< yes >}}|{{< yes >}}|{{< yes >}}| -|Abonné·e·s seulement|{{< no >}}|{{< no >}}|{{< no >}}|{{< yes >}}| -|Direct|{{< no >}}|{{< no >}}|{{< no >}}|{{< no >}}| - -Peu importe le niveau utilisé, chaque utilisateur·ice mentionné·e pourra voir le message dans ses notifications. - -**Ne partagez pas d'informations sensibles ou dangereuses par messages directs**. Mastodon n'est pas une messagerie instantanée chiffrée comme Signal ou Wire, les administrateur·ice·s des instances de l'expéditeur et du destinataire ont accès à la base de données de leurs instances et peuvent donc lire les messages. Utilisez donc les messages privés avec autant d'attention que vous feriez avec les DM Twitter, MP Discord et autres. - -## Verrouiller un compte - -Pour s'assurer que les posts privés (abonné·e·s seulement) le restent, vous devez verrouiller votre compte --sinon, n'importe qui pourrait vous suivre et voir vos posts précédents. Verrouiller son compte sur Mastodon ne fait qu'une chose : ajouter une étape de validation avant de pouvoir vous suivre. - -Une fois verrouillé, avant que quelqu'un puisse devenir votre abonné·e, vous recevrez une demande de suivi, que vous pouvez soit accepter soit refuser. - -Gardez à l'esprit que la possibilité de rendre privés ses posts se fait au cas par cas et non sur tout le compte, il n'y a donc aucun moyen de rendre instantanément les posts antérieurs privés. - -## Bloquer et masquer -### Masquer les boosts - -Si vous masquez les boosts de quelqu'un, vous ne les verrez pas dans votre timeline personnelle. - -### Masquer quelqu'un - -Quand vous masquez quelqu'un, vous avez la possibilité de masquer ou non les notifications venant de cette personne. Masquer quelqu'un sans pour autant masquer les notifications enlève de votre vue l'utilisateur·ice : - -- Vous ne verrez pas la personne dans votre timeline personnelle -- Vous ne verrez pas les autres partager ses posts -- Vous ne verrez pas les autres mentionner cette personne -- Vous ne verrez pas la personne dans les timelines publiques - -Si vous choisissez également de masquer les notifications de cette personne, vous ne recevrez pas de notifications de cette personne. - -La personne masquée ne sait à aucun moment qu'elle est masquée. - -### Bloquer quelqu'un - -Le blocage enlève de votre vue une personne : - -- Vous ne verrez pas la personne dans votre timeline personnelle -- Vous ne verrez pas les autres partager ses posts -- Vous ne verrez pas les autres mentionner cette personne -- Vous ne verrez pas la personne dans les timelines publiques -- Vous ne verrez pas les notifications de cette personne - -De plus, du côté de la personne bloquée : - -- Elle est obligée de ne plus vous suivre -- Elle ne peut pas vous suivre -- Elle ne verra pas les autres partager vos messages -- Elle ne vous verra plus dans les timelines publiques - -Si vous et la personne bloquée êtes sur la même instance, elle ne pourra plus voir vos posts en regardant votre profil tout en étant connecté. - -### Masquer toute une instance - -Si vous masquez une instance entière : - -- Vous ne verrez pas les posts de cette instance sur les timelines publiques -- Vous ne verrez pas les autres partager les posts de cette instance dans votre timeline personnelle -- Vous ne verrez pas les notifications de cette instance -- Vous perdrez les abonné·e·s que vous aviez potentiellement sur cette instance diff --git a/content/pl/_index.md b/content/pl/_index.md deleted file mode 100644 index a2ba8e77..00000000 --- a/content/pl/_index.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Dokumentacja Mastodona ---- - -Witaj w dokumentacji Mastodona! - -
- {{< youtube "IPSbNdBmWKE" >}} -
- -**Wybierz swoją drogę:** - -- [Dowiedz się jak korzystać z Mastodona]({{< relref "usage/basics.md" >}}) -- [Dowiedz się jak zainstalować Mastodona]({{< relref "administration/installation.md" >}}) -- [Dowiedz się jak napisać aplikację dla Mastodona]({{< relref path="api/guidelines.md" lang="en" >}}) diff --git a/content/pl/administration/configuration.md b/content/pl/administration/configuration.md deleted file mode 100644 index cd846035..00000000 --- a/content/pl/administration/configuration.md +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: Konfigruacja -description: Omówienie opcji konfiguracji Mastodona -menu: - docs: - parent: administration - weight: 2 ---- - -Mastodon używa zmiennych środowiskowych do konfiguracji. - -Dla zwiększenia wygody, mogą one być odczytywane z pliku `.env.production` znajdującego się w katalogu Mastodona, ale mogą zostać zawsze nadpisane przez zewnętrzny proces. Dla przykładu, pliki usług systemd mogą odczytywać zmienne środowiskowe z `EnvironmentFile` lub definicji w `Environment`, więc możesz ustawić oddzielne parametry konfiguracji dla poszczególnych usług. Mogą też być określone podczas uruchamiania Mastodona z wiersza poleceń. - -## Podstawowe -### Federacja - -- `LOCAL_DOMAIN` -- `WEB_DOMAIN` -- `ALTERNATE_DOMAINS` - -### Tajne klucze - -- `SECRET_KEY_BASE` -- `OTP_SECRET` -- `VAPID_PRIVATE_KEY` -- `VAPID_PUBLIC_KEY` - -### Deployment - -- `RAILS_ENV` -- `RAILS_SERVE_STATIC_FILES` -- `RAILS_LOG_LEVEL` -- `TRUSTED_PROXY_IP` -- `SOCKET` -- `PORT` -- `NODE_ENV` -- `BIND` - -### Opcje skalowania - -- `WEB_CONCURRENCY` -- `MAX_THREADS` -- `PREPARED_STATEMENTS` -- `STREAMING_API_BASE_URL` -- `STREAMING_CLUSTER_NUM` - -## Połączenie z bazą danych -### PostgreSQL - -- `DB_HOST` -- `DB_USER` -- `DB_NAME` -- `DB_PASS` -- `DB_PORT` -- `DATABASE_URL` - -### Redis - -- `REDIS_HOST` -- `REDIS_PORT` -- `REDIS_URL` -- `REDIS_NAMESPACE` -- `CACHE_REDIS_HOST` -- `CACHE_REDIS_PORT` -- `CACHE_REDIS_URL` -- `CACHE_REDIS_NAMESPACE` - -### ElasticSearch - -- `ES_ENABLED` -- `ES_HOST` -- `ES_PORT` -- `ES_PREFIX` - -### StatsD - -- `STATSD_ADDR` -- `STATSD_NAMESPACE` - -## Ograniczenia - -- `SINGLE_USER_MODE` -- `EMAIL_DOMAIN_WHITELIST` -- `DEFAULT_LOCALE` -- `MAX_SESSION_ACTIVATIONS` -- `USER_ACTIVE_DAYS` - -## E-mail - -- `SMTP_SERVER` -- `SMTP_PORT` -- `SMTP_LOGIN` -- `SMTP_PASSWORD` -- `SMTP_FROM_ADDRESS` -- `SMTP_DOMAIN` -- `SMTP_DELIVERY_METHOD` -- `SMTP_AUTH_METHOD` -- `SMTP_CA_FILE` -- `SMTP_OPENSSL_VERIFY_MODE` -- `SMTP_ENABLE_STARTTLS_AUTO` -- `SMTP_TLS` - -## Przechowywanie plików - -- `CDN_HOST` -- `S3_ALIAS_HOST` - -### Lokalne przechowywanie plików - -- `PAPERCLIP_ROOT_PATH` -- `PAPERCLIP_ROOT_URL` - -### Amazon S3 i kompatybilne - -- `S3_ENABLED` -- `S3_BUCKET` -- `AWS_ACCESS_KEY_ID` -- `AWS_SECRET_ACCESS_KEY` -- `S3_REGION` -- `S3_PROTOCOL` -- `S3_HOSTNAME` -- `S3_ENDPOINT` -- `S3_SIGNATURE_VERSION` - -### Swift - -- `SWIFT_ENABLED` -- `SWIFT_USERNAME` -- `SWIFT_TENANT` -- `SWIFT_PASSWORD` -- `SWIFT_PROJECT_ID` -- `SWIFT_AUTH_URL` -- `SWIFT_CONTAINER` -- `SWIFT_OBJECT_URL` -- `SWIFT_REGION` -- `SWIFT_DOMAIN_NAME` -- `SWIFT_CACHE_TTL` - -## Zewnętrzne uwierzytelnianie - -- `OAUTH_REDIRECT_AT_SIGN_IN` - -### LDAP - -- `LDAP_ENABLED` -- `LDAP_HOST` -- `LDAP_PORT` -- `LDAP_METHOD` -- `LDAP_BASE` -- `LDAP_BIND_DN` -- `LDAP_PASSWORD` -- `LDAP_UID` -- `LDAP_SEARCH_FILTER` - -### PAM - -- `PAM_ENABLED` -- `PAM_EMAIL_DOMAIN` -- `PAM_DEFAULT_SERVICE` -- `PAM_CONTROLLED_SERVICE` - -### CAS - -- `CAS_ENABLED` -- `CAS_URL` -- `CAS_HOST` -- `CAS_PORT` -- `CAS_SSL` -- `CAS_VALIDATE_URL` -- `CAS_CALLBACK_URL` -- `CAS_LOGOUT_URL` -- `CAS_LOGIN_URL` -- `CAS_UID_FIELD` -- `CAS_CA_PATH` -- `CAS_DISABLE_SSL_VERIFICATION` -- `CAS_UID_KEY` -- `CAS_NAME_KEY` -- `CAS_EMAIL_KEY` -- `CAS_NICKNAME_KEY` -- `CAS_FIRST_NAME_KEY` -- `CAS_LAST_NAME_KEY` -- `CAS_LOCATION_KEY` -- `CAS_IMAGE_KEY` -- `CAS_PHONE_KEY` - -### SAML - -- `SAML_ENABLED` -- `SAML_ACS_URL` -- `SAML_ISSUER` -- `SAML_IDP_SSO_TARGET_URL` -- `SAML_IDP_CERT` -- `SAML_IDP_CERT_FINGERPRINT` -- `SAML_NAME_IDENTIFIER_FORMAT` -- `SAML_CERT` -- `SAML_PRIVATE_KEY` -- `SAML_SECURITY_WANT_ASSERTION_SIGNED` -- `SAML_SECURITY_WANT_ASSERTION_ENCRYPTED` -- `SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED` -- `SAML_ATTRIBUTES_STATEMENTS_UID` -- `SAML_ATTRIBUTES_STATEMENTS_EMAIL` -- `SAML_ATTRIBUTES_STATEMENTS_FULL_NAME` -- `SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME` -- `SAML_ATTRIBUTES_STATEMENTS_LAST_NAME` -- `SAML_UID_ATTRIBUTE` -- `SAML_ATTRIBUTES_STATEMENTS_VERIFIED` -- `SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL` - -## Ukryte usługi - -- `http_proxy` -- `ALLOW_ACCESS_TO_HIDDEN_SERVICE` - -## Inne - -- `SKIP_POST_DEPLOYMENT_MIGRATIONS` diff --git a/content/pl/administration/installation.md b/content/pl/administration/installation.md deleted file mode 100644 index fb8dd2d2..00000000 --- a/content/pl/administration/installation.md +++ /dev/null @@ -1,339 +0,0 @@ ---- -title: Instalacja -description: Jak zainstalować Mastodona na serwerze z Ubuntu 18.04 -menu: - docs: - parent: administration - weight: 1 ---- - - - -## Podstawowa konfiguracja serwera (nieobowiązkowa) - -Jeżeli konfigurujesz nowe urządzenie, zalecane jest zabezpieczenie go. Załóżmy, że korzystasz z **Ubuntu 18.04**: - -### Nie pozwól na logowanie przez SSH z użyciem hasła (tylko kluczem) - -Na początek upewnij się, że jesteś zalogowany(-a) z użyciem klucza, nie hasła – w przeciwnym razie zostaniesz zablokowany(-a). Wielu dostawców hostingu daje możliwość wysłania klucza publicznego i automatycznie konfiguruje logowanie użytkownika root z użyciem klucza. - -Edytuj `/etc/ssh/sshd_config` i znajdź `PasswordAuthentication`. Upewnij się, że nie jest ono skomentowane i jest ustawione na `no`. Po dokonaniu zmian uruchom ponownie sshd: - -```sh -systemctl restart ssh -``` - -### Aktualizacja pakietów systemowych - -```sh -apt update && apt upgrade -y -``` - -### Instalacja fail2ban, aby blokował po wielu nieudanych próbach logowania - -```sh -apt install fail2ban -``` - -Edytuj `/etc/fail2ban/jail.local` i dodaj: - -```ini -[DEFAULT] -destemail = twój@email.tutaj -sendername = Fail2Ban - -[sshd] -enabled = true -port = 22 - -[sshd-ddos] -enabled = true -port = 22 -``` - -Na koniec, uruchom ponownie fail2ban: - -```sh -systemctl restart fail2ban -``` - -### Zainstaluj firewall i odblokuj tylko porty SSH, HTTP i HTTPS - -Na początek, zainstaluj iptables-persistent. Podczas instalacji zostaniesz zapytany(-a), czy chcesz pozostawić obecne zasady – odmów. - -```sh -apt install -y iptables-persistent -``` - -Edytuj `/etc/iptables/rules.v4` i dodaj:z - -``` -*filter - -# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0 --A INPUT -i lo -j ACCEPT --A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT - -# Accept all established inbound connections --A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT - -# Allow all outbound traffic - you can modify this to only allow certain traffic --A OUTPUT -j ACCEPT - -# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL). --A INPUT -p tcp --dport 80 -j ACCEPT --A INPUT -p tcp --dport 443 -j ACCEPT - -# Allow SSH connections -# The -dport number should be the same port number you set in sshd_config --A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT - -# Allow ping --A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT - -# Log iptables denied calls --A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 - -# Reject all other inbound - default deny unless explicitly allowed policy --A INPUT -j REJECT --A FORWARD -j REJECT - -COMMIT -``` - -Dzięki iptables-persistent, ta konfiguracja będzie ładowana w trakcie uruchomienia systemu. Ponieważ nie zamierzamy go teraz uruchomić ponownie, załadujmy ją ręcznie: - -```sh -iptables-restore < /etc/iptables/rules.v4 -``` - -## Wymagania wstępne - -- Urządzenie z systemem **Ubuntu 18.04** wraz z dostępem do roota -- **Domena** (lub subdomena) dla serwera Mastodona, np. `example.com` -- Usługa doręczania e-maili lub inny **serwer SMTP** - -Wykonaj te polecenia jako root. Jeżeli nie jesteś obecnie na koncie roota, przełącz się na nie: - -```sh -sudo -i -``` - -### Repozytoria systemu - -Upewnij się, że curl jest zainstalowany: - -```sh -apt install -y curl -``` - -#### Node.js - -```sh -curl -sL https://deb.nodesource.com/setup_8.x | bash - -``` - -#### Yarn - -```sh -curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -``` - -### Pakiety systemowe - -```sh -apt update -apt install -y \ - imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \ - g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \ - bison build-essential libssl-dev libyaml-dev libreadline6-dev \ - zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev \ - nginx redis-server redis-tools postgresql postgresql-contrib \ - certbot yarn libidn11-dev libicu-dev libjemalloc-dev -``` - -### Instalacja Ruby - -Będziemy korzystać z rbenv, aby zarządzać wersjami Ruby, ponieważ ułatwia to przejście na prawidłową wersję po pojawieniu się nowego wydania. rbenv musi zostać zainstalowany dla każdego użytkownika który będzie go używał osobno, więc zacznijmy od utworzenia użytkownika, na którym uruchomimy Mastodona: - -```sh -adduser --disabled-login mastodon -``` - -Możemy teraz zalogować się na to konto: - -```sh -su - mastodon -``` - -I przejść do instalacji rbenv i rbenv-build: - -```sh -git clone https://github.com/rbenv/rbenv.git ~/.rbenv -cd ~/.rbenv && src/configure && make -C src -echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc -echo 'eval "$(rbenv init -)"' >> ~/.bashrc -exec bash -git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build -``` - -Po zakończeniu, możemy zainstalować prawidłową wersję Ruby: - -```sh -RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.5.3 -rbenv global 2.5.3 -``` - -Domyślna wersja gem dołączona do ruby_2.5.3 nie jest kompatybilna z najnowszym bundlerem, więc musimy zaktualizować gem: - -``` -gem update --system -``` - -Musimy też zainstalować bundler: - -```sh -gem install bundler --no-document -``` - -Wróćmy na konto root: - -```sh -exit -``` - -## Konfiguracja -### Konfiguracja PostgreSQL -#### Ustawienia wydajności (nieobowiązkowe) - -Aby zwiększyć wydajność, możesz skorzystać z [pgTune](https://pgtune.leopard.in.ua/#/), aby wygenerować odpowiednie ustawienia i zmienić odpowiednie wartości w `/etc/postgresql/9.6/main/postgresql.conf` przed ponownym uruchomieniem PostgreSQL poleceniem `systemctl restart postgresql` - -#### Tworzenie użytkownika - -Musisz utowrzyć użytkownika PostgreSQL, z którego będzie mógł korzystać Mastodon. Najprościej użyć uwierzytelniania „ident” w prostym ustawieniu, tzn. użytkownik PostgreSQL nie będzie miał oddzielnego hasła i będzie mógł z niego korzystać linuksowy użytkownik o tej samej nazwie. - -Przejdź do powłoki: - -```sh -sudo -u postgres psql -``` - -Wykonaj: - -``` -CREATE USER mastodon CREATEDB; -\q -``` - -Gotowe! - -### Konfiguracja Mastodona - -Pora pobrać kod Mastodona. Przełącz się na użytkownika mastodon: - -```sh -su - mastodon -``` - -#### Pobieranie kodu - -Użyj narzędzia git, aby pobrać najnowsze stabilne wydanie Mastodona: - -```sh -git clone https://github.com/tootsuite/mastodon.git live && cd live -git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1) -``` - -#### Instalacja ostatnich zależności - -Pora na instalację zależności używających Ruby i JavaScript: - -```sh -bundle install \ - -j$(getconf _NPROCESSORS_ONLN) \ - --deployment --without development test -yarn install --pure-lockfile -``` - -#### Generowanie konfiguracji - -Uruchom interaktywny konfigurator: - -```sh -RAILS_ENV=production bundle exec rake mastodon:setup -``` - -W ten sposób: - -- utworzysz plik konfiguracyjny -- wykonasz prekompilację zasobów -- utworzysz schemat bazy danych - -Plik konfiguracyjny zostanie zapisany jako `.env.production`. Możesz przejrzeć i edytować go według swoich potrzeb. Możesz odwołać się do [documentacji konfiguracji]({{< relref "configuration.md" >}}). - -Możesz wrócić na użytkownika root: - -```sh -exit -``` - -### Konfiguracja nginx - -Skopiuj przykładową konfigurację nginx z katalogu Mastodona: - -```sh -cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon -ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon -``` - -Zedytuj `/etc/nginx/sites-available/mastodon` u zamień `example.com` na swoją domenę i dokonaj niezbędnych zmian. - -Załaduj ponownie nginx, aby wprowadzić zmiany: - -```sh -systemctl reload nginx -``` - -### Uzyskanie certyfikatu SSL - -Skorzystamy z Let's Encrypt, aby uzyskać bezpłatny certyfikat SSL: - -```sh -certbot certonly --webroot -d example.com -w /home/mastodon/live/public/ -``` - -Możesz teraz zedytować `/etc/nginx/sites-available/mastodon`, aby zmodyfikowac wiersze `ssl_certificate` i `ssl_certificate_key`. - -Załaduj ponownie nginx, aby wprowadzić zmiany: - -```sh -systemctl reload nginx -``` - -W tym momencie, po odwiedzeniu domeny w przeglądarce powinieneś(-aś) zobaczyć stronę z błędem przedstawiającą słonia uderzającego w ekran komputera. To dlatego, że nie uruchomiliśmy jeszcze Mastodona. - -### Konfiguracja usług systemd - -Skopiuj szablony usług systemd z katalogu Mastodona: - -```sh -cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/ -``` - -Zedytuj następujące pliki, aby upewnić się czy nazwa użytkownika i ścieżki są prawidłowe: - -- `/etc/systemd/system/mastodon-web.service` -- `/etc/systemd/system/mastodon-sidekiq.service` -- `/etc/systemd/system/mastodon-streaming.service` - -Na koniec, uruchom i aktywuj nowe usługi systemd: - -```sh -systemctl start mastodon-web mastodon-sidekiq mastodon-streaming -systemctl enable mastodon-* -``` - -Będą one automatycznie uruchamiane wraz z systemem. - -**Hurra! To wszystko. Możesz teraz odwiedzić swoją domenę w przeglądarce!** diff --git a/content/pl/administration/migrating.md b/content/pl/administration/migrating.md deleted file mode 100644 index e9928bf8..00000000 --- a/content/pl/administration/migrating.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: Migracja serwerów -description: Jak przenieść instancję Mastodona na inny serwer -menu: - docs: - parent: administration - weight: 6 ---- - -Czasami, z różnych powodów, możesz potrzebować przenieść swoją instancję Mastodona z jednego serwera na drugi. Na szczęście, nie jest to trudny proces, choć może spowodować niedostępność serwera przez trochę czasu. - -**Uwaga:** ten przewodnik został napisany z myślą o Ubuntu Server, proces ten może przebiegać inaczej na innych konfiguracjach. - -Podstawowe kroki ----- - -1. Skonfiguruj nowy serwer Mastodona w oparciu o [przewodnika instalacji](/administration/installation/) (nie uruchamiaj jednak `mastodon:setup`). -2. Zatrzymaj Mastodona na starym serwerze (np. `systemctl stop 'mastodon-*.service'`). -3. Wykonaj zrzut bazy danych Postgres i załaduj ją korzystając z poniższych instrukcji. -4. Wykonaj kopię plików `system/` korzystając z poniższych instrukcji. (jeżeli korzystasz z S3, możesz pominąć ten krok.) -5. Skopiuj plik `.env.production`. -6. Uruchom `RAILS_ENV=production ./bin/tootctl feeds build`, aby wygenerować oś czasu dla każdego użytkownika. -7. Uruchom Mastodona na nowym serwerze. -8. Zaktualizuj ustawienia DNS, aby kierowały na nowy serwer. -9. Zaktualizuj lub przenieś kopię konfiguracji Nginx, uruchom ponownie LetsEncrypt jeżeli to potrzebne. -10. Ciesz się nowym serwerem! - -Szczegółowe omówienie ----- - -### Jakie dane muszą zostać przeniesione - -Przede wszystkim, musisz przenieść następujące: - -- Katalog `~/live/public/system`, który zawiera zdjęcia i filmy wysłane przez użytkowników (jeżeli korzystasz z S3, nie potrzebujesz tego) -- Bazę danych Postgres (korzystając z [pg\_dump](https://www.postgresql.org/docs/9.1/static/backup-dump.html)) -- Plik `~/live/.env.production`, zawierający ustawienia serwera i tajne kody - -Oprócz tego, możesz też dla ułatwienia skopiować następujące: -Less crucially, you'll probably also want to copy the following for convenience: - -- Konfiguracja nginx (`/etc/nginx/sites-available/default`) -- Pliki konfiguracji systemd (`/etc/systemd/system/mastodon-*.service`), mogące zawierać poprawki serwera -- Konfigurację pgbouncer w `/etc/pgbouncer` (jeżeli go używasz) - -### Wykonaj i załaduj zrzut Postgres - -Zamiast uruchamiania `mastodon:setup`, utworzymy pustą bazę danych Postgres korzystając z bazy danych `template0` (przydatne przy przywracaniu zrzutów Postgres -[jak to opisano w dokumentacji pg\_dump](https://www.postgresql.org/docs/9.1/static/backup-dump.html#BACKUP-DUMP-RESTORE)). - -Uruchom następujące polecenie jako użytkownik `mastodon` na starym systemie: - -```bash -pg_dump -Fc mastodon_production -f backup.dump -``` - -Przenieś plik `backup.dump` korzystając z `rsync` lub `scp`. Na nowym systemie utwórz nową bazę danych jako użytkownik `mastodon`: - -```bash -createdb -T template0 mastodon_production -``` - -Później zaimportuj ją: - -```bash -pg_restore -U mastodon -n public --no-owner --role=mastodon \ - -d mastodon_production backup.dump -``` - -(jeżeli nazwą użytkownika na nowym serwerze nie jest `mastodon`, powinieneś(-naś) zmienić wartości `-U` i `--role` powyżej. Nazwa użytkownika może się różnić pomiędzy dwoma serwerami.) -(Note that if the username is not `mastodon` on the new server, you should change the -`-U` AND `--role` values above. It's okay if the username is different between the two servers.) - -### Kopiowanie plików - -Może to zająć trochę czasu, więc aby uniknąć niepotrzebnego kopiowania tego samego, zalecane jest użycie `rsync`. -Na poprzednim urządzeniu, jako użytkownik `mastodon`, wykonaj: - -```bash -rsync -avz ~/live/public/system/ mastodon@example.com:~/live/public/system/ -``` - -Musisz uruchomić to ponownie, jeżeli zmieni się jakiś z tych plików na poprzednim serwerze. - -Powinieneś(-naś) też skopiować plik `.env.production` zawierający konfigurację i tajne kody. - -Możesz skopiować pliki konfiguracyjne nginx, systemd i pgbouncer lub utworzyć je od nowa. - -### Podczas migracji - -Możesz zedytować stronę `~/live/public/500.html` na poprzednim serwerze, jeżeli chcesz wyświetlić informację powiadamiającą użytkowników o trwającej migracji. - -Możesz też zmienić DNS TTL na małą wartość (30-60 minut) dzień wcześniej, aby serwery DNS szybko poznały nowy adres IP. - -### Po migracji - -Możesz użyć [whatsmydns.net](http://whatsmydns.net/), aby sprawdzić, jak przepiega proces propagacji DNS. -Aby przyspieszyć ten proces, możesz zedytować plik `/etc/hosts`, aby kierował na nowy serwer, dzięki czemu możesz zacząć korzystać z niego wcześniej. diff --git a/content/pl/administration/optional-features.md b/content/pl/administration/optional-features.md deleted file mode 100644 index a2a6d718..00000000 --- a/content/pl/administration/optional-features.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Dodatkowe funkcje -description: Jak włączyć dodatkowe funkcje Mastodona -menu: - docs: - parent: administration - weight: 5 ---- - -## Wyszukiwanie tekstu - -TODO - -## Ukryte usługi - -TODO - -## Logowanie z użyciem LDAP/PAM/CAS/SAML - -TODO diff --git a/content/pl/administration/post-installation.md b/content/pl/administration/post-installation.md deleted file mode 100644 index c67010e8..00000000 --- a/content/pl/administration/post-installation.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: Kroki po instalacji -description: Co zrobić po zakończeniu instalacji Mastodona -menu: - docs: - parent: administration - weight: 3 ---- - -## Korzystanie z interfejsu wiersza poleceń - -Interfejs wiersza poleceń Mastodona jest plikiem wykonywalnym o nazwie `tootctl` znajdującym się w katalogu `bin` wewnątrz głównego katalogu Mastodona. Musisz określić, którego środowiska chcesz używać określając zmienną środowiskową `RAILS_ENV`. Jeżeli nie jesteś programistą korzystającą z urządzenia lokalnie, musisz użyć `RAILS_ENV=production`. Jeżeli masz pewność, że nigdy nie będziesz potrzebować innego środowiska, możesz dodać je dla ułatwienia do pliku `.bashrc`, np.: - -```bash -echo "export RAILS_ENV=production" >> ~/.bashrc -``` - -Jeżeli tak zrobisz, nie będziesz musiał(-a) uwzględniać go cały czas. W przeciwnym razie, wywołania `tootctl` będą wyglądały tak, zakładająć że kod Mastodona znajduje się w katalogu `/home/mastodon/live`: - -```bash -cd /home/mastodon/live -RAILS_ENV=production bin/tootctl help -``` - -## Tworzenie konta administratora -### W przeglądarce - -Po zarejestrowaniu się w przeglądarce, musisz użyć wiersza poleceń aby nadać nowo utworzonemu kontu prawa administratora. Załóżmy, że Twoja nazwa użytkownika to `alice`: - -```bash -RAILS_ENV=production bin/tootctl accounts modify alice --role admin -``` - -### W wierszu poleceń - -Możesz utworzyć nowe konto używając interfejsu wiersza poleceń. - -```bash -RAILS_ENV=production bin/tootctl accounts create \ - alice \ - --email alice@example.com \ - --confirmed \ - --role admin -``` - -W terminalu pojawi się wygenerowane losowo hasło. - -## Wypełnianie informacji o serwerze - -Po zalogowaniu się, przejdź na stronę **Ustawienia strony**. Mimo braku technicznego wymogu wypełnienia tych informacji, są one istotne dla użytkowników. - -|Ustawienie|Opis| -|----------|----| -|Nazwa użytkownika do kontaktu|Twoja nazwa użytkownika, aby inni mogli wiedzieć, do kogo należy serwer| -|Służbowy adres e-mail|Twój adres e-mail, aby osoby które nie mogą się zalogować lub nie mają konta mogły się z Tobą skontaktować| -|Opis instancji|Dlaczego ten serwer powstał? Dla kogo jest on przeznaczony? Co czyni go wyjątkowym?| -|Niestandardowy opis strony|Możesz tu umieścić różnego rodzaju informacje, ale zalecane jest umieszczenie **zasad**| - -Po wypełnieniu tych pól, naciśnij „Zapisz zmiany”. - -## Ustawienie regularnych kopii zapasowych (nieobowiązkowe, choć nie do końca) - -W przypadku rzeczywistego zastosowania, upewnij się że będziesz wykonywać kopie zapasowe serwera Mastodona. -For any real-world use, you should make sure to regularly backup your Mastodon server. - -### Omówienie - -Things that need to be backed up in order of importance: - -1. Baza danych PostgreSQL -2. Tajne klucze aplikacji z pliku `.env.production` lub odpowiadającego mu -3. Pliki wysłane przez użytkowników -4. Baza danych Redis - -### Tryby awaryjne - -Istnieją dwa rodzaje niepowodzeń przed którymi większość osób choni się: awaria sprzętu, taka jak uszkodzenie danych na dysku i błąd oprogramowania lub człowieka, taki jak przypadkowe usunięcie części danych. W tej dokumentacji omówiony zostaje tylko pierwszy przypadek. - -Utrata bazy danych PostgreSQL to najgorsza możliwość. Mastodon przechowuje tam wszystkie ważne dane. Jeżeli baza danych zniknie, wraz z nią znikną wszystkie konta i wpisy z Twojego serwera. - -Jeżeli utracisz tajne klucze aplikacji, część funkcji Mastodona przestanie działać użytkownikom, zostaną wylogowani, uwierzytelnianie dwuetapowe nie będzie dostępne i subskrypcje Web Push API przestaną działać. - -Jeżeli utracisz pliki wysłane przez użytkowników, znikną awatary, zdjęcia nagłówka i załączniki multimedialne, ale Mastodon wciąż *będzie* działać. - -Utrata bazy danych Redis jest prawie bezbolesna: jedyne nieodwracalne dane to kolejki Sidekiq i zaplanowane ponowne próby nieudanych zadań. Strumienie list i osi czasu są przechowywane przez Redis, ale mogą zostać wygenerowane ponownie z użyciem tootctl. - -Najlepsze kopie zapasowe to te na innym urządzeniu niż to, na którym uruchomiony jest Mastodon. Dla przykładu, jeżeli serwer spłonie, a dysk twardy wybuchnie, kopie zapasowe przechowywane na nim nie będą mogły zostać użyte… - -### Kopia zapasowa tajnych kodów - -Są one najprostsze do zabezpieczenia, ponieważ nigdy się nie zmieniają. Musisz tylko przechowywać `.env.production` w bezpiecznym miejscu. - -### Kopia zapasowa PostgreSQL - -PostgreSQL jest zagrożony utratą danych w wyniku utraty prądu, uszkodzeń dysku twardego i nieudanych migracji. Z tego powodu, zalecane jest tworzenie od czasu do czasu kopii zapasowej używając `pg_dump` lub `pg_dumpall`. - -Gdy ważna jest dostępność w każdym momencie, możesz używać replikacji przez strumieniowanie, aby mieć drugi serwer PostgreSQL z zawsze aktualnymi danymi i móc przełączyć się na niego, jeżeli jeden serwer przestanie działać. - -### Kopia zapasowa plików wysyłanych przez użytkowników - -Jeżeli korzystasz z zewnętrznego dostawcy object storage takiego jak Amazon S3, Google Cloud lub Wasabi, nie musisz przejmować się tworzeniem kopii zapasowych. Te firmy są odpowiedzialne za radzenie sobie z awariami sprzętu. - -Jeżeli przechowujesz pliki lokalnie, od Ciebie zależy, czy będziesz tworzyć kopie coraz większego katalogu `public/system`, gdzie domyślnie przechowywane są wysyłane pliki. - -### Kopia zapasowa Redis - -Tworzenie kopii zapasowej Redis jest proste. Redis regularnie zapisuje wszystko w `/var/lib/redis/dump.rdb`, jedynym pliku który powinieneś(-naś) gdzieś przechowywać. diff --git a/content/pl/administration/troubleshooting.md b/content/pl/administration/troubleshooting.md deleted file mode 100644 index fd312114..00000000 --- a/content/pl/administration/troubleshooting.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Rozwiązywanie problemów -description: Jak określić, co złego stało się z instalacją Mastodona -menu: - docs: - parent: administration - weight: 99 ---- - -**Widzę stronę informującą, że coś poszło nie tak. Jak mogę dowiedzieć się, co jest nie tak?** - -Wszystkie informacje o błędach wraz ze „śladem stosu” zapisywane są w systemowym dzienniku. Jeżeli korzystasz z systemd, możesz uzyskać dziennik każdej usługi systemd używając `journalctl -u mastodon-web` (zamień na prawidłową nazwę usługi). Jeżeli korzystasz z Dockera, jest wygląda to podobnie: `docker logs mastodon_web_1` (zamień na prawidłową nazwę kontenera). - -Szczegóły dotyczące błędów serwera *nigdy* nie są wyświetlane publicznie, ponieważ mogą one ujawnić jak wygląda konfiguracja od wewnątrz, mogące pomóc atakującym w dostaniu się do serwera lub bardziej skutecznym nadużywaniu systemu. - -Każda odpowiedź z serwera Mastodona zawiera nagłówek z niepowtarzalnym identyfikatorem żądania, widocznym w logach. Sprawdzając nagłówek na stronie błędu, możesz łatwo odnaleźć odpowiedni ślad stosu w dzienniku. - -**Po aktualizacji do nowej wersji, niektóre strony wyglądają dziwnie, jakby nie miały prawidłowego stylu. Dlaczego?** - -Upewnij się, czy uruchomiłeś(-aś) `RAILS_ENV=production bin/rails assets:precompile` po aktualizacji i uruchomiłeś(-aś) ponownie proces sieciowy Mastodona, ponieważ prawdopodobnie serwer korzysta z nieaktualnych arkuszy stylów i skryptów. Możliwe też, że kompliacja nie powiodła się z powodu braku RAM-u, ponieważ webpack zużywa niestety ogromną ilość pamięci. Jeżeli jest to powodem, upewnij się, że serwer ma przydzielone trochę pamięci swap. -Możesz też skompilować te zasoby na innym urządzeniu i przenieść katalog `public/packs`. - -**Po aktualizacji do nowej wersji, niektóre żądania kończą się niepowodzeniem lub zwracają informacje o brakujących kolumnach lub tablicach. Dlaczego?** - -Upewnij się, że uruchomiłeś(-aś) `RAILS_ENV=production bin/rails db:migrate` po aktualizacji, ponieważ wygląda na to że kod Mastodona próbuje uzyskać dostęp do nowszego lub starszego schematu bazy danych. Jeżeli korzystasz z PgBouncera, upewnij się że to polecenie łączy się on bezpośrednio z PostgreSQL, ponieważ PgBouncer nie obsługuje rodzaju blokad tabeli używanych w trakcie migracji. - -**Próbuję wykonać polecenie `tootctl` lub `rake`/`rails`, ale otrzymuję jedynie błąd dotyczący niezainicjalizowanych stałych. Co jest nie tak?** - -Upewnij się, że określiłeś(-aś) prawidłowe środowisko używając `RAILS_ENV=production` przed poleceniem. Zwykle, polecenia te zakładają, że są uruchamiane w środowisku nieprodukcyjnym, więc kod próbuje załadować gemy przeznaczone dla programistów. W śtodowiskach produkcyjnych, unika się instalacji tych gemów, dlatego pojawiają się te błędy. \ No newline at end of file diff --git a/content/pl/administration/upgrading.md b/content/pl/administration/upgrading.md deleted file mode 100644 index b183cd2f..00000000 --- a/content/pl/administration/upgrading.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Aktualizacja do nowego wydania -description: Jak zaktualizować Mastodona do nowszej wersji -menu: - docs: - parent: administration - weight: 5 ---- - -Kiedy pojawia się nowa wersja Mastodona, możesz znaleźć ją na [stronie wydań na GitHubie](https://github.com/tootsuite/mastodon/releases). Pamiętaj, że korzystanie z niewydanego kodu z gałęzi `master` jest możliwe, choć nie jest zalecane. - -Wydania Mastodona są przyporządkowanem tagom gita. Na początek, zaloguj się na użytkownika `mastodon`: - -```sh -su - mastodon -``` - -Przejdź do głównego katalogu Mastodona: - -```sh -cd /home/mastodon/live -``` - -Pobierz kod wydania, zakładając że nowa wersja nazywa się `v2.5.0`: - -```sh -git fetch --tags -git checkout v2.5.0 -``` - -Strona wydania zawiera listę zmian, a pod nią instrukcje aktualizacji. Dowiesz się, jak wykonać ją. Na przykład, jeżeli jest wspomniane, że musisz skompilować ponownie zasoby, powinieneś(-naś) wykonać: - -```sh -RAILS_ENV=production bundle exec rails assets:precompile -``` - -Po wykonaniu instrukcji dotyczących wydania, pozostaje uruchomić ponownie Mastodona. *Zwykle* API strumieniowania nie jest aktualizowane, więc nie wymaga ono ponownego uruchomienia. Ponowne uruchomienie API strumieniowania może wywołać niezwykle wysokie obciążenie serwera, więc zalecane jest unikanie go. - -Wróć na konto root: - -```sh -exit -``` - -Uruchom ponownie Sidekiq: - -```sh -systemctl restart mastodon-sidekiq -``` - -Załaduj ponownie proces sieciowy, aby uniknąć niedostępności serwera: - -```sh -systemctl reload mastodon-web -``` - -**To wszystko!** Twój serwer używa teraz nowej wersji Mastodona! diff --git a/content/pl/usage/basics.md b/content/pl/usage/basics.md deleted file mode 100644 index 19b7b550..00000000 --- a/content/pl/usage/basics.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: Podstawy -description: Omówienie podstawowej funkcjonalności Mastodona -menu: - docs: - parent: usage - weight: 1 ---- -## Rejestracja - -Musisz wybrać serwer na którym się zarejestrujesz, tak jak wybrał(-a)byś dostawcę e-maila lub realm w World of Warcraft dla nowej postaci. Na tym serwerze będzie znajdować się Twoje konto i strumień. - -Możesz [przejrzeć listę serwerów podzieloną według kategorii i języków na joinmastodon.org](https://joinmastodon.org/#getting-started). - -## Edycja profilu -### Zdjęcie, nazwa i opis - -- Możesz zmienić awatar -- Możesz ustawić obraz nagłówka -- Możesz ustawić nazwę wyświetlaną inną niż nazwa użytkownika -- Możesz napisać o sobie w biogramie -- Możesz tam wspomnieć o innych kontach i używać hashtagów lub niestandardowych emoji - -### Metadane profilu - -Metadane profilu są sposobem na umieszczenie dodatkowych informacji w przejrzysty sposób. Możesz wykorzystać 4 rzędy, w których określasz nazwę i zawartość. Na przykład: - -|Nazwa|Zawartość| -|-----|-------| -|Wiek|25| -|Kraj|Niemcy| -|Zaimek osobowy|he/him| - -To, co tam umieścisz zależy tylko od Ciebie – możesz wspomnieć o innych, użyć hashtagów, niestandardowych emoji i odnośników. - -### Weryfikacja odnośników - -Jeżeli umieścisz odnośnik w metadanych profilu, Mastodon sprawdzi, czy ta strona zawiera odnośnik do Twojego profilu na Mastodonie. Jeżeli tak, obok odnośnika zostanie wyświetlony znak weryfikacji, ponieważ jesteś jego potwierdzonym właścicielem. - -Mastodon sprawdza obecność artybutu `rel="me"` w tym odnośniku. Tak samo, Mastodon umieszcza `rel="me"` na odnośnikach w metadanych. - -## Tworzenie wpisów -### Tekst - -- Możesz użyć maksymalnie 500 znaków -- Możesz wspomnieć o innych użytkownikach, np. `@alice` lub `@alice@example.com` -- Jeżeli wspominasz o innych, część zawierająca domenę jest omijana przez limit znaków -- Odnośniki muszą zaczynać się od `http://` lub `https://` -- Wszystkie odnośniki liczone są jako 23 znaki, niezależnie od ich długości -- Możesz używać hashtagów tj. `#przykład`, aby inni mogli znaleźć Twój wpis używając tego tagu -- Możesz dodawać ostrzeżenia o zawartości dla wpisów -- Ostrzeżenie o zawartości to czysty tekst. Nie obsluguje wspomnień, hashtagów i odnośników - -### Zawartość multimedialna - -- Możesz wysyłać zdjęcia w JPG i PNG -- Wysyłane GIF-y są konwertowane do MP4 bez dźwięku, tak jak na Imgur i Gfycat (GIFV) -- Możesz też wysyłać bezpośrednio MP4 i WebM bez dźwięku (GIFV) -- Możesz wysyłać filmy w formacie MP4, WebM lub MOV -- Ograniczenie rozmiaru zdjęć to 8 MB -- Ograniczenie rozmiaru filmów to 40 MB -- Zdjęcia o powierzchni większej niż 1280² pikseli są skalowane w dół -- Możesz ukryć zawartość multimedialną za spoilerem - -### Niestandardowe emoji - -- Każdy serwer może oferować zestaw niestandardowych emoji, tak jak na Discordzie -- Możesz używać shortcode aby umieścić emoji, np. `:thounking:` diff --git a/content/pl/usage/decentralization.md b/content/pl/usage/decentralization.md deleted file mode 100644 index 7d450259..00000000 --- a/content/pl/usage/decentralization.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Decentralizacja -description: W jaki sposób Mastodon jest zdecentralizowany i co to w praktyce oznacza -menu: - docs: - parent: usage - weight: 2 ---- - -Mastodon jest **sfederowaną** siecią społecznościową. - -## Czym jest federacja? - -**Federacja** to rodzaj decentralizacji. Zamiast jednego, centralnego serwera używanego przez wszystkich, istnieje wiele serwerów, z których każdy może korzystać. - -|Rodzaj decentralizacji|Przykład| -|:--------------------:|--------| -|Scentralizowane|Twitter, Facebook, Instagram| -|Sfederowane|E-mail, XMPP| -|Dystrybuowane|BitTorrent, IPFS, Scuttlebutt| - -Serwer Mastodona może działać samodzielnie. Tak jak na tradycyjnej stronie internetowej, można tam zarejestrować się, publikować wiadomości, wysyłać zdjęcia i rozmawiać z innymi. *W przeciwieństwie* do tradycyjnej strony internetowej, serwery Mastodona porozumiewają się ze sobą, pozwalając na wzajemną komunikację swoich użytkowników, tak jak możesz wysłać maila adresem GMaila do kogoś używającego Outlooka. - -
- -

Od lewej do prawej: scentralizowana, sfederowana i dystrybuowana sieć

-
- -W praktyce – wyobraź sobie, że możesz obserwować użytkownika Instagrama ze swojego konta na Twitterze i komentować jego zdjęcia z tego konta. Gdyby Twitter i Instagram były sfederowanymi usługami, byłoby to możliwe. - -## Fediwersum - -Mastodon korzysta ze standaryzowanego, otwartego protokołu aby zaimplementować federację. Nazywa się on ActivityPub. Każde oprogramowanie, które zaimplementowało federację przez ActivityPub może komunikować się z Mastodonem, tak jak serwery Mastodona komunikują się ze sobą. - -**Fediwersum** („sfederowane uniwersum”) to nazwa, którą określamy wszystkie serwery mogące się ze sobą komunikować. Wliczają się w to wszystkie serwery Mastodona wraz z innymi implementacjami, np.: - -- Misskey -- Pleroma -- PeerTube -- Plume -- i wiele więcej - -Fediwesum nie jest marką, więc częściej usłyszysz „obserwuj mnie na Mastodonie”, niż „obserwuj mnie w Fediwersum”, choć to drugie jest bardziej poprawne technicznie. - -## Co to w praktyce oznacza -### Wspominanie o innych - -Nazwy użytkownika na Mastodonie składają się z dwóch części: - -- Lokalna nazwa użytkownika, np. `alice` -- Domena serwera, np. `example.com` - -To tak jak adres e-mail. Dla ułatwienia, Mastodon pozwala na ominięcie drugiej części nazwy użytkownika, kiedy wspominasz o osobie na tym samym serwerze, ale pamiętaj – dzieląc się swoją nazwą z innymi, musisz uwzględnić domenę, aby mogli Cię łatwo znaleźć. - -|{{< no >}}|{{< yes >}}| -|:--------:|:---------:| -|Nazywam się @alice na Mastodonie!|Nazywam się @alice@example.com na Mastodonie!| - -Formularz wyszukiwania na Mastodonie pozwala na znalezienie użytkowników zarówno korzystając z adresów takich jak powyższy, jak i odnośników do profili, więc możesz udostępniać tę wersję, którą wolisz. - -### Obserwowanie innych - -Jeżeli możesz spotkać osobę w interfejsie aplikacji, np. interfejsie sieciowym swojego serwera lub aplikacji mobilnej, możesz po prostu nacisnąć „śledź” – nie zauważysz różnicy, gdy ya osoba nie używa tego samego serwera. - -Jeżeli jednak napotkasz publiczny profil osoby z innego serwera, zauważysz przeszkodę – dla tego serwera jesteś anonimowym odwiedzającym. - -Kiedy naciśniesz „śledź”, pojawi się formularz z zapytaniem o pełną nazwę użytkownika (przede wszystkim część zawierającą domenę). W ten sposób zostaniesz przekierowany(-a) na swój serwer, gdzie jesteś zalogowany(-a) i możesz zaobserwować tę osobę. - -Zauważysz podobny formularz, gdy spróbujesz odpowiedzieć, podbić lub dodać do ulubionych wpis z publicznej strony na innym serwerze. - -### Przeglądanie zawartości - -Aby pozwolić na poznawanie zawartości, która może Cię zainteresować, Mastodon oferuje sposób na przeglądanie wszystkich publicznych wpisów. No dobra, nie istnieje dzielona pomiędzy wszystkimi serwerami oś czasu, więc nie możesz zobaczyć *wszystkich* publicznych wpisów. Kiedy przeglądasz **oś czasu federacji**, widzisz wszystkie publiczne wpisy znane przez serwer. Jest wiele sposobów, na które serwer może poznać wpisy, ale większość z nich pojawia się tam dlatego, że inni użytkownicy serwera śledzą ich autorów. - -Istnieje sposób na filtrowanie osi czasu, aby widzieć tylko publiczne wpisy ze swojego serwera – **lokalna oś czasu**. Pamiętaj, że „lokalna” odnosi się tu do serwera, nie położenia geograficznego. - -### Finansowanie i monetyzacja - -Serwery Mastodona są prowadzone przez różne, działające zupełnie niezależnie osoby lub organizacje. Oprogramowanie Mastodona nie zaimplementowało żadnego rozwiązania pozwalającego na monetyzację go. - -Niektóre serwery oferują płatne konta, niektóre należą do firm, które już posiadają odpowiednią infrastrukturę, a większość serwerów finansowana jest przez użytkowników za pośrednictwem Patreona i podobnych usług. Jeżeli chcesz pomóc w utrzymaniu serwera, sprawdź czy istnieje sposób na przekazanie dotacji. - -Rozwój Mastodona również jest finansowany przez społeczność na Patreonie. Odbywa się to bez udziału kapitału podwyższonego ryzyka. - -### Podszywanie się i weryfikacja - -Konto o tej samej nazwie użytkownika *może* zostać zarejestrowane na różnych serwerach, nie istnieje sposób na zajęcie ich wszystkich. Tak jak w przypadku adresów e-mail, nie oczekuj że `alice@hotmail.com` będzie tą samą osobą, co `alice@gmail.com`. - -Ponieważ możesz samodzielnie hostować Mastodona, nie istnieje lepszy sposób na potwierdzenie swojej tożsamości niż hostowanie Mastodona na własnej domenie, której inni ufają. - -Weryfikacja za okazaniem dokumentu i niebieski znaczek nie są możliwe na zdecentralizowanej usłudze. Możesz jednak potwerdzić, że odnośniki umieszczone w metadanych profilu należą do Ciebie. Jeżeli jeden z nich to Twoja osobista strona internetowa, może być to również sposób na weryfikację tożsamości tutaj. diff --git a/content/pl/usage/moderation.md b/content/pl/usage/moderation.md deleted file mode 100644 index 50226c5a..00000000 --- a/content/pl/usage/moderation.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Moderacja -description: Omówienie narzędzi moderacyjnych na Mastodonie -menu: - docs: - parent: usage - weight: 4 ---- -## Indywidualność moderacji - -Moderacja na Mastodonie zawsze działa lokalnie, tzn. tylko dla konkretnego serwera. Administrator lub moderator jednego serwera nie może wpłynąć na użytkownika innego serwera, a jedynie kopię jego profilu na swoim serwerze. - -### Wyłączenie logowania - -Konto na Mastodonie może zostać wyłączone. W ten sposób użytkownik nie może nic na nim zrobić, ale jego zawartość pozostaje nietknięta. To ograniczenie może zostać cofnięte w każdej chwili. Może zostać założone tylko na lokalnych użytkowników serwera. - -### Wyciszenie - -Wyciszenie na Mastodonie jest sposobem na jego odizolowanie. Wyciszone konto nie jest widoczne dla użytkowników, które go nie obserwują. Jego zawartość wciąż istnieje i może zostać znaleziona z użyciem wyszukiwarki, a autor wspomniany i śledzony, ale pozostaje niewidoczna. - -Obecnie wyciszenie nie wpływa na federację. Lokalnie wyciszone konto *nie* jest automatycznie wyciszone na innych serwerach. - -To ograniczenie jest odwracalne, wyciszenie możę zostać cofnięte w każdej chwili. - -### Zawieszenie - -Wyciszenie na Mastodonie jest równoznaczne z usunięciem go. Konto nie może zostać wyszukane, strona profilu, wraz ze wszystkimi jego wpisami, wysłanymi plikami i resztą danych zostają usunięte. To ograniczenie jest **nieodwracalne**. Choć zawieszenie może zostać cofnięte, a użytkownik może odzyskać konto, treść znika na zawsze. - -## Moderacja całych serweróœ - -Ponieważ samodzielne moderowanie dużej liczby użytkowników z nieprawidłowo zachowującego się serwera może być męczące, jest możliwa prewencyjna moderacja wszystkich użytkowników danego serwera nazywana **blokadą domeny**, która ma kilka poziomów swojego zakresu. - -### Odrzucanie zawartości multimedialnej - -Jeżeli ta opcja jest włączona, żadne pliki z danego serwera nie będą przetwarzane. Wliczane są w to awatary, obrazy nagłówka, niestandardowe emoji i załączniki multimedialne. - -### Wyciszenie - -Wycisza wszystkich obecnych i przyszłych użytkowników serwera. - -### Zawieszenie - -Zawiesza wszystkich obecnych i przyszłych użytkowników serwera. Nie jest przechowywana zawartość z serwera poza nazwami użytkowników. - -## Sposoby na zapobieganie spamu - -Istnieje kilka podstawowych sposobów na zapobieganie spamu na Mastodonie: - -- Rejestracja wymaga potwierdzenia adresu e-mail -- Rejestracja jest ograniczana na podstawie adresu IP. - -Doświadczony spamer może jednak ominąć je. Innym sposobem jest **czarna lista domen e-mail**. Podczas rejestracji, Mastodon sprawdza rekord A lub MX podanego adresu e-mail, np. adres IP serwera e-mail i porównuje ten adres e-mail z przechowywaną czarną listą. - -### Blokowanie na podstawie serwerów e-mail - -Spamerzy będą często używać innych domen e-maili, aby wyglądało to tak, jakby używali innych serwerów e-mail, które ciężko byłoby dodawać oddzielnie na czarną listę. Często jednak one wszystkie prowadzą do jednego adresu IP serwera e-mail. Jeżeli widzisz, że dużo spamerów rejestruje się w tym samym czasie, możesz to sprawdzić używając narzędzia wyszukiwania po DNS online lub korzystając z linuksowego narzędzia `dig` – np. `dig 1.2.3.4` wyświetli wszystkie rekordy DNS dla tego IP. Jeżeli zauważysz, że IP jest to samo dla wszystkich domen, możesz dodać je do czarnej listy domen e-mail. - -### Blokowanie po IP - -Nie jest możliwe zablokowanie odwiedzających po adresie IP z użyciem Mastodona i nie jest to zbyt dobre rozwiązanie. Adresy IP czasem są używane przez wiele osób, zmieniają się ich właściciele. Jest możliwe zablokowanie odwiedzających po adresie IP na Linuksie używając firewalla. Oto przykład korzystający z `iptables` i `ipset`: - -```bash -# Zainstaluj ipset -sudo apt install ipset -# Utwórz czarną listę o nazwie „spambots” -sudo ipset create spambots nethash -# Dodaj 1.2.3.4 na czarną listę -sudo ipset add spambots 1.2.3.4 -# Dodaj regułę firewalla opartą o czarną listę -sudo iptables -I INPUT 1 -m set --match-set spambots src -j DROP -``` - -Uważaj, aby nie zablokować siebie na własnym urządzeniu. diff --git a/content/pl/usage/privacy.md b/content/pl/usage/privacy.md deleted file mode 100644 index 3da36112..00000000 --- a/content/pl/usage/privacy.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: Prywatność -overview: Omówienie funkcji dotyczących prywatności na Mastodonie i ich skutków -menu: - docs: - parent: usage - weight: 3 ---- - -## Poziomy prywatności - -|Poziom|Publiczna oś czasu|Odnośnik bezpośredni|Widok profilu|Osi czasu| -|------|:----------------:|:------------------:|:-----------:|:-------:| -|Publiczny|{{< yes >}}|{{< yes >}}|{{< yes >}}|{{< yes >}}| -|Niewypisany|{{< no >}}|{{< yes >}}|{{< yes >}}|{{< yes >}}| -|Tylko dla śledzących|{{< no >}}|{{< no >}}|{{< no >}}|{{< yes >}}| -|Bezpośrednio|{{< no >}}|{{< no >}}|{{< no >}}|{{< no >}}| - -Niezależnie od poziomu, każdy wspomniany użytkownik może zobaczyć wiadomość w powiadomieniach. - -**Nie udostępniaj niebezpiecznych i wrażliwych informacji używając bezpośrednich wiadomości**. Mastodon nie jest aplikacją do szyfrowanych połączeń taką jak Signal i Wire, administrator bazy danych serwera nadawcy i odbiorcy ma dostęp do tekstu. Używaj ich z taką ostrożnością, jak prywatnych wiadomości na forach, Discordzie i Twitterze. - -## Blokada konta - -Aby mieć kontrolę nad tym, kto zobaczy wpisy tylko dla śledzących, musisz zablokować swoje konto – w innym przypadku, kazdy może zacząć Cię obserwować, aby zobaczyć Twoje starsze wpisy. Zablokowanie konta na Mastodonie dodaje krok autoryzacji do procesu śledzenia. - -Po zablokowaniu konta, zanim ktoś będzie mógł zacząć Cię śledzić, otrzymasz prośbę o możliwość śledzenia, którą możesz przyjąć lub odrzucić. - -Pamiętaj, że prywatność na Mastodonie odnosi się do poszczególnych kont, nie całego konta – nie istnieje sposób na natychmiastowe uczynienie wszystkich starszych wpisów prywatnymi. - -## Blokowanie i wyciszanie -### Ukrywanie podbić - -Jeżeli ukryjesz czyjeś podbicia, nie będziesz ich widzieć na osiach czasu. - -### Wyciszanie - -Gdy wyciszysz użytkownika, masz też możliwość wyciszenia powiadomień dotyczących go. Wyciszenie oznacza, że nie będziesz widzieć: - -- wpisów użytkownika na Twoim strumieniu -- wpisów tego użytkownika podbitych przez innego -- wpisów użytkowników wspominających o nim -- wpisów użytkownika na publicznych osiach czasu - -Jeżeli wyciszysz też powiadomienia, nie będziesz widzieć powiadomień od tego użytkownika. - -Użytkownik nie może dowiedzieć się, że został wyciszony. - -### Blokowanie - -Blokowanie użytkownika ukrywa: - -- wpisy użytkownika na Twoim strumieniu -- wpisy tego użytkownika podbitych przez innego -- wpisy użytkowników wspominających o nim -- wpisy użytkownika na publicznych osiach czasu -- powiadomienia od tego użytkownika - -Dodatkowo, zablokowany użytkownik: - -- zostaje zmuszony, aby przestał Cię zaobserwować -- nie może Cię zaobserwować -- nie zobaczy podbić Twoich wpisów od innych użytkowników -- nie zobaczy Twoich wpisów na publicznej osi czasu - -Jeżeli korzystasz z tego serwera co zablokowany użytkownik, nie będzie on mógł zobaczyć Twoich wpisów będąc zablokowany. - -### Ukrywanie całego serwera - -Jeżeli ukryjesz cały serwer: - -- nie zobaczysz wpisów z tego serwera na publicznej osi czasu -- nie zobaczysz podbić wpisów z tego serwera od innych użytkowników -- nie zobaczysz powiadomień z tego serwera -- utracisz wszystkie obserwacje użytkowników z tego serwera diff --git a/data/HttpCodes.toml b/data/HttpCodes.toml new file mode 100644 index 00000000..f3f0ee52 --- /dev/null +++ b/data/HttpCodes.toml @@ -0,0 +1,7 @@ +200 = "Success" +401 = "Unauthorized" +403 = "Forbidden" +404 = "Not Found" +409 = "Conflict" +410 = "Gone" +422 = "Unprocessable Entity" diff --git a/i18n/en.toml b/i18n/en.toml new file mode 100644 index 00000000..0fc441bd --- /dev/null +++ b/i18n/en.toml @@ -0,0 +1,59 @@ +[improvePage] +other = "Improve this page" + +[lastUpdated] +other = "Last updated" + +[joinTitle] +other = "Join the social media revolution" + +[joinText] +other = "Mastodon is a free, decentralized platform with over three million people" + +[joinAction] +other = "Join Mastodon now!" + +[merch] +other = "Merch" + +[shirtsAndStickers] +other = "T-shirts and stickers" + +[joinMastodon] +other = "Join Mastodon" + +[blog] +other = "Blog" + +[viewSource] +other = "View source" + +[imprint] +other = "Imprint" + +[formDataParameters] +other = "Form Data Parameters" + +[headers] +other = "Headers" + +[required] +other = "required" + +[optional] +other = "optional" + +[pathParameters] +other = "Path Parameters" + +[queryParameters] +other = "Query Parameters" + +[request] +other = "Request" + +[response] +other = "Response" + +[otherTranslations] +other = "Also available in:" diff --git a/layouts/_default/single.html b/layouts/_default/single.html index 8f2d70b3..8e731b67 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -1,14 +1,26 @@ {{ define "main" }}

{{ .Title }}

- + {{ with .Description }} +

{{.}}

+ {{ end }}
{{ .Content }}

- Last updated {{ .Lastmod.Format "January 2, 2006" }} · - Improve this page + {{ i18n "lastUpdated" }} {{ .Lastmod.Format "January 2, 2006" }}{{ with .File }} · {{ i18n "improvePage" }}{{ end }} + + {{ if .IsTranslated }} +
+ + {{ i18n "otherTranslations" }} + + {{ range .Translations }} + {{ .Language.LanguageName }} + {{ end }} + {{ end }}

+
{{ end }} diff --git a/layouts/index.html b/layouts/index.html index 9c3a9416..a98ff5a4 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -1,17 +1,28 @@ -{{ define "title"}} Mastodon documentation {{end}} +{{ define "title"}}{{ .Site.Title }}{{ end }} {{ define "main" }}

{{ .Title }}

+ {{ with .Description }} +

{{.}}

+ {{ end }} +
{{ .Content }} -

Available languages:

+

+ {{ i18n "lastUpdated" }} {{ .Lastmod.Format "January 2, 2006" }}{{ with .File }} · {{ i18n "improvePage" }}{{ end }} -

+

+
{{ end }} diff --git a/layouts/partials/cta.html b/layouts/partials/cta.html index ea8dc2d9..4b1010fb 100644 --- a/layouts/partials/cta.html +++ b/layouts/partials/cta.html @@ -1,5 +1,5 @@
-

Join the social media revolution

-

Mastodon is a free, decentralized platform with over a million people

- Join Mastodon now! +

{{ i18n "joinTitle" }}

+

{{ i18n "joinText" }}

+ {{ i18n "joinAction" }}
diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html index ccb3268e..17fb2dda 100644 --- a/layouts/partials/footer.html +++ b/layouts/partials/footer.html @@ -1,16 +1,14 @@ - - diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 3d5228e5..c8322eb5 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -4,5 +4,9 @@ - - + +{{ $css := resources.Get "style.scss" | toCSS | minify | fingerprint }} + + +{{ $js := resources.Get "main.js" | minify | fingerprint }} + diff --git a/layouts/partials/sidebar.html b/layouts/partials/sidebar.html index 848bd2ce..208ee5ec 100644 --- a/layouts/partials/sidebar.html +++ b/layouts/partials/sidebar.html @@ -1,36 +1,36 @@ - - + + -
- -
-