Airtable Screenshot Automation

Automate website screenshots in Airtable with ScreenshotRun API. Copy-paste scripts for automations, Scripting Extension, and Zapier/Make. Gallery view thumbnails, batch processing, troubleshooting.

Updated

Airtable has no built-in way to screenshot a website. The URL Preview extension handles YouTube embeds and a handful of other services, but point it at a regular webpage and you get nothing. Forum threads about this go back years, and the answer is always the same: use an external API.

That's where airtable screenshot automation with ScreenshotRun comes in. Add a URL to a record, and an automation calls the API, captures the page, and writes the image straight into an attachment field — an airtable url to image pipeline you can set up in five minutes. The screenshot shows up in gallery view, interface designer, or wherever you display attachments. You don't need browser extensions, manual captures, or images scattered across local folders.

What you need before starting

Three things:

  1. An Airtable base on a paid plan that includes the "Run a Script" automation action (check Airtable's pricing page for current plan details)
  2. A ScreenshotRun API key from the dashboard (free plan, 200 captures/month, no credit card)
  3. A table with at least two fields: a URL field for the website address and an Attachment field for the screenshot

If your base is on the free plan, skip ahead to the Zapier / Make alternative or the Scripting Extension method.

Set up airtable screenshot automation with built-in scripting

Airtable's automation engine watches for new or updated records, runs a short JavaScript script, calls the ScreenshotRun API, and saves the image as an attachment. Most direct path you'll find — no middleware, no external tools.

Step 1. Open your base and go to Automations in the top bar. Click Create automation.

Step 2. Set the trigger to "When record matches conditions". Configure it to fire when your URL field is not empty AND your Screenshot attachment field is empty. This way the automation only runs for records that have a URL but no screenshot yet.

Step 3. Add an action: "Run a script". Before writing the script, click Add an input variable and map two values from the trigger record:

  • recordId — the record's ID
  • websiteUrl — the URL field value

Step 4. Click the key icon to open Secrets. Add a secret named SCREENSHOTRUN_KEY with your API key as the value. This keeps the key out of the script text where collaborators could see it.

Step 5. Paste this script:

// Airtable Automation — capture a screenshot and save it as an attachment
const API = 'https://api.screenshotrun.com/v1/screenshots/capture';
const key = input.secrets.SCREENSHOTRUN_KEY;

const recordId = input.config().recordId;
const url = input.config().websiteUrl;

if (!url) {
    console.log('No URL provided, skipping');
    return;
}

const params = new URLSearchParams({
    url: url,
    format: 'png',
    width: '1280',
    full_page: 'false',
    block_cookies: 'true'
});

try {
    const response = await fetch(`${API}?${params}`, {
        headers: { 'Authorization': `Bearer ${key}` }
    });

    if (!response.ok) {
        console.error(`API returned ${response.status}: ${await response.text()}`);
        return;
    }

    const result = await response.json();
    const screenshotUrl = result.screenshot_url;

    const table = base.getTable('Your Table Name');
    await table.updateRecordAsync(recordId, {
        'Screenshot': [{ url: screenshotUrl, filename: `screenshot-${Date.now()}.png` }]
    });

    console.log(`Screenshot saved for ${url}`);
} catch (err) {
    console.error(`Failed to capture ${url}: ${err.message}`);
}

Replace 'Your Table Name' and 'Screenshot' with your actual table and field names. The script calls the API with the default JSON response type, which returns a temporary URL pointing to the rendered image. Airtable downloads that URL and stores its own permanent copy in the attachment field.

Turn on the automation and create a test record with any URL. Within a few seconds the attachment field should populate with a screenshot.

How the airtable screenshot automation works under the hood

When a record matches your trigger conditions, Airtable's automation runner executes the script on their servers (not in your browser). The script makes a GET request to the ScreenshotRun API, which spins up an ephemeral Chrome instance, loads the page, waits for JavaScript to finish, captures the viewport, and returns a JSON response with a temporary image URL. The script then writes that URL into the attachment field using updateRecordAsync(). Airtable fetches the image from that URL and stores a permanent copy.

From trigger to saved attachment, the whole cycle takes 3-8 seconds depending on the target page. Airtable's automation scripts have a 30-second execution timeout and a limit of 50 fetch() calls per run, which is plenty for single-record triggers. Batch processing needs a different approach, covered below.

Capture desktop and mobile airtable website thumbnails in one run

Want both a desktop and a mobile screenshot for each URL? Add a second attachment field (call it "Mobile Screenshot") and extend the script:

// After the desktop capture above, add a mobile capture
const mobileParams = new URLSearchParams({
    url: url,
    format: 'png',
    width: '390',
    device: 'mobile',
    block_cookies: 'true'
});

const mobileResponse = await fetch(`${API}?${mobileParams}`, {
    headers: { 'Authorization': `Bearer ${key}` }
});

if (mobileResponse.ok) {
    const mobileResult = await mobileResponse.json();
    await table.updateRecordAsync(recordId, {
        'Mobile Screenshot': [{ url: mobileResult.screenshot_url, filename: `mobile-${Date.now()}.png` }]
    });
}

Two API calls, two attachment fields, one automation trigger. Each record gets a 1280px desktop view and a 390px mobile view. This is useful for responsive design previews or tracking how competitor landing pages look on different devices.

Batch processing: hundreds of URLs without hitting limits

The 50-fetch limit and 30-second timeout mean you can't loop through 500 records in a single automation run. The workaround: a checkbox-based queue.

Add a checkbox field called "Needs Screenshot" to your table. Set it to checked for records that need processing. Then create a scheduled automation that runs every 5 minutes:

// Scheduled automation — process up to 10 records per run
const API = 'https://api.screenshotrun.com/v1/screenshots/capture';
const key = input.secrets.SCREENSHOTRUN_KEY;

const table = base.getTable('Your Table Name');
const query = await table.selectRecordsAsync({
    fields: ['URL', 'Screenshot', 'Needs Screenshot']
});

const pending = query.records.filter(r =>
    r.getCellValue('Needs Screenshot') &&
    r.getCellValueAsString('URL') &&
    !r.getCellValue('Screenshot')
);

const batch = pending.slice(0, 10);
console.log(`Processing ${batch.length} of ${pending.length} pending records`);

for (const record of batch) {
    const url = record.getCellValueAsString('URL');
    const params = new URLSearchParams({
        url: url,
        format: 'png',
        width: '1280',
        block_cookies: 'true'
    });

    try {
        const resp = await fetch(`${API}?${params}`, {
            headers: { 'Authorization': `Bearer ${key}` }
        });

        if (resp.ok) {
            const data = await resp.json();
            await table.updateRecordAsync(record.id, {
                'Screenshot': [{ url: data.screenshot_url, filename: `screenshot-${Date.now()}.png` }],
                'Needs Screenshot': false
            });
            console.log(`Done: ${url}`);
        } else {
            console.error(`Failed ${url}: HTTP ${resp.status}`);
        }
    } catch (err) {
        console.error(`Error on ${url}: ${err.message}`);
    }
}

Ten records per run, every 5 minutes. That's 120 records per hour, 2,880 per day — enough to capture website screenshots for your entire Airtable base overnight. The checkbox unchecks after each successful capture, so the queue shrinks automatically. If a capture fails, the checkbox stays checked and the record gets retried on the next run.

For the initial bulk load of a large table, consider using the Scripting Extension instead. It runs in your browser with no fetch limits or timeouts.

Alternative: Airtable Scripting Extension (any plan)

Scripting Extension runs JavaScript directly in your browser, so it works on the Free plan, ignores the 30-second automation timeout, and bypasses the 50-fetch cap. The tradeoff: you have to click a button to run it manually. It won't trigger automatically on new records.

Open your base, click Extensions in the top bar, add Scripting, and paste the same script structure. The only difference is the API: instead of input.config() you use input.recordAsync() or loop through a view.

Best suited for one-time bulk imports where you need to capture website pages across an entire Airtable view. Pasted 500 URLs into a table? Run the scripting extension, let it churn through the list, and close the tab when it's done. For ongoing airtable screenshot automation of new records, the trigger-based approach above is better.

Alternative: Zapier or Make.com (zero code)

If your base is on the Free plan or you'd rather avoid JavaScript entirely, route the workflow through Zapier or Make.com. The pattern:

  1. Trigger: "New Record in Airtable" (or "Updated Record")
  2. Action: HTTP GET request to https://api.screenshotrun.com/v1/screenshots/capture?url=...
  3. Action: "Update Record in Airtable" — write the screenshot URL into the attachment field

Both platforms handle this in three steps with no scripting at all. The Zapier integration guide and Make.com integration guide walk through the full setup.

What ScreenshotRun handles for you

Your Airtable automation sends a URL. Our API spins up a sandboxed Chrome instance, loads the page, waits for JavaScript and lazy-loaded content to settle, renders the viewport, and returns a hosted image URL. The browser never runs on your machine or inside Airtable's automation runner.

That consistency matters when multiple team members trigger automations from different time zones and devices. Every screenshot comes out the same. Cookie consent popups blocking the content? Add block_cookies=true to your params and they're dismissed before capture. Ad banners or live-chat widgets? block_ads=true and block_chats=true clean those up with single parameters instead of brittle CSS selectors you'd have to maintain.

For Airtable attachment fields, PNG works best (clean edges, universal support), but you can also request JPEG, WebP, AVIF, or PDF depending on your use case. Full-page captures stitch scrollable pages into a single tall image. If you only need a specific section, pass a CSS selector to the element screenshot feature and get just the pricing table, hero banner, or whatever you're tracking. The dark mode parameter triggers the site's own prefers-color-scheme dark theme, and geolocation targeting lets you see how the page renders from a specific country.

All of this is available on the free plan: 200 captures per month, every parameter included. Paid plans scale from there if you outgrow the free tier.

Gallery view: see your screenshots as a visual board

Once screenshots start populating the attachment field, switch your table to Gallery view. Set the cover field to your Screenshot attachment. Each screenshot airtable attachment becomes an airtable website thumbnail you can scan at a glance — no need to click through individual URLs.

Three workflows benefit most:

Sales teams maintaining a CRM base with prospect URLs get a visual pipeline. Instead of clicking through 50 websites to qualify leads, the team sees thumbnails inline. A quick scroll through gallery view reveals which prospects have modern, well-maintained sites (worth pursuing) and which have placeholder pages or broken layouts.

Marketing teams tracking competitors can schedule weekly screenshots and watch landing pages evolve over time. Airtable's attachment field stacks multiple images on the same record, so each URL accumulates a visual history. Did the competitor change their pricing page? The before-and-after is right there in the attachment stack.

Editorial calendars benefit too. When a referenced page changes or goes offline, the screenshot field preserves what it looked like on the day someone added it to the base.

Troubleshooting

If your automation runs but the attachment field stays empty, check these common causes:

The script logs "API returned 401" — your API key is wrong or missing. Open the automation, click the key icon, and verify the SCREENSHOTRUN_KEY secret matches what's in your ScreenshotRun dashboard.

The script logs "API returned 422". The URL is malformed or missing. Make sure the URL field contains a full address including https://. Bare domains like example.com won't work.

Screenshots are blank or show a loading spinner — the page hasn't finished loading before the capture fires. Add delay: '3' to your params to wait 3 seconds after page load, or use wait_for_selector: '.main-content' to wait for a specific element. The wait_for_selector feature page explains this in detail.

If screenshots show a cookie banner covering the content, add block_cookies: 'true' to your params. The API detects and dismisses most GDPR/CCPA consent dialogs automatically. See cookie blocking for edge cases.

The automation hits the 30-second timeout — some pages (heavy SPAs, sites with slow third-party scripts) take longer than usual to render. For these cases, use ScreenshotRun's webhook parameter: set webhook_url to an Airtable incoming webhook URL, and the API will POST the result when the capture completes instead of making you wait synchronously.

API parameters for Airtable scripts

Pass these as key-value pairs in URLSearchParams. The API accepts them as query string parameters on a GET request:

ParameterTypeDefaultWhat it does
urlstringrequiredThe website address your Airtable record points to
formatstringpngWhich file type the attachment saves as: png, jpeg, webp, avif, or pdf
widthinteger1280How wide the simulated browser window is, in pixels
heightinteger720Initial window height before scrolling begins (px)
full_pagebooleanfalseCapture below the fold — the API scrolls to the bottom and returns everything as a single file
devicestringdesktopSwitches the screen size and user-agent to match a phone, tablet, or laptop
retinabooleanfalseRenders at double resolution — gallery thumbnails look sharper on Retina screens, but each image is about 4x larger
dark_modebooleanfalseTells the browser to request dark mode — sites like GitHub and Notion will render their dark theme
selectorstring—Capture just one element by its CSS selector
delayinteger—Seconds to wait after page load before capturing (0-10)
wait_for_selectorstring—Pause until a specific element appears in the DOM
block_cookiesbooleanfalseRemoves GDPR cookie walls that would otherwise cover the top of your gallery thumbnails
block_adsbooleanfalseStrips display ads and third-party tracking embeds from the rendered page
block_chatsbooleanfalseRemoves floating support widgets (Intercom, Drift, Crisp, etc.) so they don't obscure the page
stealthbooleanfalseMakes the browser look like a regular visitor to get past bot detection
response_typestringjsonControls the response shape — use json for Airtable automations (returns a downloadable URL), image for raw bytes, or base64 for inline encoding

For Airtable automations, always use the default response_type=json. The JSON response includes a screenshot_url that Airtable can download into an attachment field. Raw bytes or base64 won't work with updateRecordAsync(). The API documentation covers every parameter, including PDF margins, geolocation, webhook callbacks, and response shapes not listed here.

ScreenshotRun vs other screenshot tools for Airtable

Several tools compete in this space. miniExtensions offers a no-code Airtable extension that captures screenshots without any scripting at all, but it gives you zero control over viewport size, format, or content blocking. What you see is what you get. Data Fetcher connects to various screenshot APIs through a marketplace extension, adding another layer between you and the captures. Some teams use Zapier zaps with Urlbox or PagePixels, which works but means paying for both Zapier and the screenshot service.

ScreenshotRun's advantage is the combination of direct Airtable integration (no middleware) with full parameter control. Block cookie banners, capture mobile views, grab just a specific element, enable stealth mode for protected sites. All from the same 15-line script, and the free tier covers enough volume for most Airtable workflows without paying anything.

Worth knowing: Airtable's "Run a Script" action requires a paid plan that includes automations with scripting. If your base doesn't have that feature, the Scripting Extension, Zapier, or Make.com all work as alternatives. That's an Airtable restriction, not a ScreenshotRun one.

FAQ#

No. Airtable's URL Preview extension only supports a limited set of services like YouTube. For general website screenshots, you need an external API like ScreenshotRun connected through an automation script or a no-code tool like Zapier.

The "Run a Script" automation action requires a paid Airtable plan that includes scripting in automations. If your plan doesn't include this, you can use the Scripting Extension (available on all plans including Free), or route through Zapier or Make.com.

ScreenshotRun's free plan includes 200 captures per month with all parameters unlocked. No credit card required, no watermarks, no feature restrictions. Paid plans start at $9/month for higher volumes.

Yes. Use a checkbox-based queue with a scheduled automation that processes 10 records every 5 minutes. That gives you 2,880 captures per day. For one-time bulk imports, the Scripting Extension has no fetch limits or timeouts.

The page likely hasn't finished loading before the capture fires. Add delay: '3' to your API parameters to wait 3 seconds after page load, or use wait_for_selector with a CSS selector for a specific element. Heavy SPAs may need the webhook parameter for async captures.

Screenshot API in a few clicks

Free plan includes 200 screenshots every month. No credit card required.

Sign up → copy your key → make your first call