> ## 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.

# The Gateway Role in the Livepeer Network

> Learn how gateways connect applications to Livepeer, route video and AI workloads, and define the demand side of the network.

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 ScrollableDiagram = ({children, title = '', maxHeight = '500px', minWidth = '100%', showControls = false, className = '', style = {}, ...rest}) => {
  const buildDiagramKey = (currentTitle = '', currentClassName = '') => {
    const source = `${currentTitle}|${currentClassName}|scrollable-diagram`;
    let hash = 0;
    for (let index = 0; index < source.length; index += 1) {
      hash = hash * 31 + source.charCodeAt(index) >>> 0;
    }
    return `docs-diagram-${hash.toString(36)}`;
  };
  const diagramKey = buildDiagramKey(title, className);
  const zoomName = `${diagramKey}-zoom`;
  const zoomLevels = [{
    label: '75%',
    value: 0.75
  }, {
    label: '100%',
    value: 1
  }, {
    label: '125%',
    value: 1.25
  }, {
    label: '150%',
    value: 1.5
  }];
  const containerStyle = {
    overflow: 'auto',
    maxHeight,
    border: '1px solid var(--lp-color-border-default)',
    borderRadius: "8px",
    padding: "var(--lp-spacing-4)",
    background: 'var(--lp-color-bg-card)',
    position: 'relative'
  };
  return <div className={className} style={{
    position: 'relative',
    marginBottom: "var(--lp-spacing-4)",
    ...style
  }} {...rest}>
      {title && <p style={{
    textAlign: 'center',
    fontStyle: 'italic',
    color: 'var(--lp-color-text-secondary)',
    marginBottom: "var(--lp-spacing-2)",
    fontSize: '0.875rem'
  }}>
          {title}
        </p>}

      {showControls ? <style>{`
          [data-docs-diagram-key="${diagramKey}"] [data-docs-diagram-content] {
            transform: scale(1);
            transform-origin: top left;
            width: max-content;
          }
          ${zoomLevels.map(zoomLevel => `
          #${diagramKey}-${zoomLevel.label.replace('%', '')}:checked ~ [data-docs-diagram-shell] [data-docs-diagram-content] {
            transform: scale(${zoomLevel.value});
          }
          #${diagramKey}-${zoomLevel.label.replace('%', '')}:checked ~ [data-docs-diagram-controls] label[for="${diagramKey}-${zoomLevel.label.replace('%', '')}"] {
            background: var(--lp-color-accent);
            color: var(--lp-color-on-accent);
            border-color: var(--lp-color-accent);
          }`).join('\n')}
        `}</style> : null}

      {showControls ? zoomLevels.map(zoomLevel => {
    const inputId = `${diagramKey}-${zoomLevel.label.replace('%', '')}`;
    return <input key={inputId} id={inputId} type="radio" name={zoomName} defaultChecked={zoomLevel.value === 1} style={{
      position: 'absolute',
      opacity: 0,
      pointerEvents: 'none'
    }} />;
  }) : null}

      <div data-docs-diagram-key={diagramKey} data-docs-diagram-shell style={containerStyle}>
        <div data-docs-diagram-content style={{
    minWidth,
    transformOrigin: 'top left',
    width: 'max-content'
  }}>
          {children}
        </div>
      </div>

      {showControls ? <div data-docs-diagram-controls style={{
    display: 'flex',
    justifyContent: 'flex-end',
    alignItems: 'center',
    gap: "var(--lp-spacing-2)",
    marginTop: "var(--lp-spacing-2)",
    flexWrap: 'wrap'
  }}>
          <span style={{
    fontSize: "0.75rem",
    color: 'var(--lp-color-text-muted)',
    marginRight: 'auto'
  }}>
            Scroll to pan
          </span>
          {zoomLevels.map(zoomLevel => {
    const inputId = `${diagramKey}-${zoomLevel.label.replace('%', '')}`;
    return <label key={inputId} htmlFor={inputId} style={{
      background: 'transparent',
      color: 'var(--lp-color-text-secondary)',
      border: '1px solid var(--lp-color-border-default)',
      borderRadius: "4px",
      padding: '4px 10px',
      cursor: 'pointer',
      fontSize: "0.75rem",
      fontWeight: '600'
    }}>
                {zoomLevel.label}
              </label>;
  })}
        </div> : null}
    </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 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 maxWidth="1100px">
  <AccordionGroup>
    <Accordion title="From a Cloud Background?" icon="cloud">
      A Gateway fills the same role as a cloud API gateway or L7 load balancer.
      It ingests traffic, routes workloads to backend GPU nodes, and manages
      session flow while Orchestrators perform the compute.

      <ScrollableDiagram title="Gateway as Cloud Infrastructure">
        ```mermaid theme={"theme":{"light":"github-light","dark":"dark-plus"}}
        %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#18794E', 'primaryTextColor': '#fff', 'primaryBorderColor': '#3CB540', 'lineColor': '#3CB540', 'mainBkg': '#18794E', 'nodeBorder': '#3CB540', 'clusterBkg': 'transparent', 'clusterBorder': '#3CB540', 'titleColor': '#3CB540', 'edgeLabelBackground': 'transparent', 'textColor': '#3CB540', 'nodeTextColor': '#fff'}}}%%
        flowchart LR
            subgraph Clients["Client / Application Layer"]
                A["Apps & SDKs<br/>• Video Ingest<br/>• AI Inference Requests<br/>• WebRTC / HTTP"]
            end

            subgraph Gateway["Gateway Layer (Livepeer Gateway)"]
                B["Gateway Node<br/><br/>Cloud Analogy:<br/>• API Gateway<br/>• L7 Load Balancer<br/>• Control Plane<br/><br/>Responsibilities:<br/>• Auth & Rate Limits<br/>• Stream Segmentation<br/>• Job Routing<br/>• Health Checks<br/>• Retry & Failover"]
            end

            subgraph Compute["Compute Layer (Supply Side)"]
                C["Orchestrators<br/>GPU Workers<br/><br/>Cloud Analogy:<br/>• Auto-scaling GPU Fleet<br/>• Managed Inference Pool"]
            end

            subgraph Settlement["Coordination & Settlement"]
                D["Ethereum + Livepeer Protocol<br/><br/>• Payments<br/>• Accounting<br/>• Slashing / Security"]
            end

            A -->|Requests| B
            B -->|Dispatch Jobs| C
            C -->|Results / Streams| B
            B -->|Responses| A
            C -->|Usage & Proof| D

            classDef default fill:#1a1a1a,color:#fff,stroke:#2d9a67,stroke-width:2px
            style Clients fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Gateway fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Compute fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Settlement fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
        ```
      </ScrollableDiagram>
    </Accordion>

    <Accordion title="From an Ethereum Background?" icon="coin">
      A Gateway plays the workload-routing role in the network.
      The closest Ethereum analogue is an L2 sequencer: it ingests requests,
      orders execution, selects Orchestrators, and forwards jobs into the compute layer.

      <ScrollableDiagram title="Gateways as L2 Sequencers">
        ```mermaid theme={"theme":{"light":"github-light","dark":"dark-plus"}}
        %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#18794E', 'primaryTextColor': '#fff', 'primaryBorderColor': '#3CB540', 'lineColor': '#3CB540', 'mainBkg': '#18794E', 'nodeBorder': '#3CB540', 'clusterBkg': 'transparent', 'clusterBorder': '#3CB540', 'titleColor': '#3CB540', 'edgeLabelBackground': 'transparent', 'textColor': '#3CB540', 'nodeTextColor': '#fff'}}}%%
        flowchart LR
            subgraph User["User Layer"]
                A["Client<br/>Video/AI Request"]
            end

            subgraph Gateway["Gateway Layer"]
                B["Livepeer Gateway<br/>= L2 Sequencer<br/><br/>• Ingests Requests<br/>• Segments/Preprocesses<br/>• Selects Orchestrators<br/>• Routes Jobs<br/>• Returns Results"]
            end

            subgraph Compute["Compute Layer"]
                C["Orchestrators<br/>GPU Workers<br/><br/>= L2 Execution Layer"]
            end

            subgraph Settlement["Settlement Layer"]
                D["Ethereum<br/>Consensus & Payment Security"]
            end

            A --> B
            B --> C
            C --> B
            B --> A
            C --> D

            classDef default fill:#1a1a1a,color:#fff,stroke:#2d9a67,stroke-width:2px
            style User fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Gateway fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Compute fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Settlement fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
        ```
      </ScrollableDiagram>
    </Accordion>

    <Accordion title="Neither? You can still run a gateway!" icon="film">
      A Gateway operator plays the producer role for a compute job.
      The Gateway takes the request, selects the specialists, manages constraints,
      and delivers the result on time.

      <ScrollableDiagram title="Gateway as Film Producer">
        ```mermaid theme={"theme":{"light":"github-light","dark":"dark-plus"}}
        %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#18794E', 'primaryTextColor': '#fff', 'primaryBorderColor': '#3CB540', 'lineColor': '#3CB540', 'mainBkg': '#18794E', 'nodeBorder': '#3CB540', 'clusterBkg': 'transparent', 'clusterBorder': '#3CB540', 'titleColor': '#3CB540', 'edgeLabelBackground': 'transparent', 'textColor': '#3CB540', 'nodeTextColor': '#fff'}}}%%
        flowchart LR
            subgraph Persona["Persona: Gateway Operator = Film Producer"]
                P["Film Producer Mindset<br/>• Owns delivery<br/>• Sets constraints<br/>• Chooses specialists<br/>• Ensures quality"]
            end

            subgraph Request["Act I - The Pitch"]
                A["Incoming Request<br/>• Live Video Stream<br/>• AI Inference Job<br/>• Quality & Latency Requirements"]
            end

            subgraph Planning["Act II - Pre-Production"]
                B["Gateway (Producer)<br/><br/>• Interpret the request<br/>• Set budget & latency constraints<br/>• Choose specialists<br/>• Plan execution"]
            end

            subgraph Crew["Act III - Production Crew"]
                C["Orchestrators / GPU Workers<br/><br/>• Transcoding<br/>• AI Inference<br/>• Real-time Processing"]
            end

            subgraph Delivery["Act IV - Final Cut & Release"]
                D["Verified Output<br/>• Stream / AI Result<br/>• Quality checked<br/>• Delivered on time"]
            end

            subgraph Settlement["Credits & Accounting"]
                E["Onchain Settlement<br/>• Usage recorded<br/>• Payments distributed<br/>• Trust enforced"]
            end

            P --> A
            A --> B
            B --> C
            C --> B
            B --> D
            C --> E

            classDef default fill:#1a1a1a,color:#fff,stroke:#2d9a67,stroke-width:2px
            style Persona fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Request fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Planning fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Crew fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Delivery fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
            style Settlement fill:#0d0d0d,stroke:#2d9a67,stroke-width:1px
        ```
      </ScrollableDiagram>
    </Accordion>
  </AccordionGroup>
