RecoupGet a free auditFree audit

API REFERENCE

Create or restore session sandbox

On this page
POST/api/sandbox

Provisions a Sandbox for the given session. If a per-org base snapshot exists, the sandbox boots from it (skipping the full repo clone, ~75s saved). Otherwise the sandbox boots from the default base snapshot and a background workflow builds an org-specific snapshot for next time. When the session has prior runtime state (a paused or running sandbox under the same sandboxName), the call resumes it instead of creating a new one. On success, the session row is updated with the new sandboxState and lifecycle is bumped to active; the lifecycle workflow is kicked to manage hibernation and expiry from there.

Authentication

x-api-key in header

BearerAuth bearer

Request

cURL
curl --request POST \
  --url 'https://api.recoupable.dev/api/sandbox' \
  --header 'x-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "repoUrl": "string"
}'

Try it

Fill in the fields, send the request from your browser, and read the live response. The curl below updates as you type.

Kept in this browser tab only and cleared when it closes.

cURL for this request
curl --request POST \
  --url 'https://recoup-api.vercel.app/api/sandbox' \
  --header 'Content-Type: application/json' \
  --data '{
  "repoUrl": "string"
}'

Request body required

application/json

repoUrlstringrequired

GitHub repository URL the sandbox should clone (e.g. https://github.com/owner/repo). Validated against GitHub URL rules; private repos require the service GitHub token configured server-side.

sessionIdstring

Owning session id. Required for the chat UX flow — the sandbox is named deterministically from the session id, enabling resume across reconnects. When omitted, a one-shot ephemeral sandbox is created (legacy).

Responses

200Sandbox provisioned and bound to the session.

application/json

createdAtintegerrequired

Epoch milliseconds when the sandbox handle was returned.

format: int64

timeoutintegerrequired

Sandbox idle-timeout in milliseconds. The lifecycle workflow uses this to schedule hibernation.

format: int64

currentBranchstringrequired

Branch the sandbox checked out.

modestring · enumrequired

Sandbox provider. Currently always vercel.

Values: "vercel"

timingobjectrequired
Properties for timing
readyMsintegerrequired

Wall-clock milliseconds from request receipt until the sandbox was ready. Useful for tracking cold-start vs warm-resume performance.

format: int64

400Invalid request body — malformed JSON, missing required fields, or invalid GitHub repository URL.

application/json

statusstring · enumrequired

Always "error" for error responses.

Values: "error"

errorstringrequired

Human-readable error message.

401Unauthorized — invalid or missing API key / Bearer token.

application/json

statusstring · enumrequired

Always "error" for error responses.

Values: "error"

errorstringrequired

Human-readable error message.

403Forbidden — the authenticated account does not own the supplied sessionId.

application/json

statusstring · enumrequired

Always "error" for error responses.

Values: "error"

errorstringrequired

Human-readable error message.

404Not found — no session exists with the given sessionId.

application/json

statusstring · enumrequired

Always "error" for error responses.

Values: "error"

errorstringrequired

Human-readable error message.

502Upstream error — the sandbox provider failed to provision a sandbox.

application/json

statusstring · enumrequired

Always "error" for error responses.

Values: "error"

errorstringrequired

Human-readable error message.

Full specification

Download the OpenAPI file for complete schemas, constraints, and examples.

Download sandbox.json
View operation source
json
{
  "summary": "Create or restore session sandbox",
  "description": "Provisions a Sandbox for the given session. If a per-org base snapshot exists, the sandbox boots from it (skipping the full repo clone, ~75s saved). Otherwise the sandbox boots from the default base snapshot and a background workflow builds an org-specific snapshot for next time. When the session has prior runtime state (a paused or running sandbox under the same `sandboxName`), the call resumes it instead of creating a new one. On success, the session row is updated with the new `sandboxState` and lifecycle is bumped to `active`; the lifecycle workflow is kicked to manage hibernation and expiry from there.",
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreateSandboxRequest"
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Sandbox provisioned and bound to the session.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/CreateSandboxResponse"
          }
        }
      }
    },
    "400": {
      "description": "Invalid request body — malformed JSON, missing required fields, or invalid GitHub repository URL.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "401": {
      "description": "Unauthorized — invalid or missing API key / Bearer token.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "403": {
      "description": "Forbidden — the authenticated account does not own the supplied `sessionId`.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "404": {
      "description": "Not found — no session exists with the given `sessionId`.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    },
    "502": {
      "description": "Upstream error — the sandbox provider failed to provision a sandbox.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}