Skip to content

Realtime

Realtime tokens, channels, publish and presence.

1. Overview

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

2. Methods (11)

2.1realtime.publish

POST /v1/realtime/publish

Publish an event to a channel.

Parameters

NameTypeRequiredDescription
channelstring
Required
Channel name.
eventstring
Required
Event name.
default: "message"
dataunknown
Required
Event payload to publish.
idempotency_keystringOptionalOptional dedup key; identical retries return the same result.

Returns

{ message_id }
NameTypeDescription
event_idstringUnique identifier for this event
channelstringChannel name or identifier
published_atstringISO 8601 timestamp when the event was published
format: date-time
vendorstringVendor that handled or will handle this request

Example

One-time prep (each example is assumed to be complete):

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/realtime/publish \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channel": "room-42", "event": "message", "data": {"text": "hi"}}'

2.2realtime.token.issue

POST /v1/realtime/token/issue

Issue a client token scoped to channels and capabilities.

Parameters

NameTypeRequiredDescription
user_idstringOptionalId of the connecting user.
channelsstring[]OptionalChannels the token may access.
ttl_secondsnumberOptionalLifetime in seconds before expiry.
≥ 1

Returns

RealtimeToken { token, client_id, expires_at, endpoint }
NameTypeDescription
tokenstringAuthentication or verification token
jtistringJWT ID; used for server-side revocation.
channelsstring[]List of channel names the token grants access to
capabilities("subscribe" | "publish" | "presence" | "history")[]List of capability permissions (publish, subscribe)
expires_atstringISO 8601 timestamp when this resource or token expires
format: date-time

Example

One-time prep (each example is assumed to be complete):

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/realtime/token/issue \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id": "user_42", "channels": ["room-42"], "capabilities": ["subscribe", "presence"], "ttl_seconds": 3600}'

2.3realtime.channel.create

POST /v1/realtime/channel/create

Create a realtime channel.

Parameters

NameTypeRequiredDescription
namestring
Required
Channel name.
type"public" | "private" | "presence"OptionalChannel visibility type.
default: "public"

Returns

{ channel_id, name, type }
NameTypeDescription
channel_idstringUnique identifier for this channel
namestringHuman-readable name for this resource
type"public" | "private" | "presence"Type discriminator for this resource
vendorstringVendor that handled or will handle this request
created_atstringISO 8601 timestamp when this resource was created
format: date-time
member_countinteger | nullNumber of members in the channel
≥ 0
last_published_atstring | nullISO 8601 timestamp of the last published event
format: date-time

Example

One-time prep (each example is assumed to be complete):

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/realtime/channel/create \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "room-42", "type": "presence"}'

2.4realtime.presence.get

GET /v1/realtime/presence/get/{channel}

Get the members currently present on a channel.

Parameters

NameTypeRequiredDescription
channelstring
Required
Channel name.

Returns

{ members: Array<{ client_id, user_id? }> }
NameTypeDescription
channelstringChannel name or identifier
membersobject[]List of presence members in the channel
members[].client_idstringClient identifier for the connected user
members[].joined_atstringISO 8601 timestamp when this member joined
format: date-time
members[].user_dataobject | nullCustom data associated with the presence member
next_cursorstring | nullPass back into presence.get() to fetch the next page; null on last page.

Example

One-time prep (each example is assumed to be complete):

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/realtime/presence/get/CHANNEL \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.5realtime.channel.get

GET /v1/realtime/channel/get/{channel}

Get the details of a single real-time channel, including type, manufacturer, number of people online, etc.

Parameters

NameTypeRequiredDescription
channelstring
Required
The channel name to be queried.

Returns

Channel { channel_id, name, type, vendor, created_at, member_count?, last_published_at? }
NameTypeDescription
channel_idstringUnique identifier for this channel
namestringHuman-readable name for this resource
type"public" | "private" | "presence"Type discriminator for this resource
vendorstringVendor that handled or will handle this request
created_atstringISO 8601 timestamp when this resource was created
format: date-time
member_countinteger | nullNumber of members in the channel
≥ 0
last_published_atstring | nullISO 8601 timestamp of the last published event
format: date-time

Example

One-time prep (each example is assumed to be complete):

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/realtime/channel/get/CHANNEL \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.6realtime.channel.delete

DELETE /v1/realtime/channel/delete/{channel}

Delete a live channel and disconnect its subscribers.

Parameters

