FerryDocs
ReferenceAPI reference

Services

Web services, private services, background workers, static sites and cron jobs: CRUD, lifecycle actions (restart, suspend, resume, scale, rollback), status and runtime logs.

List services

GET/api/v1/services

Every service with its computed fields. The state of live services reflects their running instances (degraded when some are down), from counts refreshed at most every few seconds.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Response Body

application/json

application/json

application/json

curl -X GET "https://example.com/api/v1/services" \  -H "Authorization: Bearer $FERRY_TOKEN"
[  {    "auto_deploy": true,    "branch": "string",    "build_command": "string",    "cpu_limit": 0,    "created_at": "2019-08-24T14:15:22Z",    "custom_domains": [      "string"    ],    "deploy_hook_key": "string",    "disk_mount_path": "string",    "dockerfile_path": "string",    "health_check_path": "string",    "id": "string",    "image": "string",    "instances": 0,    "live_deploy_id": "string",    "memory_limit_mb": 0,    "name": "string",    "port": 0,    "publish_dir": "string",    "repo_url": "string",    "root_dir": "string",    "runtime": "auto",    "schedule": "string",    "start_command": "string",    "suspended": true,    "type": "web_service",    "updated_at": "2019-08-24T14:15:22Z",    "deploy_hook_path": "string",    "env_groups": [      "string"    ],    "hosts": [      "string"    ],    "internal_host": "string",    "internal_port": 0,    "latest_deploy": {      "commit_message": "string",      "commit_sha": "string",      "created_at": "2019-08-24T14:15:22Z",      "error": "string",      "finished_at": "2019-08-24T14:15:22Z",      "id": "string",      "image": "string",      "port": 0,      "service_id": "string",      "source": {        "branch": "string",        "commit": "string",        "kind": "git",        "repo_url": "string"      },      "started_at": "2019-08-24T14:15:22Z",      "status": "queued",      "trigger": "create"    },    "state": "not_deployed",    "url": "string"  }]

Create a service

POST/api/v1/services

Creates the service with its own variables and env group links, then queues a first deploy (trigger create) when it has a repository or an image, unless deploy is false. Services and datastores share one namespace of names. memory_limit_mb (MiB, 16 MiB to 1 TiB) and cpu_limit (CPUs, 0.01 to 512, rounded to 0.01) limit every instance and job run of the service; omitted or 0 = the server default (see GET /api/v1/info).

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

POST /api/v1/services

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/v1/services" \  -H "Authorization: Bearer $FERRY_TOKEN" \  -H "Content-Type: application/json" \  -d '{    "name": "string"  }'
{  "auto_deploy": true,  "branch": "string",  "build_command": "string",  "cpu_limit": 0,  "created_at": "2019-08-24T14:15:22Z",  "custom_domains": [    "string"  ],  "deploy_hook_key": "string",  "disk_mount_path": "string",  "dockerfile_path": "string",  "health_check_path": "string",  "id": "string",  "image": "string",  "instances": 0,  "live_deploy_id": "string",  "memory_limit_mb": 0,  "name": "string",  "port": 0,  "publish_dir": "string",  "repo_url": "string",  "root_dir": "string",  "runtime": "auto",  "schedule": "string",  "start_command": "string",  "suspended": true,  "type": "web_service",  "updated_at": "2019-08-24T14:15:22Z",  "deploy_hook_path": "string",  "env_groups": [    "string"  ],  "hosts": [    "string"  ],  "internal_host": "string",  "internal_port": 0,  "latest_deploy": {    "commit_message": "string",    "commit_sha": "string",    "created_at": "2019-08-24T14:15:22Z",    "error": "string",    "finished_at": "2019-08-24T14:15:22Z",    "id": "string",    "image": "string",    "port": 0,    "service_id": "string",    "source": {      "branch": "string",      "commit": "string",      "kind": "git",      "repo_url": "string"    },    "started_at": "2019-08-24T14:15:22Z",    "status": "queued",    "trigger": "create"  },  "state": "not_deployed",  "url": "string"}

Get a service