</CenteredContainer>

<CenteredContainer maxWidth="960px">
  <Tip>Gateways sit between applications and Orchestrators. They are the demand side of the network, and application developers connect through the Gateway layer for video, AI inference, and real-time AI workloads.</Tip>
</CenteredContainer>

<CustomDivider />

In the early days of Livepeer, Gateways (then called **broadcasters**) had a single job: send video streams to Orchestrators for transcoding.

Today, with the off-chain Gateway operational mode shipped in Q4 2025, the role has expanded dramatically. Gateways now route AI inference, live video AI, LLM requests, and custom BYOC workloads - often with **zero ETH required**. The Gateway is where business logic, customer relationships, and service margins live.

<ScrollableDiagram title="Gateway Role Evolution" maxHeight="420px">
  ```mermaid theme={"theme":{"light":"github-light","dark":"dark-plus"}}
  %%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#18794E', 'primaryTextColor': '#fff', 'primaryBorderColor': '#3CB540', 'lineColor': '#3CB540', 'mainBkg': '#18794E', 'nodeBorder': '#3CB540', 'clusterBkg': 'transparent', 'clusterBorder': '#3CB540', 'titleColor': '#3CB540', 'edgeLabelBackground': 'transparent', 'textColor': '#3CB540', 'nodeTextColor': '#fff'}}}%%
  timeline
      2017-2024 : Broadcaster era
                 : RTMP video ingest
                 : On-chain only
                 : ETH deposit required
      Q4 2025   : Remote signer ships
                 : Off-chain operational mode
                 : Zero ETH at gateway layer
                 : Python SDK viable
      Today     : Unified gateway role
                 : Video + AI + BYOC
                 : Platform business layer
                 : NaaP multi-tenancy
  ```
