Projects

Projects represent your applications that are deployed and managed through Depfloy. Each project is linked to a server and a git repository. On this page, we will dive into the different project endpoints you can use to manage projects programmatically.

AUTH Authorization: Bearer {API_KEY} Create a token →

The project model #

The project model contains all the information about your projects, including deployment settings, environment variables, and domain configuration.

Properties #

id integer

Unique identifier for the project.

name string

The display name for the project.

server_id integer

The ID of the server where the project is deployed.

framework_id integer

The ID of the framework used for the project. You can fetch the frameworks from the /api/v1/frameworks endpoint.

project_group_id integer

The group this project is an environment of, or null when it is ungrouped. See Project groups.

environment string

Which environment this project is: production, staging or dev. null when it has not been labelled — no project is treated as production by default.

auto_deploy_is_active integer

Whether automatic deployments are enabled. 0 = Disabled, 1 = Enabled.

ssl_is_enabled integer

Whether SSL is enabled for the project. 0 = Disabled, 1 = Enabled.

installation_status integer

The installation status of the project. 0 = Not installed, 1 = Installed.

redirect_status_code integer

The redirect status code for the project. 301 = Permanent Redirect, 302 = Temporary Redirect, 307 = Temporary Redirect, 308 = Permanent Redirect.

www_redirect integer

The WWW redirect setting for the project. 0 = no redirect, 1 = www to non-www, 2 = non-www to www - Default is 0 (no redirect).

directory string

This is the directory where the project is deployed.

port integer

This is the port number for node.js based project. It is automatically set by Depfloy.

primary_domain string

The primary domain of the project.

domains array

An array of domain names configured for the project.

domains.*.domain_name string

Domain name.

domains.*.is_primary integer

Whether the domain is the primary domain. 0 = No, 1 = Yes.

domains.*.is_active integer

Whether the domain is active. 0 = No, 1 = Yes.

repository_type string

Git repository source type. “github”, “bitbucket” or “gitlab”.

source_type string

Where the project’s code comes from: git for a repository, app for an application installed from the catalog. An app project has no repository and no deployments — see One-click installs.

app_slug string

The catalog application this project runs, or null for a git project.

app_version string

The version actually installed, read from the application after it was installed or updated.

repository string

The URL of the repository to deploy.

repository_branch string

The branch of the repository to deploy.

custom_commands.dev string

The customcommand to run the project in development mode.

custom_commands.install string

The custom command to run before the project is deployed.

custom_commands.build string

The custom command to run when the project is deploying.

custom_commands.directory string

The custom working directory of the project.

custom_commands.custom string

The custom deployment script to run when the project is deploying. Example: “php artisan horizon:terminate\nphp artisan cache:clear”

maintenance_mode integer

The maintenance mode status for the project. 0 = Disabled, 1 = Enabled.

notes string

Any additional notes about the project.

created_at timestamp

Timestamp of when the project was created.

updated_at timestamp

Timestamp of when the project was last updated.


GET/api/v1/projects

List all projects #

This endpoint allows you to retrieve a paginated list of all your projects.

Optional attributes #

per_page integer

How many projects one page carries. Defaults to 10 and is capped at 100; a value that is not a positive number is ignored in favour of the default.

page integer

The page number to retrieve.

project_group_id integer

Return only the projects in this group.

environment string

Return only the projects labelled production, staging or dev.

GET /api/v1/projects Request
curl -G https://app.depfloy.com/api/v1/projects \
  -H "Authorization: Bearer {API_KEY}" \ 
  -H "Accept: application/json"
  -H "Content-Type: application/json"
  -d per_page=10 \
  -d page=1 
Response
{
    "current_page": 1,
    "data": [
        {
            "id": 35231,
            "name": "PixelPulse",
            "server_id": 183009,
            "framework_id": 2,
            "auto_deploy_is_active": 1,
            "ssl_is_enabled": 1,
            "installation_status": 1,
            "redirect_status_code": 308,
            "www_redirect": 0,
            "repository_type": "github",
            "repository_branch": "dev",
            "repository": "MyRepo/PixelPulse",
            "custom_commands": {
                "dev": "",
                "build": "",
                "install": "",
                "directory": ""
            },
            "directory": "/home/depfloy/35",
            "port": "3510",
            "notes": null,
            "maintenance_mode": false,
            "created_at": "2025-02-09T18:52:20.000000Z",
            "updated_at": "2025-02-09T18:52:35.000000Z",
            "primary_domain": "nebula-spark.org",
            "domains": [
                {
                    "domain_name": "nebula-spark.org",
                    "is_primary": 1,
                    "is_active": 1,
                    "created_at": "2025-02-09T18:52:20.000000Z",
                },
                // ... more domains
            ]
        },
        // ... more projects
    ],
    "per_page": 10,
    "total_items": 8,
    "total_pages": 1
}

