Skip to main content

Quickstart

Go from nothing to a first successful call to the MCDI API with a project key, and learn what a 401 or a 403 means.

This page takes you from nothing to a first successful call to the MCDI API with a project key. It takes about five minutes once an admin has set your project up.

What you need first

A system admin creates your project in the admin panel and gives you three things:

WhatLooks likeNotes
Project IDa UUIDPublic. It is the client_id of the login flow.
API keypk_ followed by 8 hex characters, a dot, and 64 hex charactersA secret. It is shown once, when the key is created or regenerated.
Server ID17 to 20 digitsThe Discord server the project may use. The admin grants your project access to it.

Keep the key in an environment variable or a secret manager, never in a repository or in browser code. The key is for your backend only.

bash
export MCDI_URL=http://localhost:3000/api
export MCDI_API_KEY=pk_xxxxxxxx.your-secret-here
export MCDI_SERVER_ID=900000000000000001

Make your first call

List two members of your server. The call needs the read_members scope and the READ operation on that server, which an admin grants.

bash
curl -s "$MCDI_URL/servers/$MCDI_SERVER_ID/members?limit=2" \
  -H "X-API-Key: $MCDI_API_KEY"

The response is a page of members and the paging details:

json
{
  "data": [
    {
      "discordId": "800000000000000010",
      "username": "alice",
      "globalName": null,
      "displayName": null,
      "avatar": null,
      "isClubMember": true,
      "joinedAt": "2026-10-05T18:15:38.271Z"
    },
    {
      "discordId": "800000000000000011",
      "username": "reader",
      "globalName": null,
      "displayName": null,
      "avatar": null,
      "isClubMember": true,
      "joinedAt": "2026-10-05T18:15:38.281Z"
    }
  ],
  "pagination": { "page": 1, "limit": 2, "total": 3, "pages": 2, "hasNext": true, "hasPrev": false }
}

The exact fields and every filter are in the Members reference.

When it fails

Every error is JSON with a statusCode, an error and a message. The two you meet first are a missing or wrong key, which is a 401, and a project that is not allowed to do this, which is a 403.

bash
curl -s -i "$MCDI_URL/servers/$MCDI_SERVER_ID/members"
json
{ "message": "API key is required", "error": "Unauthorized", "statusCode": 401 }

A key that does not match any active project gives Invalid API key, also a 401. A valid key that has no access to the server gives a 403:

json
{
  "message": "Project is not allowed to perform READ on server 900000000000000002",
  "error": "Forbidden",
  "statusCode": 403
}

A 403 that says Insufficient scope: 'read_members' is required means the project has access to the server but not to this kind of data. In both cases the fix is on the admin side: ask for the access or scope you need. API keys and server access explains all of them.

Where to go next

Source: apps/api/src/common/guards/api-key.guard.ts, apps/api/src/common/utils/auth.util.ts, apps/api/src/modules/members/member.controller.ts.