</ScrollableDiagram>

<CustomDivider />

## Technical Role

A Gateway is a **demand aggregation and routing layer**. It accepts workloads from applications, selects the best Orchestrator for each job, handles payment, and returns results while Orchestrators perform GPU compute.

Core responsibilities:

* **Job intake**  - receive video streams (RTMP) or AI inference requests (HTTP API)
* **Orchestrator selection**  - match jobs to capable Orchestrators by capability, price, and latency
* **Payment handling**  - generate probabilistic micropayment tickets (or delegate to a remote signer)
* **Result delivery**  - return transcoded video (HLS) or inference results to the application

See <LinkArrow href="/v2/gateways/concepts/capabilities" label="Gateway Capabilities" newline={false} /> for the workload matrix and routing details.

<CustomDivider />

## Business Role

Gateways earn at the **business layer**. The Gateway operator sets customer pricing, the protocol constrains Orchestrator payments, and the difference becomes the operator's margin.

This makes Gateways uniquely positioned as the product layer of the Livepeer Network:

* **Pricing control**  - set your own rates independently of network pricing
* **Customer relationships**  - API keys, auth, SLAs, support  - all at the Gateway layer
* **Middleware and product logic**  - billing, rate limiting, Orchestrator tiering, custom routing
* **Platform building**  - the NaaP (Network as a Platform) model wraps Livepeer as a managed service

