Sites API
List, create, and inspect sites with curl-able examples.
The sites surface lets you enumerate, inspect, and create the sites in a workspace. The REST API has no version prefix: all paths below are rooted at https://api.showly.ai.
List sites
GET /sites
Authorization: Bearer <token>
Returns paginated sites the token can see.
{
"ok": true,
"data": {
"items": [
{
"id": "site_01HZX...",
"slug": "marketing-site",
"name": "Marketing site",
"framework": "next-export",
"repositoryUrl": "https://github.com/acme/marketing",
"createdAt": "2026-03-01T10:14:22Z"
}
],
"pageInfo": { "nextCursor": null, "hasMore": false }
}
}
The framework value is auto-detected by the builder; possible values are astro, vite, next-export, static-html, custom, and unknown.
Query parameters:
limit(default 50, max 100)cursor— paginate
Get a single site
GET /sites/{siteId}
Returns the site plus the current manifest and most-recent deployment summary.
Create a site
POST /sites
Content-Type: application/json
{
"projectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Docs",
"slug": "docs",
"repositoryUrl": "https://github.com/acme/docs"
}
Returns 201 + the created site. projectId is the UUID of the project the site belongs to. slug must match ^[a-z0-9-]+$ and be unique in the workspace; if it collides you get 409 with error.code: "slug_taken". framework and repositoryUrl are optional.
Build configuration lives in a showly.json manifest committed to the repository, not in the create body. The builder auto-detects the framework and reads rootDirectory, runtime, buildCommand, output, and related fields from that file. See Site manifest for the full schema.
Deploy targets
Deploy targets are configured at the organization level, not per site. They are mounted at /deployment-targets:
| Method | Path | Purpose |
|---|---|---|
GET | /deployment-targets | List configured targets. |
GET | /deployment-targets/capabilities | List supported provider options. |
POST | /deployment-targets | Create a target. |
PATCH | /deployment-targets/:id | Update a target. |
DELETE | /deployment-targets/:id | Remove a target. |
A target carries a provider (gcp, aws, kubernetes, static, or cloudflare), a mode (serverless-container, k8s, or static-cdn), and a runtime (node, container, or static).
Curl example: end-to-end create + first deploy
# 1. Create the site
SITE=$(curl -sS -X POST https://api.showly.ai/sites \
-H "authorization: bearer $SHOWLY_TOKEN" \
-H "content-type: application/json" \
-d '{ "projectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "Demo", "slug": "demo", "repositoryUrl": "https://github.com/acme/demo" }' \
| jq -r '.data.id')
# 2. Inspect the site (and the auto-detected manifest)
curl -sS "https://api.showly.ai/sites/$SITE" \
-H "authorization: bearer $SHOWLY_TOKEN"
# 3. Request a preview deployment (siteId in the path; Idempotency-Key required)
curl -sS -X POST "https://api.showly.ai/sites/$SITE/deploy" \
-H "authorization: bearer $SHOWLY_TOKEN" \
-H "content-type: application/json" \
-H "idempotency-key: $(uuidgen)" \
-d '{ "environment": "preview" }'
The create-deployment call returns 202. The Idempotency-Key header is required on POST /sites/:siteId/deploy; without it the request returns 428, and a conflicting retry returns 409. See Deployments for the rest of the deploy lifecycle.
Errors
| Code | Status | Meaning |
|---|---|---|
site_not_found | 404 | siteId doesn't exist or token can't see it. |
slug_taken | 409 | A different site already uses that slug. |
manifest_invalid | 422 | Manifest failed schema validation. |
repo_unreachable | 502 | Git host returned an error on connect. |