Skip to main content
Create and build a new custom template with pre-installed packages and configurations. Templates allow you to pre-configure environments that boot in under 100ms using memory snapshots.

Endpoint

POST /v1/templates/build

Request

Headers

Authorization: Bearer your_api_key_here
Content-Type: application/json

Request Body

{
  "alias": "my-python-template",
  "cpu": 2,
  "memory": 2048,
  "diskGB": 10,
  "steps": [
    {
      "type": "from",
      "image": "ubuntu:22.04"
    },
    {
      "type": "apt",
      "packages": ["python3", "python3-pip", "curl"]
    },
    {
      "type": "run",
      "command": "pip3 install numpy pandas"
    }
  ]
}
Parameters:
ParameterTypeRequiredDefaultDescription
aliasstring✅ Yes-Template name (unique per organization)
cpuintegerNo2Number of vCPUs (1-64)
memoryintegerNo2048Memory in MB (128+)
diskGBintegerNo10Disk size in GB (1+)
stepsarray✅ Yes-Build steps (see below)
skipCachebooleanNofalseForce rebuild (ignore cache)

Steps Array

Each step is an object with a type field:

FROM Step (Base Image)

{
  "type": "from",
  "image": "ubuntu:22.04"
}
Supported base images:
  • ubuntu:22.04, ubuntu:20.04, ubuntu:18.04
  • debian:11, debian:10
  • alpine:3.18, alpine:3.17
  • python:3.11, python:3.10, python:3.9
  • node:18, node:20

APT Step (Install System Packages)

{
  "type": "apt",
  "packages": ["python3", "nodejs", "git", "build-essential"]
}

RUN Step (Execute Command)

{
  "type": "run",
  "command": "pip3 install flask numpy pandas"
}
Multi-line commands:
{
  "type": "run",
  "command": "apt-get update && apt-get install -y python3-dev"
}

COPY Step (Copy Files)

{
  "type": "copy",
  "src": ["file1.txt", "file2.txt"],
  "dest": "/workspace/"
}
Note: Files must be uploaded first using the Upload Template Files endpoint.

ENV Step (Environment Variables)

{
  "type": "env",
  "key": "PYTHONUNBUFFERED",
  "value": "1"
}

WORKDIR Step (Working Directory)

{
  "type": "workdir",
  "path": "/workspace"
}

Response

Status Code: 202 Accepted
{
  "build_id": "489",
  "template_id": "489",
  "status": "building",
  "logs_url": "/v1/templates/build/489/logs",
  "request_id": "req_abc123"
}
Response Fields:
FieldTypeDescription
build_idstringBuild job ID
template_idstringTemplate ID (same as build_id)
statusstringBuild status (building, active, failed)
logs_urlstringURL to stream build logs
request_idstringRequest ID for tracking

Examples

Python Data Science Template

  • cURL
  • Python
  • JavaScript
curl -X POST https://api.hopx.dev/v1/templates/build \
  -H "Authorization: Bearer hopx_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "alias": "python-datascience",
    "cpu": 4,
    "memory": 4096,
    "diskGB": 20,
    "steps": [
      {"type": "from", "image": "ubuntu:22.04"},
      {"type": "apt", "packages": ["python3", "python3-pip", "build-essential"]},
      {"type": "run", "command": "pip3 install numpy pandas matplotlib scikit-learn jupyter"}
    ]
  }'

Node.js Web App Template

{
  "alias": "nodejs-webapp",
  "cpu": 2,
  "memory": 2048,
  "diskGB": 10,
  "steps": [
    {"type": "from", "image": "node:20"},
    {"type": "run", "command": "npm install -g pm2 typescript ts-node"},
    {"type": "workdir", "path": "/workspace"},
    {"type": "env", "key": "NODE_ENV", "value": "production"}
  ]
}

Monitoring Build Progress

After initiating a build, monitor progress using:

Error Responses

400 Bad Request - Invalid request
{
  "error": "Invalid template definition",
  "message": "Template must start with a FROM step"
}
401 Unauthorized - Invalid API key
{
  "error": "Unauthorized",
  "message": "Invalid API key"
}
409 Conflict - Template alias already exists
{
  "error": "Template alias already exists",
  "message": "A template with alias 'my-template' already exists"
}

Rate Limits

Template building is rate-limited per organization:
  • 10 builds per hour (default)
  • 50 builds per day (default)
Check your limits using the Account Limits endpoint.

Next Steps