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

# Verify your Livepeer Gateway on Docker, Linux, or Windows

> Confirm your Livepeer Gateway is running correctly. Health checks, end-to-end tests, and on-chain verification for video, AI, and dual-mode nodes.

export const windowsGroup = () => <div style={{
  display: 'flex',
  gap: '0.5rem',
  alignItems: 'center',
  marginBottom: '1rem'
}}>
    <span>
      <Icon icon="windows" color="#0078d6" size={22} /> <Badge> Windows </Badge>
    </span>
  </div>;

export const linuxGroup = () => <div style={{
  display: 'flex',
  gap: '0.5rem',
  alignItems: 'center',
  marginBottom: '1rem'
}}>
    <span>
      <Icon icon="linux" color="#ff9a0e" size={22} /> <Badge> Linux </Badge>
    </span>
    <span>
      <Icon icon="apple" color="#60ba47" size={22} /> <Badge> macOS </Badge>
    </span>
  </div>;

export const dockerGroup = () => <div style={{
  display: 'flex',
  gap: '0.5rem',
  alignItems: 'center',
  marginBottom: '1rem'
}}>
    <span>
      <Icon icon="linux" color="#ff9a0e" size={22} /> <Badge> Linux </Badge>
    </span>
    <span>
      <Icon icon="windows" color="#0078d6" size={22} /> <Badge> Windows </Badge>
    </span>
    <span>
      <Icon icon="apple" color="#60ba47" size={22} /> <Badge> macOS </Badge>
    </span>
  </div>;

export const onChain = () => <span>
    <Icon icon="server" size={20} /> <strong>on-chain</strong>
  </span>;

export const offChain = () => <span>
    <Icon icon="floppy-disk" size={20} /> <strong>off-chain</strong>
  </span>;

export const dual = () => <Badge color="green">Dual-mode</Badge>;

export const ai = () => <Badge color="purple">AI</Badge>;

export const video = () => <Badge color="blue">Video</Badge>;

export const StyledStep = ({title, icon, titleSize = 'h3', iconColor = null, titleColor = null, children, className = '', style = {}, ...rest}) => {
  const styledTitle = titleColor ? <span style={{
    color: titleColor
  }}>{title}</span> : title;
  return <Step title={styledTitle} icon={icon} iconColor={iconColor || undefined} titleSize={titleSize} className={className} style={style} {...rest}>
      {children}
    </Step>;
};

export const StyledSteps = ({children, iconColor, titleColor, lineColor, iconSize = '24px', className = '', style = {}, ...rest}) => {
  const resolvedIconColor = iconColor || 'var(--accent-dark, #18794E)';
  const resolvedTitleColor = titleColor || 'var(--lp-color-accent)';
  const resolvedLineColor = lineColor || 'var(--lp-color-accent)';
  return <div className={['docs-styled-steps', className].filter(Boolean).join(' ')} style={style} {...rest}>
      <style>{`
        .docs-styled-steps .steps > div > div.absolute > div {
          background-color: ${resolvedIconColor};
        }
        .docs-styled-steps .steps > div > div.w-full > p {
          color: ${resolvedTitleColor};
        }
        .docs-styled-steps .steps > div > div.absolute.w-px {
          background-color: ${resolvedLineColor};
        }
        .docs-styled-steps .steps > div:last-child > div.absolute.w-px::after {
          content: '';
          position: absolute;
          bottom: 0;
          left: 50%;
          transform: translateX(-50%);
          width: 6px;
          height: 6px;
          background-color: ${resolvedLineColor};
          transform: translateX(-50%) rotate(45deg);
        }
      `}</style>
      <div>
        <Steps>{children}</Steps>
      </div>
    </div>;
};

