All Collections API Hatchbox API Endpoints

Hatchbox API Endpoints

Updated

Hatchbox API

The Hatchbox API lets you deploy apps, manage environment variables, domains, and processes from your own scripts and tooling.

Authentication

All requests require an API token, sent as a Bearer token:

Authorization: Bearer [TOKEN]

You can find your API token in your Hatchbox account under API Tokens.

Requests with a missing or invalid token return 401 Unauthorized with an empty body.

Base URL

https://app.hatchbox.io/api/v1

All responses are JSON.

Finding your app ID

Most endpoints are scoped to an app and need its numeric ID. Use List apps to find it.

Errors

Status

Meaning

Body

401 Unauthorized

Missing or invalid token

(empty)

404 Not Found

The record doesn't exist, or your token can't access it

{"error": "App not found"}

422 Unprocessable Content

Validation failed

{"errors": ["..."]}

Resources belonging to accounts you're not a member of return 404, not 403.


Apps

List apps

Returns every app across the accounts your token's user belongs to, sorted by name.

GET /api/v1/apps
curl https://app.hatchbox.io/api/v1/apps \
-H "Authorization: Bearer [TOKEN]"
[
{
"id": 1,
"name": "my-app",
"repository": "myuser/my-app",
"branch": "main",
"last_deploy_at": "2026-07-14T18:22:10.000Z",
"last_deploy_sha": "abc1234def5678"
}
]

Get an app

GET /api/v1/apps/[APP_ID]
curl https://app.hatchbox.io/api/v1/apps/[APP_ID] \
-H "Authorization: Bearer [TOKEN]"
{
"id": 1,
"name": "my-app",
"repository": "myuser/my-app",
"branch": "main",
"last_deploy_at": "2026-07-14T18:22:10.000Z",
"last_deploy_sha": "abc1234def5678"
}

Deploy an app

Queues a deploy of your app's configured branch.

POST /api/v1/apps/[APP_ID]/deploy

Parameter

Required

Description

sha

No

Deploy a specific commit. Defaults to the latest commit on the app's branch.

curl -X POST https://app.hatchbox.io/api/v1/apps/[APP_ID]/deploy \
-H "Authorization: Bearer [TOKEN]"
{ "id": 4212 }

The returned id is the ID of the log entry created for this deploy.

Deploys are queued and run in the background, so a successful response means the deploy was accepted, not that it finished.

If the app has no active servers to deploy to:

{ "error": "No active servers available to deploy to" }

Restart an app

Restarts all of the app's processes.

POST /api/v1/apps/[APP_ID]/restart
curl -X POST https://app.hatchbox.io/api/v1/apps/[APP_ID]/restart \
-H "Authorization: Bearer [TOKEN]"
{ "id": 4213 }

The returned id is the ID of the log entry created for this restart.


Environment variables

Environment variable names are normalized to uppercase and may only contain letters, numbers, and underscores.

Changing environment variables triggers an update on your servers.

Create environment variables

Adds new environment variables. This is all-or-nothing: if any variable is invalid, none are created.

To change a variable that already exists, use Add or update instead — creating a duplicate name returns 422.

POST /api/v1/apps/[APP_ID]/env_vars
curl -X POST https://app.hatchbox.io/api/v1/apps/[APP_ID]/env_vars \
-H "Authorization: Bearer [TOKEN]" \
-H "Content-Type: application/json" \
-d '{"env_vars": [{"name": "FOO", "value": "bar"}, {"name": "BAZ", "value": "qux"}]}'
[
{ "id": 91, "name": "FOO" },
{ "id": 92, "name": "BAZ" }
]

Values are never returned by the API.

Add or update environment variables

Updates variables that already exist (matched by name) and creates any that don't. Include "_destroy": "1" to remove a variable in the same request.

PUT /api/v1/apps/[APP_ID]/env_vars
curl -X PUT https://app.hatchbox.io/api/v1/apps/[APP_ID]/env_vars \
-H "Authorization: Bearer [TOKEN]" \
-H "Content-Type: application/json" \
-d '{"env_vars": [{"name": "FOO", "value": "new-value"}, {"name": "BAZ", "_destroy": "1"}]}'

