Skip to content
pols.so docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

pols.so API

Control plane API for pols.so developer sandboxes: full Ubuntu 24.04 VMs with root, systemd and Docker.

This file is the source of truth. The Go server interface, the Go client (pkg/api) and the TypeScript client (clients/typescript) are generated from it with make generate.

Authentication: /v1 endpoints require an org-scoped API key as a bearer token (Authorization: Bearer pols_...), except the public /v1/openapi.yaml. The CDP WebSocket endpoint also accepts the connection token described under GET /v1/sandboxes/{sandbox}/browser/cdp.

Lifecycle calls are asynchronous. They record the desired state and return at once; a reconciler drives the runtime to it. Poll GET /v1/sandboxes/{sandbox} until status equals desired_state (or is error unless deletion is pending). Conflicting stop/resume requests return 409 until the current transition finishes.

Wherever a path takes {sandbox} or {template}, either the ID (sbx_..., tpl_...) or the org-unique name is accepted.

Computer use: every sandbox has a 1920x1080 X11 desktop and Google Chrome. /computer/* takes screenshots of the whole desktop and drives its mouse and keyboard; coordinates are pixels in that 1920x1080 space, with (0, 0) at the top left. /browser/cdp connects Playwright or Puppeteer to the sandbox’s Chrome over the Chrome DevTools Protocol, proxied by the control plane; Chrome’s debugging port itself only listens inside the sandbox.

Edge: the edge serves sandbox content on its own domain (the sandbox domain, on.pols.so in production), never on the API’s or the site’s domain. A published port is at https://<sandbox>-<port>.<sandbox domain>, where <sandbox> is the sandbox ID with _ replaced by -; the desktop is at <sandbox>-desktop and the CDP endpoint at <sandbox>-cdp. Ports are private unless published as public: open them with a login link from POST /v1/sandboxes/{sandbox}/ports/{port}/link, whose token the edge exchanges for a cookie scoped to that one host. The desktop takes no cookie: its link from POST /v1/sandboxes/{sandbox}/desktop carries a token in the URL fragment, which the edge’s desktop page presents when it connects. ssh <sandbox ID>@<gateway> reaches a running sandbox with any key registered under /v1/ssh-keys.

Vault: each org has a vault of passwords and environment variables, encrypted at rest. Its owner adds, replaces and deletes entries on the website (https://my.pols.so/account); API keys can only list their names (GET /v1/vault) and name them in secrets when creating or forking a sandbox, which gets each one as an environment variable of that name. No endpoint returns a value.

Limits: /v1 calls are rate limited per client address and per org, sandbox and template lifecycle calls more tightly, and an org may have only so many exec, file, computer and CDP calls in progress at once. Over a limit the API answers 429 rate_limited with a Retry-After header. A request body that stalls is answered with 408 timeout.

Errors and headers: a failure of the sandbox host is answered with 502 runtime_error and a fixed message; the details are only in the server’s log. A {sandbox} or {template} that is neither a well-formed ID nor a name is 404 not_found. Names and descriptions must be UTF-8 text without control characters other than tab, and exec arguments and paths must not contain NUL. Every response carries X-Content-Type-Options: nosniff, Referrer-Policy: no-referrer, Content-Security-Policy: default-src 'none'; frame-ancestors 'none' and Cache-Control: no-store, except that /v1/openapi.yaml may be cached.

Version 0.1.0
Base URLhttps://api.pols.so

org

api-keys

sandboxes

exec

files

computer

browser

edge

ssh-keys

vault

templates

usage

system