Enable Services and Get Credentials
Create a project, obtain the App ID / Customer Secret / App Certificate, rotate keys and enable services.
This page explains the four things a project needs to go from activation to joining a call: create a project → get credentials → enable services → configure callbacks. For the page-by-page console UI walkthrough see the console guide; here we give the equivalent REST steps, because they can be scripted and re-run.
Prerequisites
- The control plane is running:
pnpm dev:apifrom the project root (default local port), or the combined local dev stack that starts the API and console together. - A console account. Local demo account:
owner@example.com/change-me-now(override withCONSOLE_SEED_EMAIL/CONSOLE_SEED_PASSWORD).
Step 1: Sign in to the console and get a session
curl -s -X POST "$NIMEET_API_BASE/console/auth/login" \
-H 'Content-Type: application/json' \
-d '{"email":"owner@example.com","password":"change-me-now"}'The token in the response is the Authorization: Bearer <token> value for all later /console/* calls. The session has its own expiry and is unrelated to project credentials.
Step 2: Create a project and store the one-time credentials
curl -s -X POST "$NIMEET_API_BASE/console/projects" \
-H "Authorization: Bearer $NIMEET_CONSOLE_SESSION" \
-H 'Content-Type: application/json' \
-d '{"name":"my-first-project","services":{"recording":true,"streaming":true}}'The four values in the response are the credentials for every later call:
| Field | Purpose | Returned again? |
|---|---|---|
project.appId | Client SDK initialization / REST path parameter | Yes |
project.customerId | Basic credential user name | Yes |
customerSecret | Basic credential password | No, returned only once |
appCertificate | Key for signing tokens | No, returned only once |
Step 3: Enable or disable services
Services can be enabled at project creation through services, or adjusted later on their own:
curl -s -X POST "$NIMEET_API_BASE/console/projects/$PROJECT_ID/services" \
-H "Authorization: Bearer $NIMEET_CONSOLE_SESSION" \
-H 'Content-Type: application/json' \
-d '{"recording":true,"streaming":true}'Calling a product endpoint whose service is not enabled returns 403 service_not_enabled (see the full error-code table). This rule is deliberate: it prevents "silent billing for something that was never enabled".
Step 4: Configure the callback URL (optional)
curl -s -X PUT "$NIMEET_API_BASE/console/projects/$PROJECT_ID/webhook" \
-H "Authorization: Bearer $NIMEET_CONSOLE_SESSION" \
-H 'Content-Type: application/json' \
-d '{"url":"https://example.com/hooks/nimeet","secret":"$WEBHOOK_SECRET","events":["channel_create","user_join","recording_state_changed"],"enabled":true}'secret is used to compute Agora-Signature (SHA1) and Agora-Signature-V2 (SHA256); verification and the retry schedule are covered in Callback integration. Once configured, GET .../webhook/deliveries shows the delivery log and lets you replay failed deliveries.
Step 5: Self-check
# Token generator (the same logic the console uses; signs a test token server-side)
curl -s -X POST "$NIMEET_API_BASE/console/projects/$PROJECT_ID/token" \
-H "Authorization: Bearer $NIMEET_CONSOLE_SESSION" \
-H 'Content-Type: application/json' \
-d '{"channelName":"weekly-sync","uid":10001,"role":"host","ttlSeconds":600}'Once you have the rtcToken, hand it to the example code for any platform and you can join a call (see Quickstart and that platform's "quickstart and feature guide").
Local equivalent: the demo credentials file
On first start pnpm dev:api creates a demo project and writes the one-time credentials to demo-credentials.json in the server data directory. The docs example runner reads that file by default, so you can run the examples without performing the five steps above:
node examples/run-all.mjs --only=0The demo project is regenerated after every API restart, and old tokens and old credentials stop working with it — which is exactly why it is only suitable for local verification and never as a production credential.
Common failures
| Symptom | code | Cause and handling |
|---|---|---|
| 401 | missing_authorization | No session or credential was sent |
| 401 | unauthorized | Session expired or revoked (authentication failed, not a permission problem): send the user back to sign-in instead of showing a "permission denied" message |
| 401 | invalid_credentials | Wrong account or password, or the Basic secret is the value from before a rotation |
| 403 | banned (details.permissionDenied: true) | Signed in, but this account may not access that project (projects are isolated per account) |
| 409 | project_exists | The project name is already taken; choose another name and create again |
| 403 | service_not_enabled | A service that is not enabled was called; go back to step 3 and enable it |