Migrate from Agora
Layer-by-layer differences: credentials, token service, client SDKs, REST paths, callbacks and unsupported features.
Already integrated with Agora and thinking about switching to ni-meet? This page gives a layer-by-layer difference list: what needs no code change, what must change, and how to verify the result afterwards.
Step 0: Decide which layer you are migrating
| Agora capability you use | Migration effort | Notes |
|---|---|---|
| Client SDK join/publish/subscribe | Small (almost zero on Web) | Swap the App ID and the token source; the API shape is unchanged |
| Server-side token signing | Medium | Move token issuance from Agora to POST /v1/tokens; SDKs notice nothing |
| Server-side REST (channel query/kick) | Small | The Agora-compatible /dev/v1/* paths are implemented, see below |
| Cloud Recording | Medium | Paths and envelope match, but the resourceId lease semantics must follow ni-meet's call order |
| Media Push | Medium | The entry_points that Agora has sunset are still compatible, but the current interface is rtmp-converters |
| Analytics | Medium | Metric definitions match, but the endpoints are our /v1/analytics/* |
| Callback receiving | Small | Event codes and signature headers match; the retry rhythm and delivery log are ours |
Step 1: Credentials and domains
| Item | Agora | ni-meet |
|---|---|---|
| Project identifier | App ID | appId (same concept, 32 hexadecimal characters) |
| Server credential | Customer ID / Customer Secret | customerId / customerSecret, also sent as Authorization: Basic base64(id:secret) |
| Token key | App Certificate | appCertificate (same concept, never leaves the server) |
| API base URL | https://api.agora.io | Your own control-plane address, for example https://api.your-domain.com |
The only things you must change in code are the base URL constant and the source of credentials (copied from the Agora console → obtained from our console or POST /console/projects).
Step 2: Token service (backend must change)
On Agora you are probably generating tokens locally with a library such as agora-token / agora-access-token. After switching to ni-meet:
Old: generateToken(appId, appCertificate, channel, uid, role, ttl) // computed locally
New: POST /v1/tokens { channelName, uid, role, ttlSeconds } // call the control plane- Do not implement our token format yourself: the signing key is
appCertificate, and the algorithm and payload are documented in AccessToken2 semantics,
but a second implementation means maintaining one behaviour in two places; the control plane already provides issue, renew and verify endpoints.
- Renewal semantics are the same:
token-privilege-will-expire→ callPOST /v1/tokens/renew→client.renewToken(newToken). - If tokens in your architecture are provided by the IM side (RTC Provider mode), the two RTC Provider method names match Agora's, so you only swap the implementation;
see the RTC Provider section in Token authentication.
Step 3: Client SDK (no change on Web)
Before migrating:
import AgoraRTC from 'agora-rtc-sdk-ng';After migrating (replace only this line; variable names stay the same):
import AgoraRTC from '@nimeet/rtc-web';Method chains, event names and error identifiers are all identical, so client.join(appId, channel, token, uid), client.publish([mic, cam]), client.subscribe(user, mediaType) and user.videoTrack.play('id') need no change. The only differences are:
- The media edge address is decided by the deployment, and the SDK resolves it in the order
surlfrom the token payload →window.__NIMEET_SFU_URL__→ same-origin/rtc
(the control plane does not write surl, so same-origin /rtc or an explicitly set bootstrap variable is recommended);
- Unsupported capabilities fail explicitly with
AgoraRTCError.code === 'NOT_SUPPORTED'(for example channel media relay, client-side direct CDN push, E2EE)
instead of silently succeeding — during migration, turn on client.on('exception') in your canary environment to collect them.
For non-Web platforms see that platform's "quickstart and feature guide"; runtime capability on each platform follows the published SDK package.
Step 4: REST paths
Three rules cover 90% of your calls:
| Rule | Example |
|---|---|
| Agora paths are kept as-is (same prefix, parameter names may differ) | GET /dev/v1/channel/{appid}, POST /dev/v1/kicking-rule |
Cloud Recording keeps /v1/apps/{appid}/cloud_recording/... | acquire → start → query → updateLayout → stop |
Platform-native semantics go through /v1/* | /v1/channels, /v1/recordings, /v1/analytics/* |
The only differences are path parameter naming (Agora uses cname/uid, some of our endpoints use channelName; where both are accepted the API reference is authoritative) and the response envelope: Agora uses a business code ({"success":true} / {resourceId,sid}), while we use HTTP status codes plus {code,message,reason,sdkCode}. The complete path mapping table is in "Agora path ↔ our path" in Channel management.
Step 5: Receiving callbacks (almost no change)
- Event codes match:
101–112(channel/user),201–203(recording/media push/token); - Signature headers match:
Agora-Signature(HMAC-SHA1) andAgora-Signature-V2(HMAC-SHA256), both signing the raw request body with the endpoint secret; - Difference: the retry count and backoff sequence follow ni-meet's callback event definitions (up to 9 attempts, exponential backoff starting at 5s),
and we additionally provide a delivery log and a replay endpoint.
See Callback integration for the receiver checklist and Callback event reference for field-level definitions.
Step 6: Verify that the migration worked
Verify in this order; every step leaves a repeatable artifact:
curl $BASE/healthz→{"status":"ok"};POST /v1/tokensto get a token →GET /v1/tokens/verify?token=...to read back the privilege set andpexp;- Two browsers join a call: see Quickstart; the complete "zero to two browsers in the same channel" walkthrough is that same page end to end;
- Server-side query:
GET /dev/v1/channel/{appid}shows the channel you just created; - Callbacks: after configuring a webhook, run the bundled callbacks curl example and watch the delivery log;
- Full set:
node examples/run-all.mjs --all(everything should be green).
Explicitly not supported (know this before migrating)
| Agora capability | Our status | Alternative |
|---|---|---|
| IM / RTM / Signaling | Not provided | Provided by an IM PaaS; see Token authentication for the integration |
| Conversational AI / speech transcription | ⛔ Out of scope for this round | — |
| Content moderation (Content Inspect) | ➖ Callback hook only | Moderate on your own business side |
| E2EE (end-to-end encryption) | Not provided; calls return NOT_SUPPORTED | Transport is already TLS + SRTP; for media-level encryption see Channel encryption |
| Interactive Whiteboard / flexible classroom | ⛔ Separate product line | — |