# AI Alt Text Generator - Image Alt Text & Image Captions (`tidytools/ai-alt-text-generator`) Actor

Find images missing alt text on pages, a sitemap or a whole site and write AI alt text in any language. Optional SEO title, caption and file name. WCAG accessibility, image SEO. $6/1,000.

- **URL**: https://apify.com/tidytools/ai-alt-text-generator.md
- **Developed by:** [Yukai Lin](https://apify.com/tidytools) (community)
- **Categories:** SEO tools, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.80 / 1,000 described images

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does AI Alt Text Generator do?

AI alt text generator: it finds the **images on your web pages, or across your whole site, that have no alt text** and writes **concise, descriptive alt text with AI**, in the language you choose. Better accessibility (WCAG 1.1.1 "Non-text Content") for screen-reader users and better **image SEO**, without writing hundreds of descriptions by hand. Free extras: pixel size, format and file-size checks for every image, and a quality check of existing alt text.

**Input:** page URLs or domains, a sitemap URL or direct image URLs. **Output:** one row per image with the suggested alt text (plus an optional title, caption, SEO file name and keywords), the page it was found on and a free image health check. **Price:** $6.00 per 1,000 alt texts ($8.00 with SEO fields), no start fee; skipped and failed images are free. It reads public pages only, identifies itself as TidyTools and respects `robots.txt`; images can be JPEG, PNG, WebP or GIF up to 8 MB.

Use it as a bulk **image description generator** and image captioner: alt tags for a whole product catalogue, blog or media library in one run.

- 🔎 **Finds images automatically** on each page (including lazy-loaded `data-src` / `srcset` images)
- 🗺️ **Whole-site scan**: follow the site's sitemap (or its internal links) up to a page limit; an image used on 40 pages is described **once**
- 🏷️ **Context-aware**: add your site context ("handmade silver jewellery store"); the page title and the image file name are used as hints too, while the AI describes only what is visible
- ✍️ **Specific, honest descriptions**: the AI mentions text or brand names only when it can read them in the image and never guesses product models
- 📏 **Free image health check**: `imageWidth`, `imageHeight`, `imageFormat`, `imageBytes`, `oversized` (over 200 KB) and `nextGenFormat` (WebP / AVIF)
- ✅ **Existing alt audit**: with *Only images without alt text* off, each existing alt gets `altQuality` (good / poor) and `altIssues` ("generic word", "looks like a file name", "starts with image of"…)
- 🏷️ **Optional SEO fields**: an image title, a caption, an SEO file name (`tipping-the-velvet-book-cover.jpg`) and keywords, written in the same AI call as the alt text
- 🌍 **Any language**, with a character limit you choose (125 by default)
- 🧠 **Transparent logos handled**: logos on transparent backgrounds are placed on a neutral backdrop so they can be read
- 🧹 **Skips what doesn't need alt text**: tiny icons, tracking pixels, decorative images (`role="presentation"`) and SVGs
- 💸 **Pay only for alt texts delivered**: images that fail to download or look blank are free

### How much does it cost?

| Event | Price |
|---|---|
| Described image | **$6.00 / 1,000 images** |
| Described image with SEO fields (optional) | **$8.00 / 1,000 images**, **instead of** the plain price, only when you request extra fields (title, caption, file name, keywords) |

**Example:** a site scan that finds 2,000 images needing alt text costs 2,000 × $0.006 = **$12.00**, or **$16.00** with SEO fields.

**No start fee.** Page scanning, the image health check and the existing-alt audit are free; you pay only per alt text written. Other AI alt text Actors on Apify Store charge $5–$12 per 1,000 images (checked September 2026); the two we found that also write titles, captions, file names or keywords charge $10 per 1,000 (myexcelsolutions / bulk-alt-text-generator, plus $0.001 per run; marielise.dev / ai-image-intelligence, one image per run). If the AI returns only an alt text for an image, it is charged at the plain $6 price. Higher Apify plans get volume discounts.

#### Control your cost

- **What is charged**: one event per alt text written (the SEO-fields price when you asked for extra fields and got them).
- **What is free**: page scanning, skipped images (already have alt text, tiny icons, SVG, decorative), the same image found on other pages or at other sizes (`photo.jpg?width=800` and `?width=1600`, WordPress `photo-300x200.jpg` and `photo-1024x683.jpg`, Wikimedia thumbnails of one file count once), images over *Max images*, lines that are not a URL, images that fail (unreachable, not an image, AVIF/BMP/TIFF or another format the AI cannot read, over 8 MB), and pages `robots.txt` disallows. Every row has `charged: true/false`, and failed rows say "(not charged)".
- **Max images per page** (default 20) limits how many images are described on each page.
- **Max images in total** (default 1,000; 20 in the Console form) caps a whole-site scan: *Max pages* × *Max images per page* can otherwise reach thousands of images.
- **Before describing**, the Actor logs the plan: "N images × $0.006 = at most $X", compared with your max charge per run. It is also saved as `PLAN` in the key-value store and `costPlan` in `SUMMARY`.
- **Max charge per run**: set *Maximum cost per run* in the run options (or `maxTotalChargeUsd` in the API). When it is reached, the run stops cleanly: `SUMMARY.status` is `LIMIT_REACHED` and `SUMMARY.notProcessed` lists the images that were not described (count and up to 100 image URLs).
- **Pages without images**: a scanned page that has no `<img>` at all gets one free row (`imagesFound: 0`, `charged: false`) so every input page shows up in the results. A page whose images all need no alt text (already have one, too small, SVG, decorative) gets one free row too (`imagesToDescribe: 0` and a `note`).
- **Input mistakes never fail the run**: with no usable page, sitemap or image URL, the run ends normally with free `invalid_input` rows (`charged: false`) and `SUMMARY.status` `NO_RESULTS`.
- **If Apify restarts the run** (server migration or Resurrect), items already finished are skipped and not charged again (`SUMMARY.resumedSkipped`).

### How to use it

1. Paste **page URLs or domains**, one per line (and/or direct **image URLs**). To cover a site, turn on **Scan the whole site** or paste a **sitemap URL**, and set **Max pages** and **Max images in total**. A line that is not a URL becomes one free `invalid_input` row.
2. Optional: describe the site in **Site context**.
3. Keep **Only images without alt text** on to fix gaps, or turn it off to review every image and audit existing alts.
4. Choose the **language** and **max characters**.
5. Click **Start** and export the list (image URL, page, suggested alt text) as CSV or Excel for your CMS.

#### Input example: scan a store

```json
{
    "urlsText": "https://www.allbirds.com/",
    "crawlSite": true,
    "maxPages": 3,
    "maxImagesPerPage": 2,
    "context": "sustainable shoe brand",
    "reportSkipped": true
}
```

Real results: the sitemap was found automatically, 3 pages were scanned, 4 alt texts were written, 5 images that already had alt text were skipped (and audited), and 1 image repeated on another page was counted only once. The 2560-pixel hero image is delivered as WebP but still weighs 572 KB (`oversized: true`):

```json
{
    "pageUrl": "https://www.allbirds.com/",
    "imageUrl": "https://www.allbirds.com/cdn/shop/files/26Q1_DasherNZ_Site_Homepage_Hero_Desktop_16x9-3.jpg?v=1779316981&width=2560",
    "existingAlt": "",
    "via": "backend",
    "success": true,
    "missingAlt": true,
    "suggestedAlt": "Woman wearing green leggings and white sneakers stands on sidewalk; close-up of sneakers on feet.",
    "imageBytes": 571990,
    "imageFormat": "webp",
    "imageWidth": 2560,
    "imageHeight": 1442,
    "oversized": true,
    "nextGenFormat": true
}
```

```json
{
    "pageUrl": "https://www.allbirds.com/products/mens-wool-runners",
    "imageUrl": "https://www.allbirds.com/cdn/shop/files/Allbirds_WL_RN_SF_PDP_Natural_Grey_LAT.png?v=1751143404&width=1280",
    "existingAlt": "Men's Wool Runner - Natural Grey (Light Grey Sole)",
    "success": false,
    "skipped": true,
    "reason": "already has alt text",
    "altQuality": "good",
    "altIssues": []
}
```

`imageFormat` is the format the server actually delivered to us (many CDNs send WebP or AVIF to modern browsers even for `.jpg` URLs), so `nextGenFormat: true` means visitors already get a modern format.

#### Output example: existing alt audit (real results from books.toscrape.com)

```json
{
    "pageUrl": "https://books.toscrape.com/",
    "imageUrl": "https://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg",
    "existingAlt": "A Light in the Attic",
    "pageCount": 3,
    "success": true,
    "missingAlt": false,
    "suggestedAlt": "Black and white book cover with drawing of child's face and house on head, titled \"A Light in the Attic\" by Shel Silverstein.",
    "altQuality": "good",
    "altIssues": [],
    "imageBytes": 9876,
    "imageFormat": "jpeg",
    "imageWidth": 125,
    "imageHeight": 155,
    "oversized": false,
    "nextGenFormat": false
}
```

`pageCount` and `otherPages` show where else the same image appears.

#### Output example (real results from apple.com)

```json
[
    { "imageUrl": "https://www.apple.com/v/homepage/images/logos/apple-watch-series-12/a/hero_logo_apple_watch_series_12__eze8r897c5me_large.png", "existingAlt": "", "suggestedAlt": "Apple Watch Series 12 logo." },
    { "imageUrl": "https://www.apple.com/v/homepage/images/iphone-duo/a/hero_iphone_duo_announce__fh4u8yzndpe2_large.jpg", "suggestedAlt": "Hands holding a foldable smartphone with home screen and photo on display." }
]
```

#### Output example: SEO fields (real results from books.toscrape.com)

With `"fields": ["title", "caption", "filename", "keywords"]`:

```json
{
    "imageUrl": "https://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg",
    "existingAlt": "A Light in the Attic",
    "suggestedAlt": "Book cover with drawing of child's head and house on it",
    "suggestedTitle": "A Light in the Attic book cover",
    "suggestedCaption": "The cover of 'A Light in the Attic' by Shel Silverstein",
    "suggestedFilename": "a-light-in-the-attic-cover.jpg",
    "suggestedKeywords": ["shel silverstein", "book cover", "poetry"]
}
```

File names are cleaned to lowercase words joined by hyphens and keep the image's own extension. Names and text read from an image can be misspelled (in the same test, one author's name came back as "michel houellebeeq"), so review them before renaming files.

