---
title: "Attach the layer to a live stream"
method: POST
path: "/v1/streams"
tags: ["Live"]
---

# Attach the layer to a live stream

`POST /v1/streams`

## Request

- Base URL: `https://api.tryplayhead.com`
- URL: `https://api.tryplayhead.com/v1/streams`
- Auth: HTTP bearer

**Credits flow from this call until the event is stopped.** The recorder and the readings run continuously with no further calls, and nothing else in this API spends that way.

Two roads in. `road: "pull"` opens an address you own: a private HLS playlist, an RTSP camera, an SRT or RTMP address. `road: "push"` hands back an address and a stream key, and your encoder sends to us the way it sends to a platform.

`question` is the standing question: what you are watching the event for. It is set once and every minute is read against it. The rules of your sport or your show belong in it.

Afterwards, ask the ordinary way. `POST /v1/watch_video` with the event id answers about the event, and every answer says how far the recording has got.

## Request body

- AttachStreamRequest
  - `road` 'pull' | 'push': `pull` opens an address you own. `push` hands back an address and a stream key for your own encoder.
  - `url` string: The address of the stream, for a pull event. An HLS playlist, an RTSP camera, an SRT or RTMP address.
  - `protocol` 'rtmp' | 'srt': Which one a push event listens on.
  - `headers` object: Headers a private address expects. Stored, and used again every time the recorder reconnects.
  - `question` string: What you are watching this event for. Set once, and every minute is read against it.
  - `label` string: What this event is called.

## Response `201`

The event, and the ingest address when there is one.

- AttachStreamResult
  - `stream` Stream
    - `id` string
    - `video_id` string
    - `status` 'starting' | 'live' | 'ended' | 'failed'
    - `recorded_seconds` number: How far the recording has got. The duration of an event, and it grows while the event runs.
    - `recording` boolean
    - `road` 'pull' | 'push'
    - `source` string, nullable
    - `question` string, nullable
    - `pieces_recorded` integer
    - `readings_done` integer
    - `triggers_fired` integer
    - `disconnects` integer: How many times the source went away and came back.
    - `last_error` string, nullable
    - `created_at` string, date-time
    - `started_at` string, date-time, nullable
    - `ended_at` string, date-time, nullable
  - `stream_key` string, nullable: Shown once and never again, because only a hash is stored. Null for a pull event.
  - `ingest` object, nullable: Where an encoder sends, for a push event.
    - `rtmp` string
    - `srt` string
  - `note` string

## Other responses

- `400`: No address for a pull event, or one we must not open.
- `401`: Missing, malformed or expired credential.
- `402`: The balance does not cover a recording.

---

[API](https://skmtc.dev/tryplayhead/apis/playhead-api.md) · [All operations](https://skmtc.dev/tryplayhead/apis/playhead-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tryplayhead/apis/playhead-api/revisions/21dfb775b852?raw)
