WP Webhooks / Blog / AI integration
Article · AI integration

WordPress AI Client: wp_ai_client_prompt() Explained

How the WordPress 7.0 AI Client works: provider Connectors, wp_ai_client_prompt(), model fallback chains, and when you still need your own API key.

8 min 2026-06-29
#ai#wordpress#php

TL;DR: WordPress 7.0 ships an AI Client: a provider-agnostic PHP SDK with a fluent entry point, wp_ai_client_prompt(), over centrally configured providers (Settings → Connectors).

  • WordPress stores the provider credentials — your plugin never handles or saves an API key on this path.
  • Pin a model with using_model_preference(), and fall back across providers on retryable failures like quota 429s.
  • There is no native tool calling — agents need a structured-output protocol layered on top.
  • Detect availability with function_exists() + wp_supports_ai(), and keep a bring-your-own-key path for sites that have no connector configured.

/ Overview

What is the WordPress AI Client?

The AI Client is WordPress core's provider-agnostic layer for talking to large language models. It grew out of the WordPress/php-ai-client SDK developed by the WordPress AI team, and lands in WordPress 7.0 with a global entry point: wp_ai_client_prompt(). One API, multiple providers — Anthropic, OpenAI, Google — selected by configuration rather than code.

For plugin developers this ends a real problem: every AI-flavoured plugin shipping its own SDK, its own settings screen, and its own copy of the user's API keys. With the AI Client there is one place keys live, one prompt-building API, and one registry your plugin can introspect.

/ Connectors

How do provider Connectors work?

Site owners configure AI providers once, at the WordPress level (Settings → Connectors). Every plugin using the AI Client shares those connections — which means your plugin stores no keys, renders no key field, and inherits credential rotation for free. From code, the client exposes a registry you can introspect: which providers are configured, and which models each one offers, complete with capability metadata.

Two practical notes from production use. First, model lists are fetched live from each provider's list-models endpoint, so cache them (a transient with a short TTL is enough) rather than hitting the network on every admin page load. Second, filter models by capability: a text-generation agent should skip models that advertise image, audio, video, or embedding output — the registry metadata tells you which is which.

/ The API

How does wp_ai_client_prompt() work?

It returns a fluent builder: you chain configuration and finish with a generation call.

PHP — a pinned-model text generation

$builder = wp_ai_client_prompt( $prompt )
    ->using_system_instruction( $system )
    ->using_temperature( 0.2 )
    // A single-entry preference pins this exact model (and its provider).
    ->using_model_preference( 'claude-sonnet-4-6' );

$text = $builder->generate_text();

if ( is_wp_error( $text ) ) {
    // Provider failure, quota, or misconfiguration — decide whether to retry.
}

One gotcha will bite anyone writing defensive code: the builder dispatches its fluent methods through __call(), so they are invisible to method_exists(). Do not feature-detect individual builder methods — call them inside a try/catch and let the builder surface failures from generate_text() as a WP_Error.

/ Availability

How do you detect the AI Client safely?

Three checks, all deterministic and free — none makes an API call. First, function_exists('wp_ai_client_prompt') confirms the client is present (older WordPress). Second, wp_supports_ai() confirms the site hasn't opted out of AI features — respect it. Third, ask the builder itself whether text generation is currently possible, i.e. whether any provider is actually configured:

PHP — capability check before offering AI features

public static function isAvailable(): bool {
    if ( ! function_exists( 'wp_ai_client_prompt' ) ) {
        return false;
    }
    if ( function_exists( 'wp_supports_ai' ) && ! wp_supports_ai() ) {
        return false;
    }
    try {
        return wp_ai_client_prompt( 'ping' )
            ->is_supported_for_text_generation() === true;
    } catch ( \Throwable $e ) {
        return false;
    }
}

/ Resilience

How do you build a cross-provider fallback chain?

Single-provider setups fail in boring, predictable ways: the free-tier quota runs out mid-afternoon and every request 429s until midnight. The fix is a candidate chain — the user's preferred model first, then one representative model from each other configured provider. On a retryable error (quota, rate limit, transient 5xx) you try the next candidate; on a non-retryable error (bad key, malformed request) you stop immediately, because another provider will not fix your bug.

The cross-provider part matters more than it looks. Quota exhaustion is usually per-project and shared across all of one provider's models — falling back from one model to its sibling on the same provider usually re-fails with the same 429. Jumping providers actually lands somewhere the request can succeed.

