Deploy Static Site
deployments_uploadDeploy a static site to a live URL — free, no account or API key required.
File content is plain text by default. Pass HTML/CSS/JS/JSON/SVG/etc. directly in each file's content as a regular string. Only set encoding: "base64" per-file for binary content (images, fonts) — do not base64-encode text.
Returns the live URL. Without a connected account, the response also includes a claim URL (the site expires in 3 days unless claimed) — always show both to the user. To make the site private, pass password; always show the password to the user if you set one.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ttl | No | Seconds until this deployment expires and the platform reclaims it; omit for one that never does. Only for authenticated deploys — an anonymous deployment already expires on the platform's schedule, and a requested ttl on one is refused. A deployment carrying a ttl cannot be linked to a custom domain: deploy without one if the site needs a domain. | |
| files | Yes | Files that make up the site. The site root is implied by these paths. | |
| labels | No | Labels for organizing deployments (e.g. ["production", "v1.2"]). Lowercase, 3-25 chars, allows . _ - separators. Up to 10. | |
| password | No | Optional password to gate the deployment behind an unlock prompt (6–128 characters; whitespace significant). Visitors must enter this password before viewing the site, including on any custom domains pointing at it. | |
| idempotencyKey | No | Makes this deploy replayable instead of repeatable. A deploy is not naturally idempotent: if a call times out you cannot tell "it never landed" from "it landed and the response was lost", and retrying creates a second deployment. Send the same key on the retry and the original deployment is replayed instead (within 24 hours). Key the ATTEMPT — a run id, a commit sha, a uuid minted before the first try — never one minted fresh on each retry, which would defeat the point. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Full URL to the live deployment. | |
| via | Yes | Origin tag for analytics (e.g. "gpt", "mcp", "cli", "web"). Null on legacy deployments uploaded before tagging existed. | |
| size | Yes | Total deployment size in bytes. | |
| claim | No | One-time URL that claims this anonymous deployment to a free account, making it permanent. Only present on anonymous deploys — absent when the deploy was made with a connected account. | |
| files | Yes | Number of files in the deployment. | |
| config | Yes | True if the deployment includes a `ship.json` routing config. | |
| labels | Yes | Labels attached to the deployment. | |
| status | Yes | Deployment lifecycle state. `success` means the site is live. | |
| created | Yes | Unix timestamp (seconds) when the deployment was created. | |
| expires | Yes | Unix timestamp (seconds) when the deployment expires; null when permanent. Anonymous deploys through the hosted MCP expire 3 days after creation unless claimed; an authenticated deploy carries one only when it requested a ttl. | |
| password | Yes | True if the deployment is password-protected. | |
| deployment | Yes | Deployment hostname, e.g. "happy-cat-abc1234.shipstatic.com". | |
| screenshot | Yes | Full URL to the deployment screenshot. Captured asynchronously after deploy; the URL is returned immediately but the image may take a few seconds to become available. |