Submit a prompt; the agent runs in the background.
POST/ai-builder-api/projects/:projectId/runs
Returns runId immediately. The agent executes asynchronously:
attempt workspace restore from project's prior run → materialise
scaffold (only if no prior workspace) → loop tool calls → preflight
pnpm build → flush workspace to GCS → deploy via Cloud Build →
managed runtime revision replace → mark ready with a preview URL.
Per-project runtime services receive a stable public app hostname so the iframe URL works without platform-session auth.
Idempotency: callers SHOULD send an Idempotency-Key header on
every retry. The server stores (locationId, projectId, key) →
runId for 24 h. Same key + same body → the original runId is
replayed. Same key + different body → 409 idempotency_conflict.
Modeled after standard idempotent POST contracts; safe for browser
retries, network blips, and double-click submits.
Attachment scope: when attachmentIds are present, each id is
verified against the caller's tenant + project. Cross-project or
cross-tenant reuse is rejected with 403 attachment_not_owned.
Request
Caller-generated key (UUID-v4 recommended) that makes this POST
safe to retry. Must match the prior request body byte-for-byte
on replay. Reused with a different body → 409.
Possible values: non-empty and <= 255 characters
Optional caller-supplied trace id. When omitted, the API mints
cid_<uuid> and echoes it back via the response
X-Correlation-Id header. Threaded through audit rows + logs.
Possible values: non-empty and <= 64 characters
The API version.
v3The project's id.
Possible values: Value must match regular expression ^prj_[A-Za-z0-9_-]+$
- application/json
- Body
- Example (auto)
Bodyrequired
auto(default) — agent honours the classifier'srecommended_modeand decides whether to plan, ask, or build straight through.plan— agent always proposes a plan first viapropose_planand pauses for approval. The plan is surfaced as aplan_approval_requestnarrator event; the user POSTs an approve/refine/reject verdict to/agent-runs/{runId}/plan-approval.build— agent skips planning and goes straight to file_editor (onlyask_userwhen the classifier flags a high-cost architectural unknown).plan_first— back-compat alias forplan. v1 callers still emit it; the runtime treats it asplan.
What to build or change.
Possible values: non-empty and <= 20000 characters
What the project builds; the project's own by default.
full_stackmobilelanding_pageClientPortal-only per-run switch. When false or omitted, the agent can inspect the project and apply SDUI configuration, but source-code, shell, dependency, and build tools are unavailable. When true, the existing full custom-code tool surface is enabled. This choice does not change sandbox provisioning or preview lifecycle behavior.
falseClientPortal-only context captured from the selected builder surface. Unqualified follow-ups default to this lane; explicit web, mobile, or web-and-mobile wording in the prompt takes precedence.
webmobileAn agent outside the builder (an MCP client) writes this run's code in the project's sandbox. The run skips the builder's agent: a first build asks the builder's intake questions (answered through the answers API), then every run checks, delivers, registers the sandbox with ClientPortal, and seals a publishable release.
falseDeprecated compatibility field for older mobile clients. New mobile runs use the standard builder flow with the React Native app kernel.
v2-simpleDeprecated compatibility field. Accepted for older mobile clients but no longer selects a distinct generation pipeline; production mobile codegen uses the single-loop Mastra path.
fastslowModel id from GET /api/v1/catalog/models. When provided, this
single model is used for every phase of the agent (classify,
plan, code). When omitted, the platform routes to its per-phase
defaults (Haiku → Sonnet → Opus).
Possible values: non-empty and <= 200 characters
Optional id of a user-defined agent profile created via
POST /api/v1/agents. The profile's systemInstructions and
skills are appended to the platform's catalog for this run,
and its defaultModelId is honoured when modelId is not set.
Possible values: Value must match regular expression ^agt_[A-Za-z0-9_-]+$
Run mode. The composer's 3-way segmented control surfaces:
autoplanbuildplan_firstOptional ids of attachments previously created via
POST /api/v1/projects/{projectId}/attachments/upload-url.
Surfaced to the agent as user-provided context so generated
code can reference uploaded files (logos, PDFs, brand assets).
Possible values: <= 10
Visual edits (vibe apps): the elements the creator selected in the
live preview before sending. The agent receives them as a
<selected-elements> block after the prompt, so "this" means the
element on screen. Context only: file and line are hints the agent
checks against the workspace.
Possible values: <= 20
{
"prompt": "Add a page listing upcoming events",
"productTarget": "full_stack",
"customCode": false,
"clientPortalSurface": "web",
"externalAgent": true,
"mobilePipeline": "v2-simple",
"mobilePipelineSpeed": "fast",
"modelId": "claude-sonnet-4-5",
"agentId": "agt_4c2d1e",
"mode": "auto",
"attachmentIds": [
"att_1a2b3c"
],
"selectedElements": [
{
"elementType": "h1",
"filePath": "pages/index.vue",
"lineNumber": 12
}
]
}
Accepted; agent is running.
Correlation id used for log + audit stitching.
- application/json
- Schema
- Example (auto)
Schema
The run that started.
Possible values: Value must match regular expression ^run_[A-Za-z0-9_-]+$
The run as it starts.
{
"runId": "run_8f3c2a91",
"state": {
"runId": "run_8f3c2a91",
"projectId": "prj_5f0c2a3e",
"prompt": "Add a page listing upcoming events",
"promptAuthor": {
"id": "usr_9a8b7c",
"name": "Jane Doe",
"avatarUrl": "https://images.example.com/avatars/jane.png"
},
"status": "queued",
"phase": "plan",
"phaseStatus": "running",
"awaitingQuestion": {
"capId": "cap_portal_modules",
"question": "Which areas should your portal have?",
"choices": [
"Courses",
"Communities"
],
"form": {
"kind": "record_fields",
"recordType": {
"label": "Policy",
"exists": false
},
"existingFields": [
{
"label": "Policy number",
"type": "TEXT",
"shown": true
}
],
"fields": [
{
"label": "Renewal date",
"type": "DATE"
}
],
"edit": true,
"types": [
{
"value": "TEXT",
"label": "Single line"
}
]
},
"details": "Your portal will use the Courses and Communities modules.",
"preview": {},
"multiSelect": false,
"allowOther": true,
"input": "short_text",
"placeholder": "e.g. Weekly yoga classes",
"askedAt": "2026-10-15T09:32:00.000Z"
},
"createdAt": "2026-10-15T09:30:00.000Z",
"updatedAt": "2026-10-15T09:41:12.000Z",
"previewUrl": "https://preview.example.com/my-portal",
"preview": {
"primaryUrl": "https://preview.example.com/my-portal",
"services": [
{
"name": "web",
"url": "https://preview.example.com/my-portal"
}
]
},
"sandboxUrl": "https://sbx-prj-5f0c2a3e.example.com",
"sandboxStatus": "ready",
"publishedUrl": "https://my-portal.example.com",
"publishedAt": "2026-10-14T18:02:00.000Z",
"runsSinceLastPublish": 2,
"summary": "Added an events page",
"imageUri": "registry.example.com/apps/web:run_8f3c2a91",
"imageDigest": "sha256:3b1f0c9e2d7a",
"failureMessage": "The build failed: pages/events.vue has a type error",
"failure": {
"category": "build",
"code": "build_failed",
"retryable": false,
"responsibleModule": "runtime",
"userMessage": "Describe the page you want in a sentence or two.",
"details": "No stack manifest for this template",
"provider": "anthropic",
"attempt": 3,
"failureHead": "pages/events.vue(12,5): error TS2339",
"failureTail": "Found 1 error.",
"cause": "The sandbox did not become ready in time",
"phase": "plan",
"stack": "TypeError: Cannot read properties of undefined",
"message": "The preview could not start."
},
"metadata": {
"generationFailure": {
"code": "provider_transient",
"retryable": true,
"source": "provider",
"detail": "The model provider was overloaded"
},
"failedWorkspace": {
"preservedAt": "2026-10-15T09:45:00.000Z",
"uploadedFiles": 128,
"durationMs": 2140
}
}
}
}