Devices and page checks

Render one page on several devices in a single call, and optionally get what's wrong on each: sideways scrolling and its cause, missing viewport tag, tiny text, JavaScript errors, failed requests and broken images.

Several devices at once

POST/v1/screenshots

Send url (or html), devices (1–8, e.g. ["desktop","iphone","ipad"]) and any screenshot option. You get a hosted link per device. 1 credit per device; failed devices are refunded.

curl -X POST https://shotlane.dev/v1/screenshots -H "X-API-Key: $SHOTLANE_API_KEY" -H "Content-Type: application/json" \
  -d '{"url":"https://stripe.com","devices":["desktop","iphone","ipad"],"hide_cookie_banners":true}'
ParameterDefaultDescription
devicesdesktop, iphoneDevice ids: our presets (desktop, desktop_hd, laptop, ipad, iphone, iphone_se, pixel, galaxy) or any of the 200+ in the catalog.
diagnosticsfalseAdd each device's problems, as in /v1/check.
keep_days1Keep the image links for 1–30 days, e.g. to embed them in a pull request.

Check a page

GET | POST/v1/check

Renders the page on phone, tablet and desktop (or your devices) and reports what went wrong on each, next to the screenshot. Built for checking a deploy or a preview URL, by you or by an agent. 1 credit per device; failed and blocked devices are refunded.

curl "https://shotlane.dev/v1/check?url=https://my-app-git-feature.vercel.app" -H "X-API-Key: $SHOTLANE_API_KEY"

{"url": "https://my-app-git-feature.vercel.app", "issues": 1, "credits_used": 3, "shots": [
  {"device": "iphone", "ok": true, "url": "https://shotlane.dev/r/….jpg", "status": 200,
   "issues": ["Scrolls sideways: the page is 612px wide in a 393px viewport; caused by table.pricing (580px wide, ends at 596px)."],
   "diagnostics": {"console_errors": [], "page_errors": [], "failed_requests": [],
                   "layout": {"viewport_width": 393, "page_width": 612, "horizontal_overflow": true, "overflowing_elements": [...],
                              "broken_images": [], "has_viewport_meta": true, "small_text_pct": 3}}},
  {"device": "ipad", …}, {"device": "desktop", …}]}

What it checks

  • Sideways scrolling: the page is wider than the screen and a person can pan to it, with the outermost elements that stick out. Content clipped by overflow: hidden on html and body, or on a wrapper, doesn't count.
  • Viewport tag missing on phones, which makes them render the desktop layout shrunk.
  • Small text: more than 40% of the text under 12px on a phone (small_text_pct).
  • JavaScript: uncaught errors and console errors while loading.
  • Failed requests (4xx, 5xx, network errors) and broken images a person would see; tracking pixels and hidden images don't count.

On every preview deploy

The Shotlane Visual Check action runs the check whenever a Vercel or Netlify preview (or anything that reports GitHub deployment statuses) goes live, and posts the screenshots and problems as one pull request comment, updated on every deploy. Add the secret SHOTLANE_API_KEY and this workflow:

name: Shotlane visual check
on: deployment_status
permissions:
  contents: read
  pull-requests: write
jobs:
  check:
    if: github.event.deployment_status.state == 'success' && !contains(github.event.deployment.environment, 'roduction')
    runs-on: ubuntu-latest
    steps:
      - uses: shotlane/visual-check@v1
        with:
          api-key: ${{ secrets.SHOTLANE_API_KEY }}
          pages: "/ /pricing"

