BudgetHostAPI DOCUMENTATION
API v1OpenAPI
YOUR SERVICE SLICEREST / JSON

Room for your applications

Create applications and persistent storage within your allocation. One place to see what belongs together.

Start here with your SLICE_ID and SLICE_TOKEN. The overview shows the credentials file and shell setup. You do not need a service token yet.

A slice is your shared CPU, memory and storage allocation. It can contain several independent applications. Deploying one application does not deploy its neighbours. All persistent volumes count towards combined storage usage, including WordPress files and its database. BudgetHost creates the initial slice and manages its limits.

Inspect your slice#

Run the initial credentials and shell setup first. Continue in the same shell, using SLICE_BASE, STATE, slice_api and uuid.

slice_api "$SLICE_BASE" > "$STATE/slice.json"
jq .data "$STATE/slice.json"

Inspect existing applications and storage before creating anything. If your application already exists, set SERVICE_ID to its ID from the inventory and skip the creation request. Then continue to get a service token. Do not create a second application or database volume for an existing deployment.

Create an application#

For an empty slice or a new application, keep the request body, key and returned operation ID. Retry with the same key and body after a lost response.

uuid > "$STATE/application.key"
printf '%s\n' '{"type":"application","display_name":"My App"}' > "$STATE/application-request.json"
slice_api -H 'Content-Type: application/json' \
  -H "X-Idempotency-Key: $(cat "$STATE/application.key")" \
  --data-binary @"$STATE/application-request.json" "$SLICE_BASE/services" \
  > "$STATE/application.json"
SERVICE_ID=$(jq -er '.data.service_id' "$STATE/application.json")

Get a service token#

Use your slice token to issue a narrower token for the selected application:

slice_api -X POST "$SLICE_BASE/services/$SERVICE_ID/deployment-tokens" \
  > "$STATE/service-token.json"
SERVICE_TOKEN=$(jq -er '.data.token' "$STATE/service-token.json")
jq '.data | del(.token)' "$STATE/service-token.json"

Store the token securely, along with its returned expiry date. This issuance endpoint is not idempotent: repeating it issues another token. If its response is lost, open your application's API tokens in my.budgethost to revoke the inaccessible token before issuing a replacement. You can also create, renew and revoke service tokens in my.budgethost without using this endpoint.

Save the returned credentials in a private directory outside your source tree. This does not print the token or put it in the application source tree:

SERVICE_ENV="$HOME/.config/budgethost/$SERVICE_ID.env"
mkdir -p "$(dirname "$SERVICE_ENV")"
printf 'SERVICE_ID=%q\nSERVICE_TOKEN=%q\n' \
  "$SERVICE_ID" "$SERVICE_TOKEN" > "$SERVICE_ENV"
chmod 600 "$SERVICE_ENV"

Continue with application configuration and deployment in the same shell. Keep SERVICE_ENV for future releases; those releases use the service token and do not need to create the application or issue another token.

Storage#

Create storage and attach it to a member in the same request:

uuid > "$STATE/storage.key"
jq -n --arg service "$SERVICE_ID" \
  '{name:"data",service_id:$service,mount_path:"/data"}' > "$STATE/storage-request.json"
slice_api -H 'Content-Type: application/json' \
  -H "X-Idempotency-Key: $(cat "$STATE/storage.key")" \
  --data-binary @"$STATE/storage-request.json" "$SLICE_BASE/storage" \
  > "$STATE/storage.json"

Alternatively, POST /storage with {"name":"archive"} creates unattached storage. POST /storage/attach accepts storage_id, service_id, and mount_path to attach slice-owned storage to a member. It also requires an idempotency key. Inspect slice inventory first; do not assume that failed requests created nothing. A service token can create storage only for its own service using its /storage endpoint.

Storage attachment changes desired configuration. Deploy/apply the affected application to use the new mount. Do not put databases or customer files solely in the container's writable layer; replacing the container does not preserve it.

Operations and WordPress#

If you created an application in this session, inspect its returned operation ID:

OPERATION_ID=$(jq -er '.data.operation_id' "$STATE/application.json")
slice_api "$SLICE_BASE/operations/$OPERATION_ID" | jq .data

SLICE_OPERATION_INCOMPLETE means provisioning was interrupted. Inspect the operation and slice inventory, then open the application in my.budgethost to review its progress and failure details. Contact support if reconciliation is needed; do not retry with a new key to bypass the incomplete operation.

To provision WordPress, send {"type":"wordpress","display_name":"My Site"} to POST /services with a new key. This creates a bundle and its file/database storage. Deploy the returned main service with POST /services/{serviceId}/apply and another idempotency key. The 202 response and a succeeded provisioning operation mean runtime work was queued, not that the website passed health checks. Follow the application in my.budgethost to see deployment progress, health and any failure details. Confirm it is healthy before treating the release as complete. Source/image applications use deployment polling described in the application guide.