Publish an app to its live site.
POST/ai-builder-api/projects/:projectId/infra/promote-to-production
Publishes the app to its live site: its managed address, and every custom domain attached to it (changes kind domain) once that domain is active. A domain that becomes active later joins the live site without another publish. Check GET .../publishability first and send the sourceRunId it returns, so the build the creator approved is the one that goes live. Returns a publish job: poll GET .../infra/publish-jobs/{publishJobId} until status is succeeded (publishedUrl is the live site) or failed (error says why). Send the same idempotencyKey to retry safely.
Request
The API version.
v3The project.
Possible values: Value must match regular expression ^prj_[A-Za-z0-9_-]+$
- application/json
- Body
- Example (auto)
Bodyrequired
Exact successful run backing the preview approved by the creator. When provided, publish fails closed instead of selecting a different run that became ready concurrently.
Possible values: Value must match regular expression ^run_[A-Za-z0-9_-]+$
Stable retry key. Domain-aware clients should always provide one; when omitted, source-bound requests receive a deterministic server-generated key while source-less legacy requests remain independent publish attempts.
Possible values: non-empty and <= 200 characters
{
"sourceRunId": "run_7b2c9e41",
"idempotencyKey": "publish-prj_5f0c2a3e-2026-10-23"
}
Publish job accepted.
- application/json
- Schema
- Example (auto)
Schema
The publish job; poll it with GET .../infra/publish-jobs/{publishJobId}.
The managed address the app is published to.
The active custom domains the publish also serves.
The managed address's revision this publish took.
Possible values: >= 0
The live site's address once the job succeeds.
The job's state; queued when accepted.
queuedrunningsucceededfailed{
"jobId": "job_3f9a1c2b7d4e5f6a7b8c9d0e",
"hostname": "5f0c2a3e.app.clientclub.net",
"aliases": [
"portal.acmefitness.com"
],
"domainRevision": 1,
"url": "https://5f0c2a3e.app.clientclub.net",
"status": "queued"
}