Skip to content

Protocol Reference

All messages are UTF-8 JSON text frames unless noted as binary. Fields marked ? are optional.


Opens a compile session. Must be the first message sent on a new connection.

{
"type": "compile.start",
"api_key": "pk_live_...",
"entry": "src/main.ts",
"release": true,
"target": "binary"
}
FieldTypeDescription
api_key?stringYour Pure API key. Required unless oidc_token is set. See Authentication.
oidc_token?stringA GitLab (or other supported CI provider’s) OIDC id_token, in place of api_key. Requires account_id and org_id — see Authentication → OIDC.
account_id?stringRequired with oidc_token: the user id that made the connection to authenticate against.
org_id?stringRequired with oidc_token: the org that connection bills to.
entrystringRelative path within the tarball to the TypeScript or JavaScript entry point.
pre_command?stringShell command to run before compilation (e.g. pnpm install --frozen-lockfile). Runs inside the extracted tarball directory. If omitted, Pure auto-detects the right install command from your lockfile — see Default install command below.
target?"binary" | "node-addon"Output format. "binary" (default) produces a standalone native executable. "node-addon" produces a Node.js native addon (.node) packaged as an installable npm tarball — see Node addon target below.
env?objectEnvironment variables passed into the compile sandbox (key/value strings). Reserved keys like PATH, HOME, LD_PRELOAD, NODE_OPTIONS are rejected. Max 64 vars, 32 KB total, 4 KB per value.
sandbox_mem_gib?numberMemory ceiling for the compile sandbox (GiB). Clamped to the platform maximum if exceeded.

If you don’t supply pre_command, Pure inspects the root of your tarball and runs the right install command for the package manager whose lockfile is present, checked in this order (first match wins):

LockfileCommand
package-lock.jsonnpm ci
bun.lockb or bun.lockbun install --frozen-lockfile (bun is pre-installed in the sandbox)
pnpm-lock.yamlpnpm install --frozen-lockfile
yarn.lockyarn install --frozen-lockfile
package.json onlynpm install
(none)nothing — installation is skipped

package-lock.json is checked first and wins even if a bun.lockb/bun.lock is also present in the tarball — a repo with both (e.g. mid-migration to bun, or a leftover committed lockfile) installs with npm ci, not bun.

Submit your own pre_command whenever you need a different command (e.g. forcing bun over a co-present package-lock.json, enabling optional flags, running a build step before Pure compiles, or pulling private deps with a token). Your custom pre_command has full outbound internet access, so curl | bash-style installers from any origin work.

When target is "node-addon", Pure produces a Node.js native addon instead of a standalone binary. The artifact returned via download_url is an npm tarball you install with:

Terminal window
npm install ./your-package-0.1.0.tgz

The package has the same name and version as the package.json at the root of your uploaded tarball, plus a .node file and a thin index.js shim that re-exports its surface. Your existing TypeScript types (*.d.ts) are preserved.

Use this when you want to ship a Pure-compiled module that other Node code can require() — without rewriting consumers around a separate binary.

After compile.start and before compile.upload.done, send the source tarball as one or more binary WebSocket frames. The server concatenates all frames in order.

The tarball must be a .tar.gz (gzipped tar archive) containing your project at the root level, not wrapped in an extra directory.

You may split the tarball across any number of frames. Typical usage is a single frame for small projects and multiple 64 KiB frames for larger ones.

Signals the end of the tarball upload.

{
"type": "compile.upload.done",
"total_bytes": 81920,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
FieldTypeDescription
total_bytesnumberTotal byte count of the uploaded tarball.
sha256stringLowercase hex SHA-256 of the complete tarball.

Sending compile.upload.done a second time on the same session is a no-op — the server ignores duplicate signals.

Request a list of recent jobs for an organization.

{
"type": "jobs.list",
"org_id": "org_abc123",
"limit": 20
}
FieldTypeDescription
org_idstringOrganization ID (visible in the dashboard under Settings).
limit?numberMaximum jobs to return. Defaults to 20; maximum 100.

Subscribe to real-time events for a specific job. If the job is already finished, the server replays stored events immediately.

{
"type": "jobs.subscribe",
"job_id": "job_xyz789"
}

Sent when the job is accepted and placed in the compile queue.

{
"type": "compile.queued",
"job_id": "job_xyz789",
"position": 2
}
FieldTypeDescription
job_idstringUnique identifier for this compile job. Use it for jobs.subscribe and jobs.list.
positionnumber1-based position in the queue. Position 1 means the job is next to run.

Sent when a worker picks up the job and begins processing it.

{
"type": "compile.started",
"job_id": "job_xyz789",
"step": "compiling"
}
FieldTypeDescription
job_idstringJob identifier.
step"pre_command" | "compiling""pre_command" if the worker is running the pre-compilation shell command; "compiling" when the actual compilation is underway.

A line of compiler output. Emitted zero or more times during compilation.

{
"type": "compile.log",
"job_id": "job_xyz789",
"line": "Compiling pure_hello v0.1.0",
"ts": 1714000012345
}
FieldTypeDescription
job_idstringJob identifier.
linestringOne line of compiler output (no trailing newline).
tsnumberUnix timestamp in milliseconds when the line was emitted.

Sent when compilation succeeds.

{
"type": "compile.done",
"job_id": "job_xyz789",
"download_url": "https://...",
"expires_at": 1714003600000,
"work_units": 1280
}
FieldTypeDescription
job_idstringJob identifier.
download_urlstringPresigned URL to download the compiled binary.
expires_atnumberUnix timestamp (ms) when download_url expires.
work_unitsnumberMetered usage consumed by this job. See Billing.

Sent when compilation fails or an error occurs during the session.

{
"type": "compile.error",
"job_id": "job_xyz789",
"message": "human-readable description",
"code": "JOB_FAILED"
}
FieldTypeDescription
job_id?stringJob identifier, if a job was created before the error.
messagestringHuman-readable error description.
code?stringMachine-readable error code. See Errors.

Response to a jobs.list request.

{
"type": "jobs.list.result",
"jobs": [
{
"id": "job_xyz789",
"org_id": "org_abc123",
"status": "succeeded",
"entry": "src/main.ts",
"created_at": 1714000000000,
"finished_at": 1714000030000,
"work_units": 1280
}
]
}

Job status is one of: queued, running, succeeded, failed.

Sent when authentication fails. The connection is closed immediately after.

{
"type": "auth.error",
"message": "key has been revoked",
"code": "KEY_REVOKED"
}

See Authentication for all auth error codes.


Client Server
│──── compile.start ──────────▶│
│──── [binary frame(s)] ───────▶│
│──── compile.upload.done ─────▶│
│ │◀── compile.queued
│ │◀── compile.started (step: pre_command) [optional]
│ │◀── compile.started (step: compiling)
│ │◀── compile.log [0..N]
│ │◀── compile.done OR compile.error
│ (close or start new job)

The server may send compile.error at any point — including before compile.queued if the tarball is malformed or exceeds size limits.