AI Alt Text Generator - Image Alt Text & Image Captions avatar

AI Alt Text Generator - Image Alt Text & Image Captions

Pricing

from $4.80 / 1,000 described images

Go to Apify Store
AI Alt Text Generator - Image Alt Text & Image Captions

AI Alt Text Generator - Image Alt Text & Image Captions

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.

Pricing

from $4.80 / 1,000 described images

Rating

0.0

(0)

Developer

Yukai Lin

Yukai Lin

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

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?

EventPrice
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

{
"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):

{
"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
}
{
"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)

{
"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)

[
{ "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"]:

{
"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

FieldMeaning
suggestedAltThe alt text written by AI
suggestedTitle, suggestedCaption, suggestedFilename, suggestedKeywordsOnly the extra SEO fields you asked for in fields
metadataErrorSet when extra fields were requested but the AI returned only an alt text (charged at the plain price)
inputThe page URL (or image URL) as you entered it; for pages found by a site scan, the start page
existingAlt, missingAlt, altStatusThe current alt attribute, whether it is empty, and missing / empty (alt="") / present
sameImageUrlsOther 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, chargedEventWhether this row was charged, and with which event
altQuality, altIssuesFor images that already have alt text: good or poor, and why
imageWidth, imageHeight, imageFormat, imageBytesSize and format of the file as delivered
oversized, nextGenFormatOver 200 KB; delivered as WebP or AVIF
pageUrl, pageCount, otherPagesWhere the image was found (first page, number of pages, up to 10 others)
viaHow the page was fetched: backend, direct (Apify's network) or browser
error, errorTypeFor 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".

{ "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):

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.