GET/api/v1/services/{id}

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Response Body

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/v1/services/string" \  -H "Authorization: Bearer $FERRY_TOKEN"
{  "auto_deploy": true,  "branch": "string",  "build_command": "string",  "cpu_limit": 0,  "created_at": "2019-08-24T14:15:22Z",  "custom_domains": [    "string"  ],  "deploy_hook_key": "string",  "disk_mount_path": "string",  "dockerfile_path": "string",  "health_check_path": "string",  "id": "string",  "image": "string",  "instances": 0,  "live_deploy_id": "string",  "memory_limit_mb": 0,  "name": "string",  "port": 0,  "publish_dir": "string",  "repo_url": "string",  "root_dir": "string",  "runtime": "auto",  "schedule": "string",  "start_command": "string",  "suspended": true,  "type": "web_service",  "updated_at": "2019-08-24T14:15:22Z",  "deploy_hook_path": "string",  "env_groups": [    "string"  ],  "hosts": [    "string"  ],  "internal_host": "string",  "internal_port": 0,  "latest_deploy": {    "commit_message": "string",    "commit_sha": "string",    "created_at": "2019-08-24T14:15:22Z",    "error": "string",    "finished_at": "2019-08-24T14:15:22Z",    "id": "string",    "image": "string",    "port": 0,    "service_id": "string",    "source": {      "branch": "string",      "commit": "string",      "kind": "git",      "repo_url": "string"    },    "started_at": "2019-08-24T14:15:22Z",    "status": "queued",    "trigger": "create"  },  "state": "not_deployed",  "url": "string"}

Update a service

PATCH/api/v1/services/{id}

Every field is optional; for optional string settings an empty string clears the value. instances scales, suspended suspends or resumes, custom_domains refreshes the routes; build settings take effect on the next deploy. Resource limits (memory_limit_mb, cpu_limit; 0 = back to the server default) are only saved: they take effect with the next deploy or restart, this request doesn't redeploy. Switching between a git repository and an image requires clearing the other source in the same request. When a side effect fails after the settings were saved, the error message says so.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

PATCH /api/v1/services/{id} — every field optional. For optional string settings, an empty string clears the value. Changing instances scales, suspended suspends/resumes, custom_domains refreshes routes; build settings and resource limits take effect on the next deploy.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X PATCH "https://example.com/api/v1/services/string" \  -H "Authorization: Bearer $FERRY_TOKEN" \  -H "Content-Type: application/json" \  -d '{}'
{  "auto_deploy": true,  "branch": "string",  "build_command": "string",  "cpu_limit": 0,  "created_at": "2019-08-24T14:15:22Z",  "custom_domains": [    "string"  ],  "deploy_hook_key": "string",  "disk_mount_path": "string",  "dockerfile_path": "string",  "health_check_path": "string",  "id": "string",  "image": "string",  "instances": 0,  "live_deploy_id": "string",  "memory_limit_mb": 0,  "name": "string",  "port": 0,  "publish_dir": "string",  "repo_url": "string",  "root_dir": "string",  "runtime": "auto",  "schedule": "string",  "start_command": "string",  "suspended": true,  "type": "web_service",  "updated_at": "2019-08-24T14:15:22Z",  "deploy_hook_path": "string",  "env_groups": [    "string"  ],  "hosts": [    "string"  ],  "internal_host": "string",  "internal_port": 0,  "latest_deploy": {    "commit_message": "string",    "commit_sha": "string",    "created_at": "2019-08-24T14:15:22Z",    "error": "string",    "finished_at": "2019-08-24T14:15:22Z",    "id": "string",    "image": "string",    "port": 0,    "service_id": "string",    "source": {      "branch": "string",      "commit": "string",      "kind": "git",      "repo_url": "string"    },    "started_at": "2019-08-24T14:15:22Z",    "status": "queued",    "trigger": "create"  },  "state": "not_deployed",  "url": "string"}

Delete a service

DELETE/api/v1/services/{id}

Removes its containers, routes, deploys and variables. Refused while other services reference it in their env (${{service.NAME...}}), unless force=true.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Query Parameters

force?boolean

Delete even though other services reference it (they will fail to deploy or restart).

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X DELETE "https://example.com/api/v1/services/string" \  -H "Authorization: Bearer $FERRY_TOKEN"
Empty

Restart a service

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

Rolls out the live deploy's image again (a new deploy with trigger restart), picking up changed variables.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/v1/services/string/restart" \  -H "Authorization: Bearer $FERRY_TOKEN"
{  "commit_message": "string",  "commit_sha": "string",  "created_at": "2019-08-24T14:15:22Z",  "error": "string",  "finished_at": "2019-08-24T14:15:22Z",  "id": "string",  "image": "string",  "port": 0,  "service_id": "string",  "source": {    "branch": "string",    "commit": "string",    "kind": "git",    "repo_url": "string"  },  "started_at": "2019-08-24T14:15:22Z",  "status": "queued",  "trigger": "create"}

Suspend a service

POST/api/v1/services/{id}/suspend

