Create Agent
Agents
Create Agent
POST
Create Agent
Use this API to create a new custom agent configuration. The engine stores the agent in Firestore and writes version 1 to the agent’s versions subcollection. The schema uses
Required when
MCP servers (
When
4. Agent that verifies content against an MCP server (
Errors:
.passthrough(), so any additional behavioral fields are forwarded to the service layer.
Endpoint
POST https://api.velt.dev/v2/agents/create
Headers
Your API key.
Your Auth Token.
Body
Params
Server-managed fields
The following fields are owned by the server and are rejected with a400 INVALID_ARGUMENT if present on the create or update-version payload:
| Field | Why it is server-managed |
|---|---|
managedBy | Always derived server-side — "customer" for every API-created agent. |
metadata.type | Marks built-in / system agents. |
metadata.category | Marks built-in / system agents. |
metadata.internal | true hides an agent from all list responses — allowing a client to set it would forge a hidden agent. |
metadata.apiKey | The tenant key; merged in server-side. |
id, version, createdAt, and updatedAt are likewise server-generated. Sending a reserved key returns one error per offending key, e.g. metadata.internal is a server-managed field and cannot be set via the API.
Context gathering strategies
| Strategy | What it returns |
|---|---|
web-page-text | Visible text extracted via Puppeteer |
web-page-screenshot | Full-page screenshot as image (multimodal input) |
web-page-html | Cleaned HTML content |
web-page-css | Cleaned CSS content from stylesheets |
web-page-links | All hyperlinks, classified internal/external |
web-page-accessibility | Accessibility issues (Pa11y / HTML_CodeSniffer) |
computed-styles | Browser-resolved computed CSS for specific selectors |
robots-txt | Fetched robots.txt |
sitemap-data | Discovered and parsed XML sitemaps |
lighthouse | Google Lighthouse audit (performance / a11y / best-practices / SEO) |
rest-api | Customer-configured REST endpoints fetched at runtime (see below) |
none | No context gathering (for service-only or text-only agents) |
Context gathering strategy options
Per-strategy overrides are supplied undercontextGathering.strategyOptions["<strategy>"]. All are optional unless noted.
| Strategy | Option | Type | Description |
|---|---|---|---|
web-page-text | deviceType | string | "mobile" / "desktop" (default "desktop"). |
excludeIframes | boolean | Exclude iframe content. Default false. | |
web-page-screenshot | scrollBeforeCapture | boolean | Scroll the full page before capture. |
maxPageHeightPx | number | Cap the captured page height. | |
waitUntil | string | Puppeteer wait condition. | |
deviceType | string | "mobile" / "desktop". | |
web-page-html | includeHead | boolean | Include <head>. Default true. |
includeBody | boolean | Include <body>. Default true. | |
excludeIframes | boolean | Default false. | |
waitUntil | string | Puppeteer wait condition. | |
web-page-css | includeInlineStyles | boolean | Include inline <style> content. |
computed-styles | selectors | string[] | Required — CSS selectors to inspect. |
properties | string[] | Override the curated default property list. | |
sitemap-data | maxEntries | number | Max sitemap entries. Default 500. |
lighthouse | categories | string[] | Lighthouse categories to run. |
formFactor | string | "mobile" / "desktop". | |
rest-api | (see below) | object | Required when rest-api is selected — rest-api strategy options. |
rest-api strategy options
Required when strategies includes "rest-api". Each configured endpoint is fetched at execution time and the resolved URL + description + JSON-stringified response is injected into the prompt via the {{restApiData}} template variable.
| Field | Type | Required | Description |
|---|---|---|---|
endpoints | RestApiEndpoint[] | yes | 1–10 endpoints to fetch. |
maxResponseBytes | number | no | Per-endpoint response-body cap. Default 1000000, hard-capped 5000000. |
RestApiEndpoint fields:
| Field | Type | Required | Description |
|---|---|---|---|
description | string | yes | What this endpoint is about; surfaced in the prompt alongside the URL + response. |
url | string | yes | Endpoint URL. Supports {{variable}} templating. SSRF-validated at fetch time (no internal/loopback/link-local hosts). |
method | "GET"|"POST"|"PUT"|"PATCH"|"DELETE" | no | Default "GET". |
id | string | no | Stable endpoint identifier. |
name | string | no | Human label. |
headers | object | no | Non-secret headers (templated). |
query | object | no | Query params (templated). |
body | object | string | no | Request body for write methods (templated). |
auth | object | no | Discriminated union (none|bearer|basic|header). Secret fields are encrypted at rest and redacted on read. |
cacheTtlSeconds | number | no | In-process per-instance cache TTL. Default 0 (always fresh). Max 86400. |
timeoutMs | number | no | Per-request timeout. Default 10000, hard-capped 30000. |
responsePath | string | no | Dot-path to extract a sub-field of the JSON response. |
auth shapes:
Auth secret handling (redaction-on-read):
token, password, and header values are encrypted before the Firestore write and are never returned to clients. On read (Get / List Agents), encrypted secret fields are replaced with "__redacted__". To rotate a secret, send the new plaintext value on update; to keep an existing secret, omit the field.MCP servers (mcp-tools strategy)
When execution.executionStrategy is "mcp-tools", the agent runs a model-driven tool loop: at execution time the engine connects to each remote MCP (Model Context Protocol) server declared in execution.mcpServers, lists its tools, exposes them to the model, and runs a multi-turn call→tool→call loop until the model emits a final structured response. This is how the built-in docs code-verification agent checks snippets live against the Velt docs MCP instead of a pre-ingested corpus.
The
"mcp-tools" strategy is provider-agnostic (works on both Claude and Gemini) and requires a non-empty top-level instructions field and at least one entry in execution.mcpServers. Omitting either fails validation.execution.mcpServers is an array of 1–5 server objects (MCP_MAX_SERVERS = 5). Each server object is strictly validated (unknown keys rejected):
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Min 1 char. Stable identifier for the server (used in logs + findings). |
url | string | yes | Remote MCP server URL. Must start with http(s):// or contain a {{template}} that resolves to one. SSRF-validated at connect time (no internal/loopback/link-local hosts; redirects re-validated, max 3 hops). |
name | string | no | Human-readable label. |
description | string | no | What this server provides (e.g. "Velt docs MCP"). |
transport | string | no | Transport type. Only "http" is supported (Streamable HTTP with SSE fallback). Defaults to "http". |
auth | object | no | Auth config. Discriminated union (none | bearer | basic | header) — same shape as the rest-api strategy. Secret fields are encrypted at rest and redacted on read. |
allowedTools | string[] | no | Allowlist of tool names. When set, only these tools are exposed/callable. Up to 64 tools per server are exposed (MCP_MAX_TOOLS). |
timeoutMs | number | no | Per-request timeout (ms) for connect/listTools/callTool. Default 30000, hard-capped 120000. |
auth shapes (identical to the rest-api strategy):
Auth secret handling (redaction-on-read): MCP
token, password, and header values are encrypted before the Firestore write (using an MCP-specific encryption salt) and are never returned to clients. On read (Get / List Agents, List Versions), encrypted secret fields are replaced with "__redacted__". To rotate a secret, send the new plaintext value on a version update; to keep an existing secret, omit the field.AI config (provider / model)
Bothexecution.aiConfig and contextGathering.aiConfig accept the same strictly-validated object, letting an agent override the AI provider/model used for that phase. Unknown keys are rejected.
| Field | Type | Description |
|---|---|---|
provider | string | LLM provider: "gemini", "claude", or "openai". Defaults to the platform default when omitted. |
model | string | Model name for the chosen provider (e.g. "gemini-3-flash-preview", "claude-sonnet-4-6"). |
responseMimeType | string | Requested response MIME type (e.g. "application/json"). |
maxToolTurns | number | Tool-loop turn budget for the mcp-tools strategy. Positive integer, hard-capped at runtime. |
Execution strategy options
execution.strategyOptions["<strategy>"] carries per-strategy runtime overrides. The stagehand-agent strategy accepts:
| Option | Type | Default | Description |
|---|---|---|---|
mode | string | "hybrid" | "dom" / "hybrid" / "cua". |
maxSteps | number | 25 | Max autonomous steps. |
model | string | inherited | Model override for the agent loop. |
systemPrompt | string | System prompt for the agent. | |
useStructuredOutput | boolean | true | Return structured output. |
waitUntil | string | "networkidle2" | "domcontentloaded" / "load" / "networkidle2". |
navigationTimeout | number | 30000 | Navigation timeout in ms. |
When using
stagehand-agent, set contextGathering.strategies: ["none"] — the agent handles navigation, interaction, and extraction itself.Knowledge (Memory-RAG)
execution.knowledge pulls workspace knowledge from Velt Memory into the prompt. Strictly validated — only these four fields are accepted:
| Field | Type | Range | Description |
|---|---|---|---|
useMemory | boolean | When true, retrieves knowledge/patterns/activities and injects them as {{memoryContext}}. | |
maxChunks | number | 1–20 | Max knowledge chunks to retrieve. |
maxPatterns | number | 1–20 | Max learned patterns to retrieve. |
maxActivities | number | 1–20 | Max recent activities to retrieve. |
Response Descriptions
All fields are optional strings that instruct the AI on how to populate each finding field:| Field | Description |
|---|---|
summary | Summary text of the overall analysis. |
title | Short title of the finding. |
description | Detailed description of the finding. |
severity | Severity level. Values: critical, high, medium, low, info. |
targetText | The exact text on the page this finding refers to. |
suggestion | Suggested fix or recommendation. |
isPageLevel | "true" for visual/layout findings; "false" when targetText is real DOM text. |
issueType | Issue type for match-and-merge keying (short, lowercase, hyphenated). |
confidence | Confidence score from 0 to 100. |
htmlSelector | CSS selector of the DOM element. |
findingType | Finding type classification. |
Example Requests
1. Minimal agent
2. Full custom agent with cross-page execution and Memory-RAG
3. Agent with live REST API context
4. Agent that verifies content against an MCP server (mcp-tools)
Response
Success Response
| Field | Type | Description |
|---|---|---|
data.agentId | string | Firestore document ID of the new agent |
Failure Response
INVALID_ARGUMENT (Zod validation failure — e.g. missing name, missing apiKey, a server-managed field, an unknown key inside knowledge, an invalid userContextFields.type, missing instructions for an AI/stagehand-agent/mcp-tools strategy, or missing/invalid execution.mcpServers when executionStrategy is "mcp-tools") / RESOURCE_EXHAUSTED (workspace already has the maximum number of custom agents).

