Clouzark

Management API

Automate Clouzark over HTTP.

The CLI and MCP server are built on this API; anything they do, you can do with plain HTTP.

https://api.clouzark.com/v1

Authentication

Send a team access token, created under the team's Settings → Access Tokens (or by clouzark login):

curl https://api.clouzark.com/v1/me -H "Authorization: Bearer cz_pat_..."

A token acts with its creator's current role in the team. Requests and responses are JSON, errors are { "error": "..." }, and each token can make 120 requests a minute. Wherever a path has :ref, pass a project's slug or id.

Account

Request
GET /meUser, team, role, and token expiry
DELETE /tokens/currentRevoke the calling token

Hosting projects

Request
GET /projectsList projects
GET /projects/:refOne project, including runtime_memory_mb (its instance size, null for the platform default) and the resulting runtime_limits
PATCH /projects/:ref { runtime_memory_mb }Set the instance size: 512, 1024, 2048, 4096, or null. Owner role. Returns { project, runtime_limits_applied: { updated, skipped } }
POST /projects { repo, name?, root_directory?, framework?, production_branch?, install_command?, build_command?, output_directory?, env_vars? }Import a GitHub repo (owner/name) and queue its first production build; returns { project, deployment_id }. env_vars ([{ key, value, target }]) are saved before that build
GET /projects/:ref/deployments?limit=20Recent deployments
POST /projects/:ref/deployments { branch?, skip_build_cache? }Build a branch's latest pushed commit (the production branch by default)
POST /projects/:ref/deployments/upload?environment=preview&skip_build_cache=falseBuild an uploaded .tar.gz of the project (Content-Type: application/gzip)
POST /projects/:ref/rollbackRoll production back
POST /projects/:ref/repository/syncRe-read the repo from GitHub and follow a rename or transfer to its current URL. A project ref (and app URL) made from the old repo name moves to one made from the new name, and the old app URL redirects to it. Deployer role. Returns { project, changed, previous_repo_url, previous_ref, previous_url }
GET /deployments/:id?log_offset=0Deployment status, plus build log from log_offset
POST /deployments/:id/promotePromote to production
POST /deployments/:id/redeploy { skip_build_cache? }Rebuild; skip_build_cache: true builds without the build cache
POST /deployments/:id/cancelCancel a queued deployment

Each deployment has a url (its own immutable URL) and, for a preview, a branch_url that always serves the branch's newest live deployment.

A deployment's status is one of queued, building, deploying, live, failed, canceled, or stopped; done is true once it stops changing. To follow a build, poll GET /deployments/:id and pass the previous log_length as log_offset.

Environment variables

Request
GET /projects/:ref/envNames, targets, and git_branch
GET /projects/:ref/env/values?environment=preview&branch=devResolved values for one environment (and, for preview, one branch)
POST /projects/:ref/env { key, value, target, git_branch? }Add or update. git_branch only with target: preview
PATCH /projects/:ref/env/:key?target=preview&git_branch=dev { value }Change only the value
DELETE /projects/:ref/env/:key?target=all&git_branch=Remove
GET /projects/:ref/databaseThe linked database ({ database: { id, name, ref } | null, env_keys })
PATCH /projects/:ref/database { database }Link a database by ref or id, or unlink with null; needs the deployer role. Applies from the next deployment

Domains

Request
GET /projects/:ref/domainsDomains, with the DNS records each needs
POST /projects/:ref/domains { hostname, routing? }Add, optionally with a routing choice (below)
PATCH /projects/:ref/domains/:hostname { mode, target_branch?, redirect_to?, redirect_status? }Change what it serves: production, preview, branch (with target_branch), or redirect
POST /projects/:ref/domains/:hostname/verifyCheck DNS
DELETE /projects/:ref/domains/:hostnameRemove

App cron jobs

Cron jobs are addressed by :job, the job's name or id. Creating, changing, deleting, and running jobs needs the deployer role. A job with source: "config" comes from clouzark.json: it only accepts enabled, and can't be deleted.

