---
title: Refresh a site's current state
url: https://developers.wpengine.com/docs/ai/api/reference/operations/heartbeatsite/
image: https://developers.wpengine.com/og/docs/ai/api/reference/operations/heartbeatsite.png
---

# Refresh a site's current state

POST

/v1/sites/{client_id}/heartbeat

Select code sample

```php
<?php


$client = new \GuzzleHttp\Client();


$response = $client->request('POST', 'https://api.ai.wpengine.com/v1/sites/example/heartbeat', [
  'body' => '{ "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, "wpe_plugins": { "wpe-hub": "1.2.0" } }, "plugin_status": "active", "abilities": [ { "name": "example", "label": "example", "description": "example", "category": "example", "input_schema": {}, "output_schema": {}, "meta": {}, "run_url": "https://example.com" } ] }',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);


echo $response->getBody();
```

- Current environment

Reports current WordPress environment and plugin status. When abilities are included, they replace the site’s cached ability catalog. A registration that exists but is not currently active (for example, temporarily suspended) receives a 403 with error code `site_not_active`; that state is recoverable, and clients must not clear local credentials on it — only the explicit 404 `site_authorization_revoked` response is the revocation signal.

## Authorizations

- **[bearerAuth](https://developers.wpengine.com/docs/ai/api/reference/#bearerauth)**

## Parameters

### Path Parameters

**client_id**

required

string

The OAuth client identifier of the reporting site.

## Request Bodyrequired

Media typeapplication/json

object

**site_info**

required

WordPress environment metadata collected by the plugin at registration time. All fields are optional.

object

**active_plugins**

Names of currently active WordPress plugins.

Array\<string>

<= 500 items

**php_version**

string

<= 64 characters

### Example

```
8.2.0
```

**wp_version**

string

<= 64 characters

### Example

```
6.5.0
```

**active_theme**

string

<= 256 characters

### Example

```
twentytwentyfour
```

**locale**

string

<= 64 characters

### Example

```
en_US
```

**server_software**

string

<= 256 characters

### Example

```
Apache/2.4.57
```

**db_version**

string

<= 64 characters

### Example

```
8.0.33
```

**memory_limit**

string

<= 32 characters

### Example

```
256M
```

**timezone**

string

<= 64 characters

### Example

```
America/Chicago
```

**active_plugin_count**

Total number of active plugins on the site. May exceed len(active_plugins) when the plugin list was truncated at 500 items.

integer

### Example

```json
12
```

**ssl_valid**

boolean

### Example

```json
true
```

**is_multisite**

boolean

### Example

```json
false
```

**wp_debug**

boolean

### Example

```json
false
```

**wpe_plugins**

Active WP Engine plugins mapped to their version. Optional: on the heartbeat an absent field keeps the stored map, and an empty object means none are active. An empty array is also accepted; any other array is rejected. The gateway keeps only slugs `power`, `power-*` and `wpe-*` (the Power plugin reports as `wpe-hub`), at most 20 in slug order, and drops slugs over 64 characters and entries whose version is empty, not a string or over 32 characters. `POST /v1/sites` accepts the field but does not store it; heartbeats record it.

object

**_key_**

additional properties

string

### Example

```json
{
  "wpe-hub": "1.2.0"
}
```

**plugin_status**

WP Engine AI plugin lifecycle status. Omit this property when the heartbeat is sent by a shared auth consumer that does not own Power lifecycle.

string

Allowed values: active inactive

**abilities**

Current ability descriptors. Omit this property to leave the cached catalog unchanged; send an empty array to clear it.

Array\<object>

object

**name**

required

string

**label**

string

**description**

string

**category**

string

**input_schema**

object

**output_schema**

object

**meta**

object

**run_url**

string format: uri

## Responses

### 200

Site state was refreshed.

Media typeapplication/json

object

**last_site_update_at**

required

string format: date-time

**plugin_status_updated_at**

required

string format: date-time

**abilities_synced_at**

string format: date-time

**abilities_sync_status**

required

string

Allowed values: never_synced ok stale error

**abilities_count**

required

integer

**plugin_status**

required

string

Allowed values: active inactive

#### Example

```json
{
  "abilities_sync_status": "never_synced",
  "plugin_status": "active"
}
```

### 400

Invalid request body or parameters. On agent create and update, error type “profile_unavailable” means the requested profile is not available to the caller.

Media typeapplication/json

object

**error**

required

object

**message**

required

string

**type**

required

string

**error_code**

Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.

string

**portal_url**

Where the customer can resolve the error, set on an entitlement_required refusal that has an error_code when one is configured.

string

**code**

required

integer

**request_id**

required

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.

string

#### Example

```json
{
  "error": {
    "type": "invalid_request_error",
    "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5"
  }
}
```

### 401

Missing or invalid bearer token

Media typeapplication/json

object

**error**

required

object

**message**

required

string

**type**

required

string

**error_code**

Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.

string

**portal_url**

Where the customer can resolve the error, set on an entitlement_required refusal that has an error_code when one is configured.

string

**code**

required

integer

**request_id**

required

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.

string

#### Example

```json
{
  "error": {
    "type": "invalid_request_error",
    "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5"
  }
}
```

#### Headers

**WWW-Authenticate**

string

##### Example

```
Bearer realm="ai-services"
```

### 403

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 may not use WP Engine AI, with error_code giving why when known (not_eligible, terms_required, not_enabled or suspended) and portal_url where to fix it; “account_required” means no billing account could be resolved; and “billing_account_pending” means billing isn’t set up for the account yet, usually because its setup after AI was turned on hasn’t finished. Retry shortly. 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.

Media typeapplication/json

object

**error**

required

object

**message**

required

string

**type**

required

string

**error_code**

Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.

string

**portal_url**

Where the customer can resolve the error, set on an entitlement_required refusal that has an error_code when one is configured.

string

**code**

required

integer

**request_id**

required

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.

string

#### Example

```json
{
  "error": {
    "type": "invalid_request_error",
    "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5"
  }
}
```

### 404

The authenticated site’s authorization has been revoked or no longer exists. The response error code is `site_authorization_revoked`; clients may use that explicit code to clear local credentials.

Media typeapplication/json

object

**error**

required

string

Allowed values: site_authorization_revoked

**message**

required

string

#### Example

```json
{
  "error": "site_authorization_revoked",
  "message": "this site's authorization has been revoked"
}
```

### 413

Request body exceeds the 64 KiB limit

Media typeapplication/json

object

**error**

required

object

**message**

required

string

**type**

required

string

**error_code**

Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.

string

**portal_url**

Where the customer can resolve the error, set on an entitlement_required refusal that has an error_code when one is configured.

string

**code**

required

integer

**request_id**

required

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.

string

#### Example

```json
{
  "error": {
    "type": "invalid_request_error",
    "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5"
  }
}
```

### 503

A required dependency is temporarily unavailable. Retry after a short delay with exponential back-off. An entitlement lookup failure uses error type “entitlement_unavailable”. A model without complete rate coverage uses error type “model_unpriced”. A credit balance that can’t be read uses error type “balance_unavailable”.

Media typeapplication/json

object

**error**

required

object

**message**

required

string

**type**

required

string

**error_code**

Stable, machine-readable cause, set by routes that document their codes (the AI readiness and account AI routes, and an entitlement_required refusal, where it is one of not_eligible, terms_required, not_enabled or suspended); absent elsewhere and on errors from shared layers such as authentication. Clients must allow new codes.

string

**portal_url**

Where the customer can resolve the error, set on an entitlement_required refusal that has an error_code when one is configured.

string

**code**

required

integer

**request_id**

required

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.

string

#### Example

```json
{
  "error": {
    "type": "invalid_request_error",
    "request_id": "80f1e2c3a4b5c6d7e8f9a0b1c2d3e4f5"
  }
}
```

## 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"}}]}
```
