# Mastodon: OAuth app setup and approval
Self-serve · Sourced · updated 27 Oct 2026 · https://oauth-guide.akshatsethi.com/apps/mastodon

> Mastodon is self-serve: any app can register on any Mastodon server through a public API call, and there is no review, test-user list or user cap. The work is technical. Mastodon is decentralized, so you must register a separate OAuth client on each server your users come from, usually on the fly when a user enters their server domain.

- **Your hands-on work:** 1–4 h
- **Waiting on Mastodon:** None
- **First user can connect:** Today, in about 15 to 30 minutes
- **Why Self-serve:** POST /api/v1/apps is a public endpoint that returns client credentials immediately, and the docs mention no app review or approval.
- **Using Composio?** Mastodon isn't in Composio's managed-auth catalog, managed or bring-your-own. Plan to register OAuth clients yourself on each Mastodon server.

## Path to launch
### Build: Your account
- Who can connect: You, on any Mastodon server where you've registered your app
- What users see: The server's standard authorization page, showing your app name and requested scopes
- Effort: 15–60 min · Wait: None
- Next: Add per-server client registration so users on any server can connect
- _(Docs [1, 3, 4])_

### Launch: Any Mastodon server
- Who can connect: Any user on any Mastodon server your app registers with
- What users see: The same authorization page on their own server. The docs describe no unverified-app warning.
- Effort: 1–3 h · Wait: None
- _(Docs [3, 4])_

## Before you start
- [ ] **A Mastodon account** (You). An account on any Mastodon server, used to test the authorization flow. _(Inferred [4])_
- [ ] **An absolute redirect URI** (Agent). A callback URL in your OAuth client. It must be absolute or the server returns 422. Use urn:ietf:wg:oauth:2.0:oob only for manual testing. _(Docs [3])_
- [ ] **Per-server credential storage** (Agent). Somewhere to store an encrypted client_id and client_secret for each Mastodon server domain, so you register once per server and reuse the credentials. _(Docs [3, 4, 7])_

## Steps
1. **Choose the narrowest scopes** (Agent, 5–15 min). Pick granular scopes such as read:statuses or write:statuses, or the broad read, write and profile scopes. The scopes you register are the most an authorize request can ask for. Avoid follow (deprecated since 3.5.0) and crypto (removed in 4.3.0). _(Docs [2])_
   - List the API calls your integration makes
   - Map them to scopes (e.g. read:accounts, write:statuses, write:media)
   - Add profile if you only need the user's identity (4.3.0+)
   - Agent: An agent can map the features to scopes from the scopes doc.
   - Watch out: Asking for a scope at authorize time that you didn't register makes the authorization fail.
2. **Register your app on a Mastodon server** (Agent, 5–10 min). Send POST https://{server}/api/v1/apps with client_name, redirect_uris, scopes (space-separated) and an optional website. No auth is needed. The response contains client_id and client_secret. _(Docs [3, 1])_
   - POST /api/v1/apps with client_name, redirect_uris (your redirect URI), scopes and website
   - Hand the client_id and client_secret to your backend's secret store without displaying them
   - Agent: An agent can make the call. A person or your backend should handle and store the client_secret.
   - Watch out: Before 4.3, servers could delete apps that were registered but never used. On older servers, request a client_credentials token right after registering to keep the app active.
3. **Configure your OAuth client endpoints** (Agent, 10–20 min). Set the authorize URL to https://{server}/oauth/authorize and the token URL to https://{server}/oauth/token, with response_type=code. Use PKCE (S256 only) on servers running 4.3.0 or later. _(Docs [4, 7], medium confidence)_
   - Set authorize URL and token URL for the server
   - Set scope to a subset of the registered scopes
   - Enable PKCE S256 if GET /.well-known/oauth-authorization-server returns 200
   - Agent: An agent can set up the client config. The client_secret should be loaded from your secret store, not pasted by the agent.
   - Watch out: Very long state values can break Doorkeeper redirects. Keep state short and store the rest on your server.
4. **Connect your own account and verify** (You, 5–10 min). Sign in on your server, approve the app, and exchange the code for a token. Call GET /api/v1/accounts/verify_credentials to confirm the token works. _(Docs [5, 7])_
   - Open the authorize URL and approve
   - Exchange the code at /oauth/token (a code works only once)
   - Call /api/v1/accounts/verify_credentials
   - Agent: The person signs in and approves. An agent can then run the verification call.
   - Watch out: invalid_grant usually means the redirect_uri doesn't match exactly, or the code came from a client registered on another server.
