Skip to main content
Questions or issues? Contact us at api-support@manus.ai. Manus agents can build web apps — see the Webapp feature for what the product can do. When an agent builds a site inside a task, it produces a website with its own version history and a hosted URL once published. The website.* endpoints manage those websites:
To have an agent build a website, create a task with task.create. Once the session has a website attached, the endpoints on this page take over.

Quickstart: publish a site

After the agent has built something (the task’s session now has a website), deploy it with one call and poll for the live URL:
# 1. Deploy the latest checkpoint — defaults to public
curl -X POST 'https://api.manus.ai/v2/website.publish' \
  -H 'x-manus-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"task_id": "session-xxx"}'
# → { "ok": true, "website_id": "site-abc", "version_id": "v003" }

# 2. Poll status until published / failed
while true; do
  RESP=$(curl -sS "https://api.manus.ai/v2/website.status?website_id=site-abc" \
    -H 'x-manus-api-key: YOUR_API_KEY')
  STATUS=$(echo "$RESP" | jq -r .publish_status)
  echo "status: $STATUS"
  [[ "$STATUS" == "published" || "$STATUS" == "failed" ]] && break
  sleep 2
done

# 3. Read the primary site URL and open it
echo "$RESP" | jq -r '.site_urls[0]'
Deployment is asynchronous — website.publish returns immediately while the deploy runs in the background.

Other common flows

Ship an updated build. After the agent makes more changes (new checkpoints), call website.publish again — it always deploys the latest checkpoint. There is no way to pin an older checkpoint via this API. Browse version history.
curl 'https://api.manus.ai/v2/website.listCheckpoints?task_id=session-xxx' \
  -H 'x-manus-api-key: YOUR_API_KEY'
Match each data[].version_id against published_version_id in the same response to find which checkpoint is currently live. Change metadata without redeploying.
curl -X POST 'https://api.manus.ai/v2/website.update' \
  -H 'x-manus-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"website_id": "site-abc", "title": "My landing page", "visibility": "team"}'
Pass any combination of title and visibility — omitted fields are left unchanged. This does not trigger a new deployment, only a metadata update and a CDN refresh; it works even before the site has ever been published. Take a site offline. There is no public unpublish endpoint at this time. If you need to take a site down, contact api-support@manus.ai.

Reference

Anatomy of a website

ConceptWhat it is
WebsiteThe site itself, identified by a website_id. One session (task_id) typically owns one website.
CheckpointA point-in-time snapshot of the site, backed by a git commit. Has its own version_id, message, status, created_at.
Publish stateWhether the site is deployed, and which checkpoint is live. Tracked on the site, not on individual checkpoints.
VisibilityWho can access the live site (public / team / private).

Locating a website

All four endpoints accept either task_id or website_id — exactly one must be provided:
FieldWhat it isWhere to get it
task_idSession UIDReturned by task APIs (e.g. task.create)
website_idUnique website IDReturned by website.status and website.publish
Passing both task_id and website_id — or neither — returns 400 invalid_argument. A session is expected to contain exactly one website; if more exist, the first is used.

Site URLs

When a site is published, website.status returns site_urls — an array of every hostname the site can be reached on, ordered from default to most specific:
  1. Space URLhttps://{space_id}.manus.space. Always present for a published site.
  2. Sub-domain URLhttps://{sub_domain}.manus.space. Only when the owner has configured a sub-domain.
  3. Custom domainshttps://{custom_domain} for each active custom domain bound by the owner.
For a simple “open the site” flow, site_urls[0] is enough — it’s always the space URL. The array is empty whenever publish_status is not published.

Publish states

publish_statusMeaningWhat to do
unpublishedNever published, or previously taken downCall website.publish
publishingDeployment in progressPoll again
publishedLive — site_urls is reachableRead site_urls / version_id
failedLast deployment failedRetry website.publish

Checkpoint status vs. publish state

A checkpoint’s own status (pending / success / failed / unspecified) only says whether the snapshot was generated successfully — a success checkpoint is not automatically live. To find the live version, compare website.status.version_id (or website.listCheckpoints.published_version_id) against data[].version_id.

Visibility

ValueWho can accessNotes
publicAnyone on the internetDefault for website.publish
teamTeam members of the site ownerTeam accounts only
privateOwner and invited collaboratorsAppears in website.status responses only — cannot be set via website.publish / website.update
Sites may additionally cap the maximum visibility they accept — for example, a team-only site cannot be set to public. Requests that exceed the allowed visibility return 403 permission_denied.

website.publish vs. website.update

website.publishwebsite.update
Triggers deploy✅ Deploys the latest checkpoint❌ Metadata only (title, visibility)
Default visibilitypublic when omittedOmitted = unchanged; empty string is invalid
PreconditionAt least one checkpoint (412 otherwise)None
Side effectsRuns the deployment pipelineRefreshes CDN in the background

Errors

Status / codeWhen
401 unauthenticatedMissing or invalid API key
400 invalid_argumentBoth task_id and website_id passed, neither passed, invalid visibility, or website.update with nothing to update
403 permission_deniedCaller lacks access to the site, or the requested visibility exceeds what the site allows
404 not_foundNo website for the given session, or website_id does not exist / is not a website / is not initialized yet
412 failed_preconditionwebsite.publish called on a site with no checkpoint
500 internalServer-side error — include request_id when reporting