=== AmazImg – AI Alt Text Generator for Accessibility & Image SEO ===
Contributors: m1sh0u
Tags: alt text, accessibility, image seo, ai, media library
Requires at least: 7.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.5
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

AI alt text for your images, written by the AI provider you already connected to WordPress. No credits to buy, no extra API key.

== Description ==

Images without alt text are invisible to screen reader users and to image search. AmazImg writes short, descriptive alt text for them with the vision model of the AI provider you connected in WordPress (OpenAI, Anthropic Claude or Google Gemini).

**No credits, no middleman.** Most alt text plugins sell credits and send your images through their own servers. AmazImg is built on the WordPress AI Client (WordPress 7.0+), so requests go straight from your site to your own provider, and you pay that provider's normal rates with nothing added on top.

**See it in action (~3 minutes):**

https://www.youtube.com/watch?v=acEMRWrw7CI

**What the free plugin does**

* A "Generate alt text" button in the media modal, on the attachment edit screen and in the Media Library list view. The text is saved straight away and you can edit it like any alt text.
* An "Alt text" column in the Media Library list view, so you can see at a glance which images still need it.
* An overview page with your alt text coverage and the latest images without alt text, each with its own Generate button.
* Context-aware: uses the file name, the image title and the page the image was uploaded to, so the description fits where the image is used.
* Writes in your site language or any language you choose, with a length limit you set.
* Lightweight: no external scripts, no tracking, nothing on the front end.

Good alt text helps you meet WCAG and the European Accessibility Act, but AI is a first draft: review the text for images where the details matter.

**AmazImg Pro**