5. **Register automatically for each user's server** (Agent, 1–3 h). Ask users for their server domain, look up stored credentials for that domain, and call POST /api/v1/apps if none exist. Route authorize and token requests to that server. _(Docs [4, 3])_
   - Add a server-domain input to your connect flow
   - Cache client credentials per domain, encrypted
   - Use the discovery endpoint to detect PKCE and scope support, falling back if it returns 404 (pre-4.3)
   - Agent: An agent can implement and test this logic.
   - Watch out: Mastodon doesn't support standard RFC 7591 Dynamic Client Registration, so generic DCR clients won't work. Use /api/v1/apps.

## Scopes
Mastodon has no scope review. Every scope is self-serve, but admin scopes only work for accounts with moderator or admin roles on that server.

| Scope | Grants | Level | Consequence |
|---|---|---|---|
| `profile / read:* / write:* / push` | The user's identity, plus reading and writing their data | basic | Nothing. Available immediately. |
| `admin:read / admin:write (and granular admin:*)` | Moderation and admin APIs | sensitive | No review, but only usable by staff accounts on that server |

## When you get stuck
- **422 Redirect URI must be an absolute URI.** The redirect URI passed to /api/v1/apps is relative or malformed. Fix: Register a full absolute URL, or urn:ietf:wg:oauth:2.0:oob for testing. _(Docs [3, 7])_
- **invalid_grant at token exchange.** The redirect_uri doesn't match the registered one, or the client_id belongs to a different server. Fix: Use the exact registered redirect URI and the credentials stored for that server's domain. _(Community [7], medium confidence)_
- **Discovery endpoint returns 404.** The server runs a Mastodon version before 4.3.0, which has no discovery endpoint and no PKCE. Fix: Fall back to the plain authorization code flow without PKCE and register only scopes that server supports. _(Docs [4, 2])_
- **429 Too Many Requests.** The default limit is 300 calls per 5 minutes per account and per IP. Media uploads are limited to 30 per 30 minutes. Fix: Respect the X-RateLimit headers and back off. _(Docs [6])_

## Not confirmed yet
- **Can individual server admins block or remove third-party apps, or restrict registration through /api/v1/apps?** The official docs don't cover admin controls over third-party apps. To resolve: Check the server's rules or ask its admins. Test registration on the major servers your users are on.
- **Is POST /api/v1/apps rate-limited by IP?** The rate limits page doesn't list a separate limit for app registration. To resolve: Watch the X-RateLimit headers when registering, and cache credentials so you register once per server.
- **Do Mastodon-compatible servers (forks or other ActivityPub software) behave the same way?** This research covered upstream Mastodon only. To resolve: Test against each server type your users need.

## Sources
1. [Obtaining client app access](https://docs.joinmastodon.org/client/token/) (Mastodon docs). Checked 27 Oct 2026
2. [OAuth Scopes](https://docs.joinmastodon.org/api/oauth-scopes/) (Mastodon docs). Checked 27 Oct 2026
3. [apps API methods](https://docs.joinmastodon.org/methods/apps/) (Mastodon docs). Checked 27 Oct 2026
4. [oauth API methods](https://docs.joinmastodon.org/methods/oauth/) (Mastodon docs). Checked 27 Oct 2026
5. [Logging in with an account](https://docs.joinmastodon.org/client/authorized/) (Mastodon docs). Checked 27 Oct 2026
6. [Rate limits](https://docs.joinmastodon.org/api/rate-limits/) (Mastodon docs). Checked 27 Oct 2026
7. [oauth_dropins.mastodon source](https://oauth-dropins.readthedocs.io/en/latest/_modules/oauth_dropins/mastodon.html) (oauth-dropins docs). Not yet checked
8. [Managed auth toolkits](https://docs.composio.dev/toolkits/managed-auth.md) (Composio docs). Checked 27 Oct 2026

Wrong or out of date? POST https://oauth-guide.akshatsethi.com/api/reports with {"app": "mastodon", "step": 2, "message": "what you saw"} (step is optional), or call the report_problem MCP tool. The next research run checks it.
Followed it? Say how it went: POST https://oauth-guide.akshatsethi.com/api/reports with {"app": "mastodon", "outcome": "worked" | "waiting" | "stuck", "step": 3, "message": "what happened"}, or call the report_setup MCP tool.
