Skip to content
LogoLogo

Templates

Templates let you build a custom container image from a Dockerfile and use it as the rootfs for any sandbox. You submit a Dockerfile, the system builds it asynchronously, and once the template reaches ready status you can reference it by name when creating sandboxes.

Get your API key from https://createos.sh/app/profile. Pass it as X-Api-Key: <token> on every request.

Base URL: https://api.sb.createos.sh


At a glance

  • Base URL: https://api.sb.createos.sh
  • Auth: X-Api-Key: <token> header. Get a token
  • Response envelope: JSend, {"status": "...", "data": ...}

Dockerfile restrictions

Submitted Dockerfiles must:

  • Be single-stage (exactly one FROM).
  • Use a FROM base that is in the operator allowlist (e.g. nodeops/sandbox:debian, nodeops/sandbox:alpine).
  • Not contain COPY or ADD instructions.
  • Not use ARG-substituted FROM (e.g. FROM ${BASE}).
  • Be at most 64 KiB.

Violations are rejected at submit time with a 400 response.

GET /v1/templates

List all templates owned by the caller.

Auth required: Yes

Query parameters

ParameterTypeDefaultDescription
limitinteger50Max items to return (maximum 500).
offsetinteger0Pagination offset.

Example

curl https://api.sb.createos.sh/v1/templates \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Success response 200

{
  "status": "success",
  "data": {
    "templates": [
      {
        "id": "tpl_01K…",
        "name": "my-python-env",
        "base": "nodeops/sandbox:debian",
        "status": "ready",
        "ext4_size_bytes": 536870912,
        "created_at": "2024-01-15T10:00:00Z",
        "built_at": "2024-01-15T10:01:30Z"
      }
    ]
  }
}

status values

ValueMeaning
pendingQueued, not yet picked up by a builder.
buildingBuild in progress.
readyBuild succeeded; usable as rootfs in sandbox create.
failedBuild failed; check logs.

POST /v1/templates

Submit a Dockerfile for async build. Returns immediately with the new template in pending status. Poll GET /v1/templates/{id} or stream GET /v1/templates/{id}/logs to follow progress.

Per-user concurrent build limit defaults to 2. Exceeding it returns 429.

Auth required: Yes

Request body

FieldTypeRequiredDescription
namestringYesFriendly alias used when spawning sandboxes (rootfs=<name> resolves to the latest ready template with this name). 1-63 chars, lowercase alphanumeric and dash.
dockerfilestringYesRaw Dockerfile contents. Max 64 KiB. Must pass Dockerfile restrictions above.

Example

curl -X POST https://api.sb.createos.sh/v1/templates \
  -H "X-Api-Key: $CREATEOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-python-env",
    "dockerfile": "FROM nodeops/sandbox:debian\nRUN apt-get update && apt-get install -y python3 python3-pip"
  }'

Success response 200

{
  "status": "success",
  "data": {
    "id": "tpl_01K…",
    "name": "my-python-env",
    "base": "nodeops/sandbox:debian",
    "status": "pending",
    "ext4_size_bytes": 0,
    "created_at": "2024-01-15T10:00:00Z",
    "built_at": null
  }
}

Notable errors:

StatusCause
400Invalid Dockerfile (multi-stage, disallowed base, COPY/ADD, ARG-substituted FROM, too large), or invalid name.
429Concurrent build limit exceeded.

GET /v1/templates/{id}

Get details for a single template. Resolves a friendly name to the latest ready template with that name.

Auth required: Yes

Path parameters

ParameterDescription
idtpl_<ulid> id or friendly name.

Query parameters

ParameterTypeDescription
includestringSet to dockerfile to include the original Dockerfile source in the response.

Example

curl "https://api.sb.createos.sh/v1/templates/my-python-env?include=dockerfile" \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Success response 200, same shape as the object in GET /v1/templates. When ?include=dockerfile is set, a dockerfile field is added to the data object containing the original Dockerfile source.

Notable errors: 404 template not found.

GET /v1/templates/{id}/logs

Stream the build log for a template as NDJSON. Each line is one JSON object.

Auth required: Yes

Path parameters

ParameterDescription
idtpl_<ulid> id.

Response format

The response body is a stream of newline-delimited JSON objects (Content-Type: application/x-ndjson). Each line has this shape:

{ "stream": "Step 1/3 : FROM nodeops/sandbox:debian\n" }

The stream field contains the raw build log output from the builder. The stream ends when the build completes (success or failure).

Example

curl https://api.sb.createos.sh/v1/templates/tpl_01K.../logs \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Example output

{"stream":"Step 1/3 : FROM nodeops/sandbox:debian\n"}
{"stream":" ---> a1b2c3d4e5f6\n"}
{"stream":"Step 2/3 : RUN apt-get update\n"}
{"stream":" ---> Running in f1e2d3c4b5a6\n"}
{"stream":"Step 3/3 : RUN apt-get install -y python3\n"}
{"stream":"Successfully built 9a8b7c6d5e4f\n"}

Notable errors: 404 template not found.

DELETE /v1/templates/{id}

Delete a template.

Auth required: Yes

Path parameters

ParameterDescription
idtpl_<ulid> id or friendly name.

Example

curl -X DELETE https://api.sb.createos.sh/v1/templates/tpl_01K... \
  -H "X-Api-Key: $CREATEOS_API_KEY"

Success response 200

{
  "status": "success",
  "data": {
    "id": "tpl_01K…",
    "status": "destroyed"
  }
}

Notable errors: 404 template not found.

Using a template

Once a template reaches ready status, pass its name as the rootfs field when creating a sandbox:

curl -X POST https://api.sb.createos.sh/v1/sandboxes \
  -H "X-Api-Key: $CREATEOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"shape": "s-1vcpu-1gb", "rootfs": "my-python-env"}'

The name resolves to the latest ready template with that name, so you can rebuild (re-submit with the same name) and new sandboxes automatically pick up the latest version.