ScreenshotNeo

BlogHow-to

How to Use a Screenshot API with Airtable Automations

Capture a webpage from an Airtable automation, save its result, and handle authentication, validation, failures, and asynchronous callbacks.

By the ScreenshotNeo team4 October 202611 min read

An Airtable automation can call a screenshot API from its Run a script action using JavaScript’s fetch(). Pass the page URL and provider options into the script, validate the URL, call the provider’s documented endpoint, then save the returned image URL or job status to Airtable. The request format and result type depend on the screenshot provider.

This guide uses ScreenshotNeo for a concrete synchronous example. Its API returns an image response, so the script below stores the image in an Airtable attachment by converting the bytes to a data URL. For other providers, first confirm whether they return image bytes, a hosted URL, or an asynchronous job reference; those results need different handling.

1. Choose the automation trigger and result fields

Start with the event that should cause a capture:

  • When a record is created or updated: use this when the record itself contains the page URL.
  • When a record matches conditions: use this when capture should begin only after fields reach a particular state, such as Ready.
  • When webhook received: use this when an external system should initiate the workflow. The incoming webhook URL is a secret: anyone who has it can trigger the automation.

Create fields for the source URL, capture status, captured time, and screenshot. The screenshot field should be an Attachment if you intend to retain an image file. Consider also storing a provider result reference or page verdict for diagnosis. A URL field can hold a hosted image link when the provider returns one, but a link is not the same as an Airtable-managed attachment.

Airtable automations have a trigger and one or more actions. Use a Run a script action for the outbound API call. Airtable does not provide a generic native action to send an HTTP request to any arbitrary URL. Its scripting environment supports fetch(); server-side automation calls do not need a browser CORS workaround. Check your current Airtable plan and limits: Run a script is unavailable on the Free plan.

2. Configure the Run a script action

  1. Add the trigger and test it with a representative record.
  2. Add a Run a script action.
  3. Under input variables, add recordId and pageUrl. Map them to the triggering record’s Airtable record ID and URL field.
  4. Replace YOUR_API_KEY in the script with a secret value. Store it in Airtable’s secret input feature if available in your scripting action; otherwise restrict access to the automation and avoid putting the key in a visible table field.
  5. Run the script test. Confirm the returned output, then add an Update record action to write the returned attachment and status to the triggering record. Map the script output to the matching fields.
  6. Turn the automation on and verify it with a record that is safe to capture.

In the script action, define the input variables recordId and pageUrl. This complete example calls ScreenshotNeo’s documented GET endpoint and receives an image. The conversion to a data URL lets the next Airtable action consume the image as an attachment object. Large images may exceed scripting or attachment limits; for high volume or large files, use a provider-supported hosted URL or an external workflow that uploads the image and passes Airtable an accessible URL.

const { recordId, pageUrl } = input.config();
const apiKey = 'YOUR_API_KEY';

// Limit captures to the pages this workflow is intended to process.
const allowedHosts = new Set(['example.com', 'www.example.com']);
let parsed;
try {
  parsed = new URL(pageUrl);
} catch {
  throw new Error('The page URL is missing or invalid.');
}
if (parsed.protocol !== 'https:' || !allowedHosts.has(parsed.hostname)) {
  throw new Error('Only approved HTTPS page URLs can be captured.');
}

const endpoint = new URL('https://api.screenshotneo.com/v1/shot');
endpoint.searchParams.set('access_key', apiKey);
endpoint.searchParams.set('url', parsed.href);

const response = await fetch(endpoint.toString());
if (!response.ok) {
  const detail = await response.text();
  throw new Error(`Screenshot API returned HTTP ${response.status}: ${detail.slice(0, 500)}`);
}

const contentType = response.headers.get('content-type') || '';
if (!contentType.startsWith('image/')) {
  throw new Error(`Expected an image response, received ${contentType || 'unknown content type'}.`);
}
const bytes = new Uint8Array(await response.arrayBuffer());
if (bytes.length === 0) throw new Error('Screenshot API returned an empty image.');

