Back to Blog
Guide February 23, 2026 · 5 min read

How to Auto-Generate a Narrated Demo Video on Every Pull Request

Every PR tells a story. Most teams tell it in words. This one records it. A 20-line GitHub Actions workflow that generates a narrated MP4 demo on every PR — attached directly to the thread.

With a 20-line GitHub Actions workflow and the PageBolt video API, you can automatically generate a narrated MP4 demo every time someone opens a pull request — showing the actual feature, with an AI voice walking through it, attached directly to the PR thread.

Here's how to set it up.

What you'll end up with

A GitHub Actions job that:

  1. Calls the PageBolt video API with a hardcoded walkthrough of your app
  2. Downloads the MP4 recording (with audio narration)
  3. Uploads it as a GitHub Actions artifact
  4. Posts a PR comment with a direct download link

The video is generated fresh on every PR. The steps are fixed — this works best for features with a stable URL and consistent UI.

The API call

PageBolt's /v1/video endpoint accepts a list of browser steps and returns a binary MP4. Pass audioGuide to add AI voice narration synced to each step.

curl -X POST https://api.pagebolt.dev/v1/video \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "steps": [
      { "action": "navigate", "url": "https://staging.yourapp.com", "note": "Opening the app" },
      { "action": "click", "selector": "#create-btn", "note": "Creating a new record" },
      { "action": "fill", "selector": "#name-input", "value": "Demo item" },
      { "action": "click", "selector": "#submit-btn", "note": "Submitting the form" },
      { "action": "wait", "ms": 1200 },
      { "action": "screenshot", "name": "result" }
    ],
    "audioGuide": {
      "enabled": true,
      "voice": "emma",
      "script": "Welcome to the demo. {{1}} We click Create to open the form. {{3}} Fill in the name and submit. {{5}} The record is saved."
    },
    "pace": "slow",
    "frame": { "enabled": true, "style": "macos" }
  }' \
  --output demo.mp4

That's the full call. No CLI, no special action — just curl. The --output demo.mp4 flag writes the binary response directly to disk.

The audioGuide.script field uses {{N}} markers synchronized to step numbers. The AI voice narrates as each step executes.

The GitHub Actions workflow

name: PR Demo Video

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  record-demo:
    runs-on: ubuntu-latest
    steps:
      - name: Record demo video
        run: |
          curl -X POST https://api.pagebolt.dev/v1/video \
            -H "x-api-key: ${{ secrets.PAGEBOLT_API_KEY }}" \
            -H "Content-Type: application/json" \
            -d '{
              "steps": [
                { "action": "navigate", "url": "https://staging.yourapp.com", "note": "Opening the app" },
                { "action": "click", "selector": "#create-btn", "note": "Starting a new record" },
                { "action": "fill", "selector": "#name-input", "value": "Demo item" },
                { "action": "click", "selector": "#submit-btn", "note": "Submitting" },
                { "action": "wait", "ms": 1200 },
                { "action": "screenshot", "name": "result" }
              ],
              "audioGuide": {
                "enabled": true,
                "voice": "emma",
                "script": "Welcome. {{1}} Click Create to open the form. {{3}} Fill in the name and submit. {{5}} Done."
              },
              "pace": "slow",
              "frame": { "enabled": true, "style": "macos" }
            }' \
            --output demo.mp4

      - name: Upload video artifact
        uses: actions/upload-artifact@v4
        with:
          name: pr-demo-${{ github.event.pull_request.number }}
          path: demo.mp4
          retention-days: 14

      - name: Comment on PR
        uses: actions/github-script@v7
        with:
          script: |
            const runUrl = `https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}`;
            await github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Demo video\n\nA narrated walkthrough was recorded for this PR.\n\n[Download demo.mp4](${runUrl}) — available under the **Artifacts** section of this run (requires GitHub login).\n\n*Generated by PageBolt*`
            });

Add your API key to GitHub Secrets as PAGEBOLT_API_KEY and you're done.

What reviewers see

When the workflow completes, the bot posts a comment with a link directly to the Actions run. Reviewers click through to the Artifacts panel and download the MP4. GitHub keeps artifacts for 14 days by default.

The video shows the actual UI, in the browser, with the AI narrator explaining what's happening. For features that are hard to describe in text — drag-and-drop flows, animations, multi-step forms — this makes the PR self-documenting.

Customizing the steps

The steps array maps directly to what PageBolt's browser does:

  • navigate — go to a URL
  • click — click an element by CSS selector
  • fill — type into an input
  • hover — hover over an element
  • scroll — scroll to a position
  • wait — pause for a given number of milliseconds
  • screenshot — capture a frame (these get embedded in the video timeline)

If your staging URL changes per PR (e.g., Vercel preview deployments), pass it as an environment variable:

- name: Record demo video
  env:
    STAGING_URL: ${{ github.event.deployment.payload.web_url }}
  run: |
    curl -X POST https://api.pagebolt.dev/v1/video \
      -H "x-api-key: ${{ secrets.PAGEBOLT_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d "{
        \"steps\": [
          { \"action\": \"navigate\", \"url\": \"$STAGING_URL\" },
          { \"action\": \"screenshot\", \"name\": \"home\" }
        ]
      }" \
      --output demo.mp4

Adding narration

The audioGuide parameter is where the video goes from useful to genuinely impressive. Instead of a silent screen recording, reviewers hear a voice walking through exactly what changed and why it matters.

Voices available: ava, andrew, emma, brian, aria, guy, jenny (Azure), or alloy, echo, fable, nova, onyx, shimmer (OpenAI). Switch providers with the provider field:

"audioGuide": {
  "enabled": true,
  "provider": "openai",
  "voice": "nova",
  "script": "Here's the new checkout flow. {{1}} We open the cart. {{2}} The discount is applied automatically. {{3}} Checkout completes in one click."
}

Automated video demos don't require a custom CI plugin or a dedicated recording service. One curl call, one artifact upload, one PR comment. The whole thing runs in under 30 seconds per PR.

Try it free

100 requests/month, no credit card. Add your API key to GitHub Secrets and your next PR gets a narrated demo video automatically.

Get API Key — Free