```mermaid theme={"theme":{"light":"github-light","dark":"dark-plus"}}
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#18794E', 'primaryTextColor': '#fff', 'primaryBorderColor': '#3CB540', 'lineColor': '#3CB540', 'mainBkg': '#18794E', 'nodeBorder': '#3CB540', 'clusterBkg': 'transparent', 'clusterBorder': '#3CB540', 'titleColor': '#3CB540', 'edgeLabelBackground': 'transparent', 'textColor': '#3CB540', 'nodeTextColor': '#fff'}}}%%
flowchart LR
    A["Your customers"] -->|"Pay your rate"| B["Your gateway"]
    B -->|"Pay network rate"| C["Orchestrators"]
    B -->|"Keep margin"| D["Your revenue"]

    classDef default fill:#1a1a1a,color:#fff,stroke:#2d9a67,stroke-width:2px
```

See <LinkArrow href="/v2/gateways/concepts/business-model" label="Gateway Business Model" newline={false} /> for revenue models, cost structures, and the four operator models.

<CustomDivider />

## Network Role

Gateways are the **demand side** of the Livepeer marketplace. Where Orchestrators provide compute supply, Gateways aggregate application demand and broker access to that supply.

* **Capability discovery**  - query the network for Orchestrators that support specific pipelines, models, or GPU types
* **Marketplace participation**  - select Orchestrators based on price, performance, and reliability
* **Application bridge**  - translate application-level requests into protocol-level operations
* **Ecosystem growth**  - every new Gateway adds demand capacity to the network

<Note>
  Gateways participate in the network as demand-side actors. Orchestrators handle staking, protocol rewards, and governance.
</Note>

See <LinkArrow href="/v2/gateways/concepts/architecture" label="Gateway Architecture" newline={false} /> for how Gateways connect to the protocol and Orchestrator network.

