Tagora Integration API

v0.1.0 integration.tagora.com.mx ← Stream Tester

Getting Started

Integration API for partner developers — scope=integration bearer token, device listing, and webhook management.

1

Authenticate POST /integration/v1/auth/login

Send your partner credentials. The response contains an accessToken (short-lived JWT, scope=integration) and a renewToken for silent refresh.

POST https://integration.tagora.com.mx/integration/v1/auth/login
Content-Type: application/json

{
  "email":    "partner@example.com",
  "password": "••••••••"
}

// 200 OK — all responses wrapped in {data, requestId}
{
  "data": {
    "accessToken":  "eyJhbGci...",   // Bearer — read from response.data.accessToken
    "renewToken":   "eyJhbGci...",   // persist in sessionStorage for silent refresh
    "tokenType":    "Bearer",
    "expiresIn":    3600              // seconds until accessToken expires
  },
  "requestId": "a1b2c3d4-..."
}
Token storage — store the accessToken only in memory (never localStorage). Persist the renewToken in sessionStorage if you need to survive a page reload.
2

Use the Bearer token in every request

Pass the accessToken as an Authorization header on all protected endpoints.

Authorization: Bearer <accessToken>
Content-Type: application/json
3

Renew silently before expiry POST /integration/v1/auth/renew

The accessToken is short-lived. Renew it using the renewToken — ideally ~2 minutes before the JWT's exp claim.

POST https://integration.tagora.com.mx/integration/v1/auth/renew
Content-Type: application/json

{
  "renewToken": "eyJhbGci..."
}

// 200 OK — same envelope as login
{
  "data": {
    "accessToken": "eyJhbGci...",
    "renewToken":  "eyJhbGci...",  // may rotate — always update your copy
    "expiresIn":   3600
  },
  "requestId": "b5c6d7e8-..."
}
Retry policy — on network error, retry with exponential backoff (5s, 10s, 15s). After 3 failures, treat the session as expired and redirect to login.

4

List your organization's devices GET /integration/v1/devices

Returns all devices belonging to the caller's organization. The response is automatically org-scoped — you can never see another org's devices.

GET https://integration.tagora.com.mx/integration/v1/devices?limit=100&offset=0
Authorization: Bearer <accessToken>

// 200 OK — response.data is an array
{
  "data": [
    {
      "deviceId":       "uuid-...",
      "serial":         "GT06-XXXX",
      "deviceName":     "Vehicle 01",
      "assetId":        "uuid-...",    // use this as the live-stream identifier
      "organizationId": "uuid-...",
      "status":         "active",
      "createdAt":      "2025-01-15T10:00:00Z"
    }
  ],
  "requestId": "c9d0e1f2-..."
}

Paginate with limit (max 10000) and offset. Filter by status with ?status=active.


5

Create a webhook POST /integration/v1/webhook

Register a URL where Tagora will POST your organization's live telemetry. The API validates the shape of postUrl and blocks bare private IPs — it does not call it itself.

POST https://integration.tagora.com.mx/integration/v1/webhook
Authorization: Bearer <accessToken>
Content-Type: application/json

{
  "organizationId": 42,
  "userId":         7,
  "postUrl":        "https://your-server.com/tagora/events",
  "name":           "Prod webhook"
}

// 201 Created — read from response.data
{
  "data": {
    "webhookId":    "uuid-...",
    "publicKey":    "-----BEGIN PUBLIC KEY-----\n...",  // verify signatures here
    "keyAlgorithm": "ed25519",
    "isActive":     true,
    "postUrl":      "https://your-server.com/tagora/events"
  },
  "requestId": "d1e2f3a4-..."
}
Signature verification — every delivery from Tagora is signed. Use the publicKey from the webhook response to verify the X-Tagora-Signature header on incoming POSTs.
6

Check what's in scope GET /integration/v1/webhook/{id}/scope

Returns the exact set of deviceId / serial / assetId triples whose data can flow through a specific webhook. Derived live — updates automatically when devices are added or removed from the org.

GET https://integration.tagora.com.mx/integration/v1/webhook/123/scope
Authorization: Bearer <accessToken>

// 200 OK
{
  "data": {
    "webhookId":      "uuid-...",
    "organizationId": "uuid-...",
    "serials":        ["GT06-001", "GT06-002"],
    "assetIds":       ["uuid-a", "uuid-b"],
    "items": [
      { "deviceId": "uuid-...", "serial": "GT06-001", "assetId": "uuid-a" }
    ]
  },
  "requestId": "e5f6a7b8-..."
}

!

Token lifecycle summary

POST /login
accessToken
short-lived JWT
+
renewToken
persist in sessionStorage
2 min before exp
POST /renew
new accessToken

Read the JWT exp claim to know when the token expires. Schedule renewal ~2 minutes early. If renewal fails, retry with exponential backoff (5s → 10s → 15s); after 3 failures, send the user back to login.