WordPress AI Client model preference with cross-provider fallbackA prompt is first pinned to the user's preferred model. If the provider fails with a retryable error such as a quota 429, the next candidate model from a different configured provider is tried, because quota errors are usually per-project and shared across one provider's models. Auth or bad-request errors stop the chain immediately. The first successful model returns text.

text

429 / retryable

auth / bad request

text

429 / retryable

auth / bad request

text

all failed

prompt + system instruction

preferred model
provider A

response returned

fallback model
provider B

stop: error returned

fallback model
provider C

FIG 01 — Cross-provider fallback chain
Quota errors are per-project and shared across one provider's models. Fall back across providers, not within one. — fallback design rule

/ Limits

What are the AI Client's limits?

Two matter for anything agent-shaped. There is no native tool calling: the client generates text, and if you want the model to propose operations, you must layer a structured-output protocol on top — ask for a strict JSON envelope and parse it defensively. And the prompt builder takes a single user prompt, not a message array, so multi-turn conversations must be folded into one transcript string with the system instruction passed separately via using_system_instruction().

Neither is a blocker — the plan-first agent architecture shows a production pattern for both — but they shape your design: the protocol lives in your prompts and parsers, not in the transport.

/ BYOK

When do you still need bring-your-own-key?

Whenever the AI Client cannot serve: the site runs an older WordPress, no connector is configured, or the owner simply prefers a dedicated key for your plugin. A robust integration treats the transport as swappable. The Webhook Actions plugin (in its upcoming Build with AI release) resolves it with a three-state source option — auto (prefer the AI Client when available, else BYO), or pinned to either path. On the BYO path, per-provider keys are stored encrypted in its write-only Credentials Vault, models are discovered from each provider's own models endpoint, and the same cross-provider fallback applies across the configured BYO providers.

The result is one AI feature with two credential sources presented identically — and zero keys handled by the plugin whenever WordPress can hold them instead.

ConcernHardcoding one provider SDKAI Client + BYOK fallback (Webhook Actions)
API keysYour settings page stores another copy of the keyWordPress Connectors hold them; BYO keys encrypted in a write-only vault
Provider outage / quotaFeature is down until the quota resetsRetryable failures hop to the next configured provider
Older WordPressWorks, but keys sprawl per pluginAuto mode falls back to the BYO path seamlessly
Model choiceHardcoded model id in the codebaseLive model catalog per provider, user-selectable, cached

The Webhook Actions plugin uses this exact stack for its upcoming Build with AI feature — WordPress 7.0 AI Client when configured, encrypted BYO keys when not — so describing an integration in plain language builds real, queued, retried webhooks.

/Footnotes
² WordPress AI team roadmap and announcements: make.wordpress.org/ai.
FAQ

Common questions always ask.

Don't see yours? Open an issue on GitHub or check the full reference in the API docs.

What is wp_ai_client_prompt() in WordPress? +
It is the entry point of the WordPress 7.0 AI Client — a provider-agnostic PHP layer for calling large language models. It returns a fluent builder: chain using_system_instruction(), using_temperature(), and using_model_preference(), then call generate_text(), which returns the generated string or a WP_Error.
Where does WordPress store AI provider API keys? +
At the WordPress level, in the provider Connectors settings — not in individual plugins. Every plugin using the AI Client shares those centrally managed connections, so a well-behaved plugin stores no keys and renders no API-key field of its own on this path.
How do I check if the WordPress AI Client is available? +
Three deterministic checks that make no API call: function_exists('wp_ai_client_prompt') for presence, wp_supports_ai() to respect sites that opted out of AI features, and the builder's is_supported_for_text_generation() to confirm a provider is actually configured. Wrap the last one in try/catch.
Does the WordPress AI Client support tool calling? +
No. The AI Client generates text; it has no native tool-calling or function-calling. Agent-style plugins layer a structured-output protocol on top — instructing the model to return a strict JSON envelope describing proposed operations, then parsing and executing those locally.
What happens when an AI provider hits its quota? +
The request fails with a retryable error such as a 429. A resilient integration keeps a candidate chain — the preferred model first, then one model from each other configured provider — and retries retryable failures on the next provider, because quota exhaustion is usually per-project and shared across all of one provider's models.
Ready

Stop losing webhooks.
Start logging them.

$ wp plugin install flowsystems-webhook-actions --activate