#Sandbox Services
Sandbox Services expose named ports inside a sandbox. Use them when a sandbox needs public HTTP routes with method filtering, auth, CORS, rate limits, upstream timeout, path rewrite, and route-level resume behavior.
Services are also the source model for Sandbox0 Functions. A publishable service is public and has a restartable runtime.
Service Model#
| Field | Type | Description |
|---|---|---|
id | string | Stable service ID. Must be unique in the sandbox |
display_name | string | Optional human-readable label |
port | integer | Sandbox port to proxy to |
runtime | object | Optional restartable runtime for functions |
ingress | object | Public exposure and route policy |
health_check | object | Optional readiness path |
Runtime#
Service runtime supports cmd, warm_process, and manual. Use cmd when Function Gateway should create a new command context for a restored function runtime. Use warm_process when the template already starts a long-lived process and the service should bind to that existing context. For Functions, warm_process_name must reference a cmd warm process alias or context ID; REPL warm processes are not valid HTTP service runtimes.
Ingress#
| Field | Type | Description |
|---|---|---|
public | boolean | Exposes the service on the deployment exposure domain |
routes | array | Ordered public HTTP routes for this service |
When public is true and routes is empty, Sandbox0 creates a default route using the service ID and /.
Route#
| Field | Type | Description |
|---|---|---|
id | string | Stable route ID. Must be unique within the service |
path_prefix | string | Request path prefix to match. Defaults to / |
methods | string array | Allowed HTTP methods. Empty allows every method |
rewrite_prefix | string or null | Optional path prefix replacement before proxying |
auth | object | Optional request authentication |
cors | object | Optional CORS policy |
rate_limit | object | Optional per-route rate limit |
timeout_seconds | integer | Optional upstream timeout in seconds |
resume | boolean | Whether this route may resume a paused sandbox when auto_resume is enabled |
Route rate limits use the gateway rate limit backend. Self-hosted deployments default to process-local memory for simple onboarding. Configure Sandbox0Infra.spec.redis when multiple gateway replicas need shared Redis-backed limits.
Auth#
| Field | Type | Description |
|---|---|---|
mode | string | none, bearer, or header |
bearer_token_sha256 | string | SHA-256 hex digest for bearer token auth |
header_name | string | Header name for header auth |
header_value_sha256 | string | SHA-256 hex digest for header value auth |
Route auth stores SHA-256 digests, not plaintext tokens. Hash secret values before sending service configuration.
List Services#
/api/v1/sandboxes/{id}/services
The response includes publishable, publish_blockers, and exposure_domain.
goresp, err := sandbox.GetServices(ctx) if err != nil { log.Fatal(err) } fmt.Printf("services: %d\n", len(resp.Services)) for _, service := range resp.Services { fmt.Printf("%s -> port %d\n", service.ID, service.Port) }
Replace Services#
/api/v1/sandboxes/{id}/services
The update replaces the full service list. Include every service that should remain active.
gotokenHash := sha256.Sum256([]byte(os.Getenv("PUBLIC_API_TOKEN"))) resp, err := sandbox.UpdateServices(ctx, []apispec.SandboxAppService{ { ID: "api", Port: 8080, Ingress: apispec.SandboxAppServiceIngress{ Public: true, Routes: []apispec.SandboxAppServiceRoute{ { ID: "api", PathPrefix: apispec.NewOptString("/api"), Methods: []string{"GET", "POST"}, Auth: apispec.NewOptSandboxAppServiceRouteAuth(apispec.SandboxAppServiceRouteAuth{ Mode: apispec.SandboxAppServiceRouteAuthModeBearer, BearerTokenSHA256: apispec.NewOptString(hex.EncodeToString(tokenHash[:])), }), RateLimit: apispec.NewOptSandboxAppServiceRouteRateLimit(apispec.SandboxAppServiceRouteRateLimit{ Rps: 20, Burst: 40, }), TimeoutSeconds: apispec.NewOptInt32(30), Resume: true, }, }, }, }, }) if err != nil { log.Fatal(err) } fmt.Printf("services: %d\n", len(resp.Services))
Set Services At Claim Time#
You can attach services when claiming a sandbox. This is useful when the sandbox starts a known HTTP service during boot.
gosandbox, err := client.ClaimSandbox(ctx, "default", sandbox0.WithSandboxAutoResume(true), sandbox0.WithSandboxServices([]apispec.SandboxAppService{ { ID: "web", Port: 3000, Ingress: apispec.SandboxAppServiceIngress{ Public: true, Routes: []apispec.SandboxAppServiceRoute{ { ID: "web", PathPrefix: apispec.NewOptString("/"), Resume: true, }, }, }, }, }), ) if err != nil { log.Fatal(err) }
Clear Services#
Clearing services removes public HTTP exposure from the sandbox.
go_, err := sandbox.ClearServices(ctx) if err != nil { log.Fatal(err) }
Behavior Notes#
- Public HTTP traffic must match a route on a public service.
- If
methodsis empty, every HTTP method is allowed for that route. resumeis evaluated with sandboxauto_resume. A route withresume: falsewill not resume a paused sandbox.- Public URLs are derived from the deployment exposure domain as
{sandbox_id}--p{port}.{exposure_domain}.
Next Steps#
Webhooks
Receive signed sandbox lifecycle, service, and file-related events.
Overview
Package sandbox services into versioned callable functions and manage runtime revisions.