# Delivery networks and capabilities

Video has to travel from the venue's encoder to every viewer's phone over a delivery network. Vabu Streams sits in front of the network so that you write your code once. This page explains how to keep that code independent of the network.

## The provider field

Every live stream and asset has a read-only `provider` field. It names the network that carries that video. In test mode it is `simulated`.

```json
{ "id": "ls_01J9ZQ4M8T3K6Y2E5W7N0B1C9D", "object": "live_stream", "provider": "simulated" }
```

Show it in a log or a support screen if you like. Do not branch on it. When Vabu adds networks or moves an account, a check on the name would break and a check on a capability would not.

Today each account runs on one network that Vabu chooses for it. A second network can carry a live stream as a standby: see [Staying on air](https://docs.vabu.live/guides/streams/staying-on-air.md). Choosing a network by audience region, with Nairobi first, is on [What's coming](https://docs.vabu.live/whats-coming.md).

## Capabilities

A capability is something a network can do. Networks differ, so a few capabilities are not on every stream. Check the thing itself.

| You want to | How to know | If it is not there |
|---|---|---|
| Send video over SRT | `ingest.srt_url` is set | Use `rtmp_url` |
| Send video over WHIP from a browser | `ingest.whip_url` is set | Use RTMP or SRT from an encoder |
| Use a backup address | `ingest.rtmp_backup_url` is set | Rely on the reconnect window |
| Run an audio-only stream | Create the stream with `audio_only: true`. The response confirms it. | A `422 provider_rejected` error says why |
| Keep latency low | Create the stream with `latency_mode: "low"`. The response shows what you got. | Use `standard` |
| Forward to other platforms | `POST` a simulcast target. `status` on the target says if it was accepted. | Targets with `status: "errored"` were refused |
| Cut clips from an asset | `POST /v1/streams/assets/{id}/clips` | A `409 asset_not_ready` error means wait for `ready` |
| Sign playback tokens yourself | `POST /v1/streams/signing_keys` | `409 dedicated_environment_required` |

Two rules keep your code safe:

1. Read the response, not the plan. Look at the fields you got back and branch on them.
2. Treat a refusal as information. `422 provider_rejected` and `409` errors tell you what the network cannot do, in words you can show your team.

## Ordered sources

A playback grant returns `sources`, an ordered list of links, with a `failover` rule. Play the first, and switch after `failover.max_errors` fatal errors in `failover.window_seconds`. Today the list has one item. Write the switch now, and a second source will work the day it appears. See [playback and sessions](https://docs.vabu.live/concepts/playback-and-sessions.md).

## Vabu events, not network events

Networks send their own signals when an encoder connects or a file is ready. You never see them. Vabu turns them into its own events, such as `streams.live_stream.active` and `streams.asset.ready`, with the same shape whatever the network. See [stream events](https://docs.vabu.live/concepts/stream-events.md).
