REST API Endpoints

The cmd-features plugin registers the REST routes below. A route exists only while the feature it belongs to is switched on for the site; when that feature is off the route is not registered at all and the REST API returns a 404.

Five of these six routes have a permissive permission_callback and are reachable by unauthenticated visitors. They rely on nonces, rate limiting and allowlists rather than capability checks. Read the authentication note on each route before exposing the site to untrusted traffic.

AI answers

GET /wp-json/commandmedia/v1/answer/

Runs a retrieval-augmented query and returns the generated answer. Available only while the AI features and the AI REST API are both switched on for the site.

Authentication: None. The permission callback returns true for every request, so this route is public. Protect it with the CMOPT_AI_API_LIMIT_30SEC and CMOPT_AI_API_LIMIT_HOUR rate limits before enabling it in production.

ParameterTypeRequiredDescription
querystringYesThe search query. Truncated to 400 characters before retrieval.

Returns: Always HTTP 200 with a body of { code, message, data }. The data.status field carries the real outcome: 200 on success, 400 when query is missing, 500 on an AI error. On success data.response holds the generated answer as { summary, source }, where summary is the HTML answer and source is an array of { title, url } citations. A rate-limited request currently returns data.status 200 with the message “No results found.” and an empty data.response, which is indistinguishable from a search that matched nothing; the rest_rate_limited code and data.status 429 that this route declares are not reachable today.

curl 'https://example.com/wp-json/commandmedia/v1/answer/?query=how+do+i+reset+my+password'

GET /wp-json/commandmedia/v1/status/

Reports whether this site can answer an AI query, without running one. Integrations call it to validate a site before storing a connection, so that checking a connection never bills an AI generation. Registered whenever the AI features are switched on, whether or not the answer API itself is — which is what lets a caller tell a site with the answer API disabled (503) apart from a site that has never had this plugin (404).

Authentication: None. The permission callback returns true for every request, so this route is public. It runs no query and reads no configuration, so there is nothing to rate limit.

Returns: HTTP 200 with { code, message, data } when answers are available; data.response holds { product, api_version, answer_endpoint, site_name, site_url }, where product is the string “Command Media AI”. HTTP 503 with the cmd_ai_unavailable error code when the site cannot answer — the answer API is off, or no AI connector can generate, which since 2.5.0 means WordPress 7.0 or newer with a provider connected under Settings > Connectors. Availability therefore reflects whether an answer is actually possible, not merely whether the feature flags are set. HTTP 404 from WordPress itself when the AI features are off or the plugin is not installed.

curl 'https://example.com/wp-json/commandmedia/v1/status/'

ChatKit

POST /wp-json/commandmedia/v1/chatkit-session

Creates an OpenAI ChatKit session and returns its client secret, scoped to the current user or to a guest cookie. Available only while the ChatKit prototype is switched on for the site.

Authentication: The permission callback returns true, but the handler requires a valid wp_rest nonce in the X-WP-Nonce header and applies per-IP rate limiting when limits are configured. The requested workflow must appear in the CMOPT_AI_CHATKIT_WORKFLOW_IDS allowlist.

ParameterTypeRequiredDescription
workflow_idstringNoWorkflow to open a session against. Must be present in the allowlist. When omitted, the first allowed workflow is used.

Returns: { client_secret } on success. Errors: cmd_chatkit_not_configured (500), cmd_chatkit_workflow_not_allowed (403), cmd_chatkit_session_failed (502).

Query logs and feedback

GET /wp-json/commandmedia/v1/ai-logs/

Returns the AI query log, newest first, with each row’s stored result set rebuilt as an HTML list. Available only while the AI features are switched on for the site.

Authentication: Requires an authenticated user with the edit_pages capability. This is the only route in the plugin behind a capability check.

Returns: An array of query log rows from the cmd_ai_query_logs table.

POST /wp-json/commandmedia/v1/ai-feedback/

Records a visitor’s thumbs-up or thumbs-down rating against an existing AI query log row. Available only while the AI features are switched on for the site.

Authentication: None. The permission callback returns true. The handler applies transient-backed per-IP rate limiting: 15 submissions in 60 seconds triggers a 30 minute ban.

ParameterTypeRequiredDescription
log_idintegerYesID of the query log row being rated. Must be numeric and greater than zero.
ratingintegerYes1 for a positive rating, -1 for a negative one. Any other value is rejected.
reasonstringNoOptional free-text reason. Sanitised and truncated to 2000 characters.

Returns: The result of the update against the existing log row.

POST /wp-json/commandmedia/v1/chatkit-feedback/

Records a rating for a ChatKit conversation. Unlike /ai-feedback/, this creates a new log row keyed by the client-supplied conversation ID. Available only while the AI features are switched on for the site.

Authentication: None. The permission callback returns true. The route is rate limited.

ParameterTypeRequiredDescription
conversation_idstringYesChatKit conversation identifier. Must match ^[A-Za-z0-9_-]{1,128}$.
ratingintegerYes1 for a positive rating, -1 for a negative one. Any other value is rejected.
reasonstringNoOptional free-text reason. Sanitised and truncated to 2000 characters.

Returns: The result of the insert into the query log table.