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 |
|---|---|---|
| Missing or invalid token | (empty) |
| The record doesn't exist, or your token can't access it |
|
| Validation failed |
|
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 |
|---|---|---|
| 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.