nimeet Docs
中文

Core Concepts and Domain Model

Project / Channel / Participant / Task / Callback fields and invariants, plus the two credential families.

Version v1.1.0 · Updated 2026-10-26 · revision 1

This page explains, once, the terms, fields and invariants that recur throughout the documentation. Field names follow the frozen domain interface definition: the platform API (/v1/*) uses camelCase wire fields, while the Agora-compatible endpoints use snake_case aliases.

The two credential families

CredentialShapePurposeWhere it lives
Project credentialAuthorization: Basic base64(customerId:customerSecret)Server to server: signing tokens, channel management, recording / media push, telemetry ingestionIn your backend only
Console sessionAuthorization: Bearer ses_*Console BFF: projects, key rotation, service activation, callback configuration, auditConsole pages (12-hour TTL)
App ID32 hexadecimal charactersClient initialization and path parameters (/dev/v1/channel/{appid})Visible to clients
App Certificate64 hexadecimal charactersHMAC key for signing and verifying tokensServer side only, or only as a secret-manager reference

Project

FieldDescription
idprj_*, the project primary key
appId32 hex characters, the project identifier visible to clients
customerId / customerSecretHashBasic user name; the password is stored as SHA-256 only
appCertificateToken signing key (stored hashed or in controlled storage; the plaintext is returned once)
authModetoken (default, clients present a token) or appid
statusactive / suspended; anything other than active returns 403 app_disabled
tokenTtlSecondsUpper bound of the token lifetime policy (default 3600)
privilegeTtlSecondsUpper bound of the privilege window (default 3600); the effective value is min(ttl, this value)
services{ recording, streaming, analytics } service switches
quotas{ recordingConcurrent, streamingConcurrent, maxChannels }, defaulting to 5 / 5 / 0 (0 = unlimited channels)

Channel and Participant

  • Channel name: 1–128 characters from [A-Za-z0-9_-], case-sensitive, and unique within a project.
  • Media-plane room names are namespaced by App ID: <appId>:<channelName>, so tenants cannot collide.
  • profile is communication or live and decides whether the Agora-compatible endpoints return users or broadcasters / audience.
  • A Participant is "one online presence of one user inside one channel": uid (1..2147483647), optional userId (IM identity), role, platform, joinedAt / leftAt, leaveReason, audioMuted / videoMuted, publishing.{audio,video,screen}.

Platform codes (platform) match Agora: 0 other, 1 Android, 2 iOS, 5 Windows, 6 Linux, 7 Web, 8 macOS.

Leave reasons (leaveReason / callback reason) map as follows: 1 normal/other, 2 timeout, 3 kicked or banned, 5 duplicate login/switch, 10 network disconnected.

Task

Recording and media push are both task-shaped resources with their own state machine:

text
starting → running → stopping → stopped
                 ↘ failed
                 ↘ expired (media push only: triggered by idleTimeout)
  • Every state change is persisted first, then written to the Outbox, and only then delivered as a callback (transactional outbox), so a lost callback never rolls back state — it only causes a redelivery.
  • RecordingTask additionally carries layout, storage, subscribeAudioUids / subscribeVideoUids, files[], usageSeconds, queueWaitMs, idempotencyKey.
  • StreamingTask additionally carries entryPoint, streamName, rtmpUrl, hlsUrl, idleTimeoutSeconds, lastActiveAt.

UsageEvent and QualitySample

  • Usage is billed per minute; types are audio / video / recording / streaming / transcoding. Every event carries an idempotencyKey, so duplicate observations over the webhook and reconciliation channels are never billed twice.
  • A quality sample is a per-user, per-minute aggregate: videoFreezeMs / audioFreezeMs / networkDelayMs are the raw freeze and delay durations; thresholds are applied on the server (see Analytics).
  • Six analysis dimensions: region, networkType, osType, sdkVersion, deviceType, channelSize.

CallbackEnvelope

FieldDescription
noticeIdUnique notification id per event; usable for idempotency
productIdAlways 1 (RTC)
eventTypeNumeric event code (101–112, 201–203), see Callback events
notifyMsWhen the event happened (epoch milliseconds)
sidEvent session id
payloadEvent-specific fields

Platform API vs. Agora-compatible API

The same business facts, in two envelopes:

DimensionPlatform API (/v1/*)Agora-compatible (/dev/v1/*, /v1/apps/*, /v1/projects/*)
Field namingcamelCasesnake_case (channel_name, user_count, cname, resourceId…)
List envelope{ total, pageNo, pageSize, channels }{ success: true, data: { channels, total_size } }
Task resultThe full task resource (state machine, files, queue diagnostics){ resourceId, sid, serverResponse }
Errors{ code, message, reason, sdkCode }Same (either reading habit still gets you the reason)
Best forOur SDKs / console / new integrationsMigrating from Agora with the fewest path changes

Key invariants

  • rtcUid ∈ [1, 2147483647] and is never 0 (in Agora semantics 0 means "assigned randomly by the server"); the same (appId, userId) is stable for the duration of a session.
  • Channel names are unique within a project; the SFU room name is <appId>:<channelName>.
  • A token is bound to (appId, channelName, uid, role, privilegeExpireAt, tokenExpireAt); a wildcard token uses * as its channel.
  • Every task state change is persisted first, then enters the Outbox, and is delivered as a callback last.
  • A join_channel ban applies in two places at once: token issuance (403 banned) and live sessions (the user is disconnected, with leave reason 3).
  • Usage events are idempotent on (projectId, idempotencyKey); the webhook and reconciliation channels write through the same idempotent path.
  • Callbacks carry both a SHA1 (Agora-Signature) and a SHA256 (Agora-Signature-V2) signature, computed over the raw request body bytes.

Generated by the documentation build pipeline · 2026-10-31 01:24:02 UTC · Documentation center v1.1.0.

Content follows the public API definitions.

ni-meet is a self-hosted RTC PaaS with a LiveKit-based media plane (Apache-2.0) and an Agora-compatible API.