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:
| What | Looks like | Notes |
|---|---|---|
| Project ID | a UUID | Public. It is the client_id of the login flow. |
| API key | pk_ followed by 8 hex characters, a dot, and 64 hex characters | A secret. It is shown once, when the key is created or regenerated. |
| Server ID | 17 to 20 digits | The 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.
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.
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:
{
"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.
curl -s -i "$MCDI_URL/servers/$MCDI_SERVER_ID/members"
{ "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:
{
"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
- To let members sign in to your project, read Login with MicroClub.
- To ask what a member is allowed to do, read Roles, permissions and inheritance.
- To receive forms or events from your project, read Inbound webhooks: overview.
- For every endpoint, see the Project API reference.
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.