export const BorderedBox = ({children, variant = "default", padding = "var(--lp-spacing-4)", borderRadius = "var(--lp-spacing-px-8)", margin = "", accentBar = "", style = {}, className = "", ...rest}) => {
  const variants = {
    default: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "var(--lp-color-bg-card)"
    },
    accent: {
      border: "1px solid var(--lp-color-accent)",
      backgroundColor: "var(--lp-color-bg-card)"
    },
    muted: {
      border: "1px solid var(--lp-color-border-default)",
      backgroundColor: "transparent"
    }
  };
  const accentBarColors = {
    accent: "var(--lp-color-accent)",
    positive: "var(--green-9)"
  };
  return <div data-docs-bordered-box="" data-accent-bar={accentBarColors[accentBar] ? "" : undefined} className={className} style={{
    ...variants[variant],
    padding: padding,
    borderRadius: borderRadius,
    ...margin ? {
      margin
    } : {},
    ...accentBarColors[accentBar] ? {
      position: "relative",
      '--accent-bar-color': accentBarColors[accentBar]
    } : {},
    ...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>;
};

<CustomDivider style={{margin: "0 0 -1rem 0"}} />

# <Icon icon="circle-check" size={26} /> Verify Your Gateway

Confirm your Livepeer Gateway is alive, connected, and routing jobs for {video()}, {ai()} Pipelines, or {dual()} service.

*This guide covers:*

* Health checks for {onChain()} and {offChain()} Livepeer Gateway nodes
* End-to-end tests for <span>{video()} **Video transcoding**, </span><span> {ai()} **AI inference**, </span> and <span>{dual()} **Dual-mode** </span> Gateways
* On-chain deposit and Arbitrum RPC verification

<Tip>
  Run these checks immediately after completing the [Install](/v2/Gateways/setup/install) and [Configure](/v2/Gateways/setup/configure) steps. Once verification passes, proceed to [Monitor](/v2/Gateways/setup/monitor) to set up production observability with Prometheus and Grafana.
</Tip>

<CustomDivider />

<BorderedBox>
  <Tabs>
    <Tab title="Docker" icon="docker">
      ## <Icon icon="docker" iconType="solid" size={32} /> Docker Verification

      {dockerGroup()}

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)" titleSize="h3">
        <StyledStep title="Process Health">
          Confirm the Gateway container is running and responding.

          **Check container status:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          docker ps --filter name=<container_name>
          ```

          **Check the health endpoint:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl http://localhost:8935/health
          ```

          **Expected response:**

          ```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          {"status": "OK"}
          ```

          HTTP 200 confirms the process is running. If the endpoint does not respond, check container logs:

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          docker logs <container_name> --tail 50
          ```

          <Tip>
            Add a `HEALTHCHECK` directive to your Dockerfile or Compose file for automatic container restarts on failure:

            ```dockerfile theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
              CMD curl --silent --fail http://localhost:8935/health || exit 1
            ```
          </Tip>
        </StyledStep>

        <StyledStep title="Node Status">
          Use `livepeer_cli` inside the container to inspect node identity, sessions, and on-chain balances.

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          docker exec -it <container_name> livepeer_cli -host <container_hostname> -http 5935
          ```

          Select **Option 1: Get node status**. The output shows:

          * **Version** and network connection
          * **ETH Account** address
          * **BROADCASTER STATS** – active sessions, deposit, and reserve balances

          <Warning>
            Use the container hostname (not `localhost`) inside Docker networking. Using `localhost` causes connection failures.
          </Warning>

          **Hardware check** (for nodes with GPU resources):

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl -s http://localhost:8935/hardware/stats | python3 -m json.tool
          ```

          Returns GPU utilisation, memory, and temperature.
        </StyledStep>

        <StyledStep title="End-to-End Test">
          Run a test job through the Gateway to confirm full pipeline operation.

          <Tabs>
            <Tab title="Video">
              Push a test stream via RTMP and check HLS output:

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
                -c:v libx264 -preset ultrafast \
                -f flv rtmp://localhost:1935/live/test
              ```

              In a separate terminal, fetch the HLS manifest:

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              curl http://localhost:8935/stream/test.m3u8
              ```

              A valid M3U8 playlist confirms transcoding is working end-to-end.

              **Also verify Orchestrator connectivity:**

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              curl http://localhost:5935/getOrchestrators
              ```

              The response should list at least one Orchestrator with pricing information.
            </Tab>

            <Tab title="AI">
              Submit a test inference job:

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              curl -X POST http://localhost:8935/text-to-image \
                -H "Content-Type: application/json" \
                -d '{
                  "model_id": "ByteDance/SDXL-Lightning",
                  "prompt": "a simple geometric test pattern",
                  "width": 512,
                  "height": 512,
                  "num_images_per_prompt": 1
                }'
              ```

              A successful response contains image data.

              **If the request fails, verify:**

              1. The Orchestrator supports the requested pipeline (`text-to-image`)
              2. The `model_id` exactly matches the Orchestrator's available models (case-sensitive)

              **Off-chain mode** – confirm Orchestrators in `-orchAddr` are reachable:

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              curl https://<orchestrator-address>:<port>/getOrchestratorInfo
              ```

              **On-chain mode** – the node uses `-aiServiceRegistry` for automatic discovery. Confirm via `livepeer_cli` Option 1 that sessions are available.
            </Tab>

            <Tab title="Dual">
              Dual Gateways must pass **both** the video RTMP test and the AI inference test. Both endpoints respond on port **8935** (single port architecture).

              1. Run the video RTMP test from the Video tab
              2. Run the AI inference test from the AI tab
              3. Both must succeed

              **Monitor GPU during the tests:**

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              watch -n 10 'curl -s http://localhost:8935/hardware/stats'
              ```

              Watch for `gpu_memory_used` approaching `gpu_memory_total`. If GPU memory is consistently above 85%, consider separating video and AI onto dedicated nodes.
            </Tab>
          </Tabs>
        </StyledStep>

        <StyledStep title="On-Chain Verification">
          <Note>
            Skip this step for **off-chain** deployments.
          </Note>

          **Test the Arbitrum RPC connection:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl -X POST <YOUR_ETH_URL> \
            -H "Content-Type: application/json" \
            -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
          ```

          A valid response contains a `result` field with a hex block number.

          **Verify deposit and reserve:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          docker exec -it <container_name> livepeer_cli -host <container_hostname> -http 5935
          ```

          Select **Option 1: Get node status** and check the **BROADCASTER STATS** section:

          * Both **Deposit** and **Reserve** must be non-zero
          * Minimum recommended for testing: **0.1 ETH total** (\~0.07 ETH deposit + 0.03 ETH reserve)

          <Warning>
            When the deposit reaches zero, the Gateway silently stops routing jobs with no client-facing error. Top up via `livepeer_cli` **Option 11: Deposit broadcasting funds**.
          </Warning>

          **Check your Gateway on Arbiscan:**

          Visit `https://arbiscan.io/address/<GATEWAY_ETH_ADDRESS>` to view transaction history and confirm deposits were registered on-chain.
        </StyledStep>
      </StyledSteps>

      <Card title="Next Step: Monitor your Gateway" icon="chart-line" href="/v2/gateways/setup/monitor" horizontal arrow>
        Set up Prometheus, Grafana, and alert rules for production observability
      </Card>
    </Tab>

    <Tab title="Linux" icon="linux">
      ## <Icon icon="linux" iconType="brands" size={32} /> Linux Verification

      {linuxGroup()}

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)" titleSize="h3">
        <StyledStep title="Process Health">
          Confirm the Gateway process is running and responding.

          **Check if the process is active:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          pgrep -a livepeer
          ```

          **Check the health endpoint:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl http://localhost:8935/health
          ```

          **Expected response:**

          ```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          {"status": "OK"}
          ```

          HTTP 200 confirms the process is running. If the endpoint does not respond, check your startup logs or run with `-v 6` for verbose output:

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          ./livepeer -gateway [flags] -v 6 2>&1 | tee livepeer.log
          ```

          <Tip>
            Set up a cron job to monitor Gateway health automatically:

            ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
            #!/usr/bin/env bash
            # gateway-health.sh — run every 5 minutes via cron
            GATEWAY_PORT="${1:-8935}"
            ALERT_EMAIL="ops@example.com"

            if ! curl --silent --fail --max-time 5 \
              http://localhost:${GATEWAY_PORT}/health > /dev/null 2>&1; then
              echo "Gateway on port ${GATEWAY_PORT} is not responding" | \
                mail -s "ALERT: Livepeer Gateway Down" "$ALERT_EMAIL"
            fi
            ```

            Crontab entry: `*/5 * * * * /path/to/gateway-health.sh 8935`
          </Tip>
        </StyledStep>

        <StyledStep title="Node Status">
          Use `livepeer_cli` to inspect node identity, sessions, and on-chain balances.

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          livepeer_cli -host 127.0.0.1 -http 5935
          ```

          Select **Option 1: Get node status**. The output shows:

          * **Version** and network connection
          * **ETH Account** address
          * **BROADCASTER STATS** – active sessions, deposit, and reserve balances

          **Hardware check** (for nodes with GPU resources):

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl -s http://localhost:8935/hardware/stats | python3 -m json.tool
          ```

          Returns GPU utilisation, memory, and temperature.
        </StyledStep>

        <StyledStep title="End-to-End Test">
          Run a test job through the Gateway to confirm full pipeline operation.

          <Tabs>
            <Tab title="Video">
              Push a test stream via RTMP and check HLS output:

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
                -c:v libx264 -preset ultrafast \
                -f flv rtmp://localhost:1935/live/test
              ```

              In a separate terminal, fetch the HLS manifest:

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              curl http://localhost:8935/stream/test.m3u8
              ```

              A valid M3U8 playlist confirms transcoding is working end-to-end.

              **Also verify Orchestrator connectivity:**

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              curl http://localhost:5935/getOrchestrators
              ```

              The response should list at least one Orchestrator with pricing information.
            </Tab>

            <Tab title="AI">
              Submit a test inference job:

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              curl -X POST http://localhost:8935/text-to-image \
                -H "Content-Type: application/json" \
                -d '{
                  "model_id": "ByteDance/SDXL-Lightning",
                  "prompt": "a simple geometric test pattern",
                  "width": 512,
                  "height": 512,
                  "num_images_per_prompt": 1
                }'
              ```

              A successful response contains image data.

              **If the request fails, verify:**

              1. The Orchestrator supports the requested pipeline (`text-to-image`)
              2. The `model_id` exactly matches the Orchestrator's available models (case-sensitive)

              **Off-chain mode** – confirm Orchestrators in `-orchAddr` are reachable:

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              curl https://<orchestrator-address>:<port>/getOrchestratorInfo
              ```

              **On-chain mode** – the node uses `-aiServiceRegistry` for automatic discovery. Confirm via `livepeer_cli` Option 1 that sessions are available.
            </Tab>

            <Tab title="Dual">
              Dual Gateways must pass **both** the video RTMP test and the AI inference test. Both endpoints respond on port **8935** (single port architecture).

              1. Run the video RTMP test from the Video tab
              2. Run the AI inference test from the AI tab
              3. Both must succeed

              **Monitor GPU during the tests:**

              ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
              watch -n 10 'curl -s http://localhost:8935/hardware/stats'
              ```

              Watch for `gpu_memory_used` approaching `gpu_memory_total`. If GPU memory is consistently above 85%, consider separating video and AI onto dedicated nodes.
            </Tab>
          </Tabs>
        </StyledStep>

        <StyledStep title="On-Chain Verification">
          <Note>
            Skip this step for **off-chain** deployments.
          </Note>

          **Test the Arbitrum RPC connection:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl -X POST <YOUR_ETH_URL> \
            -H "Content-Type: application/json" \
            -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
          ```

          A valid response contains a `result` field with a hex block number.

          **Verify deposit and reserve:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          livepeer_cli -host 127.0.0.1 -http 5935
          ```

          Select **Option 1: Get node status** and check the **BROADCASTER STATS** section:

          * Both **Deposit** and **Reserve** must be non-zero
          * Minimum recommended for testing: **0.1 ETH total** (\~0.07 ETH deposit + 0.03 ETH reserve)

          <Warning>
            When the deposit reaches zero, the Gateway silently stops routing jobs with no client-facing error. Top up via `livepeer_cli` **Option 11: Deposit broadcasting funds**.
          </Warning>

          **Check your Gateway on Arbiscan:**

          Visit `https://arbiscan.io/address/<GATEWAY_ETH_ADDRESS>` to view transaction history and confirm deposits were registered on-chain.
        </StyledStep>
      </StyledSteps>

      <Card title="Next Step: Monitor your Gateway" icon="chart-line" href="/v2/gateways/setup/monitor" horizontal arrow>
        Set up Prometheus, Grafana, and alert rules for production observability
      </Card>
    </Tab>

    <Tab title="Windows" icon="windows">
      ## <Icon icon="windows" iconType="brands" size={32} /> Windows Verification

      {windowsGroup()}

      <Warning>
        The Livepeer AI Gateway binary is **not available for Windows or macOS (Intel)**. Windows supports <Badge color="blue">Video</Badge> video transcoding only. For <Badge color="purple">AI</Badge> or <Badge color="green">Dual-mode</Badge> Gateways, use Docker on a Linux host or Docker Desktop with WSL2. See the Docker tab for AI and Dual verification.
      </Warning>

      <StyledSteps iconColor="var(--lp-color-accent-strong)" titleColor="var(--accent)" lineColor="var(--accent)" titleSize="h3">
        <StyledStep title="Process Health">
          Confirm the Gateway process is running and responding.

          **Check if the process is active (PowerShell):**

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          Get-Process livepeer -ErrorAction SilentlyContinue
          ```

          **Check the health endpoint:**

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          Invoke-RestMethod -Uri http://localhost:8935/health
          ```

          **Expected response:**

          ```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          {"status": "OK"}
          ```

          HTTP 200 confirms the process is running.

          **If using WSL2:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          curl http://localhost:8935/health
          ```

          If the endpoint does not respond, check the Gateway output window or restart with `-v 6` for verbose logging.
        </StyledStep>

        <StyledStep title="Node Status">
          Use `livepeer_cli` to inspect node identity, sessions, and on-chain balances.

          **PowerShell:**

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          .\livepeer_cli.exe -host 127.0.0.1 -http 5935
          ```

          **WSL2:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          livepeer_cli -host 127.0.0.1 -http 5935
          ```

          Select **Option 1: Get node status**. The output shows:

          * **Version** and network connection
          * **ETH Account** address
          * **BROADCASTER STATS** – active sessions, deposit, and reserve balances
        </StyledStep>

        <StyledStep title="End-to-End Test">
          Run a test stream to confirm the video pipeline is working.

          <Note>
            Windows supports <Badge color="blue">Video</Badge> **transcoding only**. For AI or Dual tests, use the Docker tab.
          </Note>

          Push a test stream via RTMP:

          **PowerShell (with FFmpeg installed):**

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 `
            -c:v libx264 -preset ultrafast `
            -f flv rtmp://localhost:1935/live/test
          ```

          **WSL2:**

          ```bash theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
            -c:v libx264 -preset ultrafast \
            -f flv rtmp://localhost:1935/live/test
          ```

          In a separate terminal, fetch the HLS manifest:

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          Invoke-RestMethod -Uri http://localhost:8935/stream/test.m3u8
          ```

          A valid M3U8 playlist confirms transcoding is working end-to-end.

          **Also verify Orchestrator connectivity:**

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          Invoke-RestMethod -Uri http://localhost:5935/getOrchestrators
          ```

          The response should list at least one Orchestrator with pricing information.
        </StyledStep>

        <StyledStep title="On-Chain Verification">
          <Note>
            Skip this step for **off-chain** deployments.
          </Note>

          **Test the Arbitrum RPC connection (PowerShell):**

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          $body = '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
          Invoke-RestMethod -Uri <YOUR_ETH_URL> -Method POST `
            -ContentType "application/json" -Body $body
          ```

          A valid response contains a `result` field with a hex block number.

          **Verify deposit and reserve:**

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          .\livepeer_cli.exe -host 127.0.0.1 -http 5935
          ```

          Select **Option 1: Get node status** and check the **BROADCASTER STATS** section:

          * Both **Deposit** and **Reserve** must be non-zero
          * Minimum recommended for testing: **0.1 ETH total** (\~0.07 ETH deposit + 0.03 ETH reserve)

          <Warning>
            When the deposit reaches zero, the Gateway silently stops routing jobs with no client-facing error. Top up via `livepeer_cli` **Option 11: Deposit broadcasting funds**.
          </Warning>

          **Check your Gateway on Arbiscan:**

          Visit `https://arbiscan.io/address/<GATEWAY_ETH_ADDRESS>` to view transaction history and confirm deposits were registered on-chain.
        </StyledStep>

        <StyledStep title="Port Verification">
          If you experience connection issues, verify the Gateway ports are not blocked.

          **Check port availability (PowerShell):**

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          netstat -ano | findstr :8935
          netstat -ano | findstr :1935
          netstat -ano | findstr :5935
          ```

          | Port     | Service  | Purpose                      |
          | -------- | -------- | ---------------------------- |
          | **8935** | HTTP API | Health, metrics, HLS output  |
          | **1935** | RTMP     | Video stream ingest          |
          | **5935** | CLI API  | `livepeer_cli` communication |

          If a port is occupied by another process, find and stop it:

          ```powershell theme={"theme":{"light":"github-light","dark":"dark-plus"}}
          taskkill /PID <PID> /F
          ```

          Or change the Gateway port with the corresponding flag (e.g. `-httpAddr 0.0.0.0:9000`).
        </StyledStep>
      </StyledSteps>

      <Card title="Next Step: Monitor your Gateway" icon="chart-line" href="/v2/gateways/setup/monitor" horizontal arrow>
        Set up Prometheus, Grafana, and alert rules for production observability
      </Card>
    </Tab>
  </Tabs>
</BorderedBox>