The free plugin does one image at a time. [AmazImg Pro](https://amazimg.pro/#pricing) is for whole libraries and busy sites:

* Bulk generation for every image without alt text, with pause and resume.
* Automatic alt text for new uploads.
* A review queue with one-click undo.
* Fixes alt text inside existing posts and pages, not just in the Media Library.
* Usage tracking and spending caps.
* WPML and Polylang: alt text in every language.
* Uses WooCommerce product data and your SEO plugin's focus keyword as context.
* Custom prompts, plus titles, captions and long descriptions.
* A block editor panel, WP-CLI, REST API and scheduled background runs.

The first 100 customers get **50% off** with the code **FIRST100**.

== External services ==

This plugin does not contact any AI service itself. It uses the WordPress AI Client (built into WordPress 7.0+), which sends requests to the AI provider the site owner connected in `Settings → Connectors`. Nothing is sent until a provider is connected and you generate alt text, either by clicking a "Generate" button or through a Pro automation you turn on.

For each generation the image (a resized copy when available), a text prompt and short context (file name, image title, title of the page the image is attached to) are sent to the connected provider, for example:

* **OpenAI** (api.openai.com): [Terms of use](https://openai.com/policies/terms-of-use), [Privacy policy](https://openai.com/policies/privacy-policy)
* **Anthropic** (api.anthropic.com): [Commercial terms](https://www.anthropic.com/legal/commercial-terms), [Privacy policy](https://www.anthropic.com/legal/privacy)
* **Google Gemini** (generativelanguage.googleapis.com): [Gemini API terms](https://ai.google.dev/gemini-api/terms), [Privacy policy](https://policies.google.com/privacy)

**AmazImg news (optional, off by default).** If an administrator turns on "News and tips" in Media → AI Alt Text → Settings, the plugin downloads a short list of messages from `https://amazimg.pro/wp-json/amazimg/v1/notices` at most about twice a day, when that screen is opened. The request sends only the plugin version; like any web request, it also reveals the site's IP address to the server. Nothing is requested while the option is off. [Terms of service](https://amazimg.pro/terms/), [Privacy policy](https://amazimg.pro/privacy-policy/)

== Installation ==

1. You can install the plugin by **uploading** the **.zip** file in the **plugins section** of Wordpress, or by adding the files to the folder `/wp-content/plugins/amazimg-image-description-generator`.
2. Go to **Settings → Connectors**, install a provider plugin (OpenAI, Anthropic or Google) and add its API key.
3. Optional: in **Media → AI Alt Text → Settings**, list the models you prefer, the output language and the maximum length.
4. Open any image in the Media Library and click **Generate alt text**.

= Developers =

AmazImg can be extended with PHP hooks and a small JavaScript API. The Pro add-on also adds a REST API and WP-CLI commands.

= Filters =

* `aatg_generate_args` ( $args, $attachment_id ): change the generation arguments.
* `aatg_pre_generate` ( null, $attachment_id, $args ): return a `WP_Error` to stop generation for an image.
* `aatg_context` ( $context, $attachment_id ): add context to the prompt, such as a post title or product name.
* `aatg_language` ( $language, $attachment_id ): choose the output language per image.
* `aatg_prompt` ( $prompt, $attachment_id, $context ): change the prompt sent to the AI.
* `aatg_ai_prompt_builder` ( $builder, $image, $prompt ): adjust the WordPress AI Client request before it is sent.
* `aatg_max_tokens` ( $max_tokens ): change the output limit (default 1024).
* `aatg_image_sizes` ( $sizes ): choose which image size is sent to the AI.
* `aatg_parse_response` ( null, $raw, $attachment_id ): parse a structured reply. Return an array with an `alt` key.
* `aatg_is_decorative` ( false, $attachment_id ): mark an image as decorative (empty alt text).
* `aatg_query_args` ( $query_args, $purpose, $args ): change which images are found.

= Actions =

* `aatg_before_save` ( $attachment_id, $result, $args ): runs just before alt text is saved.
* `aatg_generated` ( $attachment_id, $result, $context, $args ): runs after a successful generation.
* `aatg_generate_failed` ( $attachment_id, $error, $args ): runs after a failed generation.
* `aatg_usage` ( $provider, $model, $input_tokens, $output_tokens ): reports the AI usage of each request.

= Error codes =

* `aatg_http_429`: the AI provider is rate-limiting requests. Retry later.
* `aatg_http_5xx` (for example `aatg_http_503`): the AI provider is temporarily unavailable. Retry later.
* `aatg_http_error`: network error reaching the AI provider. Retry later.
* `aatg_ai_error`: any other AI request failure, for example an invalid API key. Don't retry.
* `aatg_no_key`: no AI provider is connected in Settings → Connectors.
* `aatg_unsupported`: the file type is not supported. Use JPEG, PNG, GIF or WebP.

= Examples =

Add brand guidance to every prompt:

`
add_filter( 'aatg_prompt', function ( $prompt, $attachment_id, $context ) {
	return $prompt . "\nMention the brand name if a logo is visible.";
}, 10, 3 );
`

Skip images uploaded to a "logos" folder:

`
add_filter( 'aatg_pre_generate', function ( $error, $attachment_id ) {
	if ( false !== strpos( (string) get_attached_file( $attachment_id ), '/logos/' ) ) {
		return new WP_Error( 'my_skip', 'Logos are handled manually.' );
	}
	return $error;
}, 10, 2 );
`

Log every generated alt text:

`
add_action( 'aatg_generated', function ( $attachment_id, $result ) {
	error_log( sprintf( 'Alt text for #%d: %s', $attachment_id, $result['alt'] ) );
}, 10, 2 );
`

= JavaScript =

In the admin, `AATG.generate( attachmentId, options )` returns a jQuery promise, and the `aatg:generated` event fires after each success:

`
AATG.generate( attachmentId, { source: 'my-plugin' } )
	.done( function ( data ) { console.log( data.alt ); } );

jQuery( document ).on( 'aatg:generated', function ( event, attachmentId, data ) {
	// data.pending is set when the result was held for review.
} );
`

= REST API (Pro) =

The Pro add-on adds routes under `/wp-json/amazimg-pro/v1`. To call them from outside WordPress, sign in with an application password (Users → Profile → Application Passwords) using HTTP Basic auth.

* `GET /stats`: total images, images missing alt text, items pending review, queue size, and this month's usage and estimated cost. Needs the `upload_files` capability.
* `GET /images?status=missing|low|all&page=1&per_page=20`: lists images with their alt text, SEO score and issues, any pending suggestion, and whether undo is possible. Paging headers: `X-WP-Total` and `X-WP-TotalPages`. Needs `upload_files`.
* `POST /images/{id}/generate`: generates alt text for one image. Parameters: `overwrite` (default false), `save` (default true; false returns only a suggestion) and `skip_review` (default false). Needs permission to edit the image.
* `POST /images/{id}/undo`: restores the alt text from before the last AI change. Returns 409 when there is nothing to undo. Needs permission to edit the image.
* `GET /queue`: queue size and the last error. Needs `upload_files`.
* `POST /queue`: adds images to the background queue. Pass `ids` (an array of attachment IDs) or `scope` (`missing`, `low` or `all`), plus `overwrite`. Needs `upload_files`.

When the monthly spending cap is reached, `generate` returns HTTP 429 with the code `aatgp_budget`.

`
curl -u 'admin:xxxx xxxx xxxx xxxx' -X POST \
  'https://example.com/wp-json/amazimg-pro/v1/images/123/generate?save=false'
`

= WP-CLI (Pro) =

`
wp amazimg generate --limit=500
wp amazimg generate 12 34 --overwrite
wp amazimg generate --scope=low --products --skip-review
wp amazimg generate --queue
wp amazimg generate --dry-run
wp amazimg undo 12 34
wp amazimg undo --run=<run-id>
wp amazimg review list|approve|reject [<id>...]
wp amazimg sync-content [--replace] [--dry-run]
wp amazimg stats --format=json
wp amazimg queue status|run|clear
`

Rate limits and provider outages are retried automatically, up to 3 times, 30 seconds apart. Run `wp help amazimg` for the full reference.

== Frequently Asked Questions ==

= Where do I enter my API key? =

In **Settings → Connectors** (WordPress 7.0+). The plugin never stores API keys; it uses the WordPress AI Client, so every AI feature on your site shares the same connection. Keys can also come from the `OPENAI_API_KEY`, `ANTHROPIC_API_KEY` or `GOOGLE_API_KEY` constants or environment variables.

= Which model is used? =

WordPress picks a connected model that can read images. To choose, enter one or more model ids under **Media → AI Alt Text → Settings → Preferred models**.

= How much does it cost? =

The plugin is free. You pay your AI provider directly. With the default small models, a single image typically costs a fraction of a cent.

= Does it overwrite my existing alt text? =

Only when you click "Regenerate" on an image that already has alt text.

= Which image formats are supported? =

JPEG, PNG, GIF and WebP.

= My images are on a CDN / S3. Does it work? =

Yes. If the file is not on the server, the plugin downloads the "large" size from its public URL.

== Screenshots ==

1. Plugin overview
2. Activity & Reports
3. Settings for the free version
4. Automation & Usage limits settings
5. Content settings
6. Alt text in posts & Exclusions settings
7. Generate alt text button in the media modal

== Changelog ==

= 1.0.5 =

* The "More from the AmazImg team" section now stays visible when a suggested plugin is already active, marked as Active.

= 1.0.4 =

* Added a "More from the AmazImg team" section at the bottom of the Overview tab. On WooCommerce stores it suggests BoxIntellect, our box packing plugin.
* Added a rating link to the admin footer of the AmazImg page.

= 1.0.3 =

* New name: AmazImg – AI Alt Text Generator for Accessibility & Image SEO. Nothing else changes; your settings are kept.

= 1.0.2 =

* Updated the readme file.

= 1.0.0 =

* Initial release.
