Skip to content

API Reference

GraphQL API for stream management, key rotation, analytics, and all platform operations.

All API interactions are performed through a single GraphQL endpoint. This allows you to fetch exactly the data you need in a single request.

https://bridge.frameworks.network/graphql

Subscriptions use WebSocket:

wss://bridge.frameworks.network/graphql/ws

All operations go through this single endpoint. Queries read data, mutations change it.

Most requests need a token in the Authorization header:

Authorization: Bearer YOUR_JWT_OR_API_TOKEN

Get your API token from Developer → API in the dashboard.

The dashboard may authenticate via httpOnly cookies.
Public allowlist (no auth required): resolveViewerEndpoint, resolveIngestEndpoint, serviceInstancesHealth, networkStatus (queries only).

The dashboard has a built-in GraphQL explorer. Go to Developer → API to run queries against your account.

Or use any GraphQL client:

Here are the most frequent operations you’ll likely need when building your integration.

query {
streamsConnection(page: { first: 20 }) {
edges {
node {
id
name
playbackId
createdAt
metrics {
status
currentViewers
}
}
}
}
}

createStream creates a push-input live stream for RTMP/E-RTMP, SRT, or WHIP ingest. Most mutations return a union result. Always check __typename.

mutation {
createStream(input: { name: "My New Stream" }) {
__typename
... on Stream {
id
name
streamKey
playbackId
}
... on ValidationError {
message
field
}
... on AuthError {
message
}
}
}

The returned streamKey is secret and is used only for ingest. The returned playbackId is the public viewer identifier used by /play URLs and the FrameWorks Player.

For pull-input streams, set ingestMode: PULL and provide pullSource.sourceUri in CreateStreamInput; see Pull-input Streams.

query {
stream(id: "stream-global-id") {
id
name
streamKey
playbackId
record
metrics {
status
currentViewers
isLive
updatedAt
}
}
}
mutation {
createStreamKey(streamId: "stream-global-id", input: { name: "OBS Key" }) {
__typename
... on StreamKey {
id
keyValue
keyName
createdAt
}
... on ValidationError {
message
field
}
... on AuthError {
message
}
}
}

Analytics queries require you to specify a time range. Data is returned in aggregated form to help you visualize viewer engagement and usage.

query {
analytics {
usage {
streaming {
streamAnalyticsDailyConnection(
streamId: "stream-global-id"
timeRange: { start: "2024-01-01T00:00:00Z", end: "2024-01-07T00:00:00Z" }
page: { first: 30 }
) {
edges {
node {
day
totalViews
uniqueViewers
egressBytes
}
}
}
}
}
}
}

Note: analytics streamId filters use the Stream global ID (Stream.id). Responses return Relay IDs; use Stream.streamId for the public UUID used outside GraphQL.

When building a custom player, use the resolveViewerEndpoint query. This ensures your viewers are routed to the geographically closest and healthiest edge node for the best possible experience.

query {
resolveViewerEndpoint(contentId: "pk_your_playback_id") {
primary {
nodeId
baseUrl
protocol
url
geoDistance
loadScore
outputs
}
fallbacks {
nodeId
baseUrl
protocol
url
}
metadata {
status
isLive
viewers
title
description
contentId
contentType
}
}
}

Returns a primary endpoint (optimal for the viewer’s location) plus fallbacks. Use the primary endpoint first, fall back to others if it fails.

contentId is a playbackId for live streams, VOD uploads, clips, and DVR recordings (not the raw hash).

If the gateway can’t determine a viewer IP (for GeoIP routing), this query will error.

GraphQL errors come in the errors array. Mutation errors for unions are returned as typed objects (check __typename).

{
"data": null,
"errors": [
{
"message": "Stream not found",
"path": ["stream"],
"extensions": {
"code": "NOT_FOUND"
}
}
]
}

Common codes:

  • UNAUTHORIZED - Missing or invalid token
  • FORBIDDEN - Token lacks required permissions
  • NOT_FOUND - Resource doesn’t exist
  • VALIDATION_ERROR - Invalid input

The fastest way to build queries for your integration:

  1. API Explorer — Go to Developer → API in the dashboard. The built-in GraphQL explorer has full schema docs, autocompletion, and lets you run queries against your account. Copy working queries directly into your code.
  2. Ask Skipper — Tell Skipper what you want to do (e.g. “create a stream from Python” or “list my clips with curl”) and it will generate a working snippet in your language, using the live schema.

Both tools stay in sync with the actual schema, so the queries they produce always work.

The examples below show the general pattern for calling the API from common languages. For the exact query fields you need, use the API Explorer or ask Skipper.

curl:

Terminal window
curl -X POST https://bridge.frameworks.network/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"query": "{ streamsConnection(page: { first: 5 }) { edges { node { id name playbackId } } } }"}'

JavaScript (using graphql-request):

import { GraphQLClient, gql } from "graphql-request";
const client = new GraphQLClient("https://bridge.frameworks.network/graphql", {
headers: { Authorization: "Bearer YOUR_TOKEN" },
});
const data = await client.request(gql`
query {
streamsConnection(page: { first: 5 }) {
edges {
node {
id
name
playbackId
}
}
}
}
`);

Python (using httpx or requests):

import httpx
resp = httpx.post(
"https://bridge.frameworks.network/graphql",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={"query": "{ streamsConnection(page: { first: 5 }) { edges { node { id name playbackId } } } }"},
)
print(resp.json()["data"])

Go:

body, _ := json.Marshal(map[string]string{
"query": `{ streamsConnection(page: { first: 5 }) { edges { node { id name playbackId } } } }`,
})
req, _ := http.NewRequest("POST", "https://bridge.frameworks.network/graphql", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_TOKEN")
resp, _ := http.DefaultClient.Do(req)

FrameWorks does not publish a first-party GraphQL SDK yet. Use any GraphQL client in your language, or generate typed bindings from the schema.

The full schema is available via introspection:

{
__schema {
types {
name
description
}
}
}

Or use the dashboard’s API Explorer (Developer → API) which shows docs inline.