Create an agent
package main
import ( "fmt" "strings" "net/http" "io")
func main() {
url := "https://api.ai.wpengine.com/v1/agents"
payload := strings.NewReader("{ \"name\": \"Site Concierge\", \"model\": \"anthropic/claude-sonnet-4-6\", \"description\": \"example\", \"system_prompt\": \"example\", \"project_id\": \"example\", \"temperature\": 1, \"max_tokens\": 1, \"reasoning_effort\": \"example\", \"scopes\": [ \"example\" ], \"settings\": {}, \"mcp_servers\": [ {} ], \"tools\": [ { \"type\": \"custom\", \"name\": \"example\", \"description\": \"example\", \"input_schema\": {}, \"label\": \"example\", \"defer_loading\": false } ], \"skills\": [ {} ], \"metadata\": { \"additionalProperty\": \"example\" } }")
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/agents';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"name":"Site Concierge","model":"anthropic/claude-sonnet-4-6","description":"example","system_prompt":"example","project_id":"example","temperature":1,"max_tokens":1,"reasoning_effort":"example","scopes":["example"],"settings":{},"mcp_servers":[{}],"tools":[{"type":"custom","name":"example","description":"example","input_schema":{},"label":"example","defer_loading":false}],"skills":[{}],"metadata":{"additionalProperty":"example"}}'};
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/agents', [ 'body' => '{ "name": "Site Concierge", "model": "anthropic/claude-sonnet-4-6", "description": "example", "system_prompt": "example", "project_id": "example", "temperature": 1, "max_tokens": 1, "reasoning_effort": "example", "scopes": [ "example" ], "settings": {}, "mcp_servers": [ {} ], "tools": [ { "type": "custom", "name": "example", "description": "example", "input_schema": {}, "label": "example", "defer_loading": false } ], "skills": [ {} ], "metadata": { "additionalProperty": "example" } }', 'headers' => [ 'Authorization' => 'Bearer <token>', 'Content-Type' => 'application/json', ],]);
echo $response->getBody();curl --request POST \ --url https://api.ai.wpengine.com/v1/agents \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "name": "Site Concierge", "model": "anthropic/claude-sonnet-4-6", "description": "example", "system_prompt": "example", "project_id": "example", "temperature": 1, "max_tokens": 1, "reasoning_effort": "example", "scopes": [ "example" ], "settings": {}, "mcp_servers": [ {} ], "tools": [ { "type": "custom", "name": "example", "description": "example", "input_schema": {}, "label": "example", "defer_loading": false } ], "skills": [ {} ], "metadata": { "additionalProperty": "example" } }'Creates a managed agent under project_id, which is required and must be a project the caller is authorized for. The agent stores the model, optional system prompt, inference parameters, knowledge-base collections, MCP servers, tools, skills, scopes, and feature settings (e.g. disable_kb_rag). The model must support the tools capability; models without this capability return HTTP 400. Accepts a service-token bearer authenticating a site (the project must belong to the site’s account) or an API key scoped to project_id — an API key’s own project must match exactly. Multiple agents in the same project may share a display name; identity is keyed by id.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
Human-readable agent name.
Example
Site ConciergeIdentifier of the model that powers the agent (e.g. anthropic/claude-sonnet-4-6).
Example
anthropic/claude-sonnet-4-6Free-form description of what the agent does.
User prompt template (site prompt) prepended to every conversation powered by this agent.
The project the agent belongs to. Required — the caller must always supply it explicitly. For a service-token caller authenticating a site, the project must be owned by the same account that owns the site. For an API key, it must match the key’s own project exactly.
Sampling temperature applied to chat completions.
Hard upper bound on output tokens per agent turn, forwarded to the model provider as max_tokens on each turn. Generation stops when the limit is reached; the response may be truncated mid-content rather than rejected. On reasoning-capable models (see capabilities on GET /v1/models), internal reasoning tokens may count against this budget alongside visible output. Omitted values leave the limit unset so provider-specific defaults apply (Anthropic defaults to 8192 when unset; OpenAI-compatible routes omit the field). Compare with the model’s max_output_tokens on GET /v1/models, which is the catalog ceiling for a single response. Values above the catalog-wide maximum are rejected with 400. When a turn exhausts this budget, session.status_idle carries stop_reason max_tokens.
Catalog-native reasoning effort for this agent’s model. Allowed values are the model’s parameters.reasoning_effort on GET /v1/models. Omit to use the provider default. Models that do not publish an enum reject any non-empty value.
Permission scopes the agent operates under. Must be drawn from the site’s existing scopes (e.g. chat, search).
Feature toggles for the agent (e.g. disable_kb_rag: true to skip knowledge-base retrieval). Capped at 32 keys and 4 KiB serialized.
object
MCP server definitions the agent may connect to.
object
Tool declarations available to the agent. See AgentTool for the per-entry contract.
object
Discriminator for the tools[] union. Omit for a plain client tool (the default); custom is the only value this schema accepts.
Unique tool name. Must be unique within the agent’s tools array (across every entry, regardless of type).
Human-readable description of what the tool does.
JSON Schema defining the tool’s input parameters.
object
Optional short human-readable name for the tool, used alongside name and description when the gateway matches a search query against deferred tools. Supply it when the tool’s name is a slug whose wording a natural-language query would not contain.
When true, the tool is declared but kept out of the model’s tool list until it is needed, so a large catalogue costs no context up front. The gateway offers the agent a search over the deferred tools and loads the matches, and a deferred tool the model names directly is loaded on demand. Once loaded, its input is enforced strictly against its schema — unlike a non-deferred tool, which keeps today’s lenient handling — so a malformed call is rejected with a model-readable error instead of failing downstream. Leave false (the default) for tools that must be callable from the first turn.
A data-source declaration — one entry per collection. The gateway fans it into every runtime tool it currently supports over the collection (search, fetch, …) and names them by convention from collection_id.
object
The knowledge-base collection to ground retrieval against.
Optional filter ceiling scoped to this collection. Null or omitted means unconstrained. Applies to every runtime tool the gateway emits from this entry — search results are constrained to matching docs, and a fetched doc that fails any dimension comes back as not_found.
object
Post types to include.
Document URIs to include.
ISO 639-1 language codes to include.
Exact-match filters keyed by metadata field; each field maps to a list of accepted values.
object
Example
{ "status": [ "publish" ], "category": [ "news", "guides" ]}Inclusive date bounds (RFC-3339). Either bound may be omitted.
object
Inclusive date bounds (RFC-3339). Either bound may be omitted.
object
object
Opts the agent into the gateway’s built-in echo tool (returns its input message unchanged). A local development aid for validating tool-call round-trips; it is only served in dev environments, where an agent declaring it elsewhere fails at session start with a toolset_incomplete error instead. Do not declare it on an agent you intend to run outside dev.
Unique wire identifier for the tool, chosen by the caller. Must be unique within the agent’s tools array.
object
Opts the agent into the gateway’s built-in random-number tool (returns an integer within a caller-given range). A local development aid for validating tool-call round-trips; it is only served in dev environments, where an agent declaring it elsewhere fails at session start with a toolset_incomplete error instead. Do not declare it on an agent you intend to run outside dev.
Unique wire identifier for the tool, chosen by the caller. Must be unique within the agent’s tools array.
Skills enabled for the agent.
object
Arbitrary string key-value metadata stored alongside the agent. The keys “scopes” and “settings” are reserved.
object
Responses
Section titled “Responses”The created agent
object
Unique identifier for the agent.
The project the agent belongs to.
User prompt template (site prompt).
Output-token limit per turn (see CreateAgentRequest.max_tokens). Omitted when unset on the agent.
Catalog-native reasoning effort stored on the agent. Omitted when unset. Allowed values follow the agent’s current model on GET /v1/models.
Permission scopes the agent operates under (round-trips the request value).
Feature toggles for the agent (round-trips the request value).
object
object
Tool declarations (client tools, knowledge_base grounding entries, and echo/random_number evaluation tool opt-ins) round-tripped from the request.
object
Discriminator for the tools[] union. Omit for a plain client tool (the default); custom is the only value this schema accepts.
Unique tool name. Must be unique within the agent’s tools array (across every entry, regardless of type). Always present for tools created since name validation was added; may be absent on an agent whose tools were stored before that validation existed.
Human-readable description of what the tool does.
JSON Schema defining the tool’s input parameters.
object
Optional short human-readable name for the tool, used alongside name and description when the gateway matches a search query against deferred tools. Supply it when the tool’s name is a slug whose wording a natural-language query would not contain.
When true, the tool is declared but kept out of the model’s tool list until it is needed, so a large catalogue costs no context up front. The gateway offers the agent a search over the deferred tools and loads the matches, and a deferred tool the model names directly is loaded on demand. Once loaded, its input is enforced strictly against its schema — unlike a non-deferred tool, which keeps today’s lenient handling — so a malformed call is rejected with a model-readable error instead of failing downstream. Leave false (the default) for tools that must be callable from the first turn.
A data-source declaration — one entry per collection. The gateway fans it into every runtime tool it currently supports over the collection (search, fetch, …) and names them by convention from collection_id.
object
The knowledge-base collection to ground retrieval against.
Optional filter ceiling scoped to this collection. Null or omitted means unconstrained. Applies to every runtime tool the gateway emits from this entry — search results are constrained to matching docs, and a fetched doc that fails any dimension comes back as not_found.
object
Post types to include.
Document URIs to include.
ISO 639-1 language codes to include.
Exact-match filters keyed by metadata field; each field maps to a list of accepted values.
object
Inclusive date bounds (RFC-3339). Either bound may be omitted.
object
Inclusive date bounds (RFC-3339). Either bound may be omitted.
object
object
Opts the agent into the gateway’s built-in echo tool (returns its input message unchanged). A local development aid for validating tool-call round-trips; it is only served in dev environments, where an agent declaring it elsewhere fails at session start with a toolset_incomplete error instead. Do not declare it on an agent you intend to run outside dev.
Unique wire identifier for the tool, chosen by the caller. Must be unique within the agent’s tools array.
object
Opts the agent into the gateway’s built-in random-number tool (returns an integer within a caller-given range). A local development aid for validating tool-call round-trips; it is only served in dev environments, where an agent declaring it elsewhere fails at session start with a toolset_incomplete error instead. Do not declare it on an agent you intend to run outside dev.
Unique wire identifier for the tool, chosen by the caller. Must be unique within the agent’s tools array.
object
User-supplied string metadata. Reserved keys (“scopes”, “settings”) are surfaced on their own top-level fields rather than appearing here.
object
Example
{ "type": "agent", "tools": [ { "type": "custom", "defer_loading": false } ]}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 caller is not permitted to perform this action — either its scope/permission is insufficient or the authenticated user is not authorized for the target account (error type “permission_error”). On /v1/chat/completions specifically, a 403 with 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" }}Rate limit exceeded. The request was throttled at the edge; wait and retry later. The response body is a short HTML page generated by the load balancer, not a structured JSON error — clients should rely on the 429 status code rather than parsing the body.
The server encountered an unexpected error while handling the request. Safe to retry once; if it persists, the cause is server-side and the request payload was not the problem.
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.
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" }}