Skip to content

Realtime comms

Realtime audio/video rooms, per-participant access tokens and participant management across LiveKit / Agora / Zego.

1. Overview

Base path: https://api.infrai.cc/v1/rtc
Auth header: Authorization: Bearer $INFRAI_API_KEY
bash
# Call any /v1/rtc capability over raw HTTP — no SDK to install.
# curl:
curl https://api.infrai.cc/v1/rtc/... \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json"

2. Methods (7)

2.1rtc.room.create

POST /v1/rtc/room/create

Create a live audio/video room on the selected RTC vendor. Some vendors (Agora/Zego) have no persistent room object — the room materializes on first join and the record is synthesized.

Parameters

NameTypeRequiredDescription
namestring
Required
Room name (unique per account).
≥ 1 chars
max_participantsnumberOptionalMaximum concurrent participants.
≥ 1
empty_timeout_snumberOptionalAuto-close after this many seconds empty.
≥ 0
metadataRecord<string, unknown>OptionalArbitrary key/value metadata.
regionstringOptionalEdge region to host the room.
vendor"livekit" | "agora" | "tencent_rtc" | "zego" | nullOptionalExplicit vendor pin.
idempotency_keystringOptionalClient-supplied key to make the call idempotent.

Returns

Room { room, name, max_participants, created_at }
NameTypeDescription
room_idstringVendor room SID or the room name when there is no SID.
namestringHuman-readable name for this resource
≥ 1 chars
vendor"livekit" | "agora" | "tencent_rtc" | "zego"Vendor that handled or will handle this request
state"active" | "closed"Current lifecycle state of this resource
max_participantsinteger | nullMaximum number of participants allowed in the room
≥ 0
num_participantsintegerCurrent number of participants in the room
≥ 0default: 0
created_atstring | nullISO 8601 timestamp when this resource was created
metadataobject | nullArbitrary key-value metadata attached to this resource

Example

一次性前置(每个范例都假定已完成):

bash
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."
bash
curl -X POST https://api.infrai.cc/v1/rtc/room/create \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "example"}'

2.2rtc.room.get

GET /v1/rtc/room/get/{room}

Fetch a single RTC room's state and live occupancy.

Parameters

NameTypeRequiredDescription
roomstring
Required
The room id.

Returns

Room
NameTypeDescription
room_idstringVendor room SID or the room name when there is no SID.
namestringHuman-readable name for this resource
≥ 1 chars
vendor"livekit" | "agora" | "tencent_rtc" | "zego"Vendor that handled or will handle this request
state"active" | "closed"Current lifecycle state of this resource
max_participantsinteger | nullMaximum number of participants allowed in the room
≥ 0
num_participantsintegerCurrent number of participants in the room
≥ 0default: 0
created_atstring | nullISO 8601 timestamp when this resource was created
metadataobject | nullArbitrary key-value metadata attached to this resource

Example

一次性前置(每个范例都假定已完成):

bash
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."
bash
curl -X GET https://api.infrai.cc/v1/rtc/room/get/ROOM \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.3rtc.room.list

GET /v1/rtc/room/list

List active RTC rooms / channels for the account.

Parameters

NameTypeRequiredDescription
cursorstringOptionalOpaque pagination cursor.
limitnumberOptionalMaximum number of items to return.

Returns

{ items: Room[], next_cursor?: string }
NameTypeDescription
itemsobject[]List of RTC room records
next_cursorstring | nullCursor for next page; null if last page

Example

一次性前置(每个范例都假定已完成):

bash
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."
bash
curl -X GET https://api.infrai.cc/v1/rtc/room/list \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.4rtc.room.delete

DELETE /v1/rtc/room/delete/{room}

Close an RTC room (vendors without a delete API auto-close when empty).

Parameters

NameTypeRequiredDescription
roomstring
Required
The room id.

Returns

{ ok: boolean }
NameTypeDescription
room_idstringVendor room SID or the room name when there is no SID.
namestringName of the deleted room
≥ 1 chars
vendor"livekit" | "agora" | "tencent_rtc" | "zego"Vendor that handled the request
state"active" | "closed"Lifecycle state after deletion (always "closed"; vendors without a delete API auto-close when empty)
max_participantsinteger | nullMaximum number of participants allowed in the room
≥ 0
num_participantsintegerCurrent number of participants in the room
≥ 0default: 0
created_atstring | nullISO 8601 timestamp when this resource was created
metadataobject | nullArbitrary key-value metadata attached to this resource

Example

一次性前置(每个范例都假定已完成):

bash
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."
bash
curl -X DELETE https://api.infrai.cc/v1/rtc/room/delete/ROOM \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.5rtc.token.issue

POST /v1/rtc/token/issue

Mint a per-participant join token (vendor-native JWT/AccessToken2/token04, signed locally). Billed per participant-minute conceptually; bandwidth/egress floored at cost.