#### Missing alt vs. alt="" (WCAG)

Every row has `altStatus`: `missing` (no alt attribute), `empty` (`alt=""`) or `present`. In WCAG, `alt=""` is the correct markup for a **decorative** image that screen readers should skip, but many shops leave alt text empty by mistake. By default `alt=""` images get a suggestion like missing ones (`missingAlt: true`); turn on **Treat alt="" as decorative** (`emptyAltIsDecorative`) to skip them for free and describe only images with no alt attribute.

### Import the alt text into your CMS

**WordPress**: export the results as CSV and keep `imageUrl` and `suggestedAlt`. Images in the Media Library are matched by their file URL; paste the text into each image's *Alternative Text* field, or use a CSV import plugin that can update media attachments. Alt text set in the Media Library is used when the image is inserted again; images already placed in posts keep the alt text stored in the post, so update those in the block editor.

**Shopify**: product images have their own alt text. In the product CSV (Products → Export), the columns `Image Src` and `Image Alt Text` hold them: match `Image Src` with our `imageUrl` (compare without the `?v=…&width=…` part) and copy `suggestedAlt` into `Image Alt Text`, then import the CSV again with "Overwrite existing products". You can also edit alt text per image in the product's media editor.

**Any CMS**: `pageUrl` tells you where each image appears; `otherPages` lists further pages that use the same image.

