---
title: Using the WordPress AI Client
description: Add AI features to a WordPress plugin or theme without calling the AI API directly.
url: https://developers.wpengine.com/docs/ai/api/wordpress-ai-client/
image: https://developers.wpengine.com/og/docs/ai/api/wordpress-ai-client.png
---

# Using the WordPress AI Client

If you’re building a WordPress plugin or theme, you may not need to call the AI API directly. WordPress 7.0 ships a built-in [AI Client](https://make.wordpress.org/core/2026/03/24/introducing-the-ai-client-in-wordpress-7-0/) with a fluent PHP API for text, image, and speech generation, and the WP Engine AI Connector plugin registers a `wpengine` provider for it — so your code never touches an API key, and auth, retries, and provider routing are handled for you.

## Prerequisites

1. Install and activate the [WP Engine AI Connector](https://wp-product-info.wpesvc.net/v1/plugins/wpe-ai-connector?download) and [WP Engine AI](https://wp-product-info.wpesvc.net/v1/plugins/wpe-hub?download) plugins.
2. From **Settings → Connectors → WP Engine AI Connector**, connect the site to a WP Engine account.
3. Run WordPress 7.0 or later. The AI Client is part of WordPress core, so your plugin or theme calls it directly — there is nothing extra to install.

> **No API key in code**
>
> Once the connector is connected to a WP Engine account, it handles authentication automatically on every request. There is no `Authorization` header for you to set.

## What it looks like

Generate text with the fluent builder. The AI Client picks a suitable model from the registered providers, sends the request through the connector, and returns the generated text.

```php
<?php
declare( strict_types = 1 );


$summary = wp_ai_client_prompt( 'Summarize the speed of light in one sentence.' )
    ->using_system_instruction( 'You are concise.' )
    ->using_temperature( 0.2 )
    ->generate_text();


if ( is_wp_error( $summary ) ) {
    // Log the error and fall back to a non-AI code path.
    return;
}
```

`generate_text()` returns a `string` on success and a `WP_Error` on failure — `wp_ai_client_prompt()` converts every AI Client exception into a `WP_Error`, so always check the result with `is_wp_error()`. For the full result object (token usage, the model that answered, finish reason) use `generate_text_result()` instead. The `wpengine` provider returns one candidate per request, so ask for a single result rather than several via `generate_texts()`.

Pin specific models when you need them for cost, latency, or capability reasons. List them in order of preference — the AI Client uses the first one the connector exposes:

```php
$summary = wp_ai_client_prompt( 'Summarize the speed of light in one sentence.' )
    ->using_provider( 'wpengine' )
    ->using_model_preference( 'google/gemini-3.5-flash', 'google/gemini-3.7-flash' )
    ->generate_text();
```

Without a preference, the connector uses the model chosen on its settings screen (Claude Sonnet 5.5 by default). If that model can’t handle the prompt, it falls back to the newest Claude Sonnet, then Haiku, then Fable, then Gemini Flash. Web search works on Claude and on Gemini 3 and newer; Gemini can only block domains, so a web search that sets allowed domains needs a Claude model. Structured output (a JSON schema) needs Gemini, because the Claude models return text only. Reorder that chain with the `wpe/ai/connector/fallback_models` filter:

```php
add_filter(
    'wpe/ai/connector/fallback_models',
    function ( array $models ): array {
        // Try Haiku before Sonnet.
        usort(
            $models,
            fn ( string $a, string $b ): int =>
                (int) str_contains( $b, 'claude-haiku-' ) <=> (int) str_contains( $a, 'claude-haiku-' )
        );


        return $models;
    }
);
```

The filter orders models; it can’t exclude them. Any model the connector offers that isn’t in the chain still comes after it, so removing one from the chain only moves it down the list. The order is stored with the cached model list, so a change takes effect after the connector settings are saved, the plugin is updated, or the cache expires (24 hours).

The connector reports itself as unavailable when the site isn’t connected, when the current request isn’t allowed to use the connection (see [Who can make requests](https://developers.wpengine.com/docs/ai/api/wordpress-ai-client/#who-can-make-requests)), and for about a minute after WP Engine AI fails to list its models. Check that before showing an AI feature, so the feature is hidden instead of surfacing an error. WordPress core doesn’t wrap this check, so call the bundled SDK class directly:

```php
use WordPress\AiClient\AiClient;


if ( ! AiClient::isConfigured( 'wpengine' ) ) {
    // Show an admin notice or fall back to a non-AI code path.
    return;
}
```

Swap `generate_text()` for `generate_image()` to produce an image instead. It returns a `WordPress\AiClient\Files\DTO\File` whose image data is inline and base64-encoded. Decode it to save the image to the uploads directory:

```php
$image = wp_ai_client_prompt( 'A pixel-art lighthouse at sunset' )
    ->using_provider( 'wpengine' )
    ->generate_image();


if ( is_wp_error( $image ) ) {
    return;
}


// $image->getMimeType() reports the format, e.g. image/png.
$upload = wp_upload_bits(
    'lighthouse.png',
    null,
    base64_decode( $image->getBase64Data() )
);
```

## Who can make requests

The connector only attaches the site’s credentials to a request when it runs as one of:

- A logged-in user with the `edit_posts` capability (Contributor and above)
- WP-CLI
- WP-Cron

For any other request — including one made while rendering a page for an anonymous visitor — `AiClient::isConfigured( 'wpengine' )` returns `false` and the connector is skipped when WordPress picks a model. A call pinned to the connector with `using_provider( 'wpengine' )` returns a `WP_Error` instead of reaching WP Engine AI.

To allow other requests, filter `wpe_ai_connector_authorize_request`. The filter also decides whether the connector is offered at all: it is called with a `GET` request to `v1/models` for that check, so a filter that inspects the request URL must allow that request too.

```php
add_filter(
    'wpe_ai_connector_authorize_request',
    function ( bool $authorized ): bool {
        return $authorized || my_plugin_can_use_ai();
    }
);
```

> **Every authorized request uses the site’s credits**
>
> Authorizing anonymous visitors lets anyone who can reach that code path spend the site’s AI credits. Put your own rate limiting or abuse protection in front of any public-facing AI feature.

## Connector Approvals

Sites can also restrict which plugins use the connector. The [WordPress AI plugin](https://wordpress.org/plugins/ai/) has an optional Connector Approval experiment, off by default. When a site admin turns it on, calls from a plugin that hasn’t been approved to use the `wpengine` connector return a `WP_Error` with the code `prompt_network_error` and a message saying the connector has not been approved for that plugin. The blocked plugin then appears as a pending request under **Tools → Connector Approvals**, where an admin can approve it.

## What it doesn’t cover

The AI Client is a provider-agnostic content-generation layer, not a full AI API client. It’s built to work against any registered AI provider, so it only exposes generation primitives generic enough to make sense across providers — it has no method surface for:

- Token counting, transcription, image alt-text, content summarization, or taxonomy suggestion
- Usage analytics or credit balance
- Site registration or connection management (handled entirely by the AI Connector plugin, not the AI Client)
- Agents, sessions, or knowledge base collections
- The MCP transport used by external clients like Claude Code

For any of those, call the [AI API](https://developers.wpengine.com/docs/ai/api/) directly — see the [API reference](https://developers.wpengine.com/docs/ai/api/reference/) for every operation.

> **Where to learn more**
>
> The AI Client also supports speech and text-to-speech generation with the same fluent surface. See [Introducing the AI Client in WordPress 7.0](https://make.wordpress.org/core/2026/03/24/introducing-the-ai-client-in-wordpress-7-0/) for the full builder API and provider model — that announcement post is the authoritative reference for the AI Client’s method surface, not this page.

---

> #### Going beyond the AI Client
>
> - [API reference — every operation the AI Client does not wrap](https://developers.wpengine.com/docs/ai/api/reference/)
> - [Getting started — call the API directly](https://developers.wpengine.com/docs/ai/api/getting-started/)
> - [Authentication — the key the gateway expects](https://developers.wpengine.com/docs/ai/api/authentication/)

## Was this helpful?

Thanks for the feedback!

```json
{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://developers.wpengine.com/#website","name":"WP Engine Product Documentation","url":"https://developers.wpengine.com/","description":"Resources for developing, deploying, and scaling on WP Engine.","inLanguage":"en-US","keywords":["API documentation","product documentation","headless WordPress","managed WordPress hosting"],"publisher":{"@id":"https://wpengine.com/#organization"}}]}
```
