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 one-time claim URL, and the site expires in 3 days unless claimed. Pass password to make the site private.
Tool call template
Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {
"files": "<files>"
},
"name": "deployments_upload"
}
}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 any 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. ["env:production", "v1.2"]). Each is a word, or a key and a value split by one ":". Lowercase, 3-63 chars, allows . _ - inside a word. 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 you get back the deployment the first try made, if it went live in the last 24 hours. A key works only within the account that sent it: without an account it is ignored, and a retry deploys again. 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 | How the deployment was created, as shown in deployment history (today one of: web, sdk, cli, mcp, git, n8n, gpt, vsc, cld, crs, gmn, api). Null on deployments older than the tag. | |
| 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; empty when none. | |
| status | Yes | Deployment lifecycle state; "success" means the site is live. One of: pending, success, failed, deleting. | |
| created | Yes | Unix timestamp (seconds) when the deployment was created. | |
| expires | Yes | Unix timestamp (seconds) when the deployment expires; null when permanent. Anonymous deployments expire 3 days after creation unless claimed; an authenticated deployment 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. Rendered on the first request for it, so the URL is returned immediately and the first request takes a few seconds; every request after that is served immediately. |