Documentation Index
Fetch the complete documentation index at: https://docs.mightynetworks.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Headless API authenticates requests with OAuth 2.0. A third-party application redirects a user to Mighty, the user signs in and approves a set of scopes, and your application receives a short-lived access token that acts on behalf of that user against the GraphQL API. This is fundamentally different from the Admin API, which uses a long-lived Bearer token tied to a network admin. Pick the one that matches your integration:| Admin API | Headless API | |
|---|---|---|
| Acts as | A specific network admin | Any authorized member, moderator, or host |
| Credential | Long-lived API token | Short-lived OAuth 2.0 access token |
| Issued to | A single admin user | An OAuth application + an end user |
| Use it for | Back-office automation, integrations, analytics | User-facing apps, mobile clients, agents, embeds |
Why OAuth 2.0
The Headless API is designed for third-party applications that act on behalf of an end user — a member reading their feed in a custom mobile app, a host pulling their network into a back-office dashboard, an AI agent summarizing a space the user belongs to. The auth model has to answer two questions a static API key can’t:- Whose data is this? Every Headless API call resolves against a specific user’s permissions in a specific network. A member token can only see what that member can already see in the product; a host token additionally exposes host-level fields. There is no “superuser” mode and no way for a third-party app to read data the authorized user can’t.
- Did the user actually consent? Before an application receives a token, the user is shown a consent screen listing the application name and the scopes it’s requesting, and explicitly approves. Mighty — not the application — collects the password. The application never sees the user’s credentials and can never act beyond the scopes the user approved.
- Delegated access without credential sharing. Users authorize applications through Mighty’s login flow. Applications never handle passwords, MFA codes, or session cookies.
- Scoped, revocable tokens. Tokens are bound to a specific user, application, and scope set, with a short expiry. A leaked token has a small blast radius; users (and hosts) can revoke an application’s access without rotating their password.
- A model that fits every client type. Server-side web apps use the Authorization Code flow with a client secret. Mobile, desktop, and single-page apps use Authorization Code + PKCE and ship no secret at all. Both target the same authorization server and the same token endpoint.
- An ecosystem of tooling. OAuth 2.0 client libraries exist for every language and framework — there’s no Mighty-specific SDK to learn, and standard tools (Postman,
curl, framework auth middleware) work out of the box. Mighty publishes the canonical endpoints at/.well-known/oauth-authorization-serverper RFC 8414.
Create an OAuth application
Before your app can request tokens, a host or admin must register an OAuth application in the network. The application provides the Client ID (and, for confidential clients, Client Secret) you’ll use in the flows below, along with the redirect URIs and allowed scopes. For the full walkthrough — client types, redirect URI rules, scope catalog, secret rotation, and revocation — see OAuth Applications.Endpoints
OAuth endpoints are served from the network’s community host, not fromapi.mn.co:
Authorization Code flow
The standard flow for user-facing apps. Public clients (mobile, desktop, single-page) must add PKCE; confidential clients (server-side web apps) should use PKCE in addition to their client secret.Step 1 — Redirect to the authorization endpoint
| Parameter | Required | Description |
|---|---|---|
response_type | Yes | Must be code. |
client_id | Yes | The Client ID from your OAuth application. |
redirect_uri | Yes | Must exactly match a URI registered on the application (scheme, host, port, path). |
scope | Yes | Space-separated list of scopes — see scopes. |
state | Yes | Cryptographically random per-request value. You must validate it on the redirect to prevent CSRF. |
code_challenge | Public clients (recommended for confidential) | PKCE challenge derived from a code_verifier your app holds. |
code_challenge_method | If code_challenge is sent | Use S256. |
Step 2 — User approves
The user signs in (if they aren’t already) and approves the requested scopes on the consent screen. Mighty redirects back to yourredirect_uri with:
state matches the value you generated. If it doesn’t, reject the callback — do not exchange the code.
Step 3 — Exchange the code for an access token
scope field reflects what was actually granted — the intersection of what the application is allowed to request, what the user approved, and what the user is permitted to do in the product. Always check it; don’t assume you got everything you asked for.
Step 4 — Call the Headless API
Pass the access token as a Bearer token on every GraphQL request:Refreshing tokens
Access tokens are short-lived (expires_in is returned with each token, typically one hour). When a token expires, exchange the refresh token for a new pair:
client_secret. The response shape matches the original token response; the refresh token may rotate, so always persist the new value if one is returned.
Refresh tokens are themselves long-lived but not permanent. They are invalidated when:
- The user revokes the application’s access.
- A host deletes the OAuth application.
- The user changes their password or is signed out network-wide.
- The refresh token reaches its absolute lifetime.
invalid_grant, the user must re-authorize — kick them back through Step 1.
Scopes and permissions
During the alpha, OAuth scopes are not enforced on the Headless API — tokens act with the underlying user’s full product permissions regardless of the scopes requested or granted. We’re still finalizing the exact scope catalog that will ship; build against the scopes documented here so your app is ready when enforcement turns on.
- A
read:postsscope granted to a member only exposes what the member could already see in the product. - A
host:read:network_postsscope is only effective when the authorized user is a host of the network — a member who approves it still won’t get host-level reads.
Errors
OAuth errors follow RFC 6749. The authorization endpoint returns errors via redirect query string; the token endpoint returns them as JSON with a400 (or 401 for client auth failures).
| Error | Where | Common cause |
|---|---|---|
invalid_request | Both | Missing or malformed parameter. |
invalid_client | /oauth/token | Wrong Client ID, wrong Client Secret, or sending a secret on a public client. |
invalid_grant | /oauth/token | Authorization code already used, expired, or redeemed against a different redirect_uri; PKCE verifier doesn’t match the challenge; refresh token revoked or expired. |
unauthorized_client | Both | The application isn’t allowed to use this grant type. |
unsupported_grant_type | /oauth/token | grant_type is not authorization_code or refresh_token. |
invalid_scope | /oauth/authorize | Requested a scope the application isn’t configured for. |
access_denied | /oauth/authorize | The user declined the consent screen. |
redirect_uri_mismatch | /oauth/authorize | redirect_uri does not exactly match a registered URI. |
Security best practices
- Use PKCE everywhere. Required for public clients; recommended for confidential clients as defense in depth.
- Validate
state. Generate a cryptographically randomstateper authorization request and reject any callback whosestatedoesn’t match. This is your CSRF defense. - Pin redirect URIs. Register the exact URIs your app uses. Never register a wildcard, a path you don’t control, or an open redirector.
- Treat the Client Secret like a password. Store it in a secret manager, never in source control, never in a client bundle. Never ship a secret in a mobile, desktop, or single-page app — use the public client type with PKCE instead.
- Request least privilege. Ask for the narrowest scopes that let the feature work. Broader scopes drive higher consent abandonment and expand the blast radius if a token leaks.
- Persist refresh tokens server-side. Refresh tokens are long-lived credentials. Store them encrypted at rest and never expose them to the browser or to logs.
- Replace applications on suspicion of secret leak. During alpha, programmatic secret rotation is not yet available. If a secret may have leaked, delete the application (which revokes every token under it) and create a replacement.
Next steps
OAuth Applications
Register, configure, and manage the OAuth applications that issue tokens.
Headless API
Use your access token against the GraphQL API.