### Output fields

| Field | Meaning |
|---|---|
| `suggestedAlt` | The alt text written by AI |
| `suggestedTitle`, `suggestedCaption`, `suggestedFilename`, `suggestedKeywords` | Only the extra SEO fields you asked for in `fields` |
| `metadataError` | Set when extra fields were requested but the AI returned only an alt text (charged at the plain price) |
| `input` | The page URL (or image URL) as you entered it; for pages found by a site scan, the start page |
| `existingAlt`, `missingAlt`, `altStatus` | The current alt attribute, whether it is empty, and `missing` / `empty` (`alt=""`) / `present` |
| `sameImageUrls` | Other URLs of the same image at other sizes (described and charged once). If the first URL cannot be downloaded, up to two of these are tried before the image counts as failed (still free) |
| `charged`, `chargedEvent` | Whether this row was charged, and with which event |
| `altQuality`, `altIssues` | For images that already have alt text: `good` or `poor`, and why |
| `imageWidth`, `imageHeight`, `imageFormat`, `imageBytes` | Size and format of the file as delivered |
| `oversized`, `nextGenFormat` | Over 200 KB; delivered as WebP or AVIF |
| `pageUrl`, `pageCount`, `otherPages` | Where the image was found (first page, number of pages, up to 10 others) |
| `via` | How the page was fetched: `backend`, `direct` (Apify's network) or `browser` |
| `error`, `errorType` | For images or pages that failed (not charged). `errorType`: `invalid_input` (not a URL, or a private/local address), `not_found`, `http_error`, `blocked`, `unsupported` (not an image, SVG, AVIF/BMP/TIFF, or a page URL that is a PDF or other file), `too_large` (over 8 MB), `network` / `timeout`, `robots_disallowed` |

The key-value store record `SUMMARY` has `status` (`SUCCESS`, `PARTIAL_RESULTS`, `FAILED`, `NO_RESULTS`, `LIMIT_REACHED`), pages scanned, and images described, skipped and repeated; `pagesSkippedByRobotsTxt` counts pages `robots.txt` disallowed.

### Use with AI agents (MCP)

Connect Apify's MCP server (https://mcp.apify.com?tools=tidytools/ai-alt-text-generator) to Claude, Cursor or any MCP client, then ask e.g. "Find the images without alt text on my site and suggest alt text for them".

```json
{ "urlsText": "https://example.com", "crawlSite": true, "maxPages": 20, "maxImages": 200 }
```

Failed items are not charged and carry an `errorType`.

### Use it from code and integrations

Run it from your own code with the Apify API. This call waits for the run and returns the results as JSON (replace `YOUR_TOKEN` with your Apify API token):

```bash
curl -X POST "https://api.apify.com/v2/acts/tidytools~ai-alt-text-generator/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urlsText":"https://www.apple.com","maxImagesPerPage":10,"maxImages":20}'
```

The synchronous endpoint waits up to 5 minutes. For bigger runs, start the run with `POST https://api.apify.com/v2/acts/tidytools~ai-alt-text-generator/runs` and read the dataset when it finishes, or use the `apify-client` package for JavaScript or Python.

**Schedules and integrations:** run it daily or weekly with Apify Schedules, get a webhook when a run finishes, or send the results to Zapier, Make, n8n, Google Sheets, Slack and other apps with Apify integrations. Results can be exported as JSON, CSV, Excel or XML.

### Tips

- Write **Site context** the way you'd describe the shop to a new employee: "handmade silver jewellery store", "Italian restaurant in Boston". It helps with product words, not with guessing.
- Descriptive file names (`red-leather-wallet.jpg`) help too; camera names like `IMG_1234.jpg` are ignored.
- Start with a small **Max pages** to check the style, then run the whole site.
- Pages you can read in a browser but the Actor cannot: set *Plain HTTP requests from* to Apify's network and add a proxy under *Advanced settings*.

### Limitations

- AI descriptions are a strong starting point; review important images (e.g. product photos) before publishing. Text read from images can contain spelling mistakes.
- SVG images are not supported. Images must be publicly downloadable (JPEG, PNG, WebP, GIF, up to 8 MB): AVIF, BMP and TIFF files, larger files and local or private addresses give a free error row. The Actor asks CDNs for WebP, PNG or JPEG, so sites that pick the format automatically (Shopify, Cloudinary, Next.js) deliver a readable one.
- Pages are read only if the site's `robots.txt` allows TidyTools (`TidyToolsFetch`, then `TidyTools`, else `*`): a page you list that it disallows gets a free `robots_disallowed` row; disallowed pages found through a sitemap or site scan are skipped (`SUMMARY.pagesSkippedByRobotsTxt`). A `robots.txt` that cannot be read does not block. Images that a page links to are downloaded like a visitor's browser does, with the page as referer, and images you list yourself are fetched as given.
- A page URL that is really an image file is described as an image; one that is a PDF or another file gets a free `unsupported` row.
- Landmarks, people and similar scenes can be misidentified by the AI (an old photo of Tokyo Tower came back as the Eiffel Tower): review them, and describe such images with the *Site context* field.
- The whole-site scan follows the sitemap (or internal links when there is none) up to *Max pages*; pages behind logins are not reached.
- Alt text describes what is visible; for images whose meaning depends on the page (charts, buttons), check that the text says what the image is for.

### FAQ

**Does the Actor collect usage data?** The Actor sends one anonymous usage counter per run (input type, item count range, outcome) to improve the tool; no URLs, content or account data.

**Does this alt text generator help with accessibility (WCAG)?** Yes. It finds images with no alt text and writes concise, descriptive alt text, for WCAG 1.1.1 "Non-text Content" and screen-reader users. In WCAG, `alt=""` marks a decorative image, so turn on **Treat alt="" as decorative** to skip those images for free and describe only images with no alt attribute.

**Can it also write image captions, titles and SEO file names?** Yes. Choose **Extra SEO fields (optional)** to get an image title, a caption, an SEO file name and/or keywords from the same AI call as the alt text. Those images cost $8.00 / 1,000 instead of (not on top of) the plain $6.00 / 1,000.

**How do I import the alt text into my CMS (WordPress, Shopify)?** Export the results as CSV. In WordPress, match Media Library images by `imageUrl` and paste `suggestedAlt` into each image's Alternative Text field, or use a CSV import plugin that can update media attachments. In Shopify, match the product CSV's `Image Src` with `imageUrl` (without the `?v=…&width=…` part), copy `suggestedAlt` into `Image Alt Text` and import the CSV again with "Overwrite existing products".

**Does it respect robots.txt?** Yes for every page it reads: it checks the site's `robots.txt` for `TidyToolsFetch` / `TidyTools` (else `*`) and does not read a page that is disallowed (free `robots_disallowed` row). Requests identify themselves as TidyTools. A `robots.txt` that cannot be read does not block.

**What is charged and what is free?** You pay only per alt text written ($6.00 / 1,000 images), with no start fee. Page scanning, the image health check, the existing-alt audit, skipped images (already have alt text, tiny icons, SVG, decorative), the same image found on other pages or at other sizes, pages `robots.txt` disallows, and images that fail (including unsupported formats and files over 8 MB) are free. Wrong input never fails the run: it ends with free `invalid_input` rows.

### Support

Open an issue in the **Issues** tab with the page URL. Issues are checked regularly.

Found this useful? A short review on the Store helps other users find it.

# Actor input Schema

## `urlsText` (type: `string`):

Main input (fill this, or `pageUrls` / `imageUrls` / `datasetId`). Web pages to check, one per line (bare domains such as apple.com work too). Images on each page are found automatically. With "Scan the whole site", these are the starting points. A line that is not a URL becomes one free error row; the rest of the run continues.

## `pageUrls` (type: `array`):

Same as "Page URLs or domains", in Apify's request list format (also accepts a link to a text file with URLs). Kept for existing integrations; new integrations should use "urlsText".

## `imageUrls` (type: `array`):

Direct links to images (JPEG, PNG, WebP, GIF) to describe.

## `crawlSite` (type: `boolean`):

Also check other pages of the same site: pages from its sitemap, or (without a sitemap) pages linked from the start pages, up to "Max pages". An image used on many pages is described once.

## `sitemapUrl` (type: `string`):

Check the pages listed in this sitemap, e.g. https://example.com/sitemap.xml (sitemap indexes are followed), up to "Max pages".

## `maxPages` (type: `integer`):

Limit for pages found through the sitemap or site scan (pages you list are always checked).

## `context` (type: `string`):

What the site is about, e.g. "handmade silver jewellery store" or "hiking travel blog". Together with the page title and the image file name, it helps the AI choose precise words; it never describes things that are not visible.

## `onlyMissingAlt` (type: `boolean`):

Skip images on pages that already have alt text. Turn off to get suggestions for every image, plus a quality check of the existing alt text (altQuality, altIssues).

## `emptyAltIsDecorative` (type: `boolean`):

In WCAG, an empty alt attribute (alt="") marks a decorative image that screen readers skip. Turn on to skip those images (free) and only describe images with no alt attribute at all. Off (default): alt="" is treated like a missing alt, since many shops leave it empty by mistake. Every row shows altStatus: missing, empty or present.

## `language` (type: `string`):

Language of the alt text, e.g. English, German, Spanish, Traditional Chinese.

## `maxCharacters` (type: `integer`):

Maximum length of each alt text. 125 is a common recommendation for screen readers.

## `fields` (type: `array`):

Also write an image title, a caption, an SEO file name (e.g. red-leather-wallet.jpg) and/or keywords, returned with the alt text from the same AI call. Images with extra fields are charged as "described image with SEO fields" ($0.008) instead of the plain alt text ($0.006).

## `maxImagesPerPage` (type: `integer`):

Limit how many images are described per page (default 20).

## `maxImages` (type: `integer`):

Cap for the whole run, across all pages (a whole-site scan can find thousands of images). Images over the cap are not described and not charged; the log and SUMMARY say how many were left out.

## `reportSkipped` (type: `boolean`):

Also list images that were skipped (already have alt text, tiny icons, SVG, decorative) and why. Existing alt texts get a free quality check.

## `datasetId` (type: `string`):

Take page or image URLs from another Actor run's dataset (links ending in .jpg, .png, .webp... are treated as images).

## `datasetField` (type: `string`):

Field with the URLs, e.g. "url" or "imageUrl". Empty = the first URL field found.

## `maxConcurrency` (type: `integer`):

How many images are described at the same time.

## `httpVia` (type: `string`):

Some sites block requests from data centers. Auto retries from a second network before falling back to a real browser. If both are refused, Auto also tries our second server (Oracle, different IP) before a real browser.

## `proxyConfiguration` (type: `object`):

Only used for requests sent from Apify's network (pages and image downloads). Apify proxy usage is billed to your Apify account.

## Actor input object example

```json
{
  "urlsText": "https://www.apple.com",
  "crawlSite": false,
  "maxPages": 50,
  "onlyMissingAlt": true,
  "emptyAltIsDecorative": false,
  "language": "English",
  "maxCharacters": 125,
  "maxImagesPerPage": 10,
  "maxImages": 20,
  "reportSkipped": false,
  "maxConcurrency": 5,
  "httpVia": "auto"
}
```

# Actor output Schema

## `altTexts` (type: `string`):

No description

## `full` (type: `string`):

No description

## `details` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urlsText": "https://www.apple.com",
    "maxImagesPerPage": 10,
    "maxImages": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("tidytools/ai-alt-text-generator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "urlsText": "https://www.apple.com",
    "maxImagesPerPage": 10,
    "maxImages": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("tidytools/ai-alt-text-generator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urlsText": "https://www.apple.com",
  "maxImagesPerPage": 10,
  "maxImages": 20
}' |
apify call tidytools/ai-alt-text-generator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tidytools/ai-alt-text-generator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/libCpYWq57jwvqqXR/builds/8fyVa4ELcbxc76cFo/openapi.json
