cloud71
Docs

API reference

Every cloud71 action is a plain HTTPS call authenticated with a bearer token — so any language, script, or AI agent can deploy and manage sites without MCP. The CLI and the MCP connector are both thin wrappers over these same endpoints.

Base URL

https://app.cloud71.host

Authenticate with Authorization: Bearer c71_…. Create a token at /dashboard/tokens — you'll see it once, so store it somewhere safe.

Endpoints

GET /api/cli/whoami

Verify a token and return the account it belongs to.

curl https://app.cloud71.host/api/cli/whoami \
  -H "Authorization: Bearer c71_…"

# 200 OK
{ "email": "[email protected]", "plan": "pro" }

GET /api/cli/sites

List the sites you own, newest first.

curl https://app.cloud71.host/api/cli/sites \
  -H "Authorization: Bearer c71_…"

# 200 OK
{ "sites": [
  { "subdomain": "my-portfolio",
    "url": "https://my-portfolio.cloud71.site",
    "status": "active",
    "updatedAt": 1718000000000 }
] }

POST /api/cli/deploy

Publish a single file or a zipped folder. Send the raw bytes as the request body and name them with the x-c71-filename header. Pass x-c71-site to update an existing site in place; omit it to create a new one.

# A single file
curl -X POST https://app.cloud71.host/api/cli/deploy \
  -H "Authorization: Bearer c71_…" \
  -H "Content-Type: application/octet-stream" \
  -H "x-c71-filename: resume.pdf" \
  --data-binary @resume.pdf

# A whole site (zip), updating an existing subdomain
curl -X POST https://app.cloud71.host/api/cli/deploy \
  -H "Authorization: Bearer c71_…" \
  -H "Content-Type: application/octet-stream" \
  -H "x-c71-filename: site.zip" \
  -H "x-c71-site: my-portfolio" \
  --data-binary @site.zip

# 200 OK
{ "ok": true, "siteId": "…",
  "subdomain": "my-portfolio",
  "url": "https://my-portfolio.cloud71.site" }

GET /api/cli/read

Inspect a site by subdomain. Without path, returns the file list; with path, returns that file's text contents — so an agent can read, edit, then redeploy.

# List files
curl "https://app.cloud71.host/api/cli/read?site=my-portfolio" \
  -H "Authorization: Bearer c71_…"
# { "site": "my-portfolio", "files": ["index.html", "style.css"] }

# Read one file
curl "https://app.cloud71.host/api/cli/read?site=my-portfolio&path=index.html" \
  -H "Authorization: Bearer c71_…"
# { "site": "…", "path": "index.html", "content": "…" }

POST /api/cli/manage

Rename a site, attach a custom domain, or delete it. Send JSON with an action. delete is owner-only; set_domain is plan-gated.

# Rename (display title)
curl -X POST https://app.cloud71.host/api/cli/manage \
  -H "Authorization: Bearer c71_…" \
  -H "Content-Type: application/json" \
  -d '{ "site": "my-portfolio", "action": "rename", "title": "My Portfolio" }'

# Attach a custom domain
-d '{ "site": "my-portfolio", "action": "set_domain", "domain": "example.com" }'

# Delete
-d '{ "site": "my-portfolio", "action": "delete" }'

Errors

Errors return a JSON body of the shape { "error": "…" } with an appropriate status:

401 Missing or invalid bearer token.
400 Bad request — e.g. an empty deploy body.
402 Plan limit hit. Body includes { error, trigger }.
404 Site or file not found.
409 Requested subdomain is already taken.

Rate & plan limits

API calls count against the same plan limits as the dashboard — storage, monthly visits, and the number of sites. Hitting a cap returns 402 with a trigger you can surface to the user. See pricing for the limits per plan.

Prefer not to write HTTP?

The cloud71 CLI wraps these endpoints for terminal and CI use, and the MCP connector exposes them to AI assistants. Same token, same capabilities.