Inputs: pages (paths to check, 1 credit per page and device), devices, url (a fixed URL instead of the deployment's), fail-on-issues, comment. For Vercel previews behind Deployment Protection, add vercel-bypass-secret; it's sent only to the preview's own host and never stored. Prefer no third-party action? Use the self-contained workflow file.

Device catalog

Any of these works as device on every endpoint, alone or in devices lists, and viewport_landscape=true turns one sideways. The same list as JSON: GET /v1/devices (no key needed).

deviceNameViewportScaleMobile
blackberry_playbookBlackberry PlayBook600×10241yes
blackberry_playbook_landscapeBlackberry PlayBook landscape1024×6001yes
blackberry_z30BlackBerry Z30360×6402yes
blackberry_z30_landscapeBlackBerry Z30 landscape640×3602yes
desktopDesktop1280×8001
desktop_chromeDesktop Chrome1280×7201
desktop_chrome_hidpiDesktop Chrome HiDPI1280×7202
desktop_edgeDesktop Edge1280×7201
desktop_edge_hidpiDesktop Edge HiDPI1280×7202
desktop_firefoxDesktop Firefox1280×7201
desktop_firefox_hidpiDesktop Firefox HiDPI1280×7202
desktop_hdDesktop HD1920×10801
desktop_safariDesktop Safari1280×7202
galaxyGalaxy360×7803yes
galaxy_a55Galaxy A55480×10402.25yes
galaxy_a55_landscapeGalaxy A55 landscape1040×4802.25yes
galaxy_note_3Galaxy Note 3360×6403yes
galaxy_note_3_landscapeGalaxy Note 3 landscape640×3603yes
galaxy_note_iiGalaxy Note II360×6402yes
galaxy_note_ii_landscapeGalaxy Note II landscape640×3602yes
galaxy_s24Galaxy S24360×7803yes
galaxy_s24_landscapeGalaxy S24 landscape780×3603yes
galaxy_s5Galaxy S5360×6403yes
galaxy_s5_landscapeGalaxy S5 landscape640×3603yes
galaxy_s8Galaxy S8360×7403yes
galaxy_s8_landscapeGalaxy S8 landscape740×3603yes
galaxy_s9_plusGalaxy S9+320×6584.5yes
galaxy_s9_plus_landscapeGalaxy S9+ landscape658×3204.5yes
galaxy_s_iiiGalaxy S III360×6402yes
galaxy_s_iii_landscapeGalaxy S III landscape640×3602yes
galaxy_tab_s4Galaxy Tab S4712×11382.25yes
galaxy_tab_s4_landscapeGalaxy Tab S4 landscape1138×7122.25yes
galaxy_tab_s9Galaxy Tab S9640×10242.5yes
galaxy_tab_s9_landscapeGalaxy Tab S9 landscape1024×6402.5yes
galaxy_z_flip_6Galaxy Z Flip 6360×8043yes
galaxy_z_flip_6_coverGalaxy Z Flip 6 Cover360×2982yes
galaxy_z_flip_6_cover_landscapeGalaxy Z Flip 6 Cover landscape322×3082yes
galaxy_z_flip_6_landscapeGalaxy Z Flip 6 landscape828×3083yes
galaxy_z_flip_7Galaxy Z Flip 7360×7643yes
galaxy_z_flip_7_coverGalaxy Z Flip 7 Cover474×4482yes
galaxy_z_flip_7_cover_landscapeGalaxy Z Flip 7 Cover landscape472×4222yes
galaxy_z_flip_7_landscapeGalaxy Z Flip 7 landscape788×3083yes
galaxy_z_fold_6Galaxy Z Fold 6928×10042yes
galaxy_z_fold_6_coverGalaxy Z Fold 6 Cover484×11122yes
galaxy_z_fold_6_cover_landscapeGalaxy Z Fold 6 Cover landscape1136×4322yes
galaxy_z_fold_6_landscapeGalaxy Z Fold 6 landscape1028×8762yes
galaxy_z_fold_7Galaxy Z Fold 7984×10162yes
galaxy_z_fold_7_coverGalaxy Z Fold 7 Cover360×7643yes
galaxy_z_fold_7_cover_landscapeGalaxy Z Fold 7 Cover landscape788×3083yes
galaxy_z_fold_7_landscapeGalaxy Z Fold 7 landscape1040×9322yes
ipadiPad820×11802
ipad_gen_11iPad (gen 11)656×9442.5yes
ipad_gen_11_landscapeiPad (gen 11) landscape944×6562.5yes
ipad_gen_5iPad (gen 5)768×10242yes
ipad_gen_5_landscapeiPad (gen 5) landscape1024×7682yes
ipad_gen_6iPad (gen 6)768×10242yes
ipad_gen_6_landscapeiPad (gen 6) landscape1024×7682yes
ipad_gen_7iPad (gen 7)810×10802yes
ipad_gen_7_landscapeiPad (gen 7) landscape1080×8102yes
ipad_miniiPad Mini768×10242yes
ipad_mini_landscapeiPad Mini landscape1024×7682yes
ipad_pro_11iPad Pro 11834×11942yes
ipad_pro_11_landscapeiPad Pro 11 landscape1194×8342yes
iphoneiPhone393×8523yes
iphone_11iPhone 11414×7152yes
iphone_11_landscapeiPhone 11 landscape800×3642yes
iphone_11_proiPhone 11 Pro375×6353yes
iphone_11_pro_landscapeiPhone 11 Pro landscape724×3253yes
iphone_11_pro_maxiPhone 11 Pro Max414×7153yes
iphone_11_pro_max_landscapeiPhone 11 Pro Max landscape808×3643yes
iphone_12iPhone 12390×6643yes
iphone_12_landscapeiPhone 12 landscape750×3403yes
iphone_12_miniiPhone 12 Mini375×6293yes
iphone_12_mini_landscapeiPhone 12 Mini landscape712×3253yes
iphone_12_proiPhone 12 Pro390×6643yes
iphone_12_pro_landscapeiPhone 12 Pro landscape750×3403yes
iphone_12_pro_maxiPhone 12 Pro Max428×7463yes
iphone_12_pro_max_landscapeiPhone 12 Pro Max landscape832×3783yes
iphone_13iPhone 13390×6643yes
iphone_13_landscapeiPhone 13 landscape750×3423yes
iphone_13_miniiPhone 13 Mini375×6293yes
iphone_13_mini_landscapeiPhone 13 Mini landscape712×3273yes
iphone_13_proiPhone 13 Pro390×6643yes
iphone_13_pro_landscapeiPhone 13 Pro landscape750×3423yes
iphone_13_pro_maxiPhone 13 Pro Max428×7463yes
iphone_13_pro_max_landscapeiPhone 13 Pro Max landscape832×3803yes
iphone_14iPhone 14390×6643yes
iphone_14_landscapeiPhone 14 landscape750×3403yes
iphone_14_plusiPhone 14 Plus428×7463yes
iphone_14_plus_landscapeiPhone 14 Plus landscape832×3783yes
iphone_14_proiPhone 14 Pro393×6603yes
iphone_14_pro_landscapeiPhone 14 Pro landscape734×3433yes
iphone_14_pro_maxiPhone 14 Pro Max430×7403yes
iphone_14_pro_max_landscapeiPhone 14 Pro Max landscape814×3803yes
iphone_15iPhone 15393×6593yes
iphone_15_landscapeiPhone 15 landscape734×3433yes
iphone_15_plusiPhone 15 Plus430×7393yes
iphone_15_plus_landscapeiPhone 15 Plus landscape814×3803yes
iphone_15_proiPhone 15 Pro393×6593yes
iphone_15_pro_landscapeiPhone 15 Pro landscape734×3433yes
iphone_15_pro_maxiPhone 15 Pro Max430×7393yes
iphone_15_pro_max_landscapeiPhone 15 Pro Max landscape814×3803yes
iphone_16iPhone 16393×6593yes
iphone_16_landscapeiPhone 16 landscape734×3433yes
iphone_16_plusiPhone 16 Plus430×7393yes
iphone_16_plus_landscapeiPhone 16 Plus landscape814×3803yes
iphone_16_proiPhone 16 Pro402×6813yes
iphone_16_pro_landscapeiPhone 16 Pro landscape756×3523yes
iphone_16_pro_maxiPhone 16 Pro Max440×7633yes
iphone_16_pro_max_landscapeiPhone 16 Pro Max landscape838×3903yes
iphone_16eiPhone 16e390×6513yes
iphone_16e_landscapeiPhone 16e landscape726×3403yes
iphone_17iPhone 17402×6813yes
iphone_17_landscapeiPhone 17 landscape756×3523yes
iphone_17_proiPhone 17 Pro402×6813yes
iphone_17_pro_landscapeiPhone 17 Pro landscape756×3523yes
iphone_17_pro_maxiPhone 17 Pro Max440×7633yes
iphone_17_pro_max_landscapeiPhone 17 Pro Max landscape838×3903yes
iphone_17eiPhone 17e390×6513yes
iphone_17e_landscapeiPhone 17e landscape726×3403yes
iphone_6iPhone 6375×6672yes
iphone_6_landscapeiPhone 6 landscape667×3752yes
iphone_6_plusiPhone 6 Plus414×7363yes
iphone_6_plus_landscapeiPhone 6 Plus landscape736×4143yes
iphone_7iPhone 7375×6672yes
iphone_7_landscapeiPhone 7 landscape667×3752yes
iphone_7_plusiPhone 7 Plus414×7363yes
iphone_7_plus_landscapeiPhone 7 Plus landscape736×4143yes
iphone_8iPhone 8375×6672yes
iphone_8_landscapeiPhone 8 landscape667×3752yes
iphone_8_plusiPhone 8 Plus414×7363yes
iphone_8_plus_landscapeiPhone 8 Plus landscape736×4143yes
iphone_airiPhone Air420×7193yes
iphone_air_landscapeiPhone Air landscape794×3703yes
iphone_seiPhone SE375×6672yes
iphone_se_3rd_geniPhone SE (3rd gen)375×6672yes
iphone_se_3rd_gen_landscapeiPhone SE (3rd gen) landscape667×3752yes
iphone_se_landscapeiPhone SE landscape568×3202yes
iphone_xiPhone X375×8123yes
iphone_x_landscapeiPhone X landscape812×3753yes
iphone_xriPhone XR414×8963yes
iphone_xr_landscapeiPhone XR landscape896×4143yes
kindle_fire_hdxKindle Fire HDX800×12802yes
kindle_fire_hdx_landscapeKindle Fire HDX landscape1280×8002yes
laptopLaptop (retina)1440×9002
lg_optimus_l70LG Optimus L70384×6401.25yes
lg_optimus_l70_landscapeLG Optimus L70 landscape640×3841.25yes
microsoft_lumia_550Microsoft Lumia 550360×6402yes
microsoft_lumia_550_landscapeMicrosoft Lumia 550 landscape640×3602yes
microsoft_lumia_950Microsoft Lumia 950360×6404yes
microsoft_lumia_950_landscapeMicrosoft Lumia 950 landscape640×3604yes
moto_g4Moto G4360×6403yes
moto_g4_landscapeMoto G4 landscape640×3603yes
nexus_10Nexus 10800×12802yes
nexus_10_landscapeNexus 10 landscape1280×8002yes
nexus_4Nexus 4384×6402yes
nexus_4_landscapeNexus 4 landscape640×3842yes
nexus_5Nexus 5360×6403yes
nexus_5_landscapeNexus 5 landscape640×3603yes
nexus_5xNexus 5X412×7322.625yes
nexus_5x_landscapeNexus 5X landscape732×4122.625yes
nexus_6Nexus 6412×7323.5yes
nexus_6_landscapeNexus 6 landscape732×4123.5yes
nexus_6pNexus 6P412×7323.5yes
nexus_6p_landscapeNexus 6P landscape732×4123.5yes
nexus_7Nexus 7600×9602yes
nexus_7_landscapeNexus 7 landscape960×6002yes
nokia_lumia_520Nokia Lumia 520320×5331.5yes
nokia_lumia_520_landscapeNokia Lumia 520 landscape533×3201.5yes
nokia_n9Nokia N9480×8541yes
nokia_n9_landscapeNokia N9 landscape854×4801yes
pixelPixel412×9152.625yes
pixel_10Pixel 10360×7323yes
pixel_10_landscapePixel 10 landscape756×3083yes
pixel_10_proPixel 10 Pro427×8763yes
pixel_10_pro_landscapePixel 10 Pro landscape900×3753yes
pixel_10_pro_xlPixel 10 Pro XL448×9213yes
pixel_10_pro_xl_landscapePixel 10 Pro XL landscape945×3963yes
pixel_2Pixel 2411×7312.625yes
pixel_2_landscapePixel 2 landscape731×4112.625yes
pixel_2_xlPixel 2 XL411×8233.5yes
pixel_2_xl_landscapePixel 2 XL landscape823×4113.5yes
pixel_3Pixel 3393×7862.75yes
pixel_3_landscapePixel 3 landscape786×3932.75yes
pixel_4Pixel 4353×7453yes
pixel_4_landscapePixel 4 landscape745×3533yes
pixel_4a_5gPixel 4a (5G)412×7652.63yes
pixel_4a_5g_landscapePixel 4a (5G) landscape840×3122.63yes
pixel_5Pixel 5393×7272.75yes
pixel_5_landscapePixel 5 landscape802×2932.75yes
pixel_6Pixel 6412×8392.625yes
pixel_6_landscapePixel 6 landscape863×3602.625yes
pixel_6_proPixel 6 Pro412×8163.5yes
pixel_6_pro_landscapePixel 6 Pro landscape840×3603.5yes
pixel_6aPixel 6a412×8392.625yes
pixel_6a_landscapePixel 6a landscape863×3602.625yes
pixel_7Pixel 7412×8392.625yes
pixel_7_landscapePixel 7 landscape863×3602.625yes
pixel_7_proPixel 7 Pro412×8163.5yes
pixel_7_pro_landscapePixel 7 Pro landscape840×3603.5yes
pixel_7aPixel 7a412×8392.625yes
pixel_7a_landscapePixel 7a landscape863×3602.625yes
pixel_8Pixel 8412×8392.625yes
pixel_8_landscapePixel 8 landscape863×3602.625yes
pixel_8_proPixel 8 Pro448×9213yes
pixel_8_pro_landscapePixel 8 Pro landscape945×3963yes
pixel_8aPixel 8a412×8392.625yes
pixel_8a_landscapePixel 8a landscape863×3602.625yes
pixel_9Pixel 9360×7323yes
pixel_9_landscapePixel 9 landscape756×3083yes
pixel_9_proPixel 9 Pro427×8763yes
pixel_9_pro_landscapePixel 9 Pro landscape900×3753yes
pixel_9_pro_xlPixel 9 Pro XL448×9213yes
pixel_9_pro_xl_landscapePixel 9 Pro XL landscape945×3963yes

Try a single page in the browser with the free mobile-friendly test.