POST/api/v1/projects

Create a project #

This endpoint allows you to create a new project. The project will be linked to the specified server and git repository.

Required attributes #

name string

The display name for the project.

server_id integer

The ID of the server where the project will be deployed.

domain string

The primary domain for the project.

framework_id integer

The framework type identifier. You can fetch the frameworks from the /api/v1/frameworks endpoint.

git_repository.repo string

The repository URL. Example: “username/repository.git”.

git_repository.type string

The repository type. “github”, “bitbucket” or “gitlab”. Example: “github”.

git_repository.branch string

The branch of the repository to deploy. Example: “main”.

Optional attributes #

environment_variables text

Environment variables with key, value, and is_secret fields. Example: “API_KEY=your-api-key\nDB_PASSWORD=your-db-password”.

www_redirect integer

WWW redirect setting (1: www to non-www, 2: non-www to www). Default is 0 (no redirect).

auto_deploy_is_active integer

Enable automatic deployments on git push. Default is 0 (disabled).

ssl_is_enabled integer

Enable SSL for the project. Default is 0 (disabled).

custom_commands.dev string

The customcommand to run the project in development mode.

custom_commands.install string

The custom command to run before the project is deployed.

custom_commands.build string

The custom command to run when the project is deploying.

custom_commands.directory string

The custom working directory of the project.

custom_commands.custom string

The custom deployment script to run when the project is deploying. Example: “php artisan horizon:terminate\nphp artisan cache:clear”

POST /api/v1/projects Request
curl https://app.depfloy.com/api/v1/projects \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "server_id": 1,
    "name": "My Website",
    "domain": "example.com",
    "framework": 3,
    "git_repository": {
      "repo": "username/repository.git",
      "type": "github",
      "branch": "main"
    },
    "environment_variables": "API_KEY=your-api-key\nDB_PASSWORD=your-db-password",
    "custom_commands": {
      "build": "npm run build",
      "install": "npm install",
      "custom" : "php artisan horizon:terminate\nphp artisan cache:clear" 
    },
    "www_redirect": 2,
    "auto_deploy_is_active": 1,
    "ssl_is_enabled": 1
  }'
Response
{
  "status": "success",
  "message": "Installation started",
  "project_id": "14532"
}

GET/api/v1/projects/:id

Retrieve a project #

This endpoint allows you to retrieve a project by providing the project id.

GET /api/v1/projects/14532 Request
curl https://app.depfloy.com/api/v1/projects/14532 \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
  -H "Content-Type: application/json"
Response
{
    "id": 14532,
    "name": "PixelPulse",
    "server_id": 2,
    "framework_id": 2,
    "auto_deploy_is_active": 1,
    "ssl_is_enabled": 1,
    "installation_status": 1,
    "redirect_status_code": 308,
    "www_redirect": 0,
    "repository_type": "github",
    "repository_branch": "dev",
    "repository": "MyRepo/PixelPulse",
    "custom_commands": {
        "dev": "",
        "build": "",
        "install": "",
        "directory": "",
        "custom": ""
    },
    "directory": "/home/depfloy/14532",
    "port": "3510",
    "notes": null,
    "maintenance_mode": false,
    "created_at": "2025-02-09T18:52:20.000000Z",
    "updated_at": "2025-02-09T18:52:35.000000Z",
    "primary_domain": "nebula-spark.org",
    "domains": [
        {
            "domain_name": "nebula-spark.org",
            "is_active": 1,
            "created_at": "2025-02-09T18:52:20.000000Z",
            "is_primary": 1
        },
        // ... more domains
    ]
}

PUT/api/v1/projects/:id

Update a project #

Update one or more settings on an existing project. Omitted fields keep their current values. Saving project settings does not start a deployment. Build settings are used by the next deployment; the markdown negotiation switch is applied to the server immediately when it changes.

Attributes for updating a project #

name string

The display name for the project.

git_repository.type string

Git repository source type: github, bitbucket, gitlab, or another configured Git source.

git_repository.repo string

The repository URL or provider repository identifier.

git_repository.branch string

The branch to deploy.

framework string

Framework name: next, nuxt, remix, reactrouter, astro, php, laravel, symfony, wordpress, or statamic. A project can switch only between frameworks in the same runtime family.

framework_id integer

Framework ID. Use either framework or framework_id. If both are present, they must identify the same framework.

project_group_id integer

