CreateSandbox
Authorization
BearerAuth A namespace-scoped API key (cpk_…) for machines, or a Xeonr Auth OIDC
token for humans. The key's namespace and role are pinned server-side.
In: header
Header Parameters
Define the version of the Connect protocol
1Define the timeout, in ms
Request Body
application/json
Deprecated: use workspaces. Treated as a single read-write mount at
/workspace when set. Setting both is an error rather than a merge.
Cache is the FUSE VFS cache policy — the only workspace presentation is FUSE.
steady-state; usually MODE_NONE
Resources is the compute envelope for a sandbox or job. Maps onto k8s requests==limits and the Docker resource knobs.
0 = never
user-defined display name (console-required)
Workload env — same contract as RunJobRequest.env: pod-spec visible, not a secret channel, platform-owned names rejected.
The filesystems this sandbox should see. Each is durable, an immutable snapshot, or ephemeral — see WorkspaceMount. Empty is legal: a sandbox with no mounts starts in its image's own WORKDIR with only /tmp writable.
Where the workload starts. Absolute; empty selects the default, which differs by primitive on purpose:
sandbox the first read-write mount — an interactive user has to land somewhere writable job the first read-write mount — inputs are already staged there app the IMAGE'S OWN WORKDIR. An App runs an image built elsewhere and that WORKDIR is part of its contract, so the platform does not override it just because the version happens to declare a writable mount.
Set it explicitly when the default is wrong: a monorepo mounted at /workspace whose build runs in /workspace/apps/web has no other way to say so, and relying on the default couples the working directory to the ORDER of the mount list, which is not something a caller expects to matter.
The command to run in this sandbox. Empty selects the environment's
default_argv, then the image's own ENTRYPOINT/CMD — so a sandbox built on
an image that starts a dev server starts it, rather than starting nothing.
BEHAVIOUR CHANGE: sandboxes previously ran a keepalive INSTEAD of the image's
entrypoint, so an existing sandbox that was only ever exec'd into may now
start running something. Set exec_only to keep the old behaviour.
Run nothing: no default_argv, no image entrypoint, just a sandbox to exec
into. This is the opt-out from the resolution above, and is NOT the same as
an empty argv — empty means "resolve one", this means "there is none".
What to do with the COMMAND when it exits. Default NEVER.
"SANDBOX_RESTART_UNSPECIFIED" | "SANDBOX_RESTART_NEVER" | "SANDBOX_RESTART_ON_FAILURE" | "SANDBOX_RESTART_ALWAYS"What to do with the SANDBOX once the run has ended and is not being restarted. Default SUSPEND_ON_SUCCESS.
"SANDBOX_ON_EXIT_UNSPECIFIED" | "SANDBOX_ON_EXIT_SUSPEND_ON_SUCCESS" | "SANDBOX_ON_EXIT_KEEP" | "SANDBOX_ON_EXIT_SUSPEND"Response Body
application/json
application/json
curl -X POST "https://containers.xeonr.io/containers.api.v1.SandboxService/CreateSandbox" \ -H "Connect-Protocol-Version: 1" \ -H "Content-Type: application/json" \ -d '{}'{
"sandbox": {
"sandboxId": "string",
"namespace": "string",
"environmentId": "string",
"workspaceId": "string",
"state": "SANDBOX_STATE_UNSPECIFIED",
"ports": [
{
"port": 0,
"url": "string",
"accessToken": "string",
"auth": "AUTH_UNSPECIFIED"
}
],
"createdAtUnix": 0,
"resources": {
"cpuMillis": 0,
"memoryMb": 0,
"ephemeralMb": 0,
"pids": 0
},
"idleSuspendSec": 0,
"maxLifetimeSec": 0,
"workspaceCache": {
"policy": "POLICY_UNSPECIFIED",
"writebackSec": 0
},
"egressGrant": {
"mode": "MODE_UNSPECIFIED",
"expiresAtUnix": 0,
"reason": "string",
"policy": {
"mode": "MODE_UNSPECIFIED",
"allow": [
{
"hostPattern": "string",
"ports": [
0
],
"mode": "RULE_MODE_UNSPECIFIED",
"pathPrefixes": [
"string"
],
"methods": [
"string"
],
"maxResponseBytes": 0,
"allowPlainHttp": true
}
],
"presets": [
"string"
],
"allowPlainHttp": true
},
"id": "string"
},
"runtimeEgress": {
"mode": "MODE_UNSPECIFIED",
"allow": [
{
"hostPattern": "string",
"ports": [
0
],
"mode": "RULE_MODE_UNSPECIFIED",
"pathPrefixes": [
"string"
],
"methods": [
"string"
],
"maxResponseBytes": 0,
"allowPlainHttp": true
}
],
"presets": [
"string"
],
"allowPlainHttp": true
},
"label": "string",
"egressGrants": [
{
"mode": "MODE_UNSPECIFIED",
"expiresAtUnix": 0,
"reason": "string",
"policy": {
"mode": "MODE_UNSPECIFIED",
"allow": [
{
"hostPattern": "string",
"ports": [
0
],
"mode": "RULE_MODE_UNSPECIFIED",
"pathPrefixes": [
"string"
],
"methods": [
"string"
],
"maxResponseBytes": 0,
"allowPlainHttp": true
}
],
"presets": [
"string"
],
"allowPlainHttp": true
},
"id": "string"
}
],
"env": {
"property1": "string",
"property2": "string"
},
"workspaces": [
{
"snapshotId": "string",
"mountPath": "string",
"readOnly": true,
"workspaceId": "string",
"ephemeral": true,
"ephemeralFromSnapshotId": "string"
}
],
"workingDir": "string",
"argv": [
"string"
],
"restart": "SANDBOX_RESTART_UNSPECIFIED",
"onExit": "SANDBOX_ON_EXIT_UNSPECIFIED",
"runState": "RUN_STATE_UNSPECIFIED",
"run": 0,
"lastExitCode": 0
}
}{
"code": "not_found",
"message": "string",
"details": [
{
"type": "string",
"value": "string",
"debug": {}
}
]
}