Developer Docs
BackLet people sign in with MewGem and access their data with consent. This is the standard OAuth 2.0 Authorization Code flow — any OAuth2 client library works.
API base: https://api.mewgem.me ·
Consent screen: https://mewgem.me/authorize
Join the developer program
Creating apps needs a verified developer account. Tell us what you are building and staff will review it — you will get an email either way. Owners of apps approved before the program started were verified automatically.
Apply to the developer program1. Register an app
Once you are a verified developer, on the Developer page, create an app with a
name, one or more redirect URIs (https, exact-matched), and the scopes you need.
You receive a client ID (app_…) and a client secret
(mgk_…).
⚠️ The client secret is shown once. Keep it server-side — never in browser or mobile code. New apps are staff-reviewed before the flow works.
2. Scopes
| Scope | Grants | Tier |
|---|---|---|
identity | Username and avatar | |
profile:read | Public profile (bio, banner) | |
email | Email address | |
spaces:read | Spaces the user belongs to | |
events:read | Events and RSVPs | |
act | Act on the user's behalf | Tier 2 |
content:write | Post/modify content as the user | Tier 2 |
billing:read | View billing & membership | Tier 2 |
Privileged scopes are only available to
Tier 2 (partner) apps, promoted by MewGem staff. Request the least you need —
userinfo returns only fields your granted scopes cover.
3. Send the user to consent
https://mewgem.me/authorize ?client_id=app_xxx &redirect_uri=https://yourapp.com/oauth/callback &scope=identity%20email &state=<random-anti-csrf>
On approve, the user is redirected back to your
redirect_uri with ?code=code_xxx&state=…. Verify state
matches what you sent. On cancel you get ?error=access_denied.
4. Exchange the code (server-side)
POST https://api.mewgem.me/oauth/token
Content-Type: application/json
{
"grant_type": "authorization_code",
"code": "code_xxx",
"client_id": "app_xxx",
"client_secret": "mgk_xxx",
"redirect_uri": "https://yourapp.com/oauth/callback"
}
Returns access_token (Bearer, valid
30 days, revocable). The code is single-use and expires in 5 minutes; the
redirect_uri must match step 3.
5. Call the API as the user
GET https://api.mewgem.me/oauth/userinfo
Authorization: Bearer at_xxx
→ { "sub": "alice", "username": "alice", "picture": "…", "email": "…" }
sub is always present; other fields
appear only for granted scopes. Revoke a token with POST /oauth/revoke
{ token }. Users can disconnect your app from Settings → Connected Apps.
6. Post into spaces
A space's admins can add your app to one of their channels. Declare an icon and your message types on the app (each a short list of fields); they are reviewed with it. Your app then posts as itself, not as a user:
POST https://api.mewgem.me/oauth/token
{ "grant_type": "client_credentials", "client_id": "app_xxx", "client_secret": "…" }
→ { "access_token": "app_xxx", "token_type": "Bearer", "expires_in": 3600 }
GET https://api.mewgem.me/apps/installs
Authorization: Bearer app_xxx
→ { "installs": [ { "installId": "int_…", "space": { "name": "…" }, "channel": "…",
"enabled": true, "messageTypes": ["stream_live"] } ] }
POST https://api.mewgem.me/apps/installs/int_…/messages
Authorization: Bearer app_xxx
{ "type": "stream_live", "values": { "title": "Finals tonight", "watch": "https://…" } }
→ { "message": "Posted", "msgid": "…" }
- You send values for your type's fields. MewGem draws the card, with the labels, layout and colour that space chose. No HTML, no pictures.
messageTypeson an install lists the types that space has left switched on. A type it turned off answersTYPE_DISABLED.- Your app cannot read a space, and its posts never ping anyone.
- At most 30 posts a minute into one space. A
429means slow down and retry. - Changing the icon or the message types sends the app back to review; it cannot post until it is approved again, and the spaces that added it keep it.
Endpoint reference
| Method & path | Purpose |
|---|---|
GET /oauth/authorize | Consent-screen data |
POST /oauth/consent | User approves → one-time code |
POST /oauth/token | Exchange code → access token, or client_credentials → app token |
GET /apps/installs | Where your app is added · app token |
POST /apps/installs/:installId/messages | Post one of your message types · app token |
GET /oauth/userinfo | The user's data (scope-filtered) |
POST /oauth/revoke | Revoke a token |
POST /dev/apps | Create an app (secret shown once) · verified developers |
GET /dev/apps | List your apps |
POST /dev/apps/update | Edit (a scope, icon or message type change → re-review) · verified developers |
POST /dev/apps/secret | Regenerate the secret · verified developers |
POST /dev/apps/delete | Delete + revoke tokens |
POST /developers/apply | Apply to the developer program |
GET /developers/mine | Your developer status and applications |
POST /developers/withdraw | Withdraw a waiting application |
Without verification, the three marked calls answer
DEVELOPER_REQUIRED. Listing and deleting your own apps always work, and nothing
your app's users do is ever gated. If staff revoke your developer access, your apps are
suspended (not deleted) and you are told why.
Security
- Keep the client secret server-side.
- Always send and verify
state(CSRF protection). - Register exact redirect URIs — MewGem matches origin + path exactly.
- Access tokens are bearer credentials: hashed at rest, revocable, 30-day expiry.
Building a MewGem-operated service (not a third-party app)? First-party services use the
cross-service auth broker for single sign-on from mewgem.me instead of OAuth.
See docs/SERVICE-AUTH-BROKER.md in the repository.