Register or update a WordPress site
package main
import ( "fmt" "strings" "net/http" "io")
func main() {
url := "https://api.ai.wpengine.com/v1/sites"
payload := strings.NewReader("{ \"site_url\": \"https://example.wpengine.com\", \"display_name\": \"My Blog\", \"project_id\": \"proj_01abc\", \"site_info\": { \"active_plugins\": [ \"example\" ], \"php_version\": \"8.2.0\", \"wp_version\": \"6.5.0\", \"active_theme\": \"twentytwentyfour\", \"locale\": \"en_US\", \"server_software\": \"Apache/2.4.57\", \"db_version\": \"8.0.33\", \"memory_limit\": \"256M\", \"timezone\": \"America/Chicago\", \"active_plugin_count\": 12, \"ssl_valid\": true, \"is_multisite\": false, \"wp_debug\": false } }")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>") req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close() body, _ := io.ReadAll(res.Body)
fmt.Println(res) fmt.Println(string(body))
}const url = 'https://api.ai.wpengine.com/v1/sites';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"site_url":"https://example.wpengine.com","display_name":"My Blog","project_id":"proj_01abc","site_info":{"active_plugins":["example"],"php_version":"8.2.0","wp_version":"6.5.0","active_theme":"twentytwentyfour","locale":"en_US","server_software":"Apache/2.4.57","db_version":"8.0.33","memory_limit":"256M","timezone":"America/Chicago","active_plugin_count":12,"ssl_valid":true,"is_multisite":false,"wp_debug":false}}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.ai.wpengine.com/v1/sites', [ 'body' => '{ "site_url": "https://example.wpengine.com", "display_name": "My Blog", "project_id": "proj_01abc", "site_info": { "active_plugins": [ "example" ], "php_version": "8.2.0", "wp_version": "6.5.0", "active_theme": "twentytwentyfour", "locale": "en_US", "server_software": "Apache/2.4.57", "db_version": "8.0.33", "memory_limit": "256M", "timezone": "America/Chicago", "active_plugin_count": 12, "ssl_valid": true, "is_multisite": false, "wp_debug": false } }', 'headers' => [ 'Authorization' => 'Bearer <token>', 'Content-Type' => 'application/json', ],]);
echo $response->getBody();curl --request POST \ --url https://api.ai.wpengine.com/v1/sites \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "site_url": "https://example.wpengine.com", "display_name": "My Blog", "project_id": "proj_01abc", "site_info": { "active_plugins": [ "example" ], "php_version": "8.2.0", "wp_version": "6.5.0", "active_theme": "twentytwentyfour", "locale": "en_US", "server_software": "Apache/2.4.57", "db_version": "8.0.33", "memory_limit": "256M", "timezone": "America/Chicago", "active_plugin_count": 12, "ssl_valid": true, "is_multisite": false, "wp_debug": false } }'Registers a WordPress site with the AI Gateway, or updates an existing registration for the same site. The caller must authenticate with a WP Engine oauth-ext access token obtained via Dynamic Client Registration (RFC 7591). The gateway returns a stable site_id for the logical site; client_id continues to identify the current OAuth registration. Re-registering the same OAuth client updates its metadata in place. Request body is capped at 64 KiB. Unknown JSON fields are rejected. Returns 409 if the token’s account_id differs from the account that originally registered the client_id (ownership conflict), or if an existing client moves to a site_url already owned by another site in the same account.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Fully-qualified URL of the WordPress site (scheme + host required). Longer than 2048 bytes is rejected with 400.
Example
https://example.wpengine.comHuman-readable name for the site, at most 255 characters (characters, not bytes — multi-byte names are measured the same way). Optional; defaults to site_url, truncated to fit.
Example
My BlogWP Engine project to associate the site with. Optional — omit when the site is not scoped to a project.
Example
proj_01abcWordPress environment metadata collected by the plugin at registration time. All fields are optional.
object
Names of currently active WordPress plugins.
Example
8.2.0Example
6.5.0Example
twentytwentyfourExample
en_USExample
Apache/2.4.57Example
8.0.33Example
256MExample
America/ChicagoTotal number of active plugins on the site. May exceed len(active_plugins) when the plugin list was truncated at 500 items.
Example
12Example
trueExample
falseExample
falseResponses
Section titled “Responses”Site registered or updated. Returns the stable site_id, client_id, registration status, the original creation timestamp (unchanged on updates), and the per-site HMAC secret for anonymous user identification.
object
Stable gateway-owned identifier for the logical site.
The current Dynamic Client Registration credential identifier for the site. It can change when the site reconnects.
Current registration status of the site.
When the site was first registered (UTC). Unchanged on subsequent updates to the same site.
Per-site HMAC secret for deriving anonymous user identifiers. 32 random bytes hex-encoded (64 chars). Preserved across re-registrations. The plugin must store this securely and never send it back to the gateway.
Example
{ "site_id": "site_01AbCdEfGhIjKlMnOpQrSt", "client_id": "client_01abc", "status": "active", "created_at": "2024-01-15T10:30:00Z", "site_hmac_secret": "abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"}Invalid request body or parameters
object
object
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}Missing or invalid bearer token
object
object
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}Headers
Section titled “Headers”Example
Bearer realm="ai-services"The token is valid, but the request is forbidden. Error type “permission_error” means the token’s scope/permission is insufficient or the authenticated user is not authorized for the target account; “entitlement_required” means the account lacks the required product entitlement; and “account_required” means no billing account could be resolved. On /v1/chat/completions when content moderation is enabled, and on /v1/sessions/{session_id}/events, error type “content_policy_violation” instead means the request content was blocked by content moderation policy; that response never identifies which filter or category matched.
object
object
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}The request conflicts with an existing resource
object
object
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}Request body exceeds the 64 KiB limit
object
object
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}A required dependency is temporarily unavailable. Retry after a short delay with exponential back-off. An entitlement lookup failure uses error type “entitlement_unavailable”.
object
object
Correlation ID for this request, matching the X-Request-ID response header — a 32-character trace ID behind the load balancer, otherwise a UUID. Quote it in support reports.
Example
{ "error": { "type": "invalid_request_error", "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5" }}