Returns 200 OK with an empty body.

Remove environment variables

DELETE /api/v1/apps/[APP_ID]/env_vars
curl -X DELETE https://app.hatchbox.io/api/v1/apps/[APP_ID]/env_vars \
-H "Authorization: Bearer [TOKEN]" \
-H "Content-Type: application/json" \
-d '{"env_vars": ["FOO", "BAZ"]}'

Returns 200 OK with an empty body.


Domains

Domains are identified by their name, not an ID — for example /domains/example.com.

Wildcard domains are supported using the format *.example.com.

List domains

GET /api/v1/apps/[APP_ID]/domains
curl https://app.hatchbox.io/api/v1/apps/[APP_ID]/domains \
-H "Authorization: Bearer [TOKEN]"
[
{
"id": 5,
"name": "example.com",
"created_at": "2026-07-14T18:22:10.000Z",
"updated_at": "2026-07-14T18:22:10.000Z"
}
]

Get a domain

GET /api/v1/apps/[APP_ID]/domains/[DOMAIN_NAME]
curl https://app.hatchbox.io/api/v1/apps/[APP_ID]/domains/example.com \
-H "Authorization: Bearer [TOKEN]"

Returns a single domain. If the domain isn't on this app:

{ "error": "Domain not found" }

Add a domain

POST /api/v1/apps/[APP_ID]/domains
curl -X POST https://app.hatchbox.io/api/v1/apps/[APP_ID]/domains \
-H "Authorization: Bearer [TOKEN]" \
-H "Content-Type: application/json" \
-d '{"domain": {"name": "example.com"}}'

Returns 201 Created with the new domain:

{
"id": 6,
"name": "example.com",
"created_at": "2026-07-14T18:22:10.000Z",
"updated_at": "2026-07-14T18:22:10.000Z"
}

A domain already connected to another app in the same cluster returns 422:

{ "errors": ["Name is already connected to another App in this Cluster"] }

Update a domain

Renames an existing domain.

PATCH /api/v1/apps/[APP_ID]/domains/[DOMAIN_NAME]
curl -X PATCH https://app.hatchbox.io/api/v1/apps/[APP_ID]/domains/example.com \
-H "Authorization: Bearer [TOKEN]" \
-H "Content-Type: application/json" \
-d '{"domain": {"name": "www.example.com"}}'

Returns 200 OK with the updated domain.

Remove a domain

DELETE /api/v1/apps/[APP_ID]/domains/[DOMAIN_NAME]
curl -X DELETE https://app.hatchbox.io/api/v1/apps/[APP_ID]/domains/example.com \
-H "Authorization: Bearer [TOKEN]"

Returns 200 OK with an empty body.


Processes

Processes are identified by their numeric ID. Use List processes to find the ID.

List processes

GET /api/v1/apps/[APP_ID]/processes
curl https://app.hatchbox.io/api/v1/apps/[APP_ID]/processes \
-H "Authorization: Bearer [TOKEN]"
[
{
"id": 15,
"name": "web",
"start_command": "bin/rails server",
"stop_command": "",
"reload_command": "",
"restart_on_deploy": true,
"server_id": 6,
"socket": false,
"systemd_type": "simple",
"active": true,
"roles": ["web"],
"created_at": "2026-07-02T17:08:01.887Z",
"updated_at": "2026-07-02T17:08:01.887Z"
}
]

Get a process

GET /api/v1/apps/[APP_ID]/processes/[PROCESS_ID]
curl https://app.hatchbox.io/api/v1/apps/[APP_ID]/processes/[PROCESS_ID] \
-H "Authorization: Bearer [TOKEN]"

Returns a single process. If the process isn't on this app:

{ "error": "Process not found" }

Restart a process

POST /api/v1/apps/[APP_ID]/processes/[PROCESS_ID]/restart
curl -X POST https://app.hatchbox.io/api/v1/apps/[APP_ID]/processes/[PROCESS_ID]/restart \
-H "Authorization: Bearer [TOKEN]"

Returns 200 OK with an empty body. Restarts are queued and run in the background.