The group this project belongs to. Send null to ungroup it. A group you cannot reach is rejected the same way a non-existent one is.

environment string

production, staging or dev. Send null to clear the label.

custom_commands.dev string

The custom command used to run the project. Send an empty string to use the framework default.

custom_commands.install string

The dependency installation command. Send an empty string to use the framework default.

custom_commands.build string

The build command. Send an empty string to use the framework default.

custom_commands.directory string

The working directory, relative to the repository root. Send an empty string to use the repository root.

custom_commands.custom string

A custom deployment script. For example: php artisan horizon:terminate\nphp artisan cache:clear. Send an empty string to remove it.

max_memory string

Node.js process memory limit, such as 512MB or 2GB. Send null or an empty string to clear it.

auto_deploy_is_active boolean

Whether a push to the configured branch starts a deployment.

always_rebuild_frontend integer

For PHP projects, set to 1 to rebuild frontend assets on every deployment, or 0 to use change detection.

markdown_negotiation_enabled boolean

Enable or disable Markdown content negotiation for the project. Changes are applied immediately.

shared_directories array

Relative directories preserved between deployments. Send null or an empty array to clear the list.

shared_files array

Relative files preserved between deployments. Send null or an empty array to clear the list.

PUT /api/v1/projects/14532 Request
Update build settings
curl -X PUT https://app.depfloy.com/api/v1/projects/14532 \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "git_repository": {
      "branch": "production"
    },
    "framework": "astro",
    "custom_commands": {
      "install": "npm ci",
      "build": "npm run build"
    },
    "max_memory": "1GB",
    "auto_deploy_is_active": false
  }'
Update name only
curl -X PUT https://app.depfloy.com/api/v1/projects/14532 \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name": "New Project Name"}'
Response
{
  "status": "success",
  "message": "Project updated successfully",
  "project_id": 14532
}

DELETE/api/v1/project/:id

Delete a project #

This endpoint allows you to delete a project. This will remove the project from the server and delete all associated deployments.

DELETE /api/v1/project/14532 Request
curl -X DELETE https://app.depfloy.com/api/v1/project/14532 \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
  -H "Content-Type: application/json"
Response
{
  "status": "success",
  "message": "Project deleted successfully",
  "project_id": "14532"
}

POST/api/v1/projects/:id/move

Move project to another server #

Move a project to a different server in the same organization. Requires the project:update permission and access to both servers.

Required attributes #

server_id integer

The ID of the destination server.

The move triggers a deployment on the destination server, copies files, and removes the project from the source. Expect a few minutes of brief unavailability. Update your DNS to point at the new server’s IP.

POST /api/v1/projects/14532/move Request
cURL
curl -X POST https://app.depfloy.com/api/v1/projects/14532/move \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "server_id": 183010
  }'
Response
{
  "status": "success",
  "message": "Project move started.",
  "project_id": "14532"
}

PUT/api/v1/projects/:id/environment-variables

Update environment variables #

Replace the full set of environment variables for a project. The supplied value becomes the new content of the project’s .env file.

Required attributes #

environment_variables string

The full env contents. Each line is KEY=VALUE. Multi-line values can be quoted.

PUT /api/v1/projects/14532/environment-variables Request
cURL
curl -X PUT https://app.depfloy.com/api/v1/projects/14532/environment-variables \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "environment_variables": "APP_ENV=production\nAPP_DEBUG=false\nDB_PASSWORD=secret"
  }'
Response
{
  "status": "success",
  "message": "Environment variables updated."
}

PUT/api/v1/projects/bulk/auto-deploy

Bulk update auto-deploy #

Turn auto-deploy on or off across a set of projects in a single call. Useful when you want to freeze deploys before a coordinated change, or re-enable them after.

Required attributes #

project_ids array

Array of project IDs to update.

auto_deploy_is_active integer

1 to enable, 0 to disable.

PUT /api/v1/projects/bulk/auto-deploy Request
cURL
curl -X PUT https://app.depfloy.com/api/v1/projects/bulk/auto-deploy \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "project_ids": [14532, 14533, 14534],
    "auto_deploy_is_active": 0
  }'
Response
{
  "status": "success",
  "updated_count": 3
}

POST/api/v1/projects/:project/maintenance/toggle

Toggle maintenance mode #

Turn maintenance mode on or off for a project. While maintenance mode is on, visitors see the maintenance template holding page instead of the application.

The response includes the new state, so the same endpoint is the right tool for both enabling and disabling.

POST /api/v1/projects/14532/maintenance/toggle Request
cURL
curl -X POST https://app.depfloy.com/api/v1/projects/14532/maintenance/toggle \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "status": "success",
  "maintenance_mode": true
}