// Convert image bytes to base64 for an Airtable attachment value.
let binary = '';
for (let i = 0; i < bytes.length; i += 0x8000) {
  binary += String.fromCharCode(...bytes.subarray(i, i + 0x8000));
}
const base64 = btoa(binary);
const extension = contentType.includes('webp') ? 'webp' : contentType.includes('jpeg') ? 'jpg' : 'png';
const attachment = {
  url: `data:${contentType};base64,${base64}`,
  filename: `screenshot-${recordId}.${extension}`
};

output.set('captureStatus', 'complete');
output.set('capturedAt', new Date().toISOString());
output.set('screenshotAttachment', [attachment]);

In the following Update record action, select the table and map recordId to Record ID, captureStatus to your status field, capturedAt to your date field, and screenshotAttachment to your attachment field. Airtable’s exact output mapping UI can vary; use the script test result to select the named outputs.

3. Validate inputs and protect the workflow

The URL may come from a form submission, imported row, or external webhook. Treat it as untrusted input. A screenshot endpoint that accepts arbitrary URLs can be abused as a capture proxy, so the example uses an explicit HTTPS host allowlist. Replace the sample host with the sites this workflow should capture. If several subdomains are legitimate, enumerate them or validate a carefully defined suffix; a naive check such as hostname.endsWith("example.com") also accepts deceptive names like notexample.com.

  • Reject non-HTTPS URLs unless your use case explicitly requires HTTP.
  • Decide whether redirects to other hosts are allowed; do not assume checking the submitted hostname validates every redirect destination.
  • Keep API credentials out of record fields, URLs exposed in logs, and script outputs. ScreenshotNeo’s documented API example uses an access key query parameter, so treat request URLs and execution logs as potentially sensitive.
  • Limit who can edit the automation and who can access an incoming webhook URL.
  • Do not pass user-controlled custom headers, cookies, or JavaScript through without validating them.

4. Handle the provider’s response format

Before building the destination fields, determine how the chosen provider completes the capture:

Provider result Airtable handling Design consideration
Image bytes in the response Convert bytes to a supported attachment value or upload through a supported external path. Confirm automation size/runtime limits; base64 increases data size.
Hosted image URL Write the URL to a URL field, or use an accessible URL as an attachment source if supported. Check link lifetime, access controls, and whether Airtable can fetch it.
Asynchronous job ID Store the job ID and status, then process completion later. Do not treat job acceptance as successful image completion.
Callback/webhook result Use Airtable’s incoming webhook trigger or an external callback service, then update the matching record. Correlate the callback with a record and protect the webhook URL.

There is no universal binary-to-Airtable procedure established for every provider and plan. Verify the selected provider’s response contract and Airtable’s current attachment behavior before relying on a direct image transfer. ScreenshotNeo supports synchronous screenshots through its shot endpoint as shown below; it also supports asynchronous jobs with signed webhooks when a job workflow is more suitable.

5. Use an incoming webhook for external starts or asynchronous returns

Choose Airtable’s When webhook received trigger if another service should start the capture, or if a callback workflow should resume after an external job completes. Configure the external service with the unique webhook URL Airtable generates and map the incoming payload fields into subsequent actions.

For asynchronous capture, store a correlation value such as the Airtable record ID alongside the provider’s job ID. When the provider calls back, validate and correlate the event before updating the row. Airtable warns that anyone with the incoming webhook URL can trigger its automation, so treat that URL like a credential. Do not publish it in a page, shared document, or client-side code. Review Airtable’s trigger availability and limits for your plan.

6. Batch workflows and Airtable’s Web API

A single-record automation should process the triggering record directly rather than scan the table. If an external batch process needs to enumerate records through Airtable’s Web API, Airtable returns list results in pages of up to 100 records; paginate when more records exist. Also respect the screenshot provider’s own batch and rate limits. ScreenshotNeo supports bulk capture of up to 100 URLs per call, but that API capability does not remove Airtable pagination or automation limits.