Request
GET /projects/:ref/cron-jobsJobs, each with source (config or api), next_run_at, and last_run
GET /projects/:ref/cron-jobs/:jobOne job
POST /projects/:ref/cron-jobs { name, path, schedule, method?, timezone?, timeout_seconds?, retries?, enabled? }Add a job. method defaults to GET, timezone to UTC, timeout_seconds to 60 (at most 300), retries to 0 (at most 3). Returns { cron_job }
PATCH /projects/:ref/cron-jobs/:job { name?, path?, schedule?, method?, timezone?, timeout_seconds?, retries?, enabled? }Change only the fields sent; enabled: false pauses the job
DELETE /projects/:ref/cron-jobs/:jobDelete the job and its runs
POST /projects/:ref/cron-jobs/:job/runCall the path now and wait; returns { run: { id, status, status_code, attempts, duration_ms, message } }
GET /projects/:ref/cron-jobs/:job/runs?limit=20Recent runs, newest first

Database projects

Request
GET /database-projectsList databases
GET /database-projects/:refOne database
POST /database-projects { name }Create
DELETE /database-projects/:refDelete permanently
POST /database-projects/:ref/query { sql, read_only? }Run SQL; returns { command, row_count, fields, rows, duration_ms }
GET /database-projects/:ref/migrationsApplied migrations
POST /database-projects/:ref/migrations { version, name, sql }Apply a migration. version is YYYYMMDDHHMMSS; re-sending the same SQL is a no-op, different SQL for an applied version is a 409
GET /database-projects/:ref/types/typescript?schemas=public,career{ types }; schemas defaults to public, and an unknown schema returns 404 with available_schemas
GET /database-projects/:ref/keys{ rest_url, anon_key, service_key }
GET /database-projects/:ref/credentialsHost, port, database, username, password, connection_string (direct), and pooled_connection_string (the connection pooler; null if unavailable)

Database cron jobs

Cron jobs are addressed by :job, the job's name or id. Creating, changing, deleting, and running jobs needs the deployer role.

Request
GET /database-projects/:ref/cron-jobsJobs, each with next_run_at and last_run
GET /database-projects/:ref/cron-jobs/:jobOne job
POST /database-projects/:ref/cron-jobs { name, schedule, command, timezone?, timeout_seconds?, enabled? }Add a job. schedule is 5-field cron; timezone defaults to UTC, timeout_seconds to 60 (at most 300). Returns { cron_job }
PATCH /database-projects/:ref/cron-jobs/:job { name?, schedule?, command?, timezone?, timeout_seconds?, enabled? }Change only the fields sent; enabled: false pauses the job
DELETE /database-projects/:ref/cron-jobs/:jobDelete the job and its runs
POST /database-projects/:ref/cron-jobs/:job/runRun now and wait; returns { run: { id, status, duration_ms, message } }
GET /database-projects/:ref/cron-jobs/:job/runs?limit=20Recent runs, newest first

Database backups

Backups are addressed by :id. Taking or downloading one needs the deployer role; restoring needs the owner role.

RequestDoes
GET /database-projects/:ref/backups{ enabled, retention_days, backups, restores }, newest first. Each backup has kind (scheduled, manual, pre_restore), status, and size_bytes
POST /database-projects/:ref/backupsBack up now and wait; returns { backup } (201, or 500 with the error if it failed)
GET /database-projects/:ref/backups/:id/download{ url }: a download link valid for 15 minutes
POST /database-projects/:ref/backups/:id/restoreStart a restore (202, { restore }). Poll GET .../backups until that restore's status is succeeded or failed

Import from Supabase

The Supabase credentials are used for that request or import only and never stored. Needs the deployer role.

RequestDoes
POST /import/supabase/inspect { connection_string, supabase_url?, service_key? }Dry run: { report } with schemas, counts, warnings, and what won't carry over
POST /import/supabase { name, connection_string, supabase_url?, service_key? }Create a database and start importing into it (202, { import_id })
GET /imports/:id{ import: { status, step, report, error, database_ref } }; poll until status is succeeded or failed

On this page