NameTypeRequiredDescription
channelstring
Required
The name of the channel to be deleted.
idempotency_keystringOptionalIdempotent keys for safe retries.

Returns

ChannelDeleteResult { channel, deleted, status }
NameTypeDescription
channelstringChannel name or identifier
deletedbooleanWhether the resource was successfully deleted
status"deleted" | "not_found"Current status of this resource

Example

One-time prep (each example is assumed to be complete):

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/realtime/channel/delete/CHANNEL \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.7realtime.channel.list

GET /v1/realtime/channel/list

List the real-time channels under the current account in pages.

Parameters

NameTypeRequiredDescription
cursorstringOptionalPage turning cursor, pass in the next_cursor returned from the previous page.
limitnumberOptionalThe maximum number of items returned on a single page.

Returns

ChannelListResult { channels: Channel[], next_cursor? }
NameTypeDescription
channelsobject[]List of channel names the token grants access to
channels[].channel_idstringUnique identifier for this channel
channels[].namestringHuman-readable name for this resource
channels[].type"public" | "private" | "presence"Type discriminator for this resource
channels[].vendorstringVendor that handled or will handle this request
channels[].created_atstringISO 8601 timestamp when this resource was created
format: date-time
channels[].member_countinteger | nullNumber of members in the channel
≥ 0
channels[].last_published_atstring | nullISO 8601 timestamp of the last published event
format: date-time
next_cursorstring | nullPass back into channel.list() to fetch the next page; null on last page.

Example

One-time prep (each example is assumed to be complete):

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/realtime/channel/list \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.8realtime.event.types

GET /v1/realtime/event/types

Lists a closed collection of live event types that can be subscribed to.

Returns

EventTypesResult { types: string[] }
NameTypeDescription
types("channel.opened" | "channel.closed" | "message.published" | "presence.join" | "presence.leave")[]List of available event types

Example

One-time prep (each example is assumed to be complete):

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/realtime/event/types \
  -H "Authorization: Bearer $INFRAI_API_KEY"

2.9realtime.publish.batch

POST /v1/realtime/publish/batch

Bulk publish messages to multiple channels in one call.

Parameters

NameTypeRequiredDescription
messagesArray<{ channel: string; event: string; data: unknown }>
Required
List of messages to publish, each containing channel, event and data.
≥ 1 item
idempotency_keystringOptionalIdempotent keys, used for safe retries to avoid repeated publishing.

Returns

PublishBatchResult { published }
NameTypeDescription
publishedintegerNumber of messages accepted for delivery.
≥ 0

Example

One-time prep (each example is assumed to be complete):

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/realtime/publish/batch \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"messages": [{"channel": "sample", "event": "sample", "data": "sample"}]}'

2.10realtime.token.revoke

POST /v1/realtime/token/revoke

Revoke a previously issued subscription token (used when logging out or banning).

Parameters

NameTypeRequiredDescription
token_or_jtistring
Required
The full token or its jti identifier.
≥ 1 chars
idempotency_keystringOptionalIdempotent keys for safe retries.

Returns

TokenRevokeResult { revoked }
NameTypeDescription
revokedbooleanWhether the token was successfully revoked

Example

One-time prep (each example is assumed to be complete):

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/realtime/token/revoke \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"token_or_jti": "sample"}'

2.11realtime.user.disconnect

POST /v1/realtime/user/disconnect

Force a client to be kicked offline, optionally limited to a single channel.

Parameters

NameTypeRequiredDescription
client_idstring
Required
The client identity to disconnect from.
≥ 1 chars
channelstringOptionalLimit disconnection to this channel; omit to disconnect all.
idempotency_keystringOptionalIdempotent keys for safe retries.

Returns

UserDisconnectResult { disconnected }
NameTypeDescription
disconnectedbooleanWhether the user was successfully disconnected

Example

One-time prep (each example is assumed to be complete):

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/realtime/user/disconnect \
  -H "Authorization: Bearer $INFRAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id": "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}

realtime.channel.create

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.

realtime.channel.createPOST /v1/realtime/channel/create

Create a realtime pub/sub channel; idempotent.

Parameters (4)
NameTypeRequiredDescription
channelstringRequiredChannel name to create.
typestringOptionalChannel type (e.g. public, private, presence).
default: "public"
vendorstring | nullOptionalPin to a specific fan-out vendor; falls back to the registry default.
idempotency_keystring | nullOptionalClient-provided idempotency key; prevents duplicate execution on retry
realtime.channel.deleteDELETE /v1/realtime/channel/delete/{channel}

