# Generate images in Airtable: an automation script that fills an attachment field

> Generate an image for each Airtable record with a Run a script automation: the script, an attachment field filled from the image URL, and the limits.

Published 2026-11-06 · https://shareglint.com/en/integrations/airtable

To generate images in Airtable, add an automation with a **Run a script** action: when a record is ready, the script sends the record's fields to `https://shareglint.com/v1/images?wait=true` and writes the returned image into an **attachment field** of the same record. The image then shows in grid and gallery views, and its URL can go into a second field for your website or scheduler. There is no native Airtable extension; the script below is the integration.

## What Airtable requires

From Airtable's support and developer documentation (read 2026-11-06):

- **Plan:** the Run a script action is unavailable on the Free plan and on a Team plan trial ([Airtable Support](https://support.airtable.com/articles/6328053615-airtable-automation-action-run-a-script)).
- **Runtime:** scripts may currently run up to 120 seconds (Airtable describes this as temporarily raised from 30 seconds), each `fetch()` times out after 30 seconds, and a run may make **50 fetch requests** (same page).
- **Attachments from a URL:** "To create new attachments, provide the url and optionally filename"; the URL must be publicly accessible, and uploading happens asynchronously ([Airtable Web API](https://airtable.com/developers/web/api/field-model#multipleattachment)). In scripts, "the specified array will overwrite the current cell value", so include existing attachments if you want to keep them.

A render finishes in seconds, well inside those limits; animated GIF and MP4 renders take longer, so keep them to a few per run.

## The table

Use a table with the template's fields as columns, plus:

- **Status** (single select): `Draft`, `Ready`, `Done`.
- **Image** (attachment).
- **Image URL** (URL) — useful because Airtable's own attachment URLs "expire 2 hours after being returned from our API", while the render URL stays the same for your plan's retention period.

## The automation

1. **Trigger:** *When a record matches conditions* — Status is `Ready`.
2. **Action:** *Run a script*. Under **Input variables** add `recordId` (the trigger record's ID) and the fields the template needs, for example `title` and `author`.
3. **Action:** *Update record* — Status to `Done` (or do it in the script, as below).

The script:

```javascript
// Run a script — renders one image for the triggering record.
const { recordId, title, author } = input.config();
const API_KEY = 'sk_live_...'; // a key made only for this base; revoke it if the base is shared

const response = await fetch('https://shareglint.com/v1/images?wait=true', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    template: 'social-post',
    format: 'png',
    modifications: { text: title, name: author },
  }),
});

const image = await response.json();
if (!response.ok) {
  throw new Error(`Render failed (${response.status}): ${JSON.stringify(image)}`);
}

const table = base.getTable('Posts');
await table.updateRecordAsync(recordId, {
  'Image': [{ url: image.url, filename: `${recordId}.png` }],
  'Image URL': image.url,
  'Status': { name: 'Done' },
});
```

Airtable downloads the file from `image.url` into the attachment field. A failed render throws, so the automation run shows as failed in its history and the record stays `Ready`. Fix the data, then set Status to `Draft` and back to `Ready` to run it again (the trigger fires when a record starts matching).

**About the key.** Anyone who can edit the base can read the script, and with it the key. Make a separate API key in the Shareglint dashboard for this base, so revoking it affects nothing else.

## Several sizes, or many records at once

- **Sizes:** add `sizes: ['square', 'story']` to the body. The response has a `renders` list with one `url` per size; write each into its own attachment field, or all into one field as an array.
- **Many records:** a script that renders one image per `fetch()` handles up to 50 records per run. For a whole table, send one `POST /v1/batches` with the records as `rows` (one call), then read the batch with `GET /v1/batches/{id}` and write each row's `url` back. Rows per batch by plan: Free 50, Starter 500, Pro 1,000, Scale 2,000, Business 5,000. Airtable's Web API, if you write back from outside Airtable, is limited to 5 requests per second per base ([Airtable rate limits](https://airtable.com/developers/web/api/rate-limits)).

Re-running a record with unchanged fields costs nothing: the same template and values return the existing image without using quota.

## Bases this fits

Airtable is often where the data behind recurring images already lives, so the automation slots into bases teams use anyway:

- **Content calendar.** One record per post with the quote or headline; the image is ready in the record when the post is approved, in the sizes each network needs ([social media images](https://shareglint.com/en/use-cases/social-media-images)).
- **Product catalogue.** Name, price and photo per product; a sale or price-drop card per record when the price field changes ([e-commerce product images](https://shareglint.com/en/use-cases/ecommerce-product-images)).
- **Events.** Speakers or attendees as records; a speaker card or badge per record ([event graphics](https://shareglint.com/en/use-cases/event-graphics)).
- **Courses.** Completions as records; a certificate per student, as a PDF with `format: 'pdf'` ([certificates](https://shareglint.com/en/use-cases/certificates)).

In each case the trigger condition is what keeps it cheap: render when the record is approved or changed, not on every edit.

## Without a script

On a plan without scripting, use [Zapier](https://shareglint.com/en/integrations/zapier), [Make](https://shareglint.com/en/integrations/make) or [n8n](https://shareglint.com/en/integrations/n8n) with an Airtable trigger and an HTTP step: the same request, and an Airtable *Update record* step that writes the URL into the attachment field.

## Cost

One render per image and size; repeats are free. The Free plan's 100 renders a month carry a watermark; Starter is $9 a month for 2,000 renders ([pricing](https://shareglint.com/en/pricing)).

## What it does not do

- It is not an Airtable extension or app: there is no button in the Airtable interface, only the automation.
- It does not read your base: each request carries only the fields the script sends.
- It does not keep images beyond your plan's retention period; the attachment field is stored by Airtable as part of the record.

## FAQ

### Can Airtable generate images from records?

Yes, with an automation: when a record is ready, a Run a script action sends its fields to the image API, and the script puts the returned image into an attachment field. There is no native Airtable extension for it; the script is about twenty lines.

### Which Airtable plan do I need?

A paid one. Airtable's support pages say the Run a script action is unavailable on the Free plan and on a Team plan trial.

### Can I put an image URL into an attachment field?

Yes. Airtable creates an attachment from an object with a public url (and optionally a filename) and downloads the file from that URL. The array you write replaces the cell's current attachments.

### How many records can one script run handle?

Airtable allows 50 fetch requests per script run, so a script that renders one image per call covers up to 50 records. For more, send them as one batch request, which counts as a single call.
