> ## Documentation Index
> Fetch the complete documentation index at: https://na-36-changelog-go-livepeer-2026-05-18.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# APIs

> Livepeer API reference: Studio REST API, AI Gateway API, authentication, base URLs, and OpenAPI spec location.

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 CustomDivider = ({color = "var(--lp-color-border-default)", middleText = "", spacing = "default", style = {}, className = "", ...rest}) => {
  const spacingPresets = {
    default: {
      margin: "24px 0"
    },
    overlap: {
      margin: "-1rem 0 -1rem 0"
    },
    tight: {
      margin: "0 0 -1rem 0"
    },
    section: {
      margin: "0 0 -2rem 0"
    },
    sectionOverlap: {
      margin: "-1rem 0 -2rem 0"
    },
    deepOverlap: {
      margin: "-1rem 0 -1.5rem 0"
    }
  };
  const spacingStyle = spacingPresets[spacing] || spacingPresets.default;
  return <div role="separator" aria-orientation="horizontal" className={className} style={{
    display: "flex",
    alignItems: "center",
    ...spacingStyle,
    fontSize: style?.fontSize || "16px",
    height: "fit-content",
    ...style
  }} {...rest}>
      <span style={{
    marginRight: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
      </span>
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      {middleText && <>
          <Icon icon="circle" size={2} />
          <span style={{
    margin: "0 8px",
    fontWeight: "bold",
    color: color,
    opacity: 0.7
  }}>
            {middleText}
          </span>
          <Icon icon="circle" size={2} />
        </>}
      <div style={{
    flex: 1,
    height: "1px",
    background: "var(--lp-color-border-default)",
    opacity: 0.4
  }}></div>
      <span style={{
    marginLeft: "var(--lp-spacing-px-8)",
    opacity: 0.2
  }}>
        <span style={{
    display: "inline-block",
    transform: "scaleX(-1)"
  }}>
          <Icon icon="/snippets/assets/logos/Livepeer-Logo-Symbol-Theme.svg" />
        </span>
      </span>
    </div>;
};

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>;
};

<CenteredContainer preset="readable90">
  <Tip>Two distinct APIs exist: the Studio REST API (streams, assets, webhooks) and the AI Gateway API (inference pipelines). They share the same authentication method but have separate base URLs and OpenAPI specs.</Tip>
</CenteredContainer>

***

<CustomDivider middleText="Studio REST API" />

## Studio REST API

**Base URL:** `https://livepeer.studio/api`

**Authentication:** `Authorization: Bearer <api-key>`

**OpenAPI spec:** Available at [https://livepeer.studio/api-reference](https://livepeer.studio/api-reference) (interactive) and as a downloadable JSON spec from the Studio dashboard under Developer > API Reference.

### Resource endpoints

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Resource</TableCell>
      <TableCell header>Base path</TableCell>
      <TableCell header>Key operations</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Streams**</TableCell>
      <TableCell>`/api/stream`</TableCell>
      <TableCell>POST (create), GET /:id, PATCH /:id, DELETE /:id, GET (list)</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Assets**</TableCell>
      <TableCell>`/api/asset`</TableCell>
      <TableCell>POST /request-upload, GET /:id, PATCH /:id, DELETE /:id, GET (list)</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Webhooks**</TableCell>
      <TableCell>`/api/webhook`</TableCell>
      <TableCell>POST (create), GET /:id, PUT /:id, DELETE /:id, POST /:id/resend</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Signing keys**</TableCell>
      <TableCell>`/api/access-control/signing-key`</TableCell>
      <TableCell>POST (create), GET (list), DELETE /:id</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Multistream targets**</TableCell>
      <TableCell>`/api/multistream/target`</TableCell>
      <TableCell>POST (create), GET /:id, PUT /:id, DELETE /:id</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Sessions**</TableCell>
      <TableCell>`/api/session`</TableCell>
      <TableCell>GET /:id, GET (list by stream)</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

### Rate limits

Rate limits are per API key and visible in the Studio dashboard under **Settings > API Keys**. The default limits for the Growth tier are sufficient for most production applications. Contact support for Enterprise rate limit increases.

<CustomDivider middleText="AI Gateway API" />

## AI Gateway API

**Base URL (Studio-managed, production):** `https://livepeer.studio/api/beta/generate`

**Base URL (public, non-production):** `https://dream-gateway.livepeer.cloud`

**Authentication:** `Authorization: Bearer <api-key>` (same Studio API key)

**Content type:** `application/json` for text payloads; `multipart/form-data` for file uploads (image-to-image, upscale, segment-anything-2, audio-to-text, image-to-text)

### Inference endpoints

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Pipeline</TableCell>
      <TableCell header>Endpoint</TableCell>
      <TableCell header>Input</TableCell>
      <TableCell header>Min VRAM</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Text to image**</TableCell>
      <TableCell>`POST /text-to-image`</TableCell>
      <TableCell>JSON: `prompt`, `model_id`, `width`, `height`, `negative_prompt`, `guidance_scale`, `num_inference_steps`</TableCell>
      <TableCell>24 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Image to image**</TableCell>
      <TableCell>`POST /image-to-image`</TableCell>
      <TableCell>multipart: `image` (file), `prompt`, `model_id`, `strength`</TableCell>
      <TableCell>20 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Image to video**</TableCell>
      <TableCell>`POST /image-to-video`</TableCell>
      <TableCell>multipart: `image` (file), `model_id`, `width`, `height`, `fps`, `motion_bucket_id`</TableCell>
      <TableCell>24 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Image to text**</TableCell>
      <TableCell>`POST /image-to-text`</TableCell>
      <TableCell>multipart: `image` (file), `model_id`, `prompt`</TableCell>
      <TableCell>4 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Audio to text**</TableCell>
      <TableCell>`POST /audio-to-text`</TableCell>
      <TableCell>multipart: `audio` (file), `model_id`, `language`</TableCell>
      <TableCell>12 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Text to speech**</TableCell>
      <TableCell>`POST /text-to-speech`</TableCell>
      <TableCell>JSON: `text`, `model_id`, `voice`</TableCell>
      <TableCell>12 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Upscale**</TableCell>
      <TableCell>`POST /upscale`</TableCell>
      <TableCell>multipart: `image` (file), `model_id`, `prompt`</TableCell>
      <TableCell>24 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Segment Anything 2**</TableCell>
      <TableCell>`POST /segment-anything-2`</TableCell>
      <TableCell>multipart: `image` (file), `model_id`, `point_coords`, `point_labels`</TableCell>
      <TableCell>6 GB</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**LLM**</TableCell>
      <TableCell>`POST /llm`</TableCell>
      <TableCell>JSON: OpenAI-compatible `messages` array, `model`</TableCell>
      <TableCell>8 GB</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

### Common response shape

All image-output pipelines return:

```json theme={null}
{
  "images": [
    {
      "url": "https://...",
      "seed": 42,
      "nsfw": false
    }
  ]
}
```

Text pipelines (`llm`, `audio-to-text`, `image-to-text`) return:

```json theme={null}
{ "text": "..." }
```

The LLM pipeline returns an OpenAI-compatible `choices` array in addition to the `text` field.

### OpenAPI spec

The AI Gateway OpenAPI spec is generated from the `ai-runner` repository via `gen_openapi.py` and output as `openapi_gateway.json`. The spec is used to auto-generate all three AI SDK language variants.

The live interactive reference for the AI API is mounted in the Gateways tab documentation at `/v2/gateways/resources/reference/technical/api-reference/AI-API/ai`.

<CustomDivider />

## Related pages

<CardGroup cols={2}>
  <Card title="SDKs" icon="code" href="/v2/developers/resources/reference/sdks">
    Official SDK packages for TypeScript, Python, Go, and React.
  </Card>

  <Card title="SDK Integration Guide" icon="laptop-code" href="/v2/developers/build/sdk-gateway">
    Full examples, error handling, and retry configuration.
  </Card>

  <Card title="AI Authentication" icon="lock" href="/v2/developers/guides/ai/authentication">
    API key types and how to use them correctly.
  </Card>
</CardGroup>
