> ## Documentation Index
> Fetch the complete documentation index at: https://docs.camb.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create an SRT Flow

> Create a stream flow: a standing SRT endpoint you can use as the source or a target of your streams.

## Overview

A **flow** is a standing SRT endpoint hosted by Camb.ai, independent of any
stream. Create one once, and use its URLs as the source or a target of any
number of streams, with no need to expose your own SRT infrastructure.

Flows come in two modes:

<Columns cols={2}>
  <Card title="Listener" icon="satellite-dish">
    Camb.ai hosts an SRT endpoint your encoder **pushes to**. You get one or
    two `push_urls` (primary/backup) and a `play_url` anyone with the key can
    pull from.
  </Card>

  <Card title="Caller" icon="phone-arrow-up-right">
    Camb.ai **pulls from your** SRT endpoint (`primary_url`) and re-serves it
    on a stable `play_url`, with optional failover to a `backup_url`.
  </Card>
</Columns>

## Using a flow with streams

The returned `play_url` is a normal SRT URL:

* **As a stream source** - set it as `source_stream.url` when
  [creating a stream](create-new-stream). Your encoder pushes to the flow's
  `push_urls`; the stream ingests from the flow.
* **As a stream target** - set it as a `target_streams[].url` with
  `"type": 1` to deliver your processed output to the flow, then distribute
  the flow's `play_url` to viewers or downstream systems.

<Tip>
  Set a `passphrase` (10–79 characters) to encrypt the flow's endpoint. It is
  embedded in the returned URLs and required to connect. To pull from an
  upstream that is itself encrypted (caller mode), append its passphrase to
  `primary_url` as a query parameter: `srt://host:port?passphrase=...`.
</Tip>

