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

# BYOC Overview

> How Bring Your Own Compute (BYOC) containers integrate with Livepeer orchestrators: the HTTP contract, capability registration, and payment flow.

export const TableCell = ({children, align = "left", header = false, style = {}, className = "", ...rest}) => {
  const Component = header ? "th" : "td";
  return <Component className={className} style={{
    padding: "0.75rem 1rem",
    textAlign: align,
    border: header ? "none" : "1px solid var(--lp-color-border-default)",
    ...style
  }} {...rest}>
      {children}
    </Component>;
};

export const TableRow = ({children, header = false, hover = false, style = {}, className = "", ...rest}) => {
  const rowId = `table-row-${Math.random().toString(36).substr(2, 9)}`;
  return <>
      {hover && <style>{`
          #${rowId}:hover {
            background-color: var(--lp-color-bg-card);
          }
        `}</style>}
      <tr id={rowId} className={className} style={{
    ...header && ({
      backgroundColor: "var(--lp-color-accent-strong)",
      color: "var(--lp-color-on-accent)",
      fontWeight: "bold"
    }),
    ...style
  }} {...rest}>
        {children}
      </tr>
    </>;
};

export const StyledTable = ({children, variant = "default", style = {}, className = "", ...rest}) => {
  const wrapperVariants = {
    default: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "var(--lp-color-bg-card)",
      overflow: "hidden"
    },
    bordered: {
      border: "2px solid var(--lp-color-accent)",
      backgroundColor: "var(--lp-color-bg-page)",
      overflow: "hidden"
    },
    minimal: {
      border: "none",
      backgroundColor: "transparent",
      overflow: "visible"
    }
  };
  return <div data-docs-styled-table-shell className={className} style={{
    width: "100%",
    padding: 0,
    margin: 0,
    ...wrapperVariants[variant],
    ...style
  }} {...rest}>
      <table data-docs-styled-table style={{
    width: "100%",
    borderCollapse: "collapse",
    borderSpacing: 0,
    margin: 0,
    backgroundColor: "transparent"
  }}>
        {children}
      </table>
    </div>;
};

export const CenteredContainer = ({children, maxWidth = "800px", padding = "0", preset = "default", width = "", minWidth = "", marginRight = "", marginBottom = "", textAlign = "", style = {}, className = "", ...rest}) => {
  const presets = {
    default: {},
    fitContent: {
      width: "fit-content",
      minWidth: "fit-content"
    },
    readable70: {
      width: "70%",
      minWidth: "fit-content"
    },
    readable80: {
      width: "80%",
      minWidth: "fit-content"
    },
    readable90: {
      width: "90%"
    },
    wide900: {
      maxWidth: "900px"
    }
  };
  const presetStyle = presets[preset] || presets.default;
  return <div className={className} style={{
    maxWidth: presetStyle.maxWidth || maxWidth,
    margin: "0 auto",
    padding: padding,
    ...presetStyle.width ? {
      width: presetStyle.width
    } : {},
    ...presetStyle.minWidth ? {
      minWidth: presetStyle.minWidth
    } : {},
    ...width ? {
      width
    } : {},
    ...minWidth ? {
      minWidth
    } : {},
    ...marginRight ? {
      marginRight
    } : {},
    ...marginBottom ? {
      marginBottom
    } : {},
    ...textAlign ? {
      textAlign
    } : {},
    ...style
  }} {...rest}>
      {children}
    </div>;
};

export const LinkArrow = ({href, label, description, newline = true, borderColor, className = '', style = {}, ...rest}) => {
  const linkArrowStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: "var(--lp-spacing-1)",
    width: 'fit-content',
    ...borderColor && ({
      borderColor
    })
  };
  return <span className={className} style={style} {...rest}>
      {newline && <br />}
      <span style={linkArrowStyle}>
        <a href={href} target="_blank" rel="noopener noreferrer">
          {label}
        </a>
        <Icon icon="arrow-up-right" size={14} color="var(--lp-color-accent)" />
      </span>
      {description && description}
      {description && <div style={{
    height: "var(--lp-spacing-3)"
  }} />}
    </span>;
};

<CenteredContainer preset="readable90">
  <Tip>BYOC lets you run any Python or Go inference service as a Livepeer pipeline. Your container exposes an HTTP endpoint; the Orchestrator handles capability advertisement, job routing, and payment settlement.</Tip>
</CenteredContainer>

***

BYOC (Bring Your Own Compute) is the mechanism for registering custom inference containers with a Livepeer Orchestrator. The Orchestrator discovers and routes jobs to BYOC containers through the same path as native `ai-runner` pipelines. Gateways select BYOC containers by their registered pipeline type and model ID via the AI Service Registry on-chain.

BYOC containers implement a small HTTP contract: a `/health` endpoint for liveness checks, and a pipeline-specific inference endpoint (e.g. `/live/video-to-video` or `/text-to-image`). The Orchestrator manages the trickle protocol transport, payment tickets, and capability advertisement.

