NAV

Introduction

The Forge API allows you to create and interact with servers and sites on Laravel Forge through a simple REST API.

Authentication

In order to use the API, you should authenticate your request by including your API key as a bearer token value:

Authorization: Bearer API_KEY_HERE

You may generate API keys in the API Dashboard.

Headers

Make sure you have the following content type headers are set on every request:

Accept: application/json Content-Type: application/json

URI

Forge API is hosted on the following base URI:

https://forge.laravel.com/api/v1

Errors

Forge uses conventional HTTP response codes to indicate the success or failure of an API request. The table below contains a summary of the typical response codes:

Code Description
200 Everything is ok.
400 Valid data was given but the request has failed.
401 No valid API Key was given.
404 The request resource could not be found.
422 The payload has missing required parameters or invalid data was given.
429 Too many attempts.
500 Request failed due to an internal error in Forge.
503 Forge is offline for maintenance.

User

show

Response

{
    "user": {
        "id": 1,
        "name": "Mohamed Said",
        "email": "[email protected]",
        "card_last_four": "1881",
        "connected_to_github": true,
        "connected_to_gitlab": true,
        "connected_to_bitbucket_two": true,
        "connected_to_digitalocean": true,
        "connected_to_linode": true,
        "connected_to_vultr": true,
        "connected_to_aws": true,
        "connected_to_hetzner": true,
        "ready_for_billing": true,
        "stripe_is_active": 1,
        "stripe_price": "yearly-basic-199-trial",
        "subscribed": 1,
        "can_create_servers": true,
        "2fa_enabled": false
    }
}

HTTP Request

GET /api/v1/user

Servers

Create Server

Payload

{
    "provider": "ocean2",
    "ubuntu_version": "22.04",
    "type": "web",
    "credential_id": 1,
    "name": "test-via-api",
    "size": "01",
    "database": "test123",
    "php_version": "php82",
    "region": "ams2",
    "recipe_id": null
}

Response

{
    "server": {
        "id": 16,
        "credential_id": 1,
        "name": "test-via-api",
        "type": "web",
        "size": "01",
        "region": "ams2",
        "php_version": "php82",
        "php_cli_version": "php82",
        "opcache_status": "enabled",
        "database_type": "mysql8",
        "ip_address": null,
        "private_ip_address": null,
        "blackfire_status": null,
        "papertrail_status": null,
        "revoked": false,
        "created_at": "2016-12-15 15:04:05",
        "is_ready": false,
        "network": []
    },
    "sudo_password": "baracoda",
    "database_password": "spotted_eagle_ray"
}

HTTP Request

POST /api/v1/servers

Parameters

Key Description
ubuntu_version The version of Ubuntu to create the server with. Valid values are "20.04" and "22.04". "22.04" is used by default if no value is defined. It is recommended to always specify a version as the default may change at any time.
type The type of server to create. Valid values are app, web, loadbalancer, cache, database, worker, meilisearch. app is used by default if no value is defined.
provider The server provider. Valid values are ocean2 for Digital Ocean, linode4, vultr2, aws, hetzner and custom.
disk_size The size of the disk in GB. Valid when the provider is aws. Minimum of 8GB. Example: 20.
circle The ID of a circle to create the server within.
credential_id This is only required when the provider is not custom.
region The name of the region where the server will be created. This value is not required you are building a Custom VPS server. Valid region identifiers.
ip_address The IP Address of the server. Only required when the provider is custom.
private_ip_address The Private IP Address of the server. Only required when the provider is custom.
php_version Valid values are php83, php82, php81, php80, php74, php73,php72,php82, php70, and php56.
database The name of the database Forge should create when building the server. If omitted, forge will be used.
database_type Valid values are mysql8, mariadb106, mariadb1011, postgres, postgres13, postgres14, postgres15, or postgres16.
network An array of server IDs that the server should be able to connect to.
recipe_id An optional ID of a recipe to run after provisioning.
aws_vpc_id ID of the existing VPC
aws_subnet_id ID of the existing subnet
aws_vpc_name When creating a new one
hetzner_network_id ID of the existing VPC
ocean2_vpc_uuid UUID of the existing VPC
ocean2_vpc_name When creating a new one
vultr2_network_id ID of the existing private network
vultr2_network_name When creating a new one

Server Status

Servers take about 10 minutes to provision. Once the server is ready to be used, the is_ready parameter on the server will be true. You should not repeatedly ping the Forge API asking if the server is ready. Instead, consider pinging the endpoint once every 2 minutes.

Valid Sizes

Check the Regions endpoint for the available sizes and regions IDs.

Custom VPS

While creating a custom VPS, the response of this endpoint will contain a provision_command attribute:

{
    "provision_command": "wget -O forge.sh https://..."
}

List Servers

Response

{
    "servers": [
        {
            "id": 1,
            "credential_id": 1,
            "name": "test-via-api",
            "size": "s-1vcpu-1gb",
            "region": "Amsterdam 2",
            "php_version": "php82",
            "php_cli_version": "php82",
            "opcache_status": "enabled",
            "database_type": "mysql8",
            "ip_address": "37.139.3.148",
            "private_ip_address": "10.129.3.252",
            "blackfire_status": null,
            "papertrail_status": null,
            "revoked": false,
            "created_at": "2016-12-15 18:38:18",
            "is_ready": true,
            "network": []
        }
    ]
}

HTTP Request

GET /api/v1/servers

Get Server

Response

{
    "server": {
        "id": 1,
        "credential_id": 1,
        "name": "test-via-api",
        "size": "s-1vcpu-1gb",
        "region": "Amsterdam 2",
        "php_version": "php82",
        "php_cli_version": "php82",
        "opcache_status": "enabled",
        "database_type": "mysql8",
        "ip_address": "37.139.3.148",
        "private_ip_address": "10.129.3.252",
        "blackfire_status": null,
        "papertrail_status": null,
        "revoked": false,
        "created_at": "2016-12-15 18:38:18",
        "is_ready": true,
        "network": []
    }
}

HTTP Request

GET /api/v1/servers/{id}

Update Server

Payload

{
    "name": "renamed-server",
    "ip_address": "192.241.143.108",
    "private_ip_address": "10.136.8.40",
    "max_upload_size": 123,
    "max_execution_time": 30,
    "network": [2, 3],
    "timezone": "Europe/London",
    "tags": ["london-server"]
}

Response

{
    "server": {
        "id": 16,
        "credential_id": 1,
        "name": "test-via-api",
        "size": "s-1vcpu-1gb",
        "region": "Amsterdam 2",
        "php_version": "php82",
        "php_cli_version": "php82",
        "opcache_status": "enabled",
        "database_type": "mysql8",
        "ip_address": null,
        "private_ip_address": null,
        "blackfire_status": null,
        "papertrail_status": null,
        "revoked": false,
        "created_at": "2016-12-15 15:04:05",
        "is_ready": false,
        "network": [2, 3],
        "tags": ["london-server"]
    }
}

HTTP Request

PUT /api/v1/servers/{id}

Update Database Password

Payload

{
    "password": "maeve"
}

HTTP Request

PUT /api/v1/servers/{serverId}/database-password