Parameters

NameTypeRequiredDescription
roomstring
Required
The room id.
≥ 1 chars
identitystring
Required
Unique per-participant identity / uid.
≥ 1 chars
display_namestringOptionalHuman-readable participant name.
ttl_snumberOptionalToken time-to-live in seconds.
≥ 1default: 3600
can_publishbooleanOptionalAllow the participant to publish media.
default: true
can_subscribebooleanOptionalAllow the participant to subscribe to media.
default: true
can_publish_databooleanOptionalAllow the participant to publish data messages.
default: true
is_adminbooleanOptionalGrant the participant admin privileges.
default: false
vendor"livekit" | "agora" | "tencent_rtc" | "zego" | nullOptionalExplicit vendor pin.
metadataRecord<string, unknown>OptionalArbitrary key/value metadata.

Returns

AccessToken { token, room, identity, expires_at }
NameTypeDescription
tokenstringAuthentication or verification token
≥ 1 chars
roomstringRoom name or identifier
identitystringIdentity string for the participant
vendor"livekit" | "agora" | "tencent_rtc" | "zego"Vendor that handled or will handle this request
expires_atstring | nullISO 8601 timestamp when this resource or token expires
format: date-time
ws_urlstring | nullVendor WebSocket / signalling URL the client connects to.

Example

一次性前置(每个范例都假定已完成):

bash
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."
bash
curl -X POST https://api.infrai.cc/v1/rtc/token/issue \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"room": "sample", "identity": "sample"}'

2.6rtc.participant.list

GET /v1/rtc/participant/list/{room}

List participants currently in a room.

Parameters

NameTypeRequiredDescription
roomstring
Required
The room id.

Returns

{ items: Array<{ identity, display_name?, joined_at }> }
NameTypeDescription
itemsobject[]Participants currently in the room (empty when the vendor has no roster read, e.g. tencent_rtc)
items[].identitystringIdentity string for the participant
items[].joined_atstring | nullISO 8601 timestamp when this member joined
items[].state"active" | "joining" | "disconnected"Current lifecycle state of this resource
items[].is_publisherbooleanWhether the participant is publishing media
default: false
items[].display_namestring | nullHuman-readable display name

Example

一次性前置(每个范例都假定已完成):

bash
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."
bash
curl -X GET https://api.infrai.cc/v1/rtc/participant/list/ROOM \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.7rtc.participant.kick

POST /v1/rtc/participant/kick/{room}

Forcibly remove (kick) a participant from a room.

Parameters

NameTypeRequiredDescription
roomstring
Required
The room id.
≥ 1 chars
identitystring
Required
Unique per-participant identity / uid.
≥ 1 chars
vendor"livekit" | "agora" | "tencent_rtc" | "zego" | nullOptionalExplicit vendor pin.

Returns

{ ok: boolean }
NameTypeDescription
okbooleanWhether the participant was kicked
identitystring | nullIdentity of the kicked participant

Example

一次性前置(每个范例都假定已完成):

bash
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at https://infrai.cc/login (Google/GitHub gives
# you $2 free credit; email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT, add
# funds at https://infrai.cc/billing (or POST /v1/account/topup and open the
# returned checkout_url).
export INFRAI_API_KEY="ifr_..."
bash
curl -X POST https://api.infrai.cc/v1/rtc/participant/kick/ROOM \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"room": "sample", "identity": "sample"}'
Advanced: pin a vendor

By default infrai routes each call to the best available provider — you do not pick a vendor. As an escape hatch, this capability accepts an optional vendor parameter to pin one specific provider. Every live vendor for this capability is available in real time from the discovery endpoint for the capability id — see the discovery API.

GET /v1/discovery/{capability}

rtc.room.create

rtc.token.issue

rtc.participant.kick

3. All capabilities

Every routed capability in this module — the complete public REST contract. The methods above are the guided walkthrough; this index is the full reference.

rtc.participant.kickPOST /v1/rtc/participant/kick/{room}

Forcibly remove (kick) a participant from a room.

Parameters (3)
NameTypeRequiredDescription
roomstringRequiredPath param; the room name.
≥ 1 chars
identitystringRequiredParticipant identity / uid to remove.
≥ 1 chars
vendor"livekit" | "agora" | "tencent_rtc" | "zego" | nullOptionalVendor that handled or will handle this request
rtc.participant.listGET /v1/rtc/participant/list/{room}

List participants currently in a room.

Parameters (1)
NameTypeRequiredDescription
roomstringRequiredPath parameter.
rtc.room.createPOST /v1/rtc/room/create

Create a live audio/video room on the selected RTC vendor. Some vendors (Agora/Zego) have no persistent room object — the room materializes on first join and the record is synthesized.

