Channel tickets
In channels with access mode ticket, users need a ticket to join. Your server issues tickets for specific users and hands each to its user through your own business API (such as the response of an "enter meeting" API), and the user's client joins with it.
| Property | Description |
|---|---|
| Bound | Each ticket is bound to one user of the app, one channel and one role; nobody else can use it |
| One-time | Invalid after one successful join |
| Validity | 30 to 300 seconds, 120 by default; hand it to the user soon after issuing |
| Not a sign-in credential | Users still sign in to IM first; tickets can't replace the User Token. open channels don't accept tickets |
Only give a ticket to the user it's bound to, and keep it out of URLs, IM messages, logs and persistent client caches.
Issue tickets
Issues tickets for 1 to 50 users. Issuing again for the same user invalidates their unused earlier tickets for this channel.
/{org_name}/{app_name}/rtc/channels/{channel_id}/ticketsPath parameters
For org_name and app_name, see Server overview; for channel_id, see Channel management.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
users | Array | Yes | 1 to 50 users, no duplicates |
users[].username | String | Yes | Username of an existing, non-banned user of the app |
users[].role | String | No | publisher or subscriber; omitted uses the channel's default_role. Giving it explicitly is recommended |
ttl_seconds | Integer | No | Validity, 30 to 300 seconds, 120 by default |
Example request
curl -X POST "$IM_API/$ORG/$APP/rtc/channels/meeting-demo/tickets" \
-H "Authorization: Bearer $APP_TOKEN" -H "Content-Type: application/json" \
-d '{"users":[{"username":"alice","role":"publisher"},{"username":"bob","role":"subscriber"}],"ttl_seconds":120}'Response
Returns 201 Created; tickets has one entry per user: username, role, ticket and expires_at. The whole batch is checked first, and if any user is invalid none are issued. Reissuing doesn't change the role of sessions already in the channel.
Don't retry automatically
Issuing isn't idempotent: every request invalidates the same user's earlier tickets. If the response is lost, let your business decide whether to issue again, and hand the user the latest ticket.
Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | The channel isn't a ticket channel; duplicate users; invalid user count, ttl_seconds or role |
| 404 | not_found | The channel or user doesn't exist |
| 403 | user_disabled | The user is banned |
| 403 | permission_denied | The user is banned from this channel, or the app's audio/video or channels are unavailable |
| 409 | conflict | The channel is closed or expired |
| 429 | rate_limited | Issuing too often; wait for Retry-After and retry |
Revoke unused tickets
Invalidates tickets users haven't used yet, for example to cancel someone's invitation. Sessions already joined aren't affected; to make someone leave or keep them out, use remove or ban.
/{org_name}/{app_name}/rtc/channels/{channel_id}/tickets/revokePath parameters
As in Issue tickets.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
operation_id | String | Yes | ID of this operation, 1 to 64 printable ASCII characters, no spaces. Keep it the same on retries |
usernames | Array<String> | Yes | 1 to 50 usernames, no duplicates |
reason | String | No | Note, at most 256 characters |
Example request
curl -X POST "$IM_API/$ORG/$APP/rtc/channels/meeting-demo/tickets/revoke" \
-H "Authorization: Bearer $APP_TOKEN" -H "Content-Type: application/json" \
-d '{"operation_id":"revoke-meeting-demo-alice-001","usernames":["alice"],"reason":"取消入会资格"}'Response
Returns 200 OK with operation_id and the number of tickets revoked, revoked_count.
Errors
Retrying with the same operation_id and parameters returns the first result.
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | Invalid parameters |
| 404 | not_found | The channel or user doesn't exist |
| 409 | conflict | details.reason is idempotency_conflict: the same operation_id was used with different parameters |
Client ticket errors
When a client joins with a ticket that's missing, invalidated, expired, already used, or bound to a different user or channel, it gets 404 not_found with details.reason channel_not_found, the same as for a channel that doesn't exist. This way nobody can probe which protected channels exist from error messages.
Clients can simply say "can't join", and ask your server for a new ticket if needed. For retrying the same request after a successful join, or resuming an existing session, see Client channel sessions.
