Skip to main content

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.

Alpha Release: The Headless API and its documentation are currently in alpha and subject to change. Schemas, fields, and behavior may be modified or updated without notice.

About the Headless API

The Mighty Networks Headless API is a GraphQL API built on the same surface area that powers the official Mighty Networks clients. It does not yet expose the entire surface, but it covers a broad cross-section today and is actively expanding as we move through alpha toward a GA release. It is the foundation for member-facing experiences (custom apps, embeds, integrations) as well as host-facing and back-office tooling that goes beyond what the Admin REST API covers. Where the Admin API is a curated REST surface intended for server-to-server administrative automation, the Headless API operates in the context of an authenticated user (member, moderator, or host) and grants the same access that user has in the product. With a host or admin token, that includes administrative reads and writes; with a member token, it’s limited to what that member can see and do. Use the Headless API when you want to:
  • Build a custom client (web, mobile, embed) that surfaces a network’s content to its members
  • Build host-facing tools, dashboards, or admin consoles that need data the Admin REST API doesn’t expose
  • Power a third-party integration that acts on behalf of a specific user (member, moderator, or host)
  • Query exactly the fields you need in a single round trip, including nested associations

What’s in the schema today

The alpha covers a broad cross-section of the product. At a glance, the public schema currently exposes:
  • Network — settings, branding, billing plan, enabled features, available space features and templates, payment currencies, Stripe connection state
  • Spaces — spaces, spaces collections, and space templates; create, update, and list
  • Posts — posts and post content (including embedded links, assets, and post tags); create, update, delete, fetch by id or slug, list per network or per space
  • Comments — threaded comments on posts; create, update, delete, list
  • Reactions — reactions and reaction groups on supported targets; create and delete
  • Events — events, event instances, and RSVPs; create, update, delete, and list across the network or a space
  • Polls — poll and poll choice types surfaced through post content
  • Notifications — list and mark-as-read for the viewer’s notifications
  • Search — cross-entity search with typed result filtering
  • Assets — images attached to posts
Everything in the schema is introspectable — see Schema and Introspection for SDL and introspection endpoints. The set above will grow as we move through alpha toward GA.

Endpoint

All GraphQL requests are issued as POST to a single per-network endpoint:
https://api.mn.co/networks/:network_id_or_subdomain/graphql
The path segment :network_id_or_subdomain accepts either:
  • The network’s numeric ID (e.g. 12345)
  • The network’s subdomain (e.g. my-community for my-community.mn.co)
Both forms resolve to the same network and execute against the same schema.
curl https://api.mn.co/networks/my-community/graphql \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "query { me { id name } }"
  }'

Authentication

The Headless API authenticates requests with OAuth 2.0. Unlike the Admin API, which uses a long-lived Bearer token tied to a network admin, the Headless API issues short-lived access tokens that act on behalf of a specific user in a specific network — member, moderator, or host. Once you have an access token, you pass it as a Bearer token on every GraphQL request.
The Headless API is in alpha and is being rolled out incrementally. OAuth application management is available on the Scale plan or above. If you don’t see Integrations > OAuth Applications in Network Admin, your network isn’t in the rollout yet — reach out to Mighty support to request access.

Create an OAuth application

OAuth applications are created and managed by network hosts under Network Admin > Integrations > OAuth Applications. For the full walkthrough — client types, redirect URI rules, scope catalog, secret rotation, and revocation — see OAuth Applications. At a glance:
  1. Sign in as a host or admin and open Network Admin.
  2. Go to Integrations > OAuth Applications and click New OAuth Application.
  3. Provide a name, choose a client type (public or confidential), register redirect URIs, and select the scopes your app needs.
  4. Mighty issues a Client ID and (for confidential clients) a Client Secret, shown once.
See OAuth Applications for the detailed setup, configuration, and management guide.

Authorization Code flow

