API Reference
REST API for programmatic access to ZeroDeploy.
Base URL
https://api.zerodeploy.dev Authentication
API requests require a token sent as a Bearer header. Tokens use fine-grained permissions in resource:action format.
- Site Tokens — Scoped to a single site. Ideal for single-site CI/CD.
- Org Tokens — Scoped to an organization. Can access any site in the org. Ideal for monorepos.
Authorization: Bearer zd_xxxxxxxxxxxx Each endpoint below shows the required permission (e.g., sites:read). Endpoints marked JWT only are not accessible via API tokens.
Create tokens via the dashboard or zerodeploy token create CLI command.
Drop API
Deploy with one HTTP call. No login, no CLI, no setup. Sites expire in 72 hours unless claimed.
/drop Public Upload a single file or tar.gz archive to deploy a site. Returns a live URL, claim token, and expiration time. Sites expire in 72 hours unless redeployed or claimed. Send Content-Type: text/html for single files, application/gzip for tar.gz archives. Use X-Claim-Token header to redeploy (update) an existing drop site.
Headers: Content-Type (text/html or application/gzip), X-Filename (optional, default: index.html), X-Claim-Token (optional, for redeployment). Rate limit: 5 deploys per hour per IP. Max file size: 10 MB, max files: 1000, max total: 25 MB.
Request Body
{
"body": "value"
} Example
curl -X POST \
-H "Content-Type: application/json" \
-d '{"body":"value"}' \
https://api.zerodeploy.dev/drop Response
{
"data": {
"data.url": "https://my-project.zerodeploy.app",
"data.claim_token": "value",
"data.expires_at": "2024-01-15T10:30:00Z",
"next_steps.redeploy": {},
"next_steps.claim": {}
}
} /drop/claim Token Transfer an ephemeral drop site to your account. Requires authentication. Optionally provide a new slug to rename the site.
Request Body
{
"claim_token": "value",
"slug": "my-org"
} Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"claim_token":"value","slug":"my-org"}' \
https://api.zerodeploy.dev/drop/claim Response
{
"data": {
"data.site.id": "550e8400-e29b-41d4-a716-446655440000",
"data.site.slug": "value",
"data.url": "https://my-project.zerodeploy.app",
"message": "Operation completed successfully"
}
} Organizations
Manage organizations (workspaces) that contain sites.
/orgs Token List all organizations the authenticated user owns or has access to.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/orgs Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"slug": "my-project",
"plan": "free",
"owner_user_id": "550e8400-e29b-41d4-a716-446655440000",
"storage_used_bytes": 10485760,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
]
} /orgs/:orgSlug Token Get a single organization by slug.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/orgs/my-org Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"slug": "my-project",
"plan": "free",
"owner_user_id": "550e8400-e29b-41d4-a716-446655440000",
"storage_used_bytes": 10485760,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
]
} Sites
Manage sites within organizations.
/sites Token List all sites across all user organizations.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"slug": "my-project",
"org_id": "550e8400-e29b-41d4-a716-446655440000",
"github_repo": null,
"current_deployment_id": null,
"storage_used_bytes": 10485760,
"suspended_at": null,
"suspension_reason": null,
"password_protection_scope": "none",
"is_ephemeral": 0,
"ephemeral_expires_at": null,
"ephemeral_ip_address": null,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
]
} /sites Token Create a new site in an organization. Org slug is provided in the request body.
Request Body
{
"slug": "my-org",
"org_slug": "my-org",
"github_repo": "value"
} Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"slug":"my-org","org_slug":"my-org","github_repo":"value"}' \
https://api.zerodeploy.dev/sites Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"slug": "my-project",
"org_id": "550e8400-e29b-41d4-a716-446655440000",
"github_repo": null,
"current_deployment_id": null,
"storage_used_bytes": 10485760,
"suspended_at": null,
"suspension_reason": null,
"password_protection_scope": "none",
"is_ephemeral": 0,
"ephemeral_expires_at": null,
"ephemeral_ip_address": null,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
} /sites/:slug Token Get a single site by slug.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"slug": "my-project",
"org_id": "550e8400-e29b-41d4-a716-446655440000",
"github_repo": null,
"current_deployment_id": null,
"storage_used_bytes": 10485760,
"suspended_at": null,
"suspension_reason": null,
"password_protection_scope": "none",
"is_ephemeral": 0,
"ephemeral_expires_at": null,
"ephemeral_ip_address": null,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
]
} /sites/:slug Token Update site GitHub repository.
Request Body
{
"github_repo": "value"
} Example
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"github_repo":"value"}' \
https://api.zerodeploy.dev/sites/my-site Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"slug": "my-project",
"org_id": "550e8400-e29b-41d4-a716-446655440000",
"github_repo": null,
"current_deployment_id": null,
"storage_used_bytes": 10485760,
"suspended_at": null,
"suspension_reason": null,
"password_protection_scope": "none",
"is_ephemeral": 0,
"ephemeral_expires_at": null,
"ephemeral_ip_address": null,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
} /sites/:slug Token Delete a site and all its deployments. This also removes all assets from storage.
Example
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site Response
{
"success": true,
"message": "Operation completed successfully"
} /sites/:slug/password Token Enable or disable password protection for a site. Requires Pro plan.
Request Body
{
"scope": "none",
"password": "s3cret"
} Example
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"scope":"none","password":"s3cret"}' \
https://api.zerodeploy.dev/sites/my-site/password Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"slug": "my-project",
"org_id": "550e8400-e29b-41d4-a716-446655440000",
"github_repo": null,
"current_deployment_id": null,
"storage_used_bytes": 10485760,
"suspended_at": null,
"suspension_reason": null,
"password_protection_scope": "none",
"is_ephemeral": 0,
"ephemeral_expires_at": null,
"ephemeral_ip_address": null,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
} Deployments
Deploy and manage site versions.
/deployments Token / Deploy Create a new deployment for a site. Returns upload URL for the tar.gz archive.
Request Body
{
"site_slug": "my-org",
"pr_number": 0
} Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"site_slug":"my-org","pr_number":0}' \
https://api.zerodeploy.dev/deployments Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"url": "https://my-project.zerodeploy.app",
"error_message": null,
"pr_number": null,
"pr_title": null,
"commit_sha": null,
"commit_message": null,
"branch": null,
"file_count": 42,
"total_size_bytes": 10485760,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null,
"org_slug": "value",
"site_slug": "value",
"preview_url": "https://my-project.zerodeploy.app",
"upload_url": "https://my-project.zerodeploy.app",
"upload_and_finalize_url": "https://my-project.zerodeploy.app",
"limits": {}
}
} /sites/:slug/deployments Token List all deployments for a site, including which one is current.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/deployments /sites/:slug/deployments/by-commit Token Find a ready deployment for one or more commit SHAs. Used by CLI to check if a preview can be promoted instead of re-deploying. Accepts comma-separated SHAs for merge commit support.
Query Parameters
-
commits— Comma-separated list of commit SHAs to check
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/example/deployments/by-commit Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"url": "https://my-project.zerodeploy.app",
"error_message": null,
"pr_number": null,
"pr_title": null,
"commit_sha": null,
"commit_message": null,
"branch": null,
"file_count": 42,
"total_size_bytes": 10485760,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
} /deployments/:id Token / Deploy Get deployment details by ID.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/deployments/abc12345 Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"url": "https://my-project.zerodeploy.app",
"error_message": null,
"pr_number": null,
"pr_title": null,
"commit_sha": null,
"commit_message": null,
"branch": null,
"file_count": 42,
"total_size_bytes": 10485760,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
} /deployments/:id/files Token List all files in a deployment. Paginated with cursor.
Query Parameters
-
cursor— Pagination cursor from previous response -
limit(default:500) — Max files to return (default 500, max 1000)
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/deployments/abc12345/files Response
{
"data": [
{
"key": "index.html",
"size": 10485760
}
]
} /deployments/:id/logs Token / Deploy Get structured logs from the deployment finalize process.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/deployments/abc12345/logs Response
{
"data": {
"timestamp": "value",
"level": "info",
"phase": "value",
"message": "Operation completed successfully",
"metadata": {},
"duration_ms": 0
}
} /deployments/:id/upload-and-finalize Token Upload a tar.gz archive and finalize the deployment in a single request. Uses multipart/form-data with an optional "archive" part and a required "metadata" part (JSON string with finalize options).
Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/deployments/abc12345/upload-and-finalize Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"url": "https://my-project.zerodeploy.app",
"error_message": null,
"pr_number": null,
"pr_title": null,
"commit_sha": null,
"commit_message": null,
"branch": null,
"file_count": 42,
"total_size_bytes": 10485760,
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null,
"preview": false
}
} /deployments/:id/diff Token Compare a manifest against the current deployment to determine which files need uploading.
Request Body
{
"manifest": {}
} Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"manifest":{}}' \
https://api.zerodeploy.dev/deployments/abc12345/diff Response
{
"data": {
"upload_files": [],
"copy_files": [],
"removed_files": [],
"previous_deployment_id": null,
"is_incremental": false
}
} /sites/:slug/diff Token Compare a manifest against the site's current deployment without creating a new one. Used by CLI to skip deploys when nothing changed.
Request Body
{
"manifest": {}
} Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"manifest":{}}' \
https://api.zerodeploy.dev/sites/my-site/diff Response
{
"data": {
"upload_files": [],
"copy_files": [],
"removed_files": [],
"previous_deployment_id": null,
"is_incremental": false
}
} /deployments/:id/rollback Token Set a previous deployment as the current one. Supports full ID or 8-char prefix.
Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/deployments/abc12345/rollback Response
{
"data": {
"deployment": {}
}
} Custom Domains
Add custom domains with automatic SSL to your sites.
/sites/:slug/domains Token Add a custom domain to a site. Returns DNS verification instructions.
Request Body
{
"domain": "example.com"
} Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com"}' \
https://api.zerodeploy.dev/sites/my-site/domains Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"domain": "example.com",
"verification_status": "pending",
"verification_token": "zerodeploy-verify=abc123",
"verified_at": null,
"redirect_mode": "none",
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null,
"verification": {},
"dns_provider": null,
"existing_records": null
}
} /sites/:slug/domains Token List all custom domains for a site.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/domains Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"domain": "example.com",
"verification_status": "pending",
"verification_token": "zerodeploy-verify=abc123",
"verified_at": null,
"redirect_mode": "none",
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
]
} /sites/:slug/domains/:domainId Token Get a single custom domain by ID.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/domains/123e4567-e89b-12d3-a456-426614174000 Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"domain": "example.com",
"verification_status": "pending",
"verification_token": "zerodeploy-verify=abc123",
"verified_at": null,
"redirect_mode": "none",
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
} /sites/:slug/domains/:domainId Token Remove a custom domain from a site. Also removes Cloudflare custom hostname.
Example
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/domains/123e4567-e89b-12d3-a456-426614174000 Response
{
"success": true,
"message": "Operation completed successfully"
} /sites/:slug/domains/:domainId/verify Token Check DNS records to verify domain ownership. Creates Cloudflare custom hostname on success.
Example
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/domains/123e4567-e89b-12d3-a456-426614174000/verify Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"domain": "example.com",
"verification_status": "pending",
"verification_token": "zerodeploy-verify=abc123",
"verified_at": null,
"redirect_mode": "none",
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null,
"site_slug": "value",
"message": "Operation completed successfully",
"cloudflare": {}
}
} /sites/:slug/domains/:domainId/redirect Token Set www/apex redirect behavior for a domain.
Request Body
{
"redirect_mode": "none"
} Example
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"redirect_mode":"none"}' \
https://api.zerodeploy.dev/sites/my-site/domains/123e4567-e89b-12d3-a456-426614174000/redirect Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"site_id": "550e8400-e29b-41d4-a716-446655440000",
"domain": "example.com",
"verification_status": "pending",
"verification_token": "zerodeploy-verify=abc123",
"verified_at": null,
"redirect_mode": "none",
"created_at": "2024-01-15T10:30:00Z",
"deleted_at": null
}
} Forms
Manage form submissions from deployed sites.
/sites/:slug/forms Token List all forms for a site. Forms are auto-created when submissions are received.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/forms Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "my-project",
"submission_count": 42,
"created_at": "2024-01-15T10:30:00Z"
}
]
} /sites/:slug/forms/:formName Token Get a single form by name.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/forms/contact Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "my-project",
"submission_count": 42,
"notification_email": null,
"created_at": "2024-01-15T10:30:00Z"
}
} /sites/:slug/forms/:formName Token Update form settings like notification email.
Request Body
{
"notification_email": "user@example.com"
} Example
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"notification_email":"user@example.com"}' \
https://api.zerodeploy.dev/sites/my-site/forms/contact Response
{
"success": true,
"form": {}
} /sites/:slug/forms/:formName Token Delete a form and all its submissions.
Example
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/forms/contact Response
{
"success": true,
"message": "Operation completed successfully"
} /sites/:slug/forms/:formName/submissions Token Get paginated form submissions with parsed data.
Query Parameters
-
limit(default:20) — Number of items to return (1-100) -
offset(default:0) — Number of items to skip -
filter—all,inbox,spam(default:all)
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/forms/contact/submissions?filter=all Response
{
"data": {
"form": {},
"submissions": [],
"total": 42,
"limit": 0,
"offset": 0
}
} /sites/:slug/forms/:formName/export Token Export all form submissions as a CSV file (up to 10,000 submissions).
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/forms/contact/export Analytics
Privacy-friendly site traffic analytics.
/sites/:slug/analytics Token Get traffic analytics for a site including requests, visitors, top pages, countries, and more.
Query Parameters
-
period—24h,7d,30d,90d(default:7d) -
page -
country -
city -
referrer -
browser -
os -
device—desktop,mobile,tablet -
utm_source -
utm_medium -
utm_campaign -
event_name -
user_id
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/analytics?period=24h&device=desktop Response
{
"data": {
"configured": true,
"message": "Operation completed successfully",
"period": "24h",
"active_filters": {},
"overview": {},
"time_series": [],
"top_pages": [],
"countries": 42,
"status_codes": [],
"referrers": [],
"cities": [],
"browsers": [],
"operating_systems": [],
"device_types": [],
"campaigns": [],
"events": [],
"not_found_pages": []
}
} /sites/:slug/analytics/realtime Token Get the number of distinct visitors on the site in the last 5 minutes.
Example
curl \
-H "Authorization: Bearer $TOKEN" \
https://api.zerodeploy.dev/sites/my-site/analytics/realtime Response
{
"data": {
"current_visitors": 0
}
} Error Responses
All errors follow a consistent format:
{
"error": "Error message",
"code": "ERROR_CODE",
"hint": "Helpful suggestion to resolve the error"
} Common Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid request body or parameters |
| 401 | UNAUTHORIZED | Missing or invalid authentication |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | NOT_FOUND | Resource not found |
| 409 | CONFLICT | Resource already exists |
| 429 | RATE_LIMITED | Too many requests |
| 500 | INTERNAL_ERROR | Server error |