Parameters (7)
NameTypeRequiredDescription
namestringRequiredRoom name (unique per account).
≥ 1 chars
max_participantsinteger | nullOptionalMaximum number of participants allowed in the room
≥ 1
empty_timeout_sinteger | nullOptionalAuto-close after this many seconds empty.
≥ 0
metadataobject | nullOptionalArbitrary key-value metadata attached to this resource
regionstring | nullOptionalGeographic region where this resource is located or processed
vendor"livekit" | "agora" | "tencent_rtc" | "zego" | nullOptionalVendor that handled or will handle this request
idempotency_keystring | nullOptionalClient-provided idempotency key; prevents duplicate execution on retry
rtc.room.deleteDELETE /v1/rtc/room/delete/{room}

Close an RTC room (vendors without a delete API auto-close when empty).

Parameters (1)
NameTypeRequiredDescription
roomstringRequiredPath parameter.
rtc.room.getGET /v1/rtc/room/get/{room}

Fetch a single RTC room's state and live occupancy.

Parameters (1)
NameTypeRequiredDescription
roomstringRequiredPath parameter.
rtc.room.listGET /v1/rtc/room/list

List active RTC rooms / channels for the account.

No request parameters.

rtc.token.issuePOST /v1/rtc/token/issue

Mint a per-participant join token (vendor-native JWT/AccessToken2/token04, signed locally). Billed per participant-minute conceptually; bandwidth/egress floored at cost.

Parameters (10)
NameTypeRequiredDescription
roomstringRequiredRoom name or identifier
≥ 1 chars
identitystringRequiredUnique per-participant identity / uid.
≥ 1 chars
display_namestring | nullOptionalHuman-readable display name
ttl_sintegerOptionalTime-to-live in seconds for the token
≥ 1default: 3600
can_publishbooleanOptionalWhether the token grants publish permission
default: true
can_subscribebooleanOptionalWhether the token grants subscribe permission
default: true
can_publish_databooleanOptionalWhether the token grants data channel publish permission
default: true
is_adminbooleanOptionalWhether the token grants admin privileges
default: false
vendor"livekit" | "agora" | "tencent_rtc" | "zego" | nullOptionalVendor that handled or will handle this request
metadataobject | nullOptionalArbitrary key-value metadata attached to this resource

4. End-to-end example

A production-style walkthrough of this module: configure once, then run the flow. It exercises most of the module's APIs.

A copy-paste-runnable single-file Python program (stdlib only, no SDK): set your INFRAI_API_KEY, run it, and walk this module's core flow with REAL billed calls — later steps reuse real fields returned by earlier ones. The 12-line helper is the entire integration.

python
#!/usr/bin/env python3
"""Infrai · rtc — runnable real-app example (single file, zero deps).

Copy this file, set your key, run it: every step is a REAL call to
api.infrai.cc, billed at the real (tiny) per-call price, printing the
live JSON response. Get a key at https://infrai.cc/login (Google/
GitHub sign-in grants $2 free credit); add funds at
https://infrai.cc/billing. No SDK — the 12-line helper below is the
entire integration."""
import json
import os
from urllib import error, request

KEY = os.environ.get("INFRAI_API_KEY") or "ifr_..."  # <- your key
BASE = "https://api.infrai.cc"


# Same raw HTTPS POST/GET as every per-method example on this page —
# wrapped once for reuse. There is nothing else to it: no SDK.
def infrai(method, path, body=None):
    req = request.Request(
        BASE + path, method=method,
        data=json.dumps(body).encode() if body is not None else None,
        headers={"Authorization": f"Bearer {KEY}",
                 "Content-Type": "application/json"})
    try:
        with request.urlopen(req, timeout=60) as r:
            return json.loads(r.read())
    except error.HTTPError as e:
        return json.loads(e.read())


def show(label, resp):
    print(f"\n== {label} ==")
    print(json.dumps(resp, indent=2, ensure_ascii=False))
    return resp


# 1) rtc.room.create — POST /v1/rtc/room/create · Create a live audio/video room on the selected RTC vendor. Some vendors (Agora/Zego) have no persistent room object — the room materializes on first join and the record is synthesized.
r1 = show("rtc.room.create", infrai("POST", "/v1/rtc/room/create", {"name":"example"}))

# 2) rtc.token.issue — POST /v1/rtc/token/issue · Mint a per-participant join token (vendor-native JWT/AccessToken2/token04, signed locally). Billed per participant-minute conceptually; bandwidth/egress floored at cost.
r2 = show("rtc.token.issue", infrai("POST", "/v1/rtc/token/issue", {"room":"sample","identity":"sample"}))

# 3) rtc.room.list — GET /v1/rtc/room/list · List active RTC rooms / channels for the account.
r3 = show("rtc.room.list", infrai("GET", "/v1/rtc/room/list"))