The standard flow for user-facing apps:
  1. Redirect the user to the authorization endpoint. OAuth endpoints live on the network’s community host, not on api.mn.co:
    https://:network_subdomain.mn.co/oauth/authorize
      ?response_type=code
      &client_id=YOUR_CLIENT_ID
      &redirect_uri=YOUR_REDIRECT_URI
      &scope=SPACE_SEPARATED_SCOPES
      &state=RANDOM_OPAQUE_STRING
      &code_challenge=PKCE_CHALLENGE
      &code_challenge_method=S256
    
    The canonical endpoint URLs are also advertised at https://:network_subdomain.mn.co/.well-known/oauth-authorization-server (RFC 8414).
  2. The user signs in (if needed) and approves the requested scopes. Mighty redirects back to your redirect_uri with a code and the state you sent.
  3. Exchange the code for an access token:
    curl https://:network_subdomain.mn.co/oauth/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=authorization_code" \
      -d "code=AUTH_CODE_FROM_REDIRECT" \
      -d "redirect_uri=YOUR_REDIRECT_URI" \
      -d "client_id=YOUR_CLIENT_ID" \
      -d "client_secret=YOUR_CLIENT_SECRET" \
      -d "code_verifier=PKCE_VERIFIER"
    
    The response contains an access_token, refresh_token, expires_in, and the granted scope:
    {
      "access_token": "eyJhbGciOi...",
      "token_type": "Bearer",
      "expires_in": 3600,
      "refresh_token": "def50200...",
      "scope": "read:posts write:posts"
    }
    
  4. Pass the access token on every GraphQL request:
    Authorization: Bearer eyJhbGciOi...
    
  5. When the access token expires, exchange the refresh token for a new one using grant_type=refresh_token against the same /oauth/token endpoint.

Token scope 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.
The access token grants exactly the access the underlying user has in the product, intersected with the scopes the user approved. A member token sees what that member sees; a host or admin token additionally exposes host- and admin-level fields and mutations. Asking for more scopes than your app needs is a smell — request the narrowest set that lets the feature work. For full details on the OAuth flows, scope catalog, and token rotation, see the Authentication Guide.

Why GraphQL

GraphQL allows us to expose the full functionality of Mighty’s platform, without making assumptions about what kinds of experience you’ll build on top of it. A REST surface forces the API designer to enumerate every endpoint, response shape, and association ahead of time — which means the only apps that fit comfortably are the ones we anticipated. That’s the wrong shape for a community platform: members, hosts, and integrators put Mighty Networks to uses we couldn’t have predicted. A consumer-mobile reader, an internal back-office dashboard, an AI agent that summarizes a space’s activity, a custom embed that pulls a single post into a marketing page — these all want different fields, different depths, and different shapes from the same underlying data. GraphQL lets a client request exactly the fields it needs, traverse associations in one request, and avoid the over-fetching that comes with rigid REST endpoints. The API surface is the schema; what you do with it is up to you. Concretely, this means:
  • One endpoint, many shapes. A mobile feed view and a desktop sidebar can hit the same query and select different fields. Same for a CRM sync job and a Discord bot — they ask for what they need and ignore the rest.
  • Typed schema. Every field, argument, and return type is described in the schema and discoverable via introspection — no out-of-band docs required to know what’s possible.
  • Composable queries. Fetch a post, its author, the author’s spaces, and the viewer’s permissions on each — in a single round trip. Build the view the app needs, not the view the API designer guessed at.
  • Forward-compatible by default. New fields and types can be added without breaking existing clients, because clients only see the fields they explicitly ask for. The schema can grow alongside the use cases we haven’t thought of yet.
If you’re new to GraphQL, the official documentation is the best starting point:

Relay conventions

The schema is designed to be consumed by Relay-compatible clients. Concretely: You don’t need to use the Relay client — any GraphQL client will work — but if you do, the schema is designed to drop straight in. Useful reading:

Making a Request

