Skip to main content
Build a custom template from a Docker image. Define the base image, build steps, resources, and ready checks. The API will build and cache your template for creating sandboxes.

Endpoint

POST /v1/templates/build

Request

Headers

Authorization: Bearer $HOPX_API_KEY
Content-Type: application/json

Body Parameters

ParameterTypeRequiredDescription
namestringYesUnique template name
from_imagestringYesBase Docker image (e.g., ubuntu:22.04, python:3.11-slim)
cpuintegerYesNumber of vCPUs (min/max from your plan)
memoryintegerYesMemory in MB (min: 512, max: 64000)
diskGBintegerYesDisk size in GB (min: 1, max: 250)
stepsarrayNoBuild steps (RUN, COPY, ENV, WORKDIR, USER, CMD)
startCmdstringNoCommand to run on sandbox start
readyCmdobjectNoReady check configuration
skipCachebooleanNoSkip build cache (default: false)
registry_credentialsobjectNoPrivate registry authentication
updatebooleanNoUpdate existing template (default: false)
Alpine Linux is not supported. Use glibc-based images like ubuntu:*, debian:*, python:*-slim, node:*-slim.

Example Request

Build a Python template:
curl -X POST https://api.hopx.dev/v1/templates/build \
  -H "Authorization: Bearer $HOPX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-python-template",
    "from_image": "python:3.11-slim",
    "cpu": 2,
    "memory": 4096,
    "diskGB": 10,
    "steps": [
      {
        "type": "RUN",
        "args": ["pip install pandas numpy matplotlib"]
      },
      {
        "type": "WORKDIR",
        "args": ["/workspace"]
      },
      {
        "type": "ENV",
        "args": ["PYTHONUNBUFFERED=1"]
      }
    ]
  }'
Build a Node.js template:
curl -X POST https://api.hopx.dev/v1/templates/build \
  -H "Authorization: Bearer $HOPX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-nodejs-template",
    "from_image": "node:18-slim",
    "cpu": 1,
    "memory": 2048,
    "diskGB": 5,
    "steps": [
      {
        "type": "RUN",
        "args": ["npm install -g typescript ts-node"]
      },
      {
        "type": "WORKDIR",
        "args": ["/app"]
      }
    ]
  }'

Response

Success (202 Accepted)

{
  "build_id": "build_abc123",
  "template_id": "template_xyz789",
  "status": "building",
  "logs_url": "https://api.hopx.dev/v1/templates/build/build_abc123/logs",
  "request_id": "req_abc123"
}

Response Fields

FieldTypeDescription
build_idstringBuild ID (same as template_id)
template_idstringTemplate ID
statusstringBuild status (building, active, failed)
logs_urlstringURL to stream build logs
request_idstringRequest ID for debugging

Status Codes

CodeDescription
202Build triggered (accepted)
400Invalid request (Alpine, invalid resources, etc.)
401Authentication required
404Template not found (when update=true)
409Template exists (when update=false)
503Service unavailable (no available nodes)

Build Steps

Supported Step Types

TypeDescriptionExample
RUNRun a shell command{"type": "RUN", "args": ["apt-get update"]}
COPYCopy files (requires file upload){"type": "COPY", "args": ["/app"], "filesHash": "sha256..."}
ENVSet environment variable{"type": "ENV", "args": ["KEY=value"]}
WORKDIRSet working directory{"type": "WORKDIR", "args": ["/workspace"]}
USERSet user{"type": "USER", "args": ["1000"]}
CMDSet default command{"type": "CMD", "args": ["python", "app.py"]}

RUN Steps

{
  "type": "RUN",
  "args": ["pip install pandas numpy"]
}

ENV Steps

{
  "type": "ENV",
  "args": ["PYTHONUNBUFFERED=1", "DEBUG=true"]
}

WORKDIR Steps

{
  "type": "WORKDIR",
  "args": ["/workspace"]
}

Errors

Alpine Not Supported (400)

{
  "error": "Alpine Linux is not supported. Use glibc-based images like ubuntu, debian, python-slim, node-slim",
  "code": "INVALID_REQUEST",
  "request_id": "req_abc123"
}
Cause: The base image is Alpine Linux, which is not supported. Fix: Use a glibc-based image like ubuntu:22.04, python:3.11-slim, or node:18-slim.

Template Exists (409)

{
  "error": "Template already exists. Set update=true to update it.",
  "code": "CONFLICT",
  "request_id": "req_abc123"
}
Cause: A template with the same name already exists and update is false. Fix: Either:
  • Use a different template name
  • Set "update": true to update the existing template

Invalid Resources (400)

{
  "error": "Invalid memory: must be between 512 and 64000 MB",
  "code": "INVALID_REQUEST",
  "request_id": "req_abc123"
}
Cause: Resource values are outside allowed limits. Fix: Ensure:
  • cpu: 1-8 (depends on your plan)
  • memory: 512-64000 MB
  • diskGB: 1-250 GB

Monitor Build Progress

After triggering a build, monitor its progress:
# Get build status
curl https://api.hopx.dev/v1/templates/build/build_abc123/status \
  -H "Authorization: Bearer $HOPX_API_KEY"

# Stream build logs
curl https://api.hopx.dev/v1/templates/build/build_abc123/logs \
  -H "Authorization: Bearer $HOPX_API_KEY"

Use Cases

Create Data Science Template

curl -X POST https://api.hopx.dev/v1/templates/build \
  -H "Authorization: Bearer $HOPX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "data-science",
    "from_image": "python:3.11-slim",
    "cpu": 4,
    "memory": 8192,
    "diskGB": 20,
    "steps": [
      {
        "type": "RUN",
        "args": ["pip install pandas numpy matplotlib scikit-learn jupyter"]
      },
      {
        "type": "WORKDIR",
        "args": ["/workspace"]
      },
      {
        "type": "ENV",
        "args": ["PYTHONUNBUFFERED=1"]
      }
    ]
  }'

Update Existing Template

curl -X POST https://api.hopx.dev/v1/templates/build \
  -H "Authorization: Bearer $HOPX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-template",
    "from_image": "python:3.11-slim",
    "cpu": 2,
    "memory": 4096,
    "diskGB": 10,
    "update": true,
    "steps": [
      {
        "type": "RUN",
        "args": ["pip install --upgrade pandas"]
      }
    ]
  }'

Next Steps