GET/api/v1/projects/:project/maintenance/status

Get maintenance status #

Read the current maintenance state without changing it.

GET /api/v1/projects/14532/maintenance/status Request
cURL
curl https://app.depfloy.com/api/v1/projects/14532/maintenance/status \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "maintenance_mode": true
}

GET/api/v1/projects/:id/publish

Publish project on Nginx #

This endpoint allows you to publish or republish the project’s Nginx configuration. This is useful when you need to update the server configuration without triggering a full deployment.

Optional query parameters #

force_ssl boolean

Force SSL configuration. Set to 1 to enable. 0 = Disable, 1 = Enable. When force_ssl is set to 1, the project’s SSL configuration will be updated. When force_ssl is set to 0, the project’s SSL configuration will be removed.

GET /api/v1/projects/14532/publish Request
With SSL
curl "https://app.depfloy.com/api/v1/projects/14532/publish?force_ssl=1" \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
  -H "Content-Type: application/json"
Without SSL
curl "https://app.depfloy.com/api/v1/projects/14532/publish?force_ssl=0" \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
  -H "Content-Type: application/json"
Response
{
  "nginx_response": {
    "ok": true,
    "system_output": [
      "[nginx] : nginx: the configuration file /etc/nginx/nginx.conf syntax is ok",
      "[nginx] : nginx: configuration file /etc/nginx/nginx.conf test is successful"
    ]
  }
}

One-click installs #

A project can also come from the application catalog instead of a repository. Such a project has source_type of app, no repository, and no deployments — asking for one is refused. See the One-Click Install guide.


GET/api/v1/servers/:id/apps

What a server can install #

The catalog as it applies to one server. Applications that cannot be installed there are still listed, with available set to false and unavailable_reasons saying why — WordPress needs MySQL or MariaDB, for instance.

inputs describes the fields that application asks for, so a client can build the form without knowing the application.

GET /api/v1/servers/183009/apps Request
cURL
curl https://app.depfloy.com/api/v1/servers/183009/apps \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "status": "success",
  "data": [
    {
      "slug": "wordpress",
      "name": "WordPress",
      "category": "cms",
      "summary": "Publishing platform behind roughly two in five websites.",
      "layout": "in_place",
      "available": true,
      "unavailable_reasons": [],
      "inputs": [
        { "key": "site_title", "label": "Site title", "type": "text", "required": true },
        { "key": "admin_password", "label": "Administrator password", "type": "password", "generated": true }
      ]
    }
  ]
}

POST/api/v1/projects/install

Install an application #

Creates the project and queues the install. Needs project:create.

Body #

name string

Project name. Must be unique in the organization.

domain string

The domain the application will answer on. Point it at the server first — the application records its own address during setup.

server_id integer

An app server that meets the application’s requirements.

app_slug string

wordpress or phpmyadmin.

inputs object

The fields that application asks for. A password left empty is generated.

www_redirect integer

0 none, 1 www → non-www, 2 non-www → www. Defaults to 0.

A server that cannot host the application is refused with 422 and the reason, before anything is written.

POST /api/v1/projects/install Request
cURL
curl -X POST https://app.depfloy.com/api/v1/projects/install \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Company Blog",
        "domain": "blog.example.com",
        "server_id": 183009,
        "app_slug": "wordpress",
        "inputs": {
          "site_title": "Company Blog",
          "admin_user": "editor",
          "admin_email": "[email protected]"
        }
      }'
Response
{
  "status": "success",
  "message": "Installing WordPress.",
  "data": {
    "id": 290,
    "server_id": 183009,
    "name": "Company Blog",
    "app_slug": "wordpress",
    "domain": "blog.example.com",
    "installation_status": 0
  }
}

GET/api/v1/projects/:id/install-steps

Follow an install #

Every step of the install and where it has got to. installation_status is 0 while it runs, 1 when the application is up and 2 when a step failed.

A step’s status is one of pending, running, completed, failed or skipped. detail carries what the step produced or, on a failure, why it stopped.

GET /api/v1/projects/290/install-steps Request
cURL
curl https://app.depfloy.com/api/v1/projects/290/install-steps \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "status": "success",
  "data": {
    "installation_status": 1,
    "app_slug": "wordpress",
    "app_version": "7.0.4",
    "steps": [
      {
        "key": "provision_database",
        "label": "Creating the database",
        "position": 3,
        "status": "completed",
        "detail": "wp_company_blog_a1b2c3",
        "duration_ms": 412
      }
    ]
  }
}

POST/api/v1/projects/:id/install/retry

Retry a failed install #

