Skip to content
OpenRelay is in early access, and the /v1 API is stable. New capabilities ship in the changelog.
Skip to Content
API ReferenceComputeSandboxes

Create many sandboxes as one group

Starts a group of sandboxes, reserving at least minReady together. Streams group progress and each sandbox as capacity becomes available. Starts the rest as capacity allows, until all n run or waitSeconds expires. The answer is a stream with a group line, one sandbox line per member as it starts, and, if some never fit, a last error line with code CAPACITY_EXHAUSTED and the count started. A 503 means minReady never fit together within waitSeconds, and nothing was started.

Required permission

Requires the sandboxes.create permission. See Permissions for the roles and API key permissions that include it.

Command line

The orl CLI wraps this endpoint:

Guided workflow: orl sandbox create-many

orl sandbox create-many --n <n> --template <template>
POST
/v1/sandbox-groups

Authorization

apiKey
headerAuthorizationBearer <token>

OpenRelay API key. Send it as Authorization: Bearer or_… (legacy vl_… keys still work).

Header Parameters

Idempotency-Key?string

Makes a retried create safe. Choose one value per create you mean to make, 1 to 512 bytes (bytes, not characters), such as a UUID, and send it again on every retry of that create. The first request with a key runs, and a 2xx answer is kept for 24 hours: a repeat with the same key and the same body gets that answer back, with the same status and the header Idempotent-Replayed: true, and creates nothing. A batch create compares the body byte for byte; a VM or pod create compares the fields it decodes, so whitespace and key order do not count. A repeat while the first request is still running answers 409; repeat it a second later. The same key with a different body answers 422. An answer other than a 2xx is not kept, so a retry after a 4xx or a 5xx runs again. A 2xx too large to keep holds the key without it: every repeat answers 409 and creates nothing. Keys are scoped to the organization and the operation.

Length1 <= length

Request Body

application/json
  1. body
template*string

A template id from GET /v1/sandbox-templates: a built-in or one of the organization's.

n*integer

How many sandboxes to start.

Range1 <= value
minReady?integer

The fewest sandboxes worth starting. None start until this many fit together. Defaults to n.

Range1 <= value
cpu?integer

As on a single create, for each member: absent, the template's.

Range1 <= value
memoryMiB?integer

As on a single create, for each member: absent, the template's.

cpuRequest?number

As on a single create, for each member.

Range0.25 <= value
Default0.25
memoryRequestMiB?integer

As on a single create, for each member.

Range128 <= value
Default128
timeoutSeconds?integer
Rangevalue <= 86400
Default300
placement?string
Default"shared"
Value in"shared""pinned"
env?
egress?
network?

As on a single create, for each member.

metadata?
ephemeral?boolean

As on a single create: every member leaves no customer history after it ends.

Defaultfalse
autoPause?boolean

As on a single create: every member consents.

Defaultfalse
waitSeconds?integer

How long the group may wait for capacity. A longer wait is cut to the maximum.

Range0 <= value <= 120
Default10

Response Body

The group's members as they start.

application/x-ndjson
  1. response
type*string
Value in"group""sandbox""error"
group?
sandbox?
started?integer

On the last error line, how many members started.

error?
Example Request
curl -X POST 'https://api.openrelay.inc/v1/sandbox-groups' \  -H 'Content-Type: application/json' \  -d '{  "template": "string",  "n": 1}'
Example Response
{  "type": "group",  "group": {    "id": "string",    "template": "string",    "requested": 0,    "minReady": 0,    "started": 0,    "createdAt": "2019-08-24T14:15:22Z"  },  "sandbox": {    "id": "string",    "template": "string",    "state": "running",    "createdAt": "2019-08-24T14:15:22Z",    "expiresAt": "2019-08-24T14:15:22Z",    "endedAt": "2019-08-24T14:15:22Z",    "exitReason": "killed",    "groupId": "string",    "metadata": {      "property1": "string",      "property2": "string"    },    "ephemeral": true,    "result": {      "execId": "string",      "exitCode": 0,      "stdout": "string",      "stderr": "string",      "truncated": true,      "error": {        "error": "string",        "code": "string",        "permission": "string",        "deniedBy": "string",        "policies": [          "string"        ],        "requestId": "string"      }    }  },  "started": 0,  "error": {    "error": "string",    "code": "string",    "permission": "string",    "deniedBy": "string",    "policies": [      "string"    ],    "requestId": "string"  }}