Skip to content
runlot
ReferenceAPIProject

Project

Covers 8 API operations in the projects category.

MethodPathDescription
GET/v1/orgs/{orgSlug}/projects—
POST/v1/orgs/{orgSlug}/projectsCreate a project
GET/v1/orgs/{orgSlug}/projects/{projectName}—
PATCH/v1/orgs/{orgSlug}/projects/{projectName}Rename a project (runlot project rename)
DELETE/v1/orgs/{orgSlug}/projects/{projectName}Delete a project (runlot project delete)
GET/v1/orgs/{orgSlug}/projects/{projectName}/overviewProject overview (dashboard home)
POST/v1/orgs/{orgSlug}/projects/{projectName}/disableDisable a project (keeps its data)
POST/v1/orgs/{orgSlug}/projects/{projectName}/enableEnable a disabled project

GET /v1/orgs/{orgSlug}/projects

operationId listProjects

Status codeDescriptionResponse body
200The organization's projectsobject
403——
404——

POST /v1/orgs/{orgSlug}/projects

Creating a project also issues its default hostname. Nothing is running yet — the project starts serving at its first deployment.

The plan's project limit is enforced here, and concurrent creates cannot exceed it.

operationId createProject

Request body: application/json · object

Status codeDescriptionResponse body
201The created projectProject
403——
409The name is already taken (project_name_taken, hostname_taken), or the plan's project limit has been reached (project_limit). The details of project_limit is {limit, count, plan} — read the numbers from there rather than parsing the message. It is 409 because retrying will not change the outcome.Error

GET /v1/orgs/{orgSlug}/projects/{projectName}

operationId getProject

Status codeDescriptionResponse body
200The projectProjectDetail
403——
404——

PATCH /v1/orgs/{orgSlug}/projects/{projectName}

Requires admin or higher. Audited as project.rename, with the old name in detail.from.

Unlike the org slug, a project name can change. It is the label inside the *.<slug>.runlot.app wildcard, so the existing certificate already covers the new name and only the project's default hostname moves. Custom domains are untouched.

No stored data moves. Your database, object storage, generation chains, usage, secrets, and git repository all stay exactly where they are.

What breaks are the copies outside: the name in everyone's runlot.json, registered git remotes, and Postgres connection strings already pasted into configs. The old address is not kept as an alias. The response carries the new addresses.

The project's email address does not follow. It is fixed when the grant is made, because the outside world already sends mail there. Revoke and re-grant to move it.

operationId updateProject

Request body: application/json · object

Status codeDescriptionResponse body
200The renamed project, with its new addressesProject
400——
403——
404——
409Another project in this org already has that name (project_name_taken), or the hostname it would take is already in use (hostname_taken). A project that is being deleted answers project_deleting.Error

DELETE /v1/orgs/{orgSlug}/projects/{projectName}

Requires admin or higher. This cannot be undone, and there is no recovery generation to restore from afterwards. Export anything you need first with runlot pg export.

The confirm field must carry the exact project name.

The project is gone when this call returns. It disappears from the project list, from GET, from git, and from mail, and its name is free to use again immediately. There is nothing to poll and nothing to wait for.

Behind that, deletion runs in two steps. The first cuts routing and drains in-flight requests, so the address stops answering within seconds. The second destroys the data — database files, object storage, repositories, bundles, and records — and does not run until purgeAfter, one month later by default. Nothing in that window is reachable by anyone, and there is no way to bring it back.

The 202 carries an operation id you can read with GET /v1/orgs/{orgSlug}/operations/{opId}, which reports the first step. Clients should not block on it.

operationId deleteProject

Request body: application/json · object

Status codeDescriptionResponse body
202Deletion startedOperationStarted
400——
403——
404——
409Another operation is in progress (op_in_flight)Error

GET /v1/orgs/{orgSlug}/projects/{projectName}/overview

Everything the project's home screen needs in one call — the deployment currently serving and who uploaded it, a handful of recent deployments, the database's last backup, whether declared resources have been provisioned, and recent notifications for this project. This answers "how is it right now", not history — the tabs cover that.

Usage is not included; call getUsage alongside it. Requires viewer or higher.

operationId getProjectOverview

Status codeDescriptionResponse body
200The project overviewProjectOverview
403——
404——

POST /v1/orgs/{orgSlug}/projects/{projectName}/disable

Requires admin or higher. The project stops serving and stops taking new backups. Nothing is deleted: the database, files, repositories and the backups already taken all stay, and enableProject brings it back. A disabled project does not count toward the plan's project limit, so this is how an organization that holds more projects than its plan allows gets its deploys back.

A project left disabled for one year is deleted permanently at deleteAfter. Calling this on a disabled project changes nothing. Audited as project.disable.

operationId disableProject

Status codeDescriptionResponse body
200The project's disabled stateProjectDisabled
403——
404——

POST /v1/orgs/{orgSlug}/projects/{projectName}/enable

Requires admin or higher. The project serves again and backups resume. Audited as project.enable.

operationId enableProject

Status codeDescriptionResponse body
200The project's disabled stateProjectDisabled
403——
404——
409project_limit — the organization already has as many active projects as its plan allows. Disable or delete another one first, or upgrade.Error

On this page