7. Performance, reliability, and cost

  • Keep the payload small: storing a full base64 image in a script output is convenient for modest images but consumes more memory and data than a hosted URL. Prefer an explicitly supported upload or URL workflow for larger captures.
  • Use clear states: write statuses such as Queued, Complete, and Error, plus a timestamp and provider reference. This makes retries and stale jobs visible.
  • Make retries safe: a rerun should update the same record rather than create duplicate rows. If a trigger can repeat, use the record ID and a capture version or request identifier to identify the latest result.
  • Set a bounded wait strategy: synchronous webpage rendering can take time. Use the provider’s supported wait options and keep within Airtable’s script runtime constraints. For long-running captures, use asynchronous jobs and callbacks.
  • Budget both services: account for Airtable plan and automation limits, provider pricing, capture volume, and any external storage. Provider costs and limits differ, so check the selected provider’s current documentation.

ScreenshotNeo bills only clean shots. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not charged; responses include X-Page-Verdict and X-Billed headers to show the result. Plans are Free for 1,000 shots per month with no card, Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free, and every feature is available on every plan. Check current plan details before choosing a volume.

8. Troubleshooting

Symptom Likely cause What to check or change
Run a script is missing The Airtable plan does not include it, or the automation setup is restricted. Check the current plan and automation documentation. Run a script is unavailable on Airtable Free.
fetch fails or times out Network issue, slow target site, provider timeout, or script runtime limit. Try a known reachable URL, review provider status/error details, reduce wait time, or use asynchronous completion.
HTTP 401/403 Missing, invalid, or unauthorized API credential. Check the key, account access, and provider authentication instructions. Do not place secrets in the Airtable record.
HTTP 400 Invalid parameter, malformed URL, or unsupported option. Log a redacted request summary, check URL parsing and provider parameter names, and remove optional settings until the basic call succeeds.
The script says it expected an image The provider returned JSON or an error page instead of image bytes. Inspect the status and a short, redacted response body. The provider may use a URL or asynchronous job response rather than raw image bytes.
Attachment is empty or rejected The response had no bytes, the data URL is too large, or Airtable does not accept that attachment transfer in this action. Check content type and byte count. Use the provider’s hosted URL or a documented upload path if supported.
Automation test works but record is not updated The Update record action is mapped to the wrong record or output. Map the trigger’s record ID and select the named script outputs from a successful test.
Callback starts unexpectedly The incoming webhook URL was shared or exposed. Restrict access, rotate or replace the webhook trigger URL if possible, and review automation history.
The capture shows a consent dialog or overlay The provider does not remove that site’s consent platform, or cleanup is disabled. Check provider cleanup options and capture settings. ScreenshotNeo accepts cookie/consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off.

9. Screenshot API request examples

These examples use ScreenshotNeo’s GET endpoint. Add the access key securely for your environment and substitute the page URL you are authorized to capture. See the ScreenshotNeo API documentation for its request options and response details.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as f:
    f.write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot API returned HTTP ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));

10. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request takes a URL and returns a PNG, JPEG, WebP, or PDF. The same call can run inside Airtable’s script action; the returned body is the image response. For Airtable, use the attachment handling pattern above or a supported hosted-result workflow.

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  • Cookie banners, popups, and chat widgets are removed before the shot.
  • Bot checks, blank pages, and failed loads are never billed.
  • An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf.
  • 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000.

Sign up free for 1,000 screenshots a month, with no card required. See the API documentation for request configuration.

FAQ

Can I call a screenshot API without a script action?

Airtable’s documented custom outbound request path is Run a script with fetch(). For a third-party automation platform or middleware, use that service’s documented HTTP action and Airtable API integration.

Can Airtable store the screenshot itself?

An Attachment field can retain an image, but the workable transfer depends on the provider’s response and Airtable’s current limits. Confirm the supported method for image bytes or hosted URLs before designing around it.

Can an external service trigger the capture?

Yes. Use Airtable’s incoming webhook trigger, or let an external system call a separate workflow that updates Airtable. Keep any Airtable webhook URL private because possession allows triggering.

Does the ScreenshotNeo API require browser automation in Airtable?

No. The script makes an HTTP request to the API. Browser rendering happens as part of the screenshot service’s capture process.

Sources