Documentation Index
Fetch the complete documentation index at: https://docs.superserve.ai/llms.txt
Use this file to discover all available pages before exploring further.
The Template class creates and manages reusable sandbox base images. Templates are built once and then used to launch any number of identically configured sandboxes in seconds.
See the Templates overview for concepts, or jump to the Create a template guide for the end-to-end flow.
Import
import { Template } from "@superserve/sdk"
Factory methods
Template.create
Register a new template and queue its first build. Returns as soon as the template row exists and a build_id is assigned - the build itself runs asynchronously. Call waitUntilReady to block until the build finishes.
const template = await Template.create({
name: "my-python-env",
vcpu: 2,
memoryMib: 2048,
diskMib: 4096,
from: "python:3.11",
steps: [
{ run: "pip install numpy pandas" },
{ env: { key: "DEBUG", value: "1" } },
{ workdir: "/app" },
{ user: { name: "appuser", sudo: true } },
],
startCmd: "python server.py",
readyCmd: "curl -f http://localhost:8080/health",
})
Options:
| Option | Type | Description |
|---|
name | string | Required. Team-scoped identifier. Must not start with superserve/. Names are unique per team among non-deleted templates and are released for reuse the moment a template is deleted. |
from / from_ | string | Required. OCI base image (e.g. python:3.11). See BuildSpec. |
vcpu | number | 1-4. Default 1. |
memoryMib / memory_mib | number | 256-4096. Default 1024. |
diskMib / disk_mib | number | 1024-8192. Default 4096. |
steps | BuildStep[] | Ordered build steps. |
startCmd / start_cmd | string | Long-running process captured in the snapshot. |
readyCmd / ready_cmd | string | Readiness probe polled every 2s after startCmd. |
apiKey / api_key | string | Overrides SUPERSERVE_API_KEY. |
baseUrl / base_url | string | Overrides SUPERSERVE_BASE_URL. |
signal | AbortSignal | TypeScript only - abort the creation request. |
Throws SandboxError if the API response is missing build_id.
Template.connect
Load an existing template by UUID.
const template = await Template.connect("7a3f2b8c-1234-...")
Template.list
List all templates visible to the authenticated team (includes system templates).
const all = await Template.list()
const mine = await Template.list({ namePrefix: "my-" })
Returns an array of TemplateInfo.
Template.deleteById / Template.delete_by_id
Delete a template by UUID without instantiating it. Idempotent on 404.
await Template.deleteById("7a3f2b8c-1234-...")
Throws ConflictError if any non-destroyed sandbox still references the template. The template’s name is released for reuse as soon as the call succeeds.
Methods on template
getInfo / get_info
Fetch the current server-side state. Returns a fresh TemplateInfo - the template’s own properties are snapshots and are not mutated.
const info = await template.getInfo()
console.log(info.status) // "pending" | "building" | "ready" | "failed"
waitUntilReady / wait_until_ready
Block until the current build reaches a terminal status. The SDK polls GET /templates/{id}/builds/{buildId} for the authoritative build status — SSE is used only for live log delivery when onLog / on_log is provided, never to detect termination. Returns a refreshed TemplateInfo with status = "ready".
const info = await template.waitUntilReady({
onLog: (event) => {
if (event.stream === "system") return
process.stdout.write(event.text)
},
})
Options:
| Option | Type | Description |
|---|
onLog / on_log | (ev: BuildLogEvent) => void | Called for every SSE log event. |
signal | AbortSignal | TypeScript only - aborts the stream and any pending poll. |
pollIntervalMs | number | TypeScript only. Build status poll interval. Default 2000. |
poll_interval_s | float | Python only. Build status poll interval. Default 2.0. |
Throws:
BuildError if the build transitions to failed. The backend’s error_message follows a "<code>: <detail>" convention; the SDK splits it so BuildError.code is the stable prefix and BuildError.message is the human-readable detail. See BuildSpec: Build error codes.
ConflictError if the build is cancelled
streamBuildLogs / stream_build_logs
Pure SSE stream of build logs. The promise resolves when the stream closes. Does not wait for a terminal status - use waitUntilReady for that.
await template.streamBuildLogs({
onEvent: (ev) => {
console.log(`[${ev.stream}] ${ev.text}`)
},
// buildId defaults to template.latestBuildId
})
Options:
| Option | Type | Description |
|---|
onEvent / on_event | (ev: BuildLogEvent) => void | Required. Called for every event. |
buildId / build_id | string | Target build. Defaults to latestBuildId / latest_build_id. |
signal | AbortSignal | TypeScript only - aborts the stream. |
Throws SandboxError if no buildId is supplied and the template has no latestBuildId.
rebuild
Queue a new build for this template. Returns the new TemplateBuildInfo. Idempotent: if an in-flight build already matches the same configuration, the existing build is returned.
const build = await template.rebuild()
console.log(build.id, build.status)
listBuilds / list_builds
List recent builds for this template, newest first.
const builds = await template.listBuilds({ limit: 10 })
Returns an array of TemplateBuildInfo.
getBuild / get_build
Fetch a single build by ID.
const build = await template.getBuild("build-uuid")
cancelBuild / cancel_build
Cancel an in-flight build. Idempotent - no-op for builds already in a terminal state, and for 404.
await template.cancelBuild(build.id)
delete
Delete this template. Idempotent on 404.
Throws ConflictError if any non-destroyed sandbox still references the template - destroy those sandboxes first.
Properties on template
All properties are read-only snapshots taken at construction. Call getInfo() / get_info() to refresh.
| Property | Type | Description |
|---|
id | string | Template UUID. |
name | string | Team-scoped identifier. |
teamId / team_id | string | Owning team UUID. |
status | TemplateStatus | Status at construction time. |
vcpu | number | vCPU count the template boots with. |
memoryMib / memory_mib | number | Memory the template boots with. |
diskMib / disk_mib | number | Disk the template boots with. |
sizeBytes? / size_bytes? | number | Snapshot size in bytes, once built. |
errorMessage? / error_message? | string | Last build’s error message, if any. |
createdAt / created_at | Date / datetime | When the template row was created. |
builtAt? / built_at? | Date / datetime | When the latest successful build finished. |
latestBuildId? / latest_build_id? | string | Most recent build UUID. |
Types
TemplateStatus
type TemplateStatus = "pending" | "building" | "ready" | "failed"
pending - template exists; first build is queued
building - a build is in progress
ready - at least one successful build exists; sandboxes can boot from this template
failed - the latest build failed; rebuild or fix the spec
TemplateBuildStatus
type TemplateBuildStatus =
| "pending"
| "building"
| "snapshotting"
| "ready"
| "failed"
| "cancelled"
TemplateInfo
interface TemplateInfo {
id: string
name: string
teamId: string
status: TemplateStatus
vcpu: number
memoryMib: number
diskMib: number
sizeBytes?: number
errorMessage?: string
createdAt: Date
builtAt?: Date
latestBuildId?: string
}
TemplateBuildInfo
interface TemplateBuildInfo {
id: string
templateId: string
status: TemplateBuildStatus
buildSpecHash: string
errorMessage?: string
startedAt?: Date
finalizedAt?: Date
createdAt: Date
}
BuildLogEvent
interface BuildLogEvent {
timestamp: Date
stream: "stdout" | "stderr" | "system"
text: string
finished?: boolean
status?: "ready" | "failed" | "cancelled"
}
stream == "system" events are status messages from the build runner (build-step boundaries, snapshot progress). Filter them out when rendering to a user-facing console. finished: true marks the last event in a stream and carries the terminal status.
BuildStep
A discriminated union - exactly one of run / env / workdir / user must be set per step. See BuildSpec: Steps for semantics.
type BuildStep =
| { run: string }
| { env: { key: string; value: string } }
| { workdir: string }
| { user: { name: string; sudo?: boolean } }
BuildError
Thrown by waitUntilReady / wait_until_ready when the build transitions to failed.
class BuildError extends SandboxError {
readonly code: string // e.g. "image_pull_failed" | "step_failed" | ...
readonly message: string // human-readable detail (prefix stripped)
readonly buildId: string
readonly templateId: string
}
The backend’s error_message follows a "<code>: <detail>" convention (e.g. "image_too_large: image is too large for the requested disk_mib"). The SDK splits it so code holds the prefix and the error message holds the detail. When the backend doesn’t include a prefix, code falls back to "build_failed" and the message falls back to "Template build failed".
See the full list of build error codes and the general Errors reference.
Retries
GET and DELETE requests (including Template.list, Template.connect, getInfo, listBuilds, getBuild, cancelBuild, delete, deleteById) auto-retry on 429, 502, 503, 504, and network errors with exponential backoff + jitter (3 attempts max). POST requests (create, rebuild) are not retried - the SDK surfaces the error so you can decide.
Errors
Template methods commonly raise:
AuthenticationError - missing or invalid API key
ValidationError - bad request body (invalid name, unsupported base image, steps with multiple keys)
NotFoundError - template or build doesn’t exist (except delete / deleteById / cancelBuild, which swallow 404)
ConflictError - template has dependent sandboxes (on delete) or build was cancelled (on waitUntilReady)
BuildError - build transitioned to failed (from waitUntilReady only)
ServerError - platform error
See Errors for the full hierarchy.