Capture a website screenshot in GitHub Actions.

Add one workflow step to capture a public webpage as PNG or JPEG, then keep the image as a run artifact. The browser runs behind the Latchshot API, so the runner does not install or cache Chromium.

Public pages only · MIT-licensed Action · Updated July 18, 2026

Copy the complete workflow.

This manually triggered workflow asks for a URL, captures it at 1440 × 900, and uploads the PNG for 14 days. The Action exposes the final path, render time, quota remaining, and navigation state as step outputs.

.github/workflows/screenshot.ymlComplete workflow
name: Capture website screenshot

on:
  workflow_dispatch:
    inputs:
      url:
        description: Public webpage URL
        required: true
        default: https://example.com

permissions:
  contents: read

jobs:
  capture:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - name: Capture webpage
        id: screenshot
        uses: BaiqingL/latchshot-action@v1
        with:
          api_key: ${{ secrets.LATCHSHOT_API_KEY }}
          url: ${{ inputs.url }}
          output: webpage.png
          width: "1440"
          height: "900"

      - name: Upload screenshot
        uses: actions/upload-artifact@v4
        with:
          name: webpage-capture
          path: ${{ steps.screenshot.outputs.path }}
          if-no-files-found: error
          retention-days: 14

No checkout step is required when the workflow only creates the screenshot artifact. Pin to the moving major tag, @v1, for compatible updates or to a full release tag when the workflow requires an immutable dependency.

Need a key for the first run?

The Free plan returns a key with 100 successful renders each UTC calendar month. No credit card or approval queue is required.

Store the API key as an Actions secret.

  1. Open the target repository on GitHub.
  2. Choose Settings → Secrets and variables → Actions.
  3. Create a repository secret named LATCHSHOT_API_KEY.
  4. Paste the Free or paid key once, then run the workflow from the Actions tab.

The workflow passes the secret through the Action input and into an HTTPS authorization header. Do not put the key in the URL, workflow source, artifact name, or job summary. GitHub does not pass repository secrets to workflows triggered from forks.

Keep the artifact and its diagnostics together.

A successful step writes the requested image and exposes four outputs. Record them in a later step when the workflow needs evidence about how the capture completed.

OutputMeaningExample
pathRequested output pathwebpage.png
render_msServer-side render duration1842
quota_remainingSuccessful renders left this month87
navigationComplete navigation or usable timed-out fallbackcomplete

Only a successful render consumes direct-plan quota. A failed step does not produce an artifact, and if-no-files-found: error prevents a green workflow with missing evidence.

Schedule a fixed public page.

Replace the manual trigger with a UTC cron schedule and a fixed URL for recurring documentation, status-page, or release evidence. Scheduled workflows run from the default branch and GitHub may delay them during busy periods.

Workflow excerptWeekdays at 06:17 UTC
on:
  schedule:
    - cron: "17 6 * * 1-5"

# Keep the capture step from the complete workflow.
with:
  api_key: ${{ secrets.LATCHSHOT_API_KEY }}
  url: https://example.com/status
  output: status-page.png

For recurring jobs, check quota_remaining, retain the previous successful artifact outside GitHub when history matters, and avoid retrying permanent 400 or 401 responses.

Choose hosted rendering when the page is public.

Moving Chromium out of the runner is a specific tradeoff, not a universal replacement for browser automation.

DecisionHosted Latchshot ActionBrowser in your runner
Browser setupNo install or cache in the workflowInstall, cache, or maintain an image
Reachable pagesPublic HTTP/HTTPS onlyCan reach the runner's private environment
CustomizationBounded capture inputsArbitrary scripts and sessions
Operating modelExternal API key and quotaRunner minutes and browser upkeep

Use a browser in your own runner for authenticated previews, private deployments, multi-step interaction, cookies, or arbitrary page scripts. Use the hosted Action when the input is a public URL and the desired output is a bounded screenshot artifact.

Make failures predictable.

  • Targets must be public HTTP or HTTPS pages on ports 80 or 443.
  • Private, loopback, link-local, special-use, and mixed public/private DNS answers are rejected.
  • Viewport dimensions, full-page height, delay, timeout, retries, concurrency, and queue depth are bounded.
  • Cookies, login sessions, arbitrary scripts, CAPTCHA solving, proxy rotation, and anti-bot bypass are not supported.
  • The Action retries transient transport failures twice and treats invalid requests or credentials as permanent errors.

The public Action source is MIT licensed and its validation workflow is visible. The hosted renderer is a separate metered service. Read the benchmark method and beta boundaries before making the capture a release gate.

Start with 100 successful artifacts.

The Free plan renews to 100 successful renders each UTC calendar month. Launch is $19 for 2,500 per month, Build is $49 for 12,000, and Scale is $149 for 50,000. Automatic overages are disabled, and failed direct renders do not consume quota.

The current supported-page benchmark is 197/200 with 2.42-second p50 and 7.68-second p95 end to end. It is engineering evidence, not an SLA.

Need the HTTP contract instead?

Use the screenshot API directly from any CI system, server, or automation tool that can make an authenticated request.

Read the API guide