<CustomDivider />

## HTTP Contract

Every BYOC container must expose:

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Endpoint</TableCell>
      <TableCell header>Method</TableCell>
      <TableCell header>Purpose</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>`/health`</TableCell>
      <TableCell>GET</TableCell>
      <TableCell>Returns `{"status": "ok"}` when the container is ready. Orchestrator polls this before routing jobs.</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>`/<pipeline>`</TableCell>
      <TableCell>POST</TableCell>
      <TableCell>Inference endpoint. For batch pipelines: accepts the request body, returns the result. For real-time pipelines: handled via trickle protocol by the Orchestrator.</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

For real-time pipelines (`live-video-to-video`), the container additionally exposes:

| Endpoint             | Method | Purpose                    |
| -------------------- | ------ | -------------------------- |
| `/api/stream/start`  | POST   | Start a processing session |
| `/api/stream/stop`   | POST   | Stop the active session    |
| `/api/stream/update` | POST   | Receive parameter updates  |
| `/api/stream/status` | GET    | Return session status      |

PyTrickle's `StreamServer` implements all four real-time endpoints automatically. See <LinkArrow href="/v2/developers/build/ai-and-agents/realtime-ai/pytrickle/overview" label="PyTrickle" newline={false} /> for the implementation pattern.

<CustomDivider />

## Registering with an Orchestrator

BYOC containers are registered in the Orchestrator's `aiModels.json` file. Each entry maps a pipeline type and model ID to a container URL:

```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
[
  {
    "pipeline": "live-video-to-video",
    "model_id": "comfystream",
    "url": "http://127.0.0.1:8188",
    "price_per_unit": 0,
    "warm": true
  },
  {
    "pipeline": "text-to-image",
    "model_id": "my-custom-diffusion",
    "url": "http://127.0.0.1:9000",
    "price_per_unit": 1000000,
    "warm": true
  }
]
```

Fields:

| Field            | Type    | Description                                                         |
| ---------------- | ------- | ------------------------------------------------------------------- |
| `pipeline`       | string  | Pipeline type identifier matching the AI worker pipeline names      |
| `model_id`       | string  | Model identifier advertised to Gateways via the AI Service Registry |
| `url`            | string  | HTTP address of the BYOC container                                  |
| `price_per_unit` | integer | Price in wei per unit of compute. 0 disables charging.              |
| `warm`           | boolean | Whether to advertise this as a warm capability on startup           |

After updating `aiModels.json`, restart the Orchestrator to pick up the new registration.

<CustomDivider />

## Network Discovery

Once registered, the Orchestrator advertises the BYOC capability to Gateways via the AI Service Registry smart contract on Arbitrum One. Gateways query the registry when routing `live-video-to-video` or batch pipeline jobs.

The capability is advertised as `pipeline/model_id`, e.g. `live-video-to-video/comfystream`. Gateways that specify a `model_id` in their request body will only route to Orchestrators advertising that model.

The network capability dashboard at `tools.livepeer.cloud/ai/network-capabilities` shows which BYOC capabilities are warm across the Active Set.

<CustomDivider />

## Payment Flow

BYOC containers receive the same probabilistic micropayment flow as native ai-runner pipelines. The Orchestrator validates payment tickets from the Gateway before forwarding jobs to the BYOC container. The BYOC container does not participate in payment logic directly; it receives jobs and returns results.

`price_per_unit` in `aiModels.json` sets the price the Orchestrator charges the Gateway per compute unit. For `live-video-to-video`, the unit is typically per-frame or per-second depending on Orchestrator configuration. For batch pipelines, pricing follows the same per-output-unit model as native pipelines.

<CustomDivider />

The [BYOC quickstart](/v2/developers/build/compute/byoc/byoc-quickstart) walks through the full cycle from FrameProcessor to registered network capability in 25 minutes.

## Related Pages

<CardGroup cols={2}>
  <Card title="BYOC Architecture" icon="diagram" href="/v2/developers/build/compute/byoc/byoc-architecture" arrow horizontal>
    Detailed container lifecycle, pipeline discovery, and the ai-runner integration.
  </Card>

  <Card title="BYOC Production" icon="server" href="/v2/developers/build/compute/byoc/byoc-production" arrow horizontal>
    Deploying BYOC containers at scale: resource management, error handling, monitoring.
  </Card>

  <Card title="ComfyStream as BYOC" icon="workflow" href="/v2/developers/build/ai-and-agents/realtime-ai/comfystream/comfystream-as-byoc" arrow horizontal>
    Worked example of registering a ComfyStream real-time pipeline as BYOC.
  </Card>

  <Card title="PyTrickle" icon="code" href="/v2/developers/build/ai-and-agents/realtime-ai/pytrickle/overview" arrow horizontal>
    Python SDK that implements the BYOC real-time container contract.
  </Card>
</CardGroup>