Stops its containers; settings, variables and deploys stay until it is resumed.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/v1/services/string/suspend" \  -H "Authorization: Bearer $FERRY_TOKEN"
{  "auto_deploy": true,  "branch": "string",  "build_command": "string",  "cpu_limit": 0,  "created_at": "2019-08-24T14:15:22Z",  "custom_domains": [    "string"  ],  "deploy_hook_key": "string",  "disk_mount_path": "string",  "dockerfile_path": "string",  "health_check_path": "string",  "id": "string",  "image": "string",  "instances": 0,  "live_deploy_id": "string",  "memory_limit_mb": 0,  "name": "string",  "port": 0,  "publish_dir": "string",  "repo_url": "string",  "root_dir": "string",  "runtime": "auto",  "schedule": "string",  "start_command": "string",  "suspended": true,  "type": "web_service",  "updated_at": "2019-08-24T14:15:22Z",  "deploy_hook_path": "string",  "env_groups": [    "string"  ],  "hosts": [    "string"  ],  "internal_host": "string",  "internal_port": 0,  "latest_deploy": {    "commit_message": "string",    "commit_sha": "string",    "created_at": "2019-08-24T14:15:22Z",    "error": "string",    "finished_at": "2019-08-24T14:15:22Z",    "id": "string",    "image": "string",    "port": 0,    "service_id": "string",    "source": {      "branch": "string",      "commit": "string",      "kind": "git",      "repo_url": "string"    },    "started_at": "2019-08-24T14:15:22Z",    "status": "queued",    "trigger": "create"  },  "state": "not_deployed",  "url": "string"}

Resume a service

POST/api/v1/services/{id}/resume

Starts the live deploy's containers again.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/v1/services/string/resume" \  -H "Authorization: Bearer $FERRY_TOKEN"
{  "auto_deploy": true,  "branch": "string",  "build_command": "string",  "cpu_limit": 0,  "created_at": "2019-08-24T14:15:22Z",  "custom_domains": [    "string"  ],  "deploy_hook_key": "string",  "disk_mount_path": "string",  "dockerfile_path": "string",  "health_check_path": "string",  "id": "string",  "image": "string",  "instances": 0,  "live_deploy_id": "string",  "memory_limit_mb": 0,  "name": "string",  "port": 0,  "publish_dir": "string",  "repo_url": "string",  "root_dir": "string",  "runtime": "auto",  "schedule": "string",  "start_command": "string",  "suspended": true,  "type": "web_service",  "updated_at": "2019-08-24T14:15:22Z",  "deploy_hook_path": "string",  "env_groups": [    "string"  ],  "hosts": [    "string"  ],  "internal_host": "string",  "internal_port": 0,  "latest_deploy": {    "commit_message": "string",    "commit_sha": "string",    "created_at": "2019-08-24T14:15:22Z",    "error": "string",    "finished_at": "2019-08-24T14:15:22Z",    "id": "string",    "image": "string",    "port": 0,    "service_id": "string",    "source": {      "branch": "string",      "commit": "string",      "kind": "git",      "repo_url": "string"    },    "started_at": "2019-08-24T14:15:22Z",    "status": "queued",    "trigger": "create"  },  "state": "not_deployed",  "url": "string"}

Scale a service

POST/api/v1/services/{id}/scale

Sets the number of instances. Cron jobs can't be scaled, and services with a disk run 1 instance.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

POST /api/v1/services/{id}/scale

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/v1/services/string/scale" \  -H "Authorization: Bearer $FERRY_TOKEN" \  -H "Content-Type: application/json" \  -d '{    "instances": 0  }'
{  "auto_deploy": true,  "branch": "string",  "build_command": "string",  "cpu_limit": 0,  "created_at": "2019-08-24T14:15:22Z",  "custom_domains": [    "string"  ],  "deploy_hook_key": "string",  "disk_mount_path": "string",  "dockerfile_path": "string",  "health_check_path": "string",  "id": "string",  "image": "string",  "instances": 0,  "live_deploy_id": "string",  "memory_limit_mb": 0,  "name": "string",  "port": 0,  "publish_dir": "string",  "repo_url": "string",  "root_dir": "string",  "runtime": "auto",  "schedule": "string",  "start_command": "string",  "suspended": true,  "type": "web_service",  "updated_at": "2019-08-24T14:15:22Z",  "deploy_hook_path": "string",  "env_groups": [    "string"  ],  "hosts": [    "string"  ],  "internal_host": "string",  "internal_port": 0,  "latest_deploy": {    "commit_message": "string",    "commit_sha": "string",    "created_at": "2019-08-24T14:15:22Z",    "error": "string",    "finished_at": "2019-08-24T14:15:22Z",    "id": "string",    "image": "string",    "port": 0,    "service_id": "string",    "source": {      "branch": "string",      "commit": "string",      "kind": "git",      "repo_url": "string"    },    "started_at": "2019-08-24T14:15:22Z",    "status": "queued",    "trigger": "create"  },  "state": "not_deployed",  "url": "string"}
POST/api/v1/services/{id}/rollback