<CustomDivider />

## Operational Mode

On-chain and off-chain describe your Gateway's **operational mode**: how it handles payment operations and Orchestrator discovery. All workloads run on Orchestrator GPU hardware. The distinction is between local ticket signing and delegated remote signing.

<Tabs>
  <Tab title="On-chain gateway" icon="link">
    Your Gateway holds ETH on Arbitrum and generates probabilistic micropayment tickets directly. This is the original operational mode. Required for video transcoding; also supports AI inference.

    * **Payment:** Gateway signs tickets locally using its own ETH deposit + reserve
    * **ETH required:** Yes - deposit (\~0.065 ETH) + reserve (\~0.03 ETH) on Arbitrum
    * **Crypto knowledge:** Wallet, keystore, Arbitrum bridging
    * **OS support:** Linux, Windows, macOS
    * **Setup time:** Hours (wallet setup, bridging, funding)
    * **Workloads:** Video transcoding, AI inference, or both
  </Tab>

  <Tab title="Off-chain gateway" icon="cloud">
    Shipped Q4 2025 via remote signing (PRs #3791, #3822). Your Gateway holds no ETH - a remote signer handles all payment operations on your behalf.

    * **Payment:** Remote signer generates tickets; your Gateway sends no on-chain transactions
    * **ETH required:** No - zero at the Gateway layer
    * **Crypto knowledge:** None required
    * **OS support:** Linux only
    * **Setup time:** Minutes (Docker command, point at remote signer)
    * **Workloads:** AI inference, LLM, live AI, audio, BYOC
  </Tab>
</Tabs>

<Note>
  An on-chain Gateway can run video, AI, or both workloads. Dual-workload configuration runs both from a single on-chain Gateway node; it is not a third operational mode. See <LinkArrow href="/v2/gateways/setup/configure" label="Dual gateway configuration" newline={false} /> for setup details.
</Note>

<StyledTable variant="bordered">
  <thead>
    <TableRow header>
      <TableCell header>Factor</TableCell>
      <TableCell header>On-chain Gateway</TableCell>
      <TableCell header>Off-chain Gateway</TableCell>
    </TableRow>
  </thead>

  <tbody>
    <TableRow>
      <TableCell>**Payment method**</TableCell>
      <TableCell>Gateway signs tickets locally</TableCell>
      <TableCell>Remote signer handles payments</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**ETH required**</TableCell>
      <TableCell>\~0.095 ETH on Arbitrum</TableCell>
      <TableCell>None</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Crypto knowledge**</TableCell>
      <TableCell>Wallet, keystore, bridging</TableCell>
      <TableCell>None required</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**OS**</TableCell>
      <TableCell>Linux, Windows, macOS</TableCell>
      <TableCell>Linux only</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Ingest protocol**</TableCell>
      <TableCell>RTMP (port 1935) and/or HTTP API (port 8935)</TableCell>
      <TableCell>HTTP API (port 8935)</TableCell>
    </TableRow>

    <TableRow>
      <TableCell>**Time to first job**</TableCell>
      <TableCell>Hours</TableCell>
      <TableCell>Minutes</TableCell>
    </TableRow>
  </tbody>
</StyledTable>

## Related Pages

<CardGroup cols={2}>
  <Card title="Gateway Capabilities" icon="gears" href="/v2/gateways/concepts/capabilities" arrow horizontal>
    Workload types, supported pipelines, and what Gateways can route.
  </Card>

  <Card title="Gateway Architecture" icon="diagram-project" href="/v2/gateways/concepts/architecture" arrow horizontal>
    How Gateways connect to Orchestrators and the protocol layer.
  </Card>

  <Card title="Gateway Business Model" icon="chart-line" href="/v2/gateways/concepts/business-model" arrow horizontal>
    Revenue models, cost structures, and the four operator models.
  </Card>

  <Card title="Navigator" icon="compass" href="/v2/gateways/navigator" arrow horizontal>
    Find the right path for your goals and experience level.
  </Card>
</CardGroup>