## Example: listener flow for a stadium encoder

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://client.camb.ai/apis/flows" \
    -H "x-api-key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "label": "stadium-encoder",
      "mode": "listener",
      "failover": true
    }'
  ```

  ```python Python theme={null}
  import requests

  payload = {
      "label": "stadium-encoder",
      "mode": "listener",
      "failover": True,
  }

  response = requests.post(
      "https://client.camb.ai/apis/flows",
      headers={"x-api-key": "YOUR_API_KEY"},
      json=payload,
  )

  response.raise_for_status()
  flow = response.json()
  print(flow["push_urls"])  # give these to your encoder
  print(flow["play_url"])   # use this as source_stream.url
  ```
</CodeGroup>

The response contains everything needed to use the flow:

<CodeGroup>
  ```json Response theme={null}
  {
    "id": 42,
    "label": "stadium-encoder",
    "mode": "listener",
    "failover": true,
    "active": true,
    "team_id": 7,
    "key": "k3yk3yk3yk3yk3yk3yk3yk3yk",
    "play_url": "srt://live.camb.ai:20121?streamid=play/42/k3yk3yk3yk3yk3yk3yk3yk3yk",
    "push_urls": [
      {
        "role": "primary",
        "url": "srt://live.camb.ai:20121?streamid=publish/42-primary/k3yk3yk3yk3yk3yk3yk3yk3yk"
      },
      {
        "role": "backup",
        "url": "srt://live.camb.ai:20121?streamid=publish/42-backup/k3yk3yk3yk3yk3yk3yk3yk3yk"
      }
    ],
    "passphrase": null
  }
  ```
</CodeGroup>

## Validation rules

* `label` must be unique within your team.
* `caller` mode requires `primary_url`; `listener` mode must not set URLs.
* `backup_url` requires `failover: true` (and is required for caller flows
  with failover).

## Errors

* `403` - Your subscription does not include streaming.
* `422` - Validation error (see the rules above).

## Related endpoints

* [List SRT Flows](list-flows)
* [Get an SRT Flow](get-flow)
* [Update an SRT Flow](update-flow)
* [Delete an SRT Flow](delete-flow)


## OpenAPI

````yaml post /flows
openapi: 3.1.0
info:
  title: FastAPI
  version: 0.1.0
servers:
  - url: https://client.camb.ai/apis
security: []
paths:
  /flows:
    post:
      tags:
        - Apis
        - Streaming
      summary: Create Flow
      description: >-
        Create a stream flow: a standing SRT endpoint, independent of any
        stream, that you can use as the source or a target of streams. In
        `listener` mode Camb.ai hosts an endpoint your encoder pushes to; in
        `caller` mode Camb.ai pulls from your upstream and re-serves it.
      operationId: create_flow_flows_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlowCreateIn'
            example:
              label: stadium-encoder
              mode: listener
              failover: true
      responses:
        '201':
          description: The created flow, including its play and push URLs.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FlowOut'
        '403':
          description: Your subscription does not include streaming.
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - APIKeyHeader: []
components:
  schemas:
    FlowCreateIn:
      type: object
      required:
        - label
        - mode
      title: FlowCreateIn
      description: >-
        Configuration for a new stream flow - a standing SRT endpoint you can
        use as the source or a target of any stream.
      properties:
        label:
          type: string
          title: Label
          description: Human-readable name for the flow. Must be unique within your team.
        mode:
          $ref: '#/components/schemas/FlowMode'
        failover:
          type: boolean
          default: false
          title: Failover
          description: >-
            Enable a second (backup) leg. Caller flows then require
            `backup_url`; listener flows get a backup push URL.
        primary_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Primary URL
          description: >-
            SRT URL of your upstream (caller mode only; required there,
            forbidden for listeners). To dial an encrypted upstream, append its
            passphrase as a query parameter: `srt://host:port?passphrase=...`.
        backup_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Backup URL
          description: >-
            SRT URL of the backup upstream. Caller mode with `failover` enabled
            only.
        passphrase:
          anyOf:
            - type: string
              minLength: 10
              maxLength: 79
            - type: 'null'
          title: Passphrase
          description: >-
            Optional SRT encryption passphrase for the flow's own endpoint
            (10-79 characters). When set, it is embedded in the returned
            play/push URLs and required to connect.
    FlowOut:
      type: object
      title: FlowOut
      properties:
        id:
          type: integer
          title: ID
          description: Flow identifier.
        label:
          type: string
          title: Label
        mode:
          $ref: '#/components/schemas/FlowMode'
        failover:
          type: boolean
          title: Failover
        active:
          type: boolean
          title: Active
          description: Whether the flow's relay is currently online.
        team_id:
          type: integer
          title: Team ID
        key:
          type: string
          title: Key
          description: Access key embedded in the flow's URLs.
        play_url:
          type: string
          title: Play URL
          description: >-
            SRT URL the flow serves. Use it as `source_stream.url` or as a
            `target_streams[].url`, or play it directly.
        push_urls:
          type: array
          items:
            $ref: '#/components/schemas/PushUrl'
          title: Push URLs
          description: SRT URLs to push into (listener mode). Empty for caller flows.
        passphrase:
          anyOf:
            - type: string
            - type: 'null'
          title: Passphrase
          description: The flow's SRT encryption passphrase, when one is set.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    FlowMode:
      type: string
      enum:
        - caller
        - listener
      title: FlowMode
      description: >-
        `caller`: Camb.ai connects out to your SRT endpoint (`primary_url`) and
        re-serves it. `listener`: Camb.ai hosts an SRT endpoint that your
        encoder pushes to.
    PushUrl:
      type: object
      title: PushUrl
      properties:
        role:
          type: string
          enum:
            - primary
            - backup
          title: Role
          description: Which leg of the flow this URL feeds.
        url:
          type: string
          title: URL
          description: SRT URL to push to.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        The `x-api-key` is a custom header required for authenticating requests
        to our API. Include this header in your request with the appropriate API
        key value to securely access our endpoints. You can find your API key(s)
        in the 'API' section of our studio website.

````