Queues a deploy (trigger rollback) reusing the image of an earlier deploy of this service that went live.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

POST /api/v1/services/{id}/rollback

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/v1/services/string/rollback" \  -H "Authorization: Bearer $FERRY_TOKEN" \  -H "Content-Type: application/json" \  -d '{    "deploy_id": "string"  }'
{  "commit_message": "string",  "commit_sha": "string",  "created_at": "2019-08-24T14:15:22Z",  "error": "string",  "finished_at": "2019-08-24T14:15:22Z",  "id": "string",  "image": "string",  "port": 0,  "service_id": "string",  "source": {    "branch": "string",    "commit": "string",    "kind": "git",    "repo_url": "string"  },  "started_at": "2019-08-24T14:15:22Z",  "status": "queued",  "trigger": "create"}
POST/api/v1/services/{id}/deploy-hook/rotate

Replaces the secret of the service's deploy hook URL: the old URL stops working, the new one is the returned deploy_hook_path.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/v1/services/string/deploy-hook/rotate" \  -H "Authorization: Bearer $FERRY_TOKEN"
{  "auto_deploy": true,  "branch": "string",  "build_command": "string",  "cpu_limit": 0,  "created_at": "2019-08-24T14:15:22Z",  "custom_domains": [    "string"  ],  "deploy_hook_key": "string",  "disk_mount_path": "string",  "dockerfile_path": "string",  "health_check_path": "string",  "id": "string",  "image": "string",  "instances": 0,  "live_deploy_id": "string",  "memory_limit_mb": 0,  "name": "string",  "port": 0,  "publish_dir": "string",  "repo_url": "string",  "root_dir": "string",  "runtime": "auto",  "schedule": "string",  "start_command": "string",  "suspended": true,  "type": "web_service",  "updated_at": "2019-08-24T14:15:22Z",  "deploy_hook_path": "string",  "env_groups": [    "string"  ],  "hosts": [    "string"  ],  "internal_host": "string",  "internal_port": 0,  "latest_deploy": {    "commit_message": "string",    "commit_sha": "string",    "created_at": "2019-08-24T14:15:22Z",    "error": "string",    "finished_at": "2019-08-24T14:15:22Z",    "id": "string",    "image": "string",    "port": 0,    "service_id": "string",    "source": {      "branch": "string",      "commit": "string",      "kind": "git",      "repo_url": "string"    },    "started_at": "2019-08-24T14:15:22Z",    "status": "queued",    "trigger": "create"  },  "state": "not_deployed",  "url": "string"}

Runtime status

GET/api/v1/services/{id}/status

The live state of each container: Docker state, host port, restarts, CPU and memory.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Response Body

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/v1/services/string/status" \  -H "Authorization: Bearer $FERRY_TOKEN"
{  "desired_instances": 0,  "instances": [    {      "container_id": "string",      "cpu_limit": 0,      "cpu_percent": 0,      "deploy_id": "string",      "exit_code": 0,      "host_port": 0,      "memory_bytes": 0,      "memory_limit_bytes": 0,      "name": "string",      "oom_killed": true,      "restart_count": 0,      "started_at": "string",      "state": "string"    }  ],  "service_id": "string",  "state": "not_deployed"}

Runtime logs (SSE)

GET/api/v1/services/{id}/logs

The merged output of the service's current containers (instance names the container). Cron jobs have no long-running containers: their stream is a few system lines pointing at the job logs.

Authorization

AuthorizationBearer <token>

An API token: one created in the dashboard or by ferry login, or the server token stored in <data-dir>/api_token. GET requests may send it as ?access_token= instead.

In: header

Path Parameters

id*string

Service id or name.

Query Parameters

follow?boolean

Keep the stream open and send new lines as they are written.

tail?integer

Start with at most this many recent lines per container.

Range0 <= value

Response Body

text/event-stream

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/api/v1/services/string/logs" \  -H "Authorization: Bearer $FERRY_TOKEN"
"event: log\ndata: {\"ts\":\"2026-01-01T12:00:00Z\",\"stream\":\"system\",\"line\":\"==> Build succeeded\"}\n\nevent: end\ndata: \n\n"