This endpoint will update Forge's copy of the primary database password which should be used to authenticate the creation of new databases and database users. This is typically only needed if you are working with a Forge server that was built before database administration was added to Forge.

Delete Server

HTTP Request

DELETE /api/v1/servers/{id}

Reboot Server

HTTP Request

POST /api/v1/servers/{id}/reboot

Revoke Forge access to server

HTTP Request

POST /api/v1/servers/{id}/revoke

Reconnect revoked server

Response

{
    "public_key": "CONTENT_OF_THE_PUBLIC_KEY"
}

HTTP Request

POST /api/v1/servers/{id}/reconnect

This endpoint will return an SSH key which you will need to add to the server. Once the key has been added to the server, you may "reactivate" it.

Reactivate revoked server

HTTP Request

POST /api/v1/servers/{id}/reactivate

Get Recent Events

Response

[
    {
        "server_id": 18,
        "ran_as": "forge",
        "server_name": "billowing-cliff",
        "description": "Deploying PHP Info Page.",
        "created_at": "2017-04-28 18:08:44"
    }
]

HTTP Request

GET /api/v1/servers/events

Parameters

Key Description
server_id Optionally specify a server_id to get recent events of only this server.

Get Server Events

Response

{
    "events": [
        {
            "server_id": 18,
            "ran_as": "forge",
            "server_name": "billowing-cliff",
            "description": "Deploying PHP Info Page.",
            "created_at": "2017-04-28 18:08:44"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{id}/events

Get Server Event Output

Response

{
    "output": "Some command output."
}

HTTP Request

GET /api/v1/servers/{id}/events/{event}

Services

Start Service

HTTP Request

POST /api/v1/servers/{id}/services/start

Payload

{
    "service": "service-name"
}

Stop Service

HTTP Request

POST /api/v1/servers/{id}/services/stop

Payload

{
    "service": "service-name"
}

Restart Service

HTTP Request

POST /api/v1/servers/{id}/services/restart

Payload

{
    "service": "service-name"
}

Reboot MySQL

HTTP Request

POST /api/v1/servers/{id}/mysql/reboot

Stop MySQL

HTTP Request

POST /api/v1/servers/{id}/mysql/stop

Reboot Nginx

HTTP Request

POST /api/v1/servers/{id}/nginx/reboot

Stop Nginx

HTTP Request

POST /api/v1/servers/{id}/nginx/stop

Test Nginx

Response

{
  "result": "nginx: [emerg] a duplicate listen 0.0.0.0:80 in \/etc\/nginx\/sites-enabled\/default:6\nnginx: configuration file \/etc\/nginx\/nginx.conf test failed\n"
}

HTTP Request

GET /api/v1/servers/{id}/nginx/test

Reboot Postgres

HTTP Request

POST /api/v1/servers/{id}/postgres/reboot

Stop Postgres

HTTP Request

POST /api/v1/servers/{id}/postgres/stop

Reboot PHP

Payload

{
    "version": "php74"
}

HTTP Request

POST /api/v1/servers/{id}/php/reboot

Install Blackfire

Payload

{
    "server_id": "...",
    "server_token": "..."
}

HTTP Request

POST /api/v1/servers/{id}/blackfire/install

Remove Blackfire

HTTP Request

DELETE /api/v1/servers/{id}/blackfire/remove

Install Papertrail

Payload

{
    "host": "192.241.143.108"
}

HTTP Request

POST /api/v1/servers/{id}/papertrail/install

Remove Papertrail

HTTP Request

DELETE /api/v1/servers/{id}/papertrail/remove

Daemons

Create Daemon

Payload

{
    "command": "COMMAND",
    "user": "root",
    "directory": "/home/forge/foo.com"
}

Response

{
  "daemon": {
    "id": 2,
    "command": "php artisan queue:work",
    "user": "forge",
    "directory": "/home/forge/foo.com",
    "processes": 1,
    "startsecs": 1,
    "stopwaitsecs": 10,
    "stopsignal": "SIGTERM",
    "status": "installing",
    "created_at": "2022-02-14 09:29:18"
  }
}

HTTP Request

POST /api/v1/servers/{serverId}/daemons

List Daemons

Response

{
    "daemons": [
      {
        "id": 2,
        "command": "php artisan queue:work",
        "user": "forge",
        "directory": "/home/forge/foo.com",
        "processes": 1,
        "startsecs": 1,
        "stopwaitsecs": 10,
        "stopsignal": "SIGTERM",
        "status": "installing",
        "created_at": "2022-02-14 09:29:18"
      }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/daemons

Get Daemon

Response

{
    "daemon": {
      "id": 2,
      "command": "php artisan queue:work",
      "user": "forge",
      "directory": "/home/forge/foo.com",
      "processes": 1,
      "startsecs": 1,
      "stopwaitsecs": 10,
      "stopsignal": "SIGTERM",
      "status": "installing",
      "created_at": "2022-02-14 09:29:18"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/daemons/{daemonId}

Delete Daemon

HTTP Request

DELETE /api/v1/servers/{serverId}/daemons/{daemonId}

Restart Daemon

HTTP Request

POST /api/v1/servers/{serverId}/daemons/{daemonId}/restart

Firewall Rules

Create Rule

Payload

{
    "name": "rule name",
    "ip_address": "192.168.1.1",
    "port": 88,
    "type": "allow"
}

Response

{
    "rule": {
        "id": 4,
        "name": "rule",
        "port": 123,
        "type": "allow",
        "ip_address": null,
        "status": "installing",
        "created_at": "2016-12-16 15:50:17"
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/firewall-rules

Available Rule Types

You may specify allow or deny as the rule type.

List Rules

Response

{
    "rules": [
        {
            "id": 4,
            "name": "rule",
            "port": 123,
            "type": "allow",
            "ip_address": null,
            "status": "installing",
            "created_at": "2016-12-16 15:50:17"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/firewall-rules

Get Rule

Response

{
    "rule": {
        "id": 4,
        "name": "rule",
        "port": 123,
        "type": "allow",
        "ip_address": null,
        "status": "installing",
        "created_at": "2016-12-16 15:50:17"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/firewall-rules/{ruleId}

Delete Rule

HTTP Request

DELETE /api/v1/servers/{serverId}/firewall-rules/{ruleId}

Scheduled Jobs

Create Job

Payload

{
    "command": "COMMAND_THE_JOB_RUNS",
    "frequency": "custom",
    "user": "root",
    "minute": "*",
    "hour": "*",
    "day": "*",
    "month": "*",
    "weekday": "*"
}

Response

{
    "job": {
        "id": 2,
        "command": "COMMAND_THE_JOB_RUNS",
        "user": "root",
        "frequency": "Nightly",
        "cron": "0 0 * * *",
        "status": "installing",
        "created_at": "2016-12-16 15:56:59"
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/jobs

Parameters

Key Description
frequency The frequency in which the job should run. Valid values are minutely, hourly, nightly, weekly, monthly, reboot, and custom
minute Required if the frequency is custom.
hour Required if the frequency is custom.
day Required if the frequency is custom.
month Required if the frequency is custom.
weekday Required if the frequency is custom.

List Jobs

Response

{
    "jobs": [
        {
            "id": 2,
            "command": "COMMAND_THE_JOB_RUNS",
            "user": "root",
            "frequency": "nightly",
            "cron": "0 0 * * *",
            "status": "installing",
            "created_at": "2016-12-16 15:56:59"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/jobs

Get Job

Response

{
    "job": {
        "id": 2,
        "command": "COMMAND_THE_JOB_RUNS",
        "user": "root",
        "frequency": "Nightly",
        "cron": "0 0 * * *",
        "status": "installing",
        "created_at": "2016-12-16 15:56:59"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/jobs/{jobId}

Delete Job

HTTP Request

DELETE /api/v1/servers/{serverId}/jobs/{jobId}

Get Job Output

Response

{
    "output": "The output of the job will be returned here."
}

HTTP Request

GET /api/v1/servers/{serverId}/jobs/{jobId}/output

PHP

List PHP Versions

Response

[
      {
            "id": 29,
            "version": "php74",
            "status": "installed",
            "displayable_version": "PHP 7.4",
            "binary_name": "php7.4",
            "used_as_default": false,
            "used_on_cli": false
      },
      {
            "id": 30,
            "version": "php73",
            "status": "installed",
            "displayable_version": "PHP 7.3",
            "binary_name": "php7.3",
            "used_as_default": true,
            "used_on_cli": true
      },
      {
            "id": 31,
            "version": "php72",
            "status": "installed",
            "displayable_version": "PHP 7.2",
            "binary_name": "php7.2",
            "used_as_default": false,
            "used_on_cli": false
      },
      {
            "id": 32,
            "version": "php71",
            "status": "installed",
            "displayable_version": "PHP 7.1",
            "binary_name": "php7.1",
            "used_as_default": false,
            "used_on_cli": false
      },
      {
            "id": 33,
            "version": "php56",
            "status": "installed",
            "displayable_version": "PHP 5.6",
            "binary_name": "php5.6",
            "used_as_default": false,
            "used_on_cli": false
      }
]

HTTP Request

GET /api/v1/servers/{serverId}/php

Install PHP Version

HTTP Request

POST /api/v1/servers/{serverId}/php

Payload

{
    "version": "php74"
}

Available Versions

Key Description
php83 PHP 8.3
php82 PHP 8.2
php81 PHP 8.1
php80 PHP 8.0
php74 PHP 7.4
php73 PHP 7.3
php72 PHP 7.2
php71 PHP 7.1
php70 PHP 7.0
php56 PHP 5.6

Upgrade PHP Patch Version

You must supply the version to be patched.

HTTP Request

POST /api/v1/servers/{serverId}/php/update

Payload

{
    "version": "php74"
}

Enable OPCache

HTTP Request

POST /api/v1/servers/{serverId}/php/opcache

Disable OPCache

HTTP Request

DELETE /api/v1/servers/{serverId}/php/opcache

Databases

Create Database

Payload

{
    "name": "forge",
    "user": "forge",
    "password": "dolores"
}

Response

{
    "database": {
        "id": 1,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:12:22"
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/databases

Parameters

Key Description
user This field is optional. If passed, it will be used to create a new Database User with access to the newly created database.
password This field is only required when a user value is given.

Sync Database

HTTP Request

POST /api/v1/servers/{serverId}/databases/sync

List Databases

Response

{
    "databases": [
        {
            "id": 1,
            "name": "forge",
            "status": "installing",
            "created_at": "2016-12-16 16:12:22"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/databases

Get Database

Response

{
    "database": {
        "id": 1,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:12:22"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/databases/{databaseId}

Delete Database

HTTP Request

DELETE /api/v1/servers/{serverId}/databases/{databaseId}

Database Users

Create User

Payload

{
    "name": "forge",
    "password": "dolores",
    "databases": [1]
}

Response

{
    "user": {
        "id": 2,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:19:01",
        "databases": [
            1
        ]
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/database-users

Parameters

Key Description
databases An array of database IDs referencing the databases the user has access to.
password The password to assign the user.

List Users

Response

{
    "users": [
        {
            "id": 2,
            "name": "forge",
            "status": "installing",
            "created_at": "2016-12-16 16:19:01",
            "databases": [
                1
            ]
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/database-users

Get User

Response

{
    "user": {
        "id": 2,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:19:01",
        "databases": [
            1
        ]
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/database-users/{userId}

Update User

Payload

{
    "databases": [2]
}

Response

{
    "user": {
        "id": 2,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:19:01",
        "databases": [
            1
        ]
    }
}

HTTP Request

PUT /api/v1/servers/{serverId}/database-users/{userId}

This endpoint may be used to update the databases the Database User has access to.

Delete User

HTTP Request

DELETE /api/v1/servers/{serverId}/database-users/{userId}

MySQL Databases

The /mysql endpoints is now deprecated in favour of the new /databases endpoint.

Create Database

Payload

{
    "name": "forge",
    "user": "forge",
    "password": "dolores"
}

Response

{
    "database": {
        "id": 1,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:12:22"
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/mysql

Parameters

Key Description
user This field is optional. If passed, it will be used to create a new MySQL user with access to the newly created database.
password This field is only required when a user value is given.

List Databases

Response

{
    "databases": [
        {
            "id": 1,
            "name": "forge",
            "status": "installing",
            "created_at": "2016-12-16 16:12:22"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/mysql

Get Database

Response

{
    "database": {
        "id": 1,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:12:22"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/mysql/{databaseId}

Delete Database

HTTP Request

DELETE /api/v1/servers/{serverId}/mysql/{databaseId}

MySQL Database Users

The /mysql-users endpoint is now deprecated in favour of the new /database-users endpoint.

Create User

Payload

{
    "name": "forge",
    "password": "dolores",
    "databases": [1]
}

Response

{
    "user": {
        "id": 2,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:19:01",
        "databases": [
            1
        ]
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/mysql-users

Parameters

Key Description
databases An array of database IDs referencing the databases the user has access to.

List Users

Response

{
    "users": [
        {
            "id": 2,
            "name": "forge",
            "status": "installing",
            "created_at": "2016-12-16 16:19:01",
            "databases": [
                1
            ]
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/mysql-users

Get User

Response

{
    "user": {
        "id": 2,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:19:01",
        "databases": [
            1
        ]
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/mysql-users/{userId}

Update User

Payload

{
    "databases": [2]
}

Response

{
    "user": {
        "id": 2,
        "name": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:19:01",
        "databases": [
            1
        ]
    }
}

HTTP Request

PUT /api/v1/servers/{serverId}/mysql-users/{userId}

This endpoint may be used to update the databases the MySQL user has access to.

Delete User

HTTP Request

DELETE /api/v1/servers/{serverId}/mysql-users/{userId}

Nginx Templates

Create Template

Payload

{
    "name": "My Nginx Template",
    "content": "server { listen {{ PORT }}; location = / { ... } }"
}

Response

{
    "template": {
        "id": 1,
        "server_id": 50,
        "name": "My Nginx Template",
        "content": "server { listen {{ PORT }}; location = / { ... } }"
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/nginx/templates

Variables

Nginx templates support multiple variables that will be replaced with real data when the site is being created. For more information on variables, see the Nginx templates documentation.

List Nginx Templates

Response

{
    "templates": [
        {
            "id": 1,
            "server_id": 50,
            "name": "My Nginx Template",
            "content": "server { listen {{ PORT }}; location = / { ... } }"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/nginx/templates/default

Get Default Nginx Template

When a site is created without a custom Nginx template selected, this is the Nginx configuration that Forge will use.

Response

{
    "template": {
        "server_id": 50,
        "name": "Forge Default",
        "content": "..."
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/nginx/templates/{templateId}

Get Nginx Template

Response

{
    "template": {
        "id": 1,
        "server_id": 50,
        "name": "My Nginx Template",
        "content": "server { listen {{ PORT }}; location = / { ... } }"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/nginx/templates/{templateId}

Update Nginx Template

Request

{
    "name": "My New Name",
    "content": "My new content"
}

Response

{
    "template": {
        "id": 1,
        "server_id": 50,
        "name": "My New Name",
        "content": "My new content"
    }
}

HTTP Request

PUT /api/v1/servers/{serverId}/nginx/templates/{templateId}

Delete Nginx Template

HTTP Request

DELETE /api/v1/servers/{serverId}/nginx/templates/{templateId}

Sites

Create Site

Payload

{
    "domain": "site.com",
    "project_type": "php",
    "aliases": ["alias1.com", "alias2.com"],
    "directory": "/test",
    "isolated": true,
    "username": "laravel",
    "database": "site-com-db",
    "php_version": "php81",
    "nginx_template": 1
}

Response

{
    "site": {
        "id": 2,
        "name": "site.com",
        "aliases": ["alias1.com", "alias2.com"],
        "directory": "/test",
        "wildcards": false,
        "isolated": true,
        "username": "forge",
        "status": "installing",
        "repository": null,
        "repository_provider": null,
        "repository_branch": null,
        "repository_status": null,
        "quick_deploy": false,
        "project_type": "php",
        "app": null,
        "php_version": "php81",
        "app_status": null,
        "slack_channel": null,
        "telegram_chat_id": null,
        "telegram_chat_title": null,
        "created_at": "2016-12-16 16:38:08",
        "deployment_url": "...",
        "tags": []
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/sites

Available site types

Key Description
php PHP / Laravel / Symfony
octane Laravel Octane
html Static HTML / Nuxt.js / Next.js
symfony Symfony <= 3.x
symfony_dev Symfony <= 3.x (Dev)

Nginx Templates

You may leave the nginx_template key off to use the default template, or supply nginx_template: "default".

List Sites

Response

{
    "sites": [
        {
            "id": 2,
            "name": "site.com",
            "username": "laravel",
            "directory": "/test",
            "wildcards": false,
            "status": "installing",
            "repository": null,
            "repository_provider": null,
            "repository_branch": null,
            "repository_status": null,
            "quick_deploy": false,
            "project_type": "php",
            "app": null,
            "php_version": "php81",
            "app_status": null,
            "slack_channel": null,
            "telegram_chat_id": null,
            "telegram_chat_title": null,
            "deployment_url": "...",
            "created_at": "2016-12-16 16:38:08",
            "tags": []
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/sites

Get Site

Response

{
    "site": {
        "id": 2,
        "name": "site.com",
        "aliases": ["alias1.com"],
        "username": "laravel",
        "directory": "/test",
        "wildcards": false,
        "status": "installing",
        "repository": null,
        "repository_provider": null,
        "repository_branch": null,
        "repository_status": null,
        "quick_deploy": false,
        "project_type": "php",
        "app": null,
        "php_version": "php81",
        "app_status": null,
        "slack_channel": null,
        "telegram_chat_id": null,
        "telegram_chat_title": null,
        "deployment_url": "...",
        "created_at": "2016-12-16 16:38:08",
        "tags": []
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}

Update Site

Payload

{
    "directory": "/some/path",
    "name": "site-new-name.com",
    "php_version": "php81",
    "aliases": ["alias1.com", "alias2.com"],
    "wildcards": true
}

Response

{
    "site": {
        "id": 2,
        "name": "site-new-name.com",
        "aliases": ["alias1.com", "alias2.com"],
        "username": "laravel",
        "directory": "/some/path",
        "wildcards": false,
        "status": "installing",
        "repository": null,
        "repository_provider": null,
        "repository_branch": null,
        "repository_status": null,
        "quick_deploy": false,
        "project_type": "php",
        "app": null,
        "app_status": null,
        "slack_channel": null,
        "telegram_chat_id": null,
        "telegram_chat_title": null,
        "deployment_url": "...",
        "created_at": "2016-12-16 16:38:08",
        "tags": []
    }
}

HTTP Request

PUT /api/v1/servers/{serverId}/sites/{siteId}

This endpoint is used to update the "web directory", primary name, aliases or whether to use wildcard sub-domains for a given site.

Change Site PHP Version

Payload

{
    "version": "php74"
}

HTTP Request

PUT /api/v1/servers/{serverId}/sites/{siteId}/php

Add Site Aliases

Payload

{
    "aliases": ["alias1.com", "alias2.com"]
}

Response

{
    "site": {
        "id": 2,
        "name": "site.com",
        "aliases": ["alias1.com", "alias2.com"],
        "username": "laravel",
        "directory": "/",
        "wildcards": false,
        "status": "installing",
        "repository": null,
        "repository_provider": null,
        "repository_branch": null,
        "repository_status": null,
        "quick_deploy": false,
        "project_type": "php",
        "app": null,
        "app_status": null,
        "slack_channel": null,
        "telegram_chat_id": null,
        "telegram_chat_title": null,
        "deployment_url": "...",
        "created_at": "2016-12-16 16:38:08",
        "tags": []
    }
}

HTTP Request

PUT /api/v1/servers/{serverId}/sites/{siteId}/aliases

Use this endpoint to add additional site aliases and keep the existing ones.

Delete Site

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}

Load Balancing

Response

{
  "nodes": [
    {
      "server_id": 2,
      "weight": 5,
      "down": false,
      "backup": false,
      "port": 80
    }, {
      "server_id": 3,
      "weight": 1,
      "down": false,
      "backup": true,
      "port": 80
    }, {
      "server_id": 4,
      "weight": 1,
      "down": true,
      "backup": false,
      "port": 80
    }
  ]
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/balancing

Update Load Balancing

Payload

{
    "servers": [{
        "id": 2,
        "weight": 5
    }, {
        "id": 3,
        "backup": true
    }, {
        "id": 4,
        "down": true
    }],
    "method": "least_conn"
}

HTTP Request

PUT /api/v1/servers/{serverId}/sites/{siteId}/balancing

If the server is a load balancer, this endpoint may be used to specify the servers the load balancer should send traffic to.

Load Balancing Methods

Key Description
round_robin Requests are evenly distributed across servers
least_conn Requests are sent to the server with the least number of active connections
ip_hash The server to which a request is sent is determined from the client IP address

Site Log

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/logs

Response

{
    "content": "[2020-08-18 10:32:56] local.INFO: Test  \n"
}

SSL Certificates

Create Certificate

Payload

{
    "type": "new",
    "domain": "domain.com",
    "country": "US",
    "state": "NY",
    "city": "New York",
    "organization": "Company Name",
    "department": "IT"
}

Response

{
    "certificate": {
        "domain": "domain.com",
        "request_status": "creating",
        "created_at": "2016-12-17 07:02:35",
        "id": 3,
        "existing": false,
        "active": false
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/certificates

Installing An Existing Certificate

Payload

{
    "type": "existing",
    "key": "PRIVATE_KEY_HERE",
    "certificate": "CERTIFICATE_HERE"
}

Response

{
    "certificate": {
        "domain": "domain.com",
        "request_status": "creating",
        "created_at": "2016-12-17 07:02:35",
        "id": 3,
        "existing": false,
        "active": false
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/certificates

Cloning An Existing Certificate

Payload

{
    "type": "clone",
    "certificate_id": 1
}

Response

{
    "certificate": {
        "domain": "domain.com",
        "request_status": "creating",
        "created_at": "2016-12-17 07:02:35",
        "id": 3,
        "existing": false,
        "active": false
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/certificates

Obtain A LetsEncrypt Certificate

The dns_provider object is only required for wildcard sub-domains.

Payload

{
    "domains": ["www.site.com"],
    "dns_provider": {
        "type": "xxx",
        "cloudflare_api_token": "xxx",
        "route53_key": "xxx",
        "route53_secret": "xxx",
        "digitalocean_token": "xxx",
        "dnssimple_token": "xxx",
        "linode_token": "xxx",
        "ovh_endpoint": "xxx",
        "ovh_app_key": "xxx",
        "ovh_app_secret": "xxx",
        "ovh_consumer_key": "xxx",
        "google_credentials_file": "xxx",
    }
}

Response

{
    "certificate": {
        "domain": "www.test.com",
        "type": "letsencrypt",
        "request_status": "created",
        "status": "installing",
        "created_at": "2017-02-09 17:14:34",
        "id": 1,
        "existing": true,
        "active": false
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/certificates/letsencrypt

DNS Provider Types

Type Extra Fields
cloudflare cloudflare_api_token.
route53 route53_key and route53_secret
digitalocean digitalocean_token
dnssimple dnssimple_token
linode linode_token
ovh ovh_endpoint, ovh_app_key, ovh_app_secret and ovh_consumer_key
google google_credentials_file

List Certificates

Response

{
    "certificates": [
        {
            "domain": "domain.com",
            "request_status": "creating",
            "created_at": "2016-12-17 07:02:35",
            "id": 3,
            "existing": false,
            "active": false
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/certificates

Get Certificate

Response

{
    "certificate": {
        "domain": "domain.com",
        "request_status": "creating",
        "created_at": "2016-12-17 07:02:35",
        "id": 3,
        "existing": false,
        "active": false
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/certificates/{id}

Get Signing Request

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/certificates/{id}/csr

This endpoint may be used to get the full certificate signing request content.

Install Certificate

Payload

{
    "certificate": "certificate content",
    "add_intermediates": false
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/certificates/{id}/install

Activate Certificate

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/certificates/{id}/activate

Delete Certificate

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/certificates/{id}

SSH Keys

Create Key

Payload

{
    "name": "test-key",
    "key": "KEY_CONTENT_HERE",
    "username": "forge"
}

Response

{
    "key": {
        "id": 9,
        "name": "test-key",
        "username": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:31:16"
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/keys

List Keys

Response

{
    "keys": [
        {
            "id": 9,
            "name": "test-key",
            "username": "forge",
            "status": "installing",
            "created_at": "2016-12-16 16:31:16"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/keys

Get Key

Response

{
    "key": {
        "id": 9,
        "name": "test-key",
        "username": "forge",
        "status": "installing",
        "created_at": "2016-12-16 16:31:16"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/keys/{keyId}

Delete Key

HTTP Request

DELETE /api/v1/servers/{serverId}/keys/{keyId}

Workers

Create Worker

You may pass php as the php_version value to use the server's default PHP CLI version.

Payload

{
    "connection": "sqs",
    "timeout": 90,
    "sleep": 60,
    "tries": null,
    "processes": 1,
    "stopwaitsecs": 600,
    "daemon": true,
    "force": false,
    "php_version": "php72",
    "queue": "hotfix"
}

Response

{
    "worker": {
        "id": 1,
        "connection": "rule",
        "command": "php7.2 /home/forge/default/artisan queue:work rule --sleep=60 --daemon --quiet --timeout=90",
        "queue": null,
        "timeout": 90,
        "sleep": 60,
        "tries": null,
        "processes": 1,
        "stopwaitsecs": 600,
        "environment": null,
        "php_version": "php72",
        "daemon": 1,
        "force": 0,
        "status": "installing",
        "created_at": "2016-12-17 07:15:03"
    }
}

Queue Options

The queue key can be left blank for the default queue.

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/workers

List Workers

Response

{
    "workers": [
        {
            "id": 1,
            "connection": "rule",
            "command": "php7.2 /home/forge/default/artisan queue:work rule --sleep=60 --daemon --quiet --timeout=90",
            "queue": null,
            "timeout": 90,
            "sleep": 60,
            "tries": null,
            "processes": 1,
            "stopwaitsecs": null,
            "environment": null,
            "php_version": "php72",
            "daemon": 1,
            "force": 0,
            "status": "installing",
            "created_at": "2016-12-17 07:15:03"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/workers

Get Worker

Response

{
    "worker": {
        "id": 1,
        "connection": "rule",
        "command": "php7.2 /home/forge/default/artisan queue:work rule --sleep=60 --daemon --quiet --timeout=90",
        "queue": null,
        "timeout": 90,
        "sleep": 60,
        "tries": null,
        "processes": 1,
        "stopwaitsecs": null,
        "environment": null,
        "php_version": "php72",
        "daemon": 1,
        "force": 0,
        "status": "installing",
        "created_at": "2016-12-17 07:15:03"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/workers/{id}

Delete Worker

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/workers/{id}

Restart Worker

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/workers/{id}/restart

Get Worker Output

Response

{
    "output": "The output of the worker will be returned here."
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId/}/workers/{workerId}/output

Redirect Rules

Create Rule

Payload

{
    "from": "/docs",
    "to": "/docs/1.1",
    "type": "redirect"
}

Response

{
    "redirect_rule": {
        "id": 15,
        "from": "/docs",
        "to": "/docs/1.1",
        "type": "redirect",
        "created_at": "2018-03-07 16:33:20"
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/redirect-rules

Type Description
redirect Creates a temporary 302 redirect
permanent Create a permanent 301 redirect

List Redirect Rules

Response

{
    "redirect_rules": [
        {
            "id": 15,
            "from": "/docs",
            "to": "/docs/1.1",
            "type": "redirect",
            "created_at": "2018-03-07 16:33:20"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/redirect-rules

Get Rule

Response

{
    "redirect_rule": {
        "id": 15,
        "from": "/docs",
        "to": "/docs/1.1",
        "type": "redirect",
        "created_at": "2018-03-07 16:33:20"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/redirect-rules/{id}

Delete Rule

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/redirect-rules/{id}

Security Rules

Create Security Rule

Payload

{
    "name": "Access Restricted",
    "path": null,
    "credentials": [
      {
        "username": "taylor.otwell",
        "password": "password123"
      }, {
        "username": "james.brooks",
        "password": "secret123"
      }
    ]
}

Response

{
    "security_rule": {
        "id": 15,
        "name": "Access Restricted",
        "path": null,
        "created_at": "2020-07-30 10:11:10",
        "credentials": [
          {
            "id": 20,
            "username": "taylor.otwell",
            "created_at": "2020-07-30 10:11:10"
          }, {
             "id": 21,
             "username": "james.brooks",
             "created_at": "2020-07-30 10:11:10"
          }
        ]
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/security-rules

You may leave path empty to protect all routes within your site.

List Security Rules

Response

{
    "security_rules": [
        {
             "id": 15,
             "name": "Access Restricted",
             "path": null,
             "created_at": "2020-07-30 10:11:10",
             "credentials": [
               {
                 "id": 20,
                 "username": "taylor.otwell",
                 "created_at": "2020-07-30 10:11:10"
               }, {
                  "id": 21,
                  "username": "james.brooks",
                  "created_at": "2020-07-30 10:11:10"
               }
             ]
         }
    ]
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/security-rules

Get Security Rule

Response

{
    "security_rule": {
        "id": 15,
        "name": "Access Restricted",
        "path": null,
        "created_at": "2020-07-30 10:11:10",
        "credentials": [
          {
            "id": 20,
            "username": "taylor.otwell",
            "created_at": "2020-07-30 10:11:10"
          }, {
             "id": 21,
             "username": "james.brooks",
             "created_at": "2020-07-30 10:11:10"
          }
        ]
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/security-rules/{id}

Delete Security Rule

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/security-rules/{id}

Deployment

Enable Quick Deployment

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/deployment

Disable Quick Deployment

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/deployment

Get Deployment Script

The response is a string for this request.

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/deployment/script

Update Deployment Script

Payload

{
    "content": "CONTENT_OF_THE_SCRIPT",
    "auto_source": false
}

HTTP Request

PUT /api/v1/servers/{serverId}/sites/{siteId}/deployment/script

Parameters

Key Description
content The contents of the deployment script. This field is required.
auto_source Whether to automatically source environment variables into the deployment script.

Deploy Now

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/deployment/deploy

Reset Deployment Status

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/deployment/reset

Get Deployment Log

The response is a string for this request.

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/deployment/log

Deployment History

List Deployments

Response

{
  "deployments": [
    {
      "id": 71,
      "server_id": 196,
      "site_id": 110,
      "type": 4,
      "commit_hash": "1aa50f0e4c49fed3a2335e866b03d4178ab93c4e",
      "commit_author": "Dries Vints",
      "commit_message": "Merge branch '8.x'\n\n# Conflicts:\n#\tCHANGELOG.md",
      "started_at": "2020-11-05 12:56:05",
      "ended_at": "2020-11-05 12:56:11",
      "status": "failed",
      "displayable_type": "Deployment API"
    }
  ]
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/deployment-history

Get Deployment

Response

{
  "deployment": {
      "id": 71,
      "server_id": 196,
      "site_id": 110,
      "type": 4,
      "commit_hash": "1aa50f0e4c49fed3a2335e866b03d4178ab93c4e",
      "commit_author": "Dries Vints",
      "commit_message": "Merge branch '8.x'\n\n# Conflicts:\n#\tCHANGELOG.md",
      "started_at": "2020-11-05 12:56:05",
      "ended_at": "2020-11-05 12:56:11",
      "status": "failed",
      "displayable_type": "Deployment API"
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/deployment-history/{deploymentId}

Get Deployment Output

Response

{
  "output": "Thu 05 Nov 2020 12:42:30 PM UTC\nFrom github.com:laravel\/laravel\n * branch              master     -> FETCH_HEAD\nAlready up to date.\nInstalling dependencies from lock file (including require-dev)\nVerifying lock file contents can be installed on current platform.\nNothing to install, update or remove\nGenerating optimized autoload files\n> Illuminate\\Foundation\\ComposerScripts::postAutoloadDump\n> @php artisan package:discover --ansi\nDiscovered Package: fideloper\/proxy\nDiscovered Package: fruitcake\/laravel-cors\nDiscovered Package: laravel\/tinker\nDiscovered Package: nesbot\/carbon\nDiscovered Package: nunomaduro\/collision\nPackage manifest generated successfully.\n73 packages you are using are looking for funding.\nUse the `composer fund` command to find out more!\nRestarting FPM...\n\n   Illuminate\\Database\\QueryException \n\n  SQLSTATE[HY000] [1049] Unknown database 'laravel' (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')\n\n  at vendor\/laravel\/framework\/src\/Illuminate\/Database\/Connection.php:671\n    667▕         \/\/ If an exception occurs when attempting to run a query, we'll format the error\n    668▕         \/\/ message to include the bindings with SQL, which will make this exception a\n    669▕         \/\/ lot more helpful to the developer instead of just the database's errors.\n    670▕         catch (Exception $e) {\n  ➜ 671▕             throw new QueryException(\n    672▕                 $query, $this->prepareBindings($bindings), $e\n    673▕             );\n    674▕         }\n    675▕\n\n      +33 vendor frames \n  34  artisan:37\n      Illuminate\\Foundation\\Console\\Kernel::handle()\n"
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/deployment-history/{deploymentId}/output

Configuration Files

Get Nginx Configuration

The response is a string for this request.

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/nginx

Update Nginx Configuration

Payload

{
    "content": "CONTENT"
}

HTTP Request

PUT /api/v1/servers/{serverId}/sites/{siteId}/nginx

Get .env File

The response is a string for this request.

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/env

Update .env File

Payload

{
    "content": "CONTENT"
}

HTTP Request

PUT /api/v1/servers/{serverId}/sites/{siteId}/env

Git Projects

Install New

Payload

{
    "provider": "github",
    "repository": "username/repository",
    "branch": "master",
    "composer": true
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/git

Parameters

Key Description
provider The repository provider. Valid values are github, gitlab, gitlab-custom, bitbucket, and custom.
composer Whether to install Composer dependencies. Valid values are true or false.

Update Repository

Payload

{
    "provider": "github",
    "repository": "username/repository",
    "branch": "master"
}

HTTP Request

PUT /api/v1/servers/{serverId}/sites/{siteId}/git

Remove Project

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/git

Create Deploy Key

Response

{
  "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDM9Uq4P4rrJCwFHqfvA5vJ6CfvlVZNpGeopmxXRKmN7yjyaMDXEBHSoOwftTsaqNE+Y1M12yctCUyyFpHxVHOhvqiT6XRsYVDSASMYm7rZWQjt\/zXJSdl80NvY\/2m5dSbLWfr9CoHcRROx3Ja213b8Qc9BOQfINbsT4OsGPrOlvpHyCFWDgu4wQvmVcmaGa2soJr92TaGTkJv6T73BjUXD8ZdfYmCkX5y3L2cXgUiNhcDTDm9G+tQebfdr77CRhGcOUi473MsSDuEPCV7RtDHSVA5\/SSSReZyOW3MocObl3LPyq18gmiX9kUO5bVCAev7Yf5QCB2SJFUl5StZ9Wn1yLtY+P02fFZNr+GrmqbAlhv2rTf8UqOBzal46j8oGYbBaRC4BvUKzmxjM7VbUVGO3+8DJIiJYSZoEr+9ptQbs+0YVo1lVah8O1TGm1uoh1LEV36d3GzHbeUjfN71Oqrq5929gt3Ppt\/phxSli7VAQgBIKYvhtWlVxeAz\/EekxMCYSmWT8ZtGOLWlFLQMNEFn5wP\/+CW5VxzQaQbvzsW4EEkBFH5BW0BRt99FQlbhJ7RZmRYD+v1r8Du8Er9I8WGj8f\/cP8PmxlfvVVPokrxvWr4E7GU5mNHIFQTz7hAq4DIxbaR96IEcd6INxa1wfoWgib+9YW77edyX1C1iF2bGGIw== [email protected]"
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/deploy-key

Delete Deploy Key

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/deploy-key

Site Commands

Execute Command

Payload

{
  "command": "ls -la"
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/commands

List Command History

Response

{
  "commands": [
    {
      "id": 68,
      "server_id": 34,
      "site_id": 48,
      "user_id": 1,
      "event_id": 730,
      "command": "ls -lah",
      "status": "finished",
      "created_at": "2021-04-16 14:46:55",
      "updated_at": "2021-04-16 14:47:00",
      "profile_photo_url": "https:\/\/unavatar.vercel.app\/james%40brooks.page?fallback=https%3A%2F%2Fui-avatars.com%2Fapi%3Fname%3DJames%2BBrooks%26color%3D7F9CF4%26background%3DEBF4FF",
      "user_name": "James Brooks"
    },
    {
      "id": 69,
      "server_id": 34,
      "site_id": 48,
      "user_id": 1,
      "event_id": 731,
      "command": "echo 'Hello!'",
      "status": "finished",
      "created_at": "2021-04-16 14:48:01",
      "updated_at": "2021-04-16 14:48:07",
      "profile_photo_url": "https:\/\/unavatar.vercel.app\/james%40brooks.page?fallback=https%3A%2F%2Fui-avatars.com%2Fapi%3Fname%3DJames%2BBrooks%26color%3D7F9CF4%26background%3DEBF4FF",
      "user_name": "James Brooks"
    }
  ]
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/commands

Get Command

Response

{
  "command": {
      "id": 69,
      "server_id": 34,
      "site_id": 48,
      "user_id": 1,
      "event_id": 731,
      "command": "echo 'Hello!'",
      "status": "finished",
      "created_at": "2021-04-16 14:48:01",
      "updated_at": "2021-04-16 14:48:07",
      "profile_photo_url": "https:\/\/unavatar.vercel.app\/james%40brooks.page?fallback=https%3A%2F%2Fui-avatars.com%2Fapi%3Fname%3DJames%2BBrooks%26color%3D7F9CF4%26background%3DEBF4FF",
      "user_name": "James Brooks"
  },
  "output": "Hello!"
}

HTTP Request

GET /api/v1/servers/{serverId}/sites/{siteId}/commands/{commandId}

WordPress

Install

Payload

{
    "database": "forge",
    "user": 1
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/wordpress

Uninstall WordPress

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/wordpress

This endpoint will uninstall WordPress and revert the site back to a default state.

phpMyAdmin

Install

Payload

{
    "database": "forge",
    "user": 1
}

HTTP Request

POST /api/v1/servers/{serverId}/sites/{siteId}/phpmyadmin

Uninstall phpMyAdmin

HTTP Request

DELETE /api/v1/servers/{serverId}/sites/{siteId}/phpmyadmin

This endpoint will uninstall phpMyAdmin and revert the site back to a default state.

Webhooks

List

Response

{
    "webhooks": [
        {
            "id": 10,
            "url": "http://domain.com",
            "created_at": "2018-10-10 17:01:18"
        }
    ]
}

HTTP Request

GET /api/v1/servers/{server_id}/sites/{site_id}/webhooks

Show

Response

{
    "webhook": {
        "id": 10,
        "url": "http://domain.com",
        "created_at": "2018-10-10 17:01:18"
    }
}

HTTP Request

GET /api/v1/servers/{server_id}/sites/{site_id}/webhooks/{id}

Create

Response

{
    "url": "http://domain.com"
}

HTTP Request

POST /api/v1/servers/{server_id}/sites/{site_id}/webhooks

Delete

Response

{
    "url": "http://domain.com"
}

HTTP Request

DELETE /api/v1/servers/{server_id}/sites/{site_id}/webhooks/{id}

Recipes

Create Recipe

Payload

{
    "name": "Recipe Name",
    "user": "root",
    "script": "SCRIPT_CONTENT"
}

Response

{
    "recipe": {
        "id": 1,
        "name": "Recipe Name",
        "user": "root",
        "script": "SCRIPT_CONTENT",
        "created_at": "2016-12-16 16:24:05"
    }
}

HTTP Request

POST /api/v1/recipes

List Recipes

Response

{
    "recipes": [
        {
            "id": 1,
            "name": "Recipe Name",
            "user": "root",
            "script": "SCRIPT_CONTENT",
            "created_at": "2016-12-16 16:24:05"
        }
    ]
}

HTTP Request

GET /api/v1/recipes

Get Recipe

Response

{
    "recipe": {
        "id": 1,
        "name": "Recipe Name",
        "user": "root",
        "script": "SCRIPT_CONTENT",
        "created_at": "2016-12-16 16:24:05"
    }
}

HTTP Request

GET /api/v1/recipes/{recipeId}

Update Recipe

Payload

{
    "name": "Recipe Name",
    "user": "root",
    "script": "SCRIPT_CONTENT"
}

Response

{
    "recipe": {
        "id": 1,
        "name": "Recipe Name",
        "user": "root",
        "script": "SCRIPT_CONTENT",
        "created_at": "2016-12-16 16:24:05"
    }
}

HTTP Request

PUT /api/v1/recipes/{recipeId}

Delete Recipe

HTTP Request

DELETE /api/v1/recipes/{recipeId}

Run Recipe

Payload

{
    "servers": [1,2],
    "notify": true
}

HTTP Request

POST /api/v1/recipes/{recipeId}/run

Regions

List

Response

{
  "regions": {
    "ocean2": [
      {
        "id": "ams2",
        "name": "Amsterdam 2",
        "sizes": [
          {
            "id": "01",
            "size": "s-1vcpu-1gb",
            "name": "1GB RAM - 1 CPU Core - 25GB SSD"
          }
        ]
      }
    ],
    "linode": [],
    "vultr": [],
    "aws": []
  }
}

HTTP Request

GET /api/v1/regions

Credentials

List

Response

{
  "credentials": [
    {
      "id": 1,
      "type": "ocean2",
      "name": "Personal"
    }
  ]
}

HTTP Request

GET /api/v1/credentials

Backups

List Backup Configurations

HTTP Request

GET /api/v1/servers/{serverId}/backup-configs

Response

{
    "backups": [
        {
            "id": 10,
            "day_of_week": null,
            "time": null,
            "provider" : "spaces",
            "provider_name": "DigitalOcean Spaces",
            "status": "installed",
            "databases": [{
                "id": 100,
                "name": "forge",
                "status": "installed",
                "created_at": "2020-01-01 10:00:00"
            }],
            "backups": [
                {
                    "id": 144,
                    "backup_id": 10,
                    "status": "success",
                    "restore_status": null,
                    "archive_path": "s3://backup-configs/server/db/backup-10-20200101123601.tar.gz",
                    "duration": 4,
                    "date": "1st Jan 12:36 PM"
                }
            ],
            "last_backup_time": "3 days ago"
        }
    ]
}

Create Backup Configuration

Payload

{
    "provider": "spaces",
    "credentials": {
        "endpoint": "https://my-endpoint.com",
        "region": "region-key",
        "bucket": "bucket-name",
        "access_key": "",
        "secret_key": ""
    },
    "frequency": {
        "type": "weekly",
        "time": "12:30",
        "day": 1
    },
    "directory": "backups/server/db",
    "email": "[email protected]",
    "retention": 7,
    "databases": [
        24
    ]
}

Response

{
    "backup": {
        "id": 10,
        "day_of_week": null,
        "time": null,
        "provider" : "spaces",
        "provider_name": "DigitalOcean Spaces",
        "status": "installing",
        "databases": [
            {
                "id": 24,
                "name": "forge",
                "status": "installed",
                "created_at": "2020-01-13 15:47:33"
            }
        ],
        "backups": [],
        "last_backup_time": null
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/backup-configs

Available providers

Key Description
s3 Amazon S3
spaces DigitalOcean Spaces
custom Custom (S3 Compatible, e.g. MinIO)

When supplying a custom provider, you must also provide an endpoint.

Frequency options

Update Backup Configuration

Payload

{
    "provider": "spaces",
    "credentials": {
        "endpoint": "https://my-endpoint.com",
        "region": "region-key",
        "bucket": "bucket-name",
        "access_key": "",
        "secret_key": ""
    },
    "frequency": {
        "type": "weekly",
        "time": "12:30",
        "day": 1
    },
    "directory": "backups/server/db",
    "email": "[email protected]",
    "retention": 7,
    "databases": [
      24,
      25
    ]
}

Response

{
    "backup": {
        "id": 10,
        "day_of_week": null,
        "time": null,
        "provider" : "spaces",
        "provider_name": "DigitalOcean Spaces",
        "status": "updating",
        "databases": [
            {
                "id": 24,
                "name": "forge",
                "status": "installed",
                "created_at": "2020-01-13 15:47:33"
            }
        ],
        "backups": [],
        "last_backup_time": null
    }
}

The payload and options are the same for updating as they are for creating.

Get Backup Configuration

Response

{
    "backup": {
        "id": 10,
        "day_of_week": null,
        "time": null,
        "provider" : "spaces",
        "provider_name": "DigitalOcean Spaces",
        "status": "installed",
        "databases": [
            {
                "id": 24,
                "name": "forge",
                "status": "installed",
                "created_at": "2020-01-13 15:47:33"
            }
        ],
        "backups": [],
        "last_backup_time": null
    }
}

HTTP Request

GET /api/v1/servers/{serverId}/backup-configs/{backupConfigurationId}

Run Backup Configuration

Manually run a backup configuration.

HTTP Request

POST /api/v1/servers/{serverId}/backup-configs/{backupConfigurationId}

Delete Backup Configuration

HTTP Request

DELETE /api/v1/servers/{serverId}/backup-configs/{backupConfigurationId}

Restore Backup

Payload

{
  "database": 7
}

If no database value is provided, Forge will restore the first database available.

HTTP Request

POST /api/v1/servers/{serverId}/backup-configs/{backupConfigurationId}/backups/{backupId}

Delete Backup

HTTP Request

DELETE /api/v1/servers/{serverId}/backup-configs/{backupConfigurationId}/backups/{backupId}

Monitoring

List Monitors

HTTP Request

GET /api/v1/servers/{serverId}/monitors

Response

{
    "monitors": [
        {
            "id": 3,
            "status": "installed",
            "type": "free_memory",
            "operator": "lte",
            "threshold": 70,
            "minutes": 5,
            "state": "ALERT",
            "state_changed_at": "2020-03-01 12:45:00"
        },
        {
            "id": 7,
            "status": "installed",
            "type": "disk",
            "operator": "lte",
            "threshold": 25,
            "minutes": 0,
            "state": "OK",
            "state_changed_at": "2020-03-01 12:45:00"
        }
    ]
}

Create Monitor

Payload

{
    "type": "cpu_load",
    "operator": "gte",
    "threshold": "1.3",
    "minutes": "5",
    "notify": "[email protected]"
}

Response

{
    "monitor": {
        "id": 8,
        "status": "installed",
        "type": "disk",
        "operator": "lte",
        "threshold": 25,
        "minutes": 0,
        "state": "OK",
        "state_changed_at": "2020-03-01 12:45:00"
    }
}

HTTP Request

POST /api/v1/servers/{serverId}/monitors

Available Monitors

Monitors work on a % value.

Key Description
disk The used disk space
used_memory The amount of used memory
cpu_load The CPU load

Operators

Get Monitor

HTTP Request

GET /api/v1/servers/{serverId}/monitors/{monitorId}

Response

{
    "monitor": {
        "id": 3,
        "status": "installed",
        "type": "free_memory",
        "operator": "lte",
        "threshold": 70,
        "minutes": 5,
        "state": "ALERT",
        "state_changed_at": "2020-03-01 12:45:00"
    }
}

Delete Monitor

HTTP Request

DELETE /api/v1/servers/{serverId}/monitors/{monitorId}

Server Logs

Get Log

HTTP Request

GET /api/v1/servers/{serverId}/logs

Response

{
      "path": "\/var\/log\/mysql\/error.log",
      "content": "2020-08-18T10:22:01.238990Z 0 [System] [MY-010931] [Server] \/usr\/sbin\/mysqld: ready for connections. Version: '8.0.21'  socket: '\/var\/run\/mysqld\/mysqld.sock'  port: 3306  MySQL Community Server - GPL.\n2020-08-18T10:22:01.359309Z 0 [System] [MY-013172] [Server] Received SHUTDOWN from user <via user signal>. Shutting down mysqld (Version: 8.0.21).\n2020-08-18T10:22:03.644177Z 0 [System] [MY-010910] [Server] \/usr\/sbin\/mysqld: Shutdown complete (mysqld 8.0.21)  MySQL Community Server - GPL.\n2020-08-18T10:22:04.183385Z 0 [System] [MY-010116] [Server] \/usr\/sbin\/mysqld (mysqld 8.0.21) starting as process 42752\n2020-08-18T10:22:04.193962Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.\n2020-08-18T10:22:04.530305Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.\n2020-08-18T10:22:04.662877Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: \/var\/run\/mysqld\/mysqlx.sock\n2020-08-18T10:22:04.749019Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.\n2020-08-18T10:22:04.749453Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.\n2020-08-18T10:22:04.775994Z 0 [System] [MY-010931] [Server] \/usr\/sbin\/mysqld: ready for connections. Version: '8.0.21'  socket: '\/var\/run\/mysqld\/mysqld.sock'  port: 3306  MySQL Community Server - GPL.\n"
}

File Types

You must specify one of the below file types: