Alt Text BYOK is a GitHub Action: on every pull request it finds the images in your
Markdown, MDX, HTML, JSX and TSX files whose ALT is missing, empty or a placeholder
(image, screenshot, IMG_2041, the file name…), looks at
the image itself and writes a real description — committed to the PR, or proposed as one-click
review suggestions. It runs in your own Actions runner with your own vision AI key: no server of
ours, no credits, no monthly plan. The accessibility gate is free; Pro is $39 per year per
organization, no auto-renewal.
Get the Pro key — $39/year Install free
Screenshots go into READMEs and docs as  or
<img src="hero.png">, because writing a description is the step nobody has time
for in a PR. Screen-reader users hear “image” or a file name, image search sees nothing,
and accessibility audits (WCAG 1.1.1, the European Accessibility Act) flag every one of them.
This action fixes it where it starts: in the same pull request. Before and after, on a README:
README.md before
- 
- 
- <img src="docs/img/logo.svg" alt="">
README.md after (commit by github-actions[bot])
+ 
+ 
<img src="docs/img/logo.svg" alt=""> ← alt="" is decorative (WCAG): left alone
Example output. The paragraph before each image is sent as context, so the
description fits the text around it. alt={t('…')} and other code-generated ALT
are left alone; SVG, images over 8 MB and dynamic src={var} are listed in the job
summary instead.
Add your provider key as the repository secret AI_API_KEY, then save this as
.github/workflows/alt-text.yml.
# .github/workflows/alt-text.yml
name: Alt text
on:
pull_request:
paths: ['**.md', '**.mdx', '**.html', '**.jsx', '**.tsx']
permissions: { contents: write, pull-requests: write }
jobs:
alt-text:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { ref: "${{ github.head_ref }}" }
- uses: lumnika/alt-text-action@v1
with:
mode: fix # or: suggest (review comments), check (gate only)
provider: openai # anthropic, gemini, openrouter, groq, mistral, custom
ai-api-key: ${{ secrets.AI_API_KEY }}
# language: Italian # free: one fixed language
# license-key: ${{ secrets.LICENSE_KEY }} # Pro: no limit + language: auto
Just want the gate? No AI key, no write permission — the job fails with one annotation per image without ALT:
- uses: actions/checkout@v4
- uses: lumnika/alt-text-action@v1
with: { mode: check }
Marketplace listing coming soon: until then the action is distributed directly to customers — write to deus@lumnika.com for early access.
| Free | Pro | |
|---|---|---|
check gate (any number of images) | yes | yes |
fix (commit) and suggest (review suggestions) | yes | yes |
| Providers: OpenAI, Anthropic, Gemini, OpenRouter, Groq, Mistral, any OpenAI-compatible | yes | yes |
| Images described per run | 20 (the rest on the next run) | no limit |
| Language | one, fixed | language: auto — each document in its own language |
| Price | free | $39 per year per organization |
The license key is shown right after payment. Save it as the repository or organization secret
LICENSE_KEY and uncomment the license-key line in the workflow. From the
next pull request on: every image described in one run, in the language of each document.
🔒 Secure checkout by Stripe, your card details never touch our servers · 7-day money-back guarantee, no questions asked (deus@lumnika.com) · no account required.
One short vision call per image. Token counts per image from the providers' documentation, plus about 150 tokens of instructions and context in and 60 tokens out:
| Option | 100 images | Per year, at 100 images a month |
|---|---|---|
| Gemini 2.5 Flash-Lite, your key ($0.10 / $0.40 per 1M tokens) | ≈ $0.01 | ≈ $0.11 + $39 Pro |
OpenAI gpt-4.1-nano, your key ($0.10 / $0.40) | ≈ $0.02 | ≈ $0.28 + $39 Pro |
OpenAI gpt-4.1-mini, your key ($0.40 / $1.60) | ≈ $0.07 | ≈ $0.78 + $39 Pro |
| Claude Haiku 4.5, your key ($1 / $5) | ≈ $0.15 | ≈ $1.78 + $39 Pro |
| AltText.ai Bronze (100 credits/month) | $5 | $60 |
| ImageSEO Starter (100 credits/month) | €4.99 | ≈ €60 |
Your own numbers, every provider: alt text cost calculator (official prices with sources, checked 30 September 2026). Under 20 images per pull request the free tier is enough and you only pay your tokens. On private repositories the job also uses your GitHub Actions minutes.
image, photo,
a file name…) is touched. alt="" in HTML/JSX means decorative and is left alone,
and so is any ALT built in code.only-changed: false scans the
whole repository, e.g. on a weekly schedule). Code fences, inline code and HTML comments are ignored.fix commits to the PR branch as github-actions[bot];
suggest posts one review with a suggestion per line, accepted with one click;
check only reports and fails the job.Images in a WordPress media library rather than a repository? The Alt Text BYOK WordPress plugin fills missing ALT in bulk and on upload, with the same bring-your-own-key model.