Runs the install again from the top. Every step is safe to repeat, and the database created on the first attempt is reused rather than duplicated.

Only a failed install can be retried; anything else answers 422. Needs project:create.

POST /api/v1/projects/290/install/retry Request
cURL
curl -X POST https://app.depfloy.com/api/v1/projects/290/install/retry \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "status": "success",
  "message": "Retrying the installation."
}

GET/api/v1/projects/:id/app

Retrieve an application #

The application’s details and the credentials the installer set. Needs project:update — seeing that a project exists and holding its administrator password are two different things to be allowed.

A project that came from a repository answers 404.

GET /api/v1/projects/290/app Request
cURL
curl https://app.depfloy.com/api/v1/projects/290/app \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "status": "success",
  "data": {
    "app_slug": "wordpress",
    "app_name": "WordPress",
    "app_version": "7.0.4",
    "admin_url": "https://blog.example.com/wp-admin/",
    "updatable": true,
    "credentials": {
      "admin_user": { "label": "Administrator username", "value": "editor", "secret": false },
      "admin_password": { "label": "Administrator password", "value": "…", "secret": true }
    },
    "database": {
      "engine": "mysql",
      "name": "wp_company_blog_a1b2c3",
      "username": "wp_company_blog_a1b2c3",
      "password": "…",
      "host": "127.0.0.1"
    }
  }
}

POST/api/v1/projects/:id/app/update

Update an application #

Runs the application’s own updater. For WordPress: core, then the database changes that come with it, then plugins and themes.

Queued, not run inline — a WordPress update with every plugin takes minutes. The version is re-read afterwards rather than assumed, so app_version reflects what the updater actually landed on.

An application Depfloy cannot update in place, such as phpMyAdmin, answers 422. Needs project:update.

POST /api/v1/projects/290/app/update Request
cURL
curl -X POST https://app.depfloy.com/api/v1/projects/290/app/update \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "status": "success",
  "message": "Updating WordPress."
}

Project groups #

A group is a name for the environments of one application — the production, staging and dev copies of a shop, or one group per client in an agency. A project carries project_group_id and environment; both are optional, and a project with neither is ungrouped and unlabelled.

Reading groups needs project:read and changing them needs project:update — the same permissions that govern projects. There is no separate group permission.

GET/api/v1/project-groups

List groups #

Returns the groups in the current organization, ordered by name, 25 per page. Each carries a projects_count.

GET /api/v1/project-groups Request
curl -G https://app.depfloy.com/api/v1/project-groups \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "current_page": 1,
  "data": [
    {
      "id": 4,
      "name": "Acme Shop",
      "description": "Storefront and its staging copy",
      "projects_count": 3
    }
  ],
  "per_page": 25,
  "total_items": 1,
  "total_pages": 1
}
POST/api/v1/project-groups

Create a group #

Attributes #

name string

Required. Up to 100 characters.

description string

Optional. Up to 2000 characters.

Answers 201 with the new group.

POST /api/v1/project-groups Request
curl -X POST https://app.depfloy.com/api/v1/project-groups \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Shop"}'
Response
{
  "status": "success",
  "message": "Group created",
  "data": {
    "id": 4,
    "name": "Acme Shop",
    "description": null
  }
}
GET/api/v1/project-groups/:id

Retrieve a group #

Returns the group with the projects in it, each with its environment.

GET /api/v1/project-groups/4 Request
curl -G https://app.depfloy.com/api/v1/project-groups/4 \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "status": "success",
  "data": {
    "id": 4,
    "name": "Acme Shop",
    "description": null,
    "projects": [
      { "id": 231, "name": "acme-shop", "environment": "production", "server_id": 59 },
      { "id": 240, "name": "acme-shop-staging", "environment": "staging", "server_id": 59 }
    ]
  }
}
PUT/api/v1/project-groups/:id

Update a group #

Takes name and description, same limits as creating one. Answers with the updated group.

PUT /api/v1/project-groups/4 Request
curl -X PUT https://app.depfloy.com/api/v1/project-groups/4 \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name": "Acme Storefront"}'
DELETE/api/v1/project-groups/:id

Delete a group #

Deletes the group only. The projects in it are untouched and become ungrouped, and the message says how many that was.

DELETE /api/v1/project-groups/4 Request
curl -X DELETE https://app.depfloy.com/api/v1/project-groups/4 \
  -H "Authorization: Bearer {API_KEY}" \
  -H "Accept: application/json"
Response
{
  "status": "success",
  "message": "Group deleted. 3 project(s) are now ungrouped and were not changed otherwise.",
  "ungrouped_projects": 3
}