02 โ€” API reference

  • Base URL: https://calls.arzbridge.com/api/v1
  • Auth: Authorization: Bearer KEY:SECRET (or X-Api-Key/X-Api-Secret)
  • Success: { "data": ... } ยท Error: { "error": { code, message } }

In the examples below:

KEY=YOUR_API_KEY; SECRET=YOUR_API_SECRET
AUTH="Authorization: Bearer $KEY:$SECRET"
BASE=https://calls.arzbridge.com/api/v1

Health & account

GET /ping โ€” liveness (no auth)

curl -s $BASE/ping       # { "pong": true, "time": "..." }

GET /me โ€” your project profile, quotas, usage

curl -s -H "$AUTH" $BASE/me

GET /health โ€” deep health (app, db, media)

curl -s -H "$AUTH" $BASE/health

Tokens

POST /tokens โ€” issue a join token (the main endpoint)

Also available as POST /rooms/{room}/tokens (room from the path).

Body

Field Type Default Notes
room string โ€” (required) Room name
identity string โ€” (required) Unique per participant in the room
name string โ€“ Display name
ttl int (sec) 21600 30โ€“86400
metadata object โ€“ Attached to participant, visible to others
attributes object โ€“ Key/value attributes
can_publish bool true May send audio/video
can_subscribe bool true May receive others
can_publish_data bool true May send data messages
hidden bool false Join invisibly
room_admin bool false Server-side admin rights
curl -s -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{"room":"team-sync","identity":"user-42","name":"Alice","ttl":3600}' \
  $BASE/tokens

Response

{ "data": {
  "token": "<jwt>",
  "ws_url": "wss://calls.arzbridge.com",
  "room": "team-sync",
  "identity": "user-42",
  "expires_in": 3600
}}

Rooms

GET /rooms โ€” list your active rooms

curl -s -H "$AUTH" $BASE/rooms

POST /rooms โ€” create a room (optional; tokens auto-create too)

Field Type Notes
name string (required) Room name
display_name string Friendly label
max_participants int Cap room size
empty_timeout int (sec) Auto-close after empty (default 300)
metadata object Arbitrary metadata
recording bool Hint flag
curl -s -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{"name":"webinar-1","max_participants":500}' $BASE/rooms

GET /rooms/{name} โ€” room details + live participants

DELETE /rooms/{name} โ€” close/end a room (disconnects everyone)

curl -s -X DELETE -H "$AUTH" $BASE/rooms/webinar-1

Participants

GET /rooms/{room}/participants โ€” who's in the room

GET /rooms/{room}/participants/{identity} โ€” one participant

DELETE /rooms/{room}/participants/{identity} โ€” remove (kick)

curl -s -X DELETE -H "$AUTH" $BASE/rooms/team-sync/participants/user-42

POST /rooms/{room}/participants/{identity}/mute โ€” mute a track

curl -s -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{"track_sid":"TR_xxx","muted":true}' \
  $BASE/rooms/team-sync/participants/user-42/mute

POST /rooms/{room}/data โ€” send a data message to the room

curl -s -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{"data":"{\"type\":\"hand_raised\"}","topic":"signals"}' \
  $BASE/rooms/team-sync/data

Optional destination_identities: ["user-42"] to target specific participants.


Recordings

Room-composite recording to MP4. Requires the recordings.write scope on your API key (listing needs only a valid key).

GET /recordings โ€” list recordings (filter ?room=)

POST /rooms/{room}/recordings โ€” start recording (layout: grid|speaker|single-speaker)

DELETE /recordings/{egressId} โ€” stop recording

GET /recordings/{egressId}/download โ€” download the finished file

# start
curl -s -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{"layout":"grid"}' $BASE/rooms/team-sync/recordings

# download once status = complete (follow the redirect)
curl -L -H "$AUTH" -o recording.mp4 $BASE/recordings/EG_xxx/download
# or get the signed URL as JSON (valid ~15 min):
curl -s -H "$AUTH" "$BASE/recordings/EG_xxx/download?format=json"

Recording is asynchronous. POST returns immediately with the job (status starting/active). When the recording finishes you learn the result either by:

  • polling GET /recordings โ€” the job's status becomes complete and output.files[] lists the produced file(s) (filename, size, duration), or
  • webhook โ€” subscribe an endpoint to egress_ended; the payload's egress object includes the same files[] (see 08).

Then download it with GET /recordings/{egressId}/download: it redirects (302) to a short-lived signed URL, so curl -L (or a browser) fetches the MP4 directly โ€” no storage credentials needed. Add ?format=json to get the signed URL in the body ({"data":{"url","expires_in":900}}) instead of a redirect. Returns 409 if the recording isn't finished yet.

A recording only starts capturing once at least one participant is publishing.


Webhook endpoints โ€” see 08

Register URLs to receive signed event notifications on your backend.

Method Path Scope Description
GET /webhook-endpoints โ€“ List your endpoints (secret omitted)
POST /webhook-endpoints webhooks.write Create an endpoint. Body: url, events?[], description?. Returns secret once
DELETE /webhook-endpoints/{id} webhooks.write Delete an endpoint
POST /webhook-endpoints/{id}/test webhooks.write Send a ping test event
curl -s -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{"url":"https://api.yourapp.com/webhooks/calls","events":["participant_joined","participant_left"]}' \
  $BASE/webhook-endpoints

Notes

  • All operations are scoped to your project automatically โ€” you only ever see and affect your own rooms.
  • For real-time server-side notifications, register a webhook endpoint (above) and verify signatures โ€” full guide in 08-receiving-webhooks.md.