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
/v1/screenshotsSend 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}'
| Parameter | Default | Description |
|---|---|---|
devices | desktop, iphone | Device ids: our presets (desktop, desktop_hd, laptop, ipad, iphone, iphone_se, pixel, galaxy) or any of the 200+ in the catalog. |
diagnostics | false | Add each device's problems, as in /v1/check. |
keep_days | 1 | Keep the image links for 1–30 days, e.g. to embed them in a pull request. |
Check a page
/v1/checkRenders 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: hiddenonhtmlandbody, 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).
| device | Name | Viewport | Scale | Mobile |
|---|---|---|---|---|
blackberry_playbook | Blackberry PlayBook | 600×1024 | 1 | yes |
blackberry_playbook_landscape | Blackberry PlayBook landscape | 1024×600 | 1 | yes |
blackberry_z30 | BlackBerry Z30 | 360×640 | 2 | yes |
blackberry_z30_landscape | BlackBerry Z30 landscape | 640×360 | 2 | yes |
desktop | Desktop | 1280×800 | 1 | |
desktop_chrome | Desktop Chrome | 1280×720 | 1 | |
desktop_chrome_hidpi | Desktop Chrome HiDPI | 1280×720 | 2 | |
desktop_edge | Desktop Edge | 1280×720 | 1 | |
desktop_edge_hidpi | Desktop Edge HiDPI | 1280×720 | 2 | |
desktop_firefox | Desktop Firefox | 1280×720 | 1 | |
desktop_firefox_hidpi | Desktop Firefox HiDPI | 1280×720 | 2 | |
desktop_hd | Desktop HD | 1920×1080 | 1 | |
desktop_safari | Desktop Safari | 1280×720 | 2 | |
galaxy | Galaxy | 360×780 | 3 | yes |
galaxy_a55 | Galaxy A55 | 480×1040 | 2.25 | yes |
galaxy_a55_landscape | Galaxy A55 landscape | 1040×480 | 2.25 | yes |
galaxy_note_3 | Galaxy Note 3 | 360×640 | 3 | yes |
galaxy_note_3_landscape | Galaxy Note 3 landscape | 640×360 | 3 | yes |
galaxy_note_ii | Galaxy Note II | 360×640 | 2 | yes |
galaxy_note_ii_landscape | Galaxy Note II landscape | 640×360 | 2 | yes |
galaxy_s24 | Galaxy S24 | 360×780 | 3 | yes |
galaxy_s24_landscape | Galaxy S24 landscape | 780×360 | 3 | yes |
galaxy_s5 | Galaxy S5 | 360×640 | 3 | yes |
galaxy_s5_landscape | Galaxy S5 landscape | 640×360 | 3 | yes |
galaxy_s8 | Galaxy S8 | 360×740 | 3 | yes |
galaxy_s8_landscape | Galaxy S8 landscape | 740×360 | 3 | yes |
galaxy_s9_plus | Galaxy S9+ | 320×658 | 4.5 | yes |
galaxy_s9_plus_landscape | Galaxy S9+ landscape | 658×320 | 4.5 | yes |
galaxy_s_iii | Galaxy S III | 360×640 | 2 | yes |
galaxy_s_iii_landscape | Galaxy S III landscape | 640×360 | 2 | yes |
galaxy_tab_s4 | Galaxy Tab S4 | 712×1138 | 2.25 | yes |
galaxy_tab_s4_landscape | Galaxy Tab S4 landscape | 1138×712 | 2.25 | yes |
galaxy_tab_s9 | Galaxy Tab S9 | 640×1024 | 2.5 | yes |
galaxy_tab_s9_landscape | Galaxy Tab S9 landscape | 1024×640 | 2.5 | yes |
galaxy_z_flip_6 | Galaxy Z Flip 6 | 360×804 | 3 | yes |
galaxy_z_flip_6_cover | Galaxy Z Flip 6 Cover | 360×298 | 2 | yes |
galaxy_z_flip_6_cover_landscape | Galaxy Z Flip 6 Cover landscape | 322×308 | 2 | yes |
galaxy_z_flip_6_landscape | Galaxy Z Flip 6 landscape | 828×308 | 3 | yes |
galaxy_z_flip_7 | Galaxy Z Flip 7 | 360×764 | 3 | yes |
galaxy_z_flip_7_cover | Galaxy Z Flip 7 Cover | 474×448 | 2 | yes |
galaxy_z_flip_7_cover_landscape | Galaxy Z Flip 7 Cover landscape | 472×422 | 2 | yes |
galaxy_z_flip_7_landscape | Galaxy Z Flip 7 landscape | 788×308 | 3 | yes |
galaxy_z_fold_6 | Galaxy Z Fold 6 | 928×1004 | 2 | yes |
galaxy_z_fold_6_cover | Galaxy Z Fold 6 Cover | 484×1112 | 2 | yes |
galaxy_z_fold_6_cover_landscape | Galaxy Z Fold 6 Cover landscape | 1136×432 | 2 | yes |
galaxy_z_fold_6_landscape | Galaxy Z Fold 6 landscape | 1028×876 | 2 | yes |
galaxy_z_fold_7 | Galaxy Z Fold 7 | 984×1016 | 2 | yes |
galaxy_z_fold_7_cover | Galaxy Z Fold 7 Cover | 360×764 | 3 | yes |
galaxy_z_fold_7_cover_landscape | Galaxy Z Fold 7 Cover landscape | 788×308 | 3 | yes |
galaxy_z_fold_7_landscape | Galaxy Z Fold 7 landscape | 1040×932 | 2 | yes |
ipad | iPad | 820×1180 | 2 | |
ipad_gen_11 | iPad (gen 11) | 656×944 | 2.5 | yes |
ipad_gen_11_landscape | iPad (gen 11) landscape | 944×656 | 2.5 | yes |
ipad_gen_5 | iPad (gen 5) | 768×1024 | 2 | yes |
ipad_gen_5_landscape | iPad (gen 5) landscape | 1024×768 | 2 | yes |
ipad_gen_6 | iPad (gen 6) | 768×1024 | 2 | yes |
ipad_gen_6_landscape | iPad (gen 6) landscape | 1024×768 | 2 | yes |
ipad_gen_7 | iPad (gen 7) | 810×1080 | 2 | yes |
ipad_gen_7_landscape | iPad (gen 7) landscape | 1080×810 | 2 | yes |
ipad_mini | iPad Mini | 768×1024 | 2 | yes |
ipad_mini_landscape | iPad Mini landscape | 1024×768 | 2 | yes |
ipad_pro_11 | iPad Pro 11 | 834×1194 | 2 | yes |
ipad_pro_11_landscape | iPad Pro 11 landscape | 1194×834 | 2 | yes |
iphone | iPhone | 393×852 | 3 | yes |
iphone_11 | iPhone 11 | 414×715 | 2 | yes |
iphone_11_landscape | iPhone 11 landscape | 800×364 | 2 | yes |
iphone_11_pro | iPhone 11 Pro | 375×635 | 3 | yes |
iphone_11_pro_landscape | iPhone 11 Pro landscape | 724×325 | 3 | yes |
iphone_11_pro_max | iPhone 11 Pro Max | 414×715 | 3 | yes |
iphone_11_pro_max_landscape | iPhone 11 Pro Max landscape | 808×364 | 3 | yes |
iphone_12 | iPhone 12 | 390×664 | 3 | yes |
iphone_12_landscape | iPhone 12 landscape | 750×340 | 3 | yes |
iphone_12_mini | iPhone 12 Mini | 375×629 | 3 | yes |
iphone_12_mini_landscape | iPhone 12 Mini landscape | 712×325 | 3 | yes |
iphone_12_pro | iPhone 12 Pro | 390×664 | 3 | yes |
iphone_12_pro_landscape | iPhone 12 Pro landscape | 750×340 | 3 | yes |
iphone_12_pro_max | iPhone 12 Pro Max | 428×746 | 3 | yes |
iphone_12_pro_max_landscape | iPhone 12 Pro Max landscape | 832×378 | 3 | yes |
iphone_13 | iPhone 13 | 390×664 | 3 | yes |
iphone_13_landscape | iPhone 13 landscape | 750×342 | 3 | yes |
iphone_13_mini | iPhone 13 Mini | 375×629 | 3 | yes |
iphone_13_mini_landscape | iPhone 13 Mini landscape | 712×327 | 3 | yes |
iphone_13_pro | iPhone 13 Pro | 390×664 | 3 | yes |
iphone_13_pro_landscape | iPhone 13 Pro landscape | 750×342 | 3 | yes |
iphone_13_pro_max | iPhone 13 Pro Max | 428×746 | 3 | yes |
iphone_13_pro_max_landscape | iPhone 13 Pro Max landscape | 832×380 | 3 | yes |
iphone_14 | iPhone 14 | 390×664 | 3 | yes |
iphone_14_landscape | iPhone 14 landscape | 750×340 | 3 | yes |
iphone_14_plus | iPhone 14 Plus | 428×746 | 3 | yes |
iphone_14_plus_landscape | iPhone 14 Plus landscape | 832×378 | 3 | yes |
iphone_14_pro | iPhone 14 Pro | 393×660 | 3 | yes |
iphone_14_pro_landscape | iPhone 14 Pro landscape | 734×343 | 3 | yes |
iphone_14_pro_max | iPhone 14 Pro Max | 430×740 | 3 | yes |
iphone_14_pro_max_landscape | iPhone 14 Pro Max landscape | 814×380 | 3 | yes |
iphone_15 | iPhone 15 | 393×659 | 3 | yes |
iphone_15_landscape | iPhone 15 landscape | 734×343 | 3 | yes |
iphone_15_plus | iPhone 15 Plus | 430×739 | 3 | yes |
iphone_15_plus_landscape | iPhone 15 Plus landscape | 814×380 | 3 | yes |
iphone_15_pro | iPhone 15 Pro | 393×659 | 3 | yes |
iphone_15_pro_landscape | iPhone 15 Pro landscape | 734×343 | 3 | yes |
iphone_15_pro_max | iPhone 15 Pro Max | 430×739 | 3 | yes |
iphone_15_pro_max_landscape | iPhone 15 Pro Max landscape | 814×380 | 3 | yes |
iphone_16 | iPhone 16 | 393×659 | 3 | yes |
iphone_16_landscape | iPhone 16 landscape | 734×343 | 3 | yes |
iphone_16_plus | iPhone 16 Plus | 430×739 | 3 | yes |
iphone_16_plus_landscape | iPhone 16 Plus landscape | 814×380 | 3 | yes |
iphone_16_pro | iPhone 16 Pro | 402×681 | 3 | yes |
iphone_16_pro_landscape | iPhone 16 Pro landscape | 756×352 | 3 | yes |
iphone_16_pro_max | iPhone 16 Pro Max | 440×763 | 3 | yes |
iphone_16_pro_max_landscape | iPhone 16 Pro Max landscape | 838×390 | 3 | yes |
iphone_16e | iPhone 16e | 390×651 | 3 | yes |
iphone_16e_landscape | iPhone 16e landscape | 726×340 | 3 | yes |
iphone_17 | iPhone 17 | 402×681 | 3 | yes |
iphone_17_landscape | iPhone 17 landscape | 756×352 | 3 | yes |
iphone_17_pro | iPhone 17 Pro | 402×681 | 3 | yes |
iphone_17_pro_landscape | iPhone 17 Pro landscape | 756×352 | 3 | yes |
iphone_17_pro_max | iPhone 17 Pro Max | 440×763 | 3 | yes |
iphone_17_pro_max_landscape | iPhone 17 Pro Max landscape | 838×390 | 3 | yes |
iphone_17e | iPhone 17e | 390×651 | 3 | yes |
iphone_17e_landscape | iPhone 17e landscape | 726×340 | 3 | yes |
iphone_6 | iPhone 6 | 375×667 | 2 | yes |
iphone_6_landscape | iPhone 6 landscape | 667×375 | 2 | yes |
iphone_6_plus | iPhone 6 Plus | 414×736 | 3 | yes |
iphone_6_plus_landscape | iPhone 6 Plus landscape | 736×414 | 3 | yes |
iphone_7 | iPhone 7 | 375×667 | 2 | yes |
iphone_7_landscape | iPhone 7 landscape | 667×375 | 2 | yes |
iphone_7_plus | iPhone 7 Plus | 414×736 | 3 | yes |
iphone_7_plus_landscape | iPhone 7 Plus landscape | 736×414 | 3 | yes |
iphone_8 | iPhone 8 | 375×667 | 2 | yes |
iphone_8_landscape | iPhone 8 landscape | 667×375 | 2 | yes |
iphone_8_plus | iPhone 8 Plus | 414×736 | 3 | yes |
iphone_8_plus_landscape | iPhone 8 Plus landscape | 736×414 | 3 | yes |
iphone_air | iPhone Air | 420×719 | 3 | yes |
iphone_air_landscape | iPhone Air landscape | 794×370 | 3 | yes |
iphone_se | iPhone SE | 375×667 | 2 | yes |
iphone_se_3rd_gen | iPhone SE (3rd gen) | 375×667 | 2 | yes |
iphone_se_3rd_gen_landscape | iPhone SE (3rd gen) landscape | 667×375 | 2 | yes |
iphone_se_landscape | iPhone SE landscape | 568×320 | 2 | yes |
iphone_x | iPhone X | 375×812 | 3 | yes |
iphone_x_landscape | iPhone X landscape | 812×375 | 3 | yes |
iphone_xr | iPhone XR | 414×896 | 3 | yes |
iphone_xr_landscape | iPhone XR landscape | 896×414 | 3 | yes |
kindle_fire_hdx | Kindle Fire HDX | 800×1280 | 2 | yes |
kindle_fire_hdx_landscape | Kindle Fire HDX landscape | 1280×800 | 2 | yes |
laptop | Laptop (retina) | 1440×900 | 2 | |
lg_optimus_l70 | LG Optimus L70 | 384×640 | 1.25 | yes |
lg_optimus_l70_landscape | LG Optimus L70 landscape | 640×384 | 1.25 | yes |
microsoft_lumia_550 | Microsoft Lumia 550 | 360×640 | 2 | yes |
microsoft_lumia_550_landscape | Microsoft Lumia 550 landscape | 640×360 | 2 | yes |
microsoft_lumia_950 | Microsoft Lumia 950 | 360×640 | 4 | yes |
microsoft_lumia_950_landscape | Microsoft Lumia 950 landscape | 640×360 | 4 | yes |
moto_g4 | Moto G4 | 360×640 | 3 | yes |
moto_g4_landscape | Moto G4 landscape | 640×360 | 3 | yes |
nexus_10 | Nexus 10 | 800×1280 | 2 | yes |
nexus_10_landscape | Nexus 10 landscape | 1280×800 | 2 | yes |
nexus_4 | Nexus 4 | 384×640 | 2 | yes |
nexus_4_landscape | Nexus 4 landscape | 640×384 | 2 | yes |
nexus_5 | Nexus 5 | 360×640 | 3 | yes |
nexus_5_landscape | Nexus 5 landscape | 640×360 | 3 | yes |
nexus_5x | Nexus 5X | 412×732 | 2.625 | yes |
nexus_5x_landscape | Nexus 5X landscape | 732×412 | 2.625 | yes |
nexus_6 | Nexus 6 | 412×732 | 3.5 | yes |
nexus_6_landscape | Nexus 6 landscape | 732×412 | 3.5 | yes |
nexus_6p | Nexus 6P | 412×732 | 3.5 | yes |
nexus_6p_landscape | Nexus 6P landscape | 732×412 | 3.5 | yes |
nexus_7 | Nexus 7 | 600×960 | 2 | yes |
nexus_7_landscape | Nexus 7 landscape | 960×600 | 2 | yes |
nokia_lumia_520 | Nokia Lumia 520 | 320×533 | 1.5 | yes |
nokia_lumia_520_landscape | Nokia Lumia 520 landscape | 533×320 | 1.5 | yes |
nokia_n9 | Nokia N9 | 480×854 | 1 | yes |
nokia_n9_landscape | Nokia N9 landscape | 854×480 | 1 | yes |
pixel | Pixel | 412×915 | 2.625 | yes |
pixel_10 | Pixel 10 | 360×732 | 3 | yes |
pixel_10_landscape | Pixel 10 landscape | 756×308 | 3 | yes |
pixel_10_pro | Pixel 10 Pro | 427×876 | 3 | yes |
pixel_10_pro_landscape | Pixel 10 Pro landscape | 900×375 | 3 | yes |
pixel_10_pro_xl | Pixel 10 Pro XL | 448×921 | 3 | yes |
pixel_10_pro_xl_landscape | Pixel 10 Pro XL landscape | 945×396 | 3 | yes |
pixel_2 | Pixel 2 | 411×731 | 2.625 | yes |
pixel_2_landscape | Pixel 2 landscape | 731×411 | 2.625 | yes |
pixel_2_xl | Pixel 2 XL | 411×823 | 3.5 | yes |
pixel_2_xl_landscape | Pixel 2 XL landscape | 823×411 | 3.5 | yes |
pixel_3 | Pixel 3 | 393×786 | 2.75 | yes |
pixel_3_landscape | Pixel 3 landscape | 786×393 | 2.75 | yes |
pixel_4 | Pixel 4 | 353×745 | 3 | yes |
pixel_4_landscape | Pixel 4 landscape | 745×353 | 3 | yes |
pixel_4a_5g | Pixel 4a (5G) | 412×765 | 2.63 | yes |
pixel_4a_5g_landscape | Pixel 4a (5G) landscape | 840×312 | 2.63 | yes |
pixel_5 | Pixel 5 | 393×727 | 2.75 | yes |
pixel_5_landscape | Pixel 5 landscape | 802×293 | 2.75 | yes |
pixel_6 | Pixel 6 | 412×839 | 2.625 | yes |
pixel_6_landscape | Pixel 6 landscape | 863×360 | 2.625 | yes |
pixel_6_pro | Pixel 6 Pro | 412×816 | 3.5 | yes |
pixel_6_pro_landscape | Pixel 6 Pro landscape | 840×360 | 3.5 | yes |
pixel_6a | Pixel 6a | 412×839 | 2.625 | yes |
pixel_6a_landscape | Pixel 6a landscape | 863×360 | 2.625 | yes |
pixel_7 | Pixel 7 | 412×839 | 2.625 | yes |
pixel_7_landscape | Pixel 7 landscape | 863×360 | 2.625 | yes |
pixel_7_pro | Pixel 7 Pro | 412×816 | 3.5 | yes |
pixel_7_pro_landscape | Pixel 7 Pro landscape | 840×360 | 3.5 | yes |
pixel_7a | Pixel 7a | 412×839 | 2.625 | yes |
pixel_7a_landscape | Pixel 7a landscape | 863×360 | 2.625 | yes |
pixel_8 | Pixel 8 | 412×839 | 2.625 | yes |
pixel_8_landscape | Pixel 8 landscape | 863×360 | 2.625 | yes |
pixel_8_pro | Pixel 8 Pro | 448×921 | 3 | yes |
pixel_8_pro_landscape | Pixel 8 Pro landscape | 945×396 | 3 | yes |
pixel_8a | Pixel 8a | 412×839 | 2.625 | yes |
pixel_8a_landscape | Pixel 8a landscape | 863×360 | 2.625 | yes |
pixel_9 | Pixel 9 | 360×732 | 3 | yes |
pixel_9_landscape | Pixel 9 landscape | 756×308 | 3 | yes |
pixel_9_pro | Pixel 9 Pro | 427×876 | 3 | yes |
pixel_9_pro_landscape | Pixel 9 Pro landscape | 900×375 | 3 | yes |
pixel_9_pro_xl | Pixel 9 Pro XL | 448×921 | 3 | yes |
pixel_9_pro_xl_landscape | Pixel 9 Pro XL landscape | 945×396 | 3 | yes |
Try a single page in the browser with the free mobile-friendly test.