Delete a realtime channel and disconnect its subscribers.

Parameters (1)
NameTypeRequiredDescription
channelstringRequiredPath parameter.
realtime.channel.getGET /v1/realtime/channel/get/{channel}

Get a single realtime channel's details (type, vendor, online count, etc.).

Parameters (1)
NameTypeRequiredDescription
channelstringRequiredPath parameter.
realtime.channel.listGET /v1/realtime/channel/list

List the account's realtime channels with pagination.

No request parameters.

realtime.event.typesGET /v1/realtime/event/types

List the closed set of subscribable realtime event types.

No request parameters.

realtime.presence.getGET /v1/realtime/presence/get/{channel}

Get the current presence state of members online in a channel.

Parameters (1)
NameTypeRequiredDescription
channelstringRequiredPath parameter.
realtime.publishPOST /v1/realtime/publish

Publish an event message to a realtime pub/sub channel.

Parameters (5)
NameTypeRequiredDescription
channelstringRequiredChannel to publish to.
eventstringOptionalEvent name.
default: "message"
dataanyOptionalEvent payload (any JSON value).
account_idstring | nullOptionalAccount identifier that owns this resource
idempotency_keystring | nullOptionalClient-provided idempotency key; prevents duplicate execution on retry
realtime.publish.batchPOST /v1/realtime/publish/batch

Publish messages to multiple channels in a single batch call.

Parameters (2)
NameTypeRequiredDescription
messagesobject[]RequiredList of messages to publish or process
≥ 1 item
idempotency_keystring | nullOptionalClient-provided idempotency key; prevents duplicate execution on retry
realtime.token.issuePOST /v1/realtime/token/issue

Issue a short-lived infrai-HMAC client auth token for pub/sub realtime channels (NOT for AI voice sessions — see ai.voice.session).

Parameters (5)
NameTypeRequiredDescription
client_idstringRequiredIdentity the issued token is bound to.
≥ 1 chars
channelsstring[] | nullOptionalChannels the token may attach to; omit for an account-scoped token.
capabilities("subscribe" | "publish" | "presence" | "history")[] | nullOptionalCapability bits; constrained to the RealtimeCapability closed set. Defaults to subscribe.
ttl_secondsinteger | nullOptionalRequested lifetime; clamped to MAX_TTL_SECONDS (<=0 or invalid -> REALTIME_TOKEN_TTL_INVALID 400).
≥ 1
idempotency_keystring | nullOptionalClient-provided idempotency key; prevents duplicate execution on retry
realtime.token.revokePOST /v1/realtime/token/revoke

Revoke a previously issued subscription token (e.g., on logout or ban).

Parameters (2)
NameTypeRequiredDescription
token_or_jtistringRequiredEither the full token or its jti.
≥ 1 chars
idempotency_keystring | nullOptionalClient-provided idempotency key; prevents duplicate execution on retry
realtime.user.disconnectPOST /v1/realtime/user/disconnect

Forcibly disconnect a client, optionally scoped to a single channel.

Parameters (3)
NameTypeRequiredDescription
client_idstringRequiredClient identifier for the connected user
≥ 1 chars
channelstring | nullOptionalRestrict the disconnect to this channel; omit for all.
idempotency_keystring | nullOptionalClient-provided idempotency key; prevents duplicate execution on retry

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 · realtime — 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) realtime.publish — POST /v1/realtime/publish · Publish an event message to a realtime pub/sub channel.
r1 = show("realtime.publish", infrai("POST", "/v1/realtime/publish", {"channel":"sample"}))

# 2) realtime.token.issue — POST /v1/realtime/token/issue · Issue a short-lived infrai-HMAC client auth token for pub/sub realtime channels.
r2 = show("realtime.token.issue", infrai("POST", "/v1/realtime/token/issue", {"client_id":"sample"}))

# 3) realtime.channel.create — POST /v1/realtime/channel/create · Create a realtime pub/sub channel; idempotent.
r3 = show("realtime.channel.create", infrai("POST", "/v1/realtime/channel/create", {"channel":"sample"}))

# 4) realtime.channel.list — GET /v1/realtime/channel/list · List the account's realtime channels with pagination.
r4 = show("realtime.channel.list", infrai("GET", "/v1/realtime/channel/list"))

5. Developer guides

Move from endpoint details to complete workflows, production patterns and troubleshooting guides verified against the live API.

Realtime developer guides