A GraphQL request is a POST with a JSON body containing query and (optionally) variables and operationName.
Requests to api.mn.co must include a non-empty User-Agent header. Requests without one are blocked by bot protection and receive an HTML challenge page with HTTP 403 — a JSON-parse error on the client. We recommend your-app-name/version (+url).
POST /networks/my-community/graphql HTTP/1.1
Host: api.mn.co
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
User-Agent: my-app/1.0 (+https://example.com)

{
  "query": "query Post($id: ID!) { network { post(idOrSlug: $id) { id title author { id name } } } }",
  "variables": { "id": "12345" }
}
Successful responses return an HTTP 200 with a data object:
{
  "data": {
    "network": {
      "post": {
        "id": "12345",
        "title": "Welcome to the network",
        "author": { "id": "678", "name": "Jane" }
      }
    }
  }
}
Errors are returned as an errors array alongside (or instead of) data. Each error carries a human-readable message, an extensions.code for programmatic handling, and (where applicable) a path indicating which field produced the error.
{
  "data": null,
  "errors": [
    {
      "message": "Post not found",
      "path": ["post"],
      "extensions": { "code": "NOT_FOUND" }
    }
  ]
}
GraphQL returns HTTP 200 for most application-level errors. Inspect the errors array on every response, not just the HTTP status.

Schema and Introspection

The schema is fully introspectable. You can explore it with any standard GraphQL tool (GraphiQL, Apollo Sandbox, Insomnia, Postman) by pointing the tool at your network’s endpoint and supplying a valid Bearer token.

GraphiQL Explorer

Each network ships with a hosted GraphiQL explorer for ad-hoc queries and schema browsing. It lives on the network’s community host (not on api.mn.co) and uses the signed-in session — there’s no Bearer token to paste in:
https://:network_subdomain.mn.co/public/graphiql
Sign in to the network in the same browser, then open the URL above to issue queries as your current user.

Fetching the schema

The fastest way to get a code-generation-ready schema is the dedicated SDL endpoint, which returns the network’s GraphQL schema as Schema Definition Language. No authentication required:
GET https://api.mn.co/networks/:network_id_or_subdomain/graphql/schema
curl https://api.mn.co/networks/my-community/graphql/schema > schema.graphql
The response is the public surface filtered to the types, fields, and arguments actually exposed by the GraphQL endpoint — the same surface your queries execute against. Pipe it straight into graphql-code-generator, the Relay compiler, or any other tool that consumes SDL.
Start here for codegen. The SDL endpoint is unauthenticated, cacheable, and avoids the round-trip overhead of running a full introspection query.

Introspection (alternative)

The GraphQL endpoint also responds to the standard introspection query, which returns the type system as JSON. Use this if your tooling expects an introspection result instead of SDL, or if you want to query schema metadata at runtime. A minimal introspection query:
query {
  __schema {
    types {
      name
      kind
    }
  }
}
For a complete dump, use the canonical introspection query published in graphql-js — every popular tool ships a copy of it. Common ways to fetch and persist it:
# Install: npm i -g get-graphql-schema
get-graphql-schema \
  --header "Authorization=Bearer YOUR_ACCESS_TOKEN" \
  https://api.mn.co/networks/my-community/graphql \
  > schema.graphql

Rate Limits

The Headless API follows the same rate-limit and quota model described in the Admin API, but its quota is tracked separately — Headless API usage does not count against the Admin API quota and vice versa. The unit of accounting is the GraphQL operation rather than the REST request, and highly nested queries may additionally be subject to query-complexity limits.

Errors

Errors follow the GraphQL error spec. Each error includes a message, an extensions.code for programmatic handling, and (where applicable) a path indicating which field produced the error. The code vocabulary mirrors Apollo Server’s defaults, so any GraphQL client library that already understands those codes will work without configuration:
CodeMeaning
UNAUTHENTICATEDMissing, expired, or invalid Bearer token. Also returned with HTTP 401 from the bearer-auth layer.
FORBIDDENAuthenticated, but the viewer lacks permission for the action.
NOT_FOUNDThe referenced resource does not exist, or the viewer cannot see it. Visibility checks collapse to NOT_FOUND rather than FORBIDDEN to avoid leaking existence.
BAD_USER_INPUTAn argument failed semantic validation (e.g. malformed cursor, unknown enum value).
INTERNAL_SERVER_ERRORAn unexpected error escaped the resolver. The message is generic — details are recorded server-side.
Most application-level errors are returned with HTTP 200 and an errors array; only UNAUTHENTICATED from the bearer-auth layer (missing or invalid Bearer token) and 404 (network does not exist or Headless API is not enabled) surface as non-200 HTTP statuses.

Headless API vs. Admin API

Headless APIAdmin API
StyleGraphQLREST
Endpointapi.mn.co/networks/:id_or_subdomain/graphqlapi.mn.co/admin/v1/...
Acts asThe authenticated user (member, moderator, or host)Network administrator
Surface areaBroad — the full product surface, including host and admin capabilitiesCurated — a stable subset for administrative automation
Best forCustom clients, member- and host-facing apps, embeds, and integrations that act on behalf of a userServer-to-server automation and bulk admin tasks where REST and a stable contract are preferable

Support

Authentication

Generate and manage tokens for the Headless API.

Admin API

Compare with the REST-based admin surface.