# API

Every endpoint of the Parity API, with the permission each one needs.

{/* Generated by scripts/reference.mjs from generated/*.json. Do not edit. */}

All requests go to `https://api.parity.ninja` with a bearer token. Responses are JSON. Errors are RFC 9457 problem details; see [Errors](/reference/errors).

```sh title="Request"
curl -H "Authorization: Bearer $PARITY_TOKEN" https://api.parity.ninja/v0/sandboxes
```

The CLI and the MCP server call these endpoints and return the same JSON. Every endpoint names one permission; the role table is in [Permissions](/security/permissions).

## Token [#token]

### Describe the token [#describe-the-token]

<Endpoint method="GET" path="/v0/token" permission="logs.read · Viewer+" />



## Projects [#projects]

### List projects [#list-projects]

<Endpoint method="GET" path="/v0/projects" permission="logs.read · Viewer+" />



### Create a project [#create-a-project]

<Endpoint method="POST" path="/v0/projects" permission="projects.create · Admin+" />



### Check a project name [#check-a-project-name]

<Endpoint method="GET" path="/v0/projects/name-check" permission="projects.create · Admin+" />



### Get a project [#get-a-project]

<Endpoint method="GET" path="/v0/projects/{project}" permission="logs.read · Viewer+" />

Path: `project`. 

### Check a manifest against the project [#check-a-manifest-against-the-project]

<Endpoint method="POST" path="/v0/projects/{project}/manifest/check" permission="sandbox.create · Developer+" />

Path: `project`. 

### Create a project token [#create-a-project-token]

<Endpoint method="POST" path="/v0/projects/{project}/tokens" permission="sandbox.create · Developer+" />

Path: `project`. 

### Promote a manifest [#promote-a-manifest]

<Endpoint method="POST" path="/v0/projects/{project}/promote" permission="environments.deploy · Developer+ · people only" />

Path: `project`. 

### environment_list [#environment_list]

<Endpoint method="GET" path="/v0/projects/{project}/environments" permission="logs.read · Viewer+" />

Path: `project`. 

### Environment status [#environment-status]

<Endpoint method="GET" path="/v0/projects/{project}/environments/{environment}" permission="logs.read · Viewer+" />

Read a project's environments (staging, production, customer deployments: whatever its manifest declares): whether each is frozen or pinned by a rollback, its current rollout and status, and the block jobs waiting for a person with their prompts. With environment, that one in full. Builds move between environments through releases: see release_status. Agents can't promote, approve or reject: tell the user what is waiting and that they decide it (parity approve &lt;step&gt; --env &lt;environment&gt;, or the console).

Path: `project`, `environment`. Arguments and behaviour match the MCP tool [`environment_status`](/reference/mcp#environment_status).

### environment_retry [#environment_retry]

<Endpoint method="POST" path="/v0/projects/{project}/environments/{environment}/retry" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `environment`. 

### environment_rollback [#environment_rollback]

<Endpoint method="POST" path="/v0/projects/{project}/environments/{environment}/rollback" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `environment`. 

### environment_delete [#environment_delete]

<Endpoint method="DELETE" path="/v0/projects/{project}/environments/{environment}" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `environment`. 

### environment_promote [#environment_promote]

<Endpoint method="POST" path="/v0/projects/{project}/environments/{environment}/promote" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `environment`. 

### step_approve [#step_approve]

<Endpoint method="POST" path="/v0/projects/{project}/environments/{environment}/steps/{step}/approve" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `environment`, `step`. 

### step_reject [#step_reject]

<Endpoint method="POST" path="/v0/projects/{project}/environments/{environment}/steps/{step}/reject" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `environment`, `step`. 

### release_list [#release_list]

<Endpoint method="GET" path="/v0/projects/{project}/releases" permission="logs.read · Viewer+" />

Path: `project`. 

### Release status [#release-status]

<Endpoint method="GET" path="/v0/projects/{project}/releases/{release}" permission="logs.read · Viewer+" />

Read a project's releases, newest first: each is one build moving through the manifest's release steps (promote into environments, block for approval, wait, run a job, group). Shows where each release is and what it waits for: a block's prompt and approvals, a promote's environments (held: frozen or pinned by a rollback), a wait's end. With number, that release in full. Agents can't approve, reject or skip: tell the user what waits and that they decide it (parity approve &lt;step&gt;, or the console).

Path: `project`, `release`. Arguments and behaviour match the MCP tool [`release_status`](/reference/mcp#release_status).

### release_step_approve [#release_step_approve]

<Endpoint method="POST" path="/v0/projects/{project}/releases/{release}/steps/{step}/approve" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `release`, `step`. 

### release_step_reject [#release_step_reject]

<Endpoint method="POST" path="/v0/projects/{project}/releases/{release}/steps/{step}/reject" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `release`, `step`. 

### release_step_skip [#release_step_skip]

<Endpoint method="POST" path="/v0/projects/{project}/releases/{release}/steps/{step}/skip" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `release`, `step`. 

### Freeze an environment [#freeze-an-environment]

<Endpoint method="PUT" path="/v0/projects/{project}/freezes/{environment}" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `environment`. 

### Lift a freeze [#lift-a-freeze]

<Endpoint method="DELETE" path="/v0/projects/{project}/freezes/{environment}" permission="environments.deploy · Developer+ · people only" />

Path: `project`, `environment`. 

### List build runners [#list-build-runners]

<Endpoint method="GET" path="/v0/projects/{project}/runners" permission="logs.read · Viewer+" />

Path: `project`. 

## GitHub [#github]

### List GitHub App installations [#list-github-app-installations]

<Endpoint method="GET" path="/v0/github/installations" permission="projects.create · Admin+" />



### Start a GitHub App installation [#start-a-github-app-installation]

<Endpoint method="POST" path="/v0/github/install" permission="projects.create · Admin+" />



### Finish a GitHub App installation [#finish-a-github-app-installation]

<Endpoint method="POST" path="/v0/github/callback" permission="projects.create · Admin+" />



### List an installation's repositories [#list-an-installations-repositories]

<Endpoint method="GET" path="/v0/github/installations/{installation}/repos" permission="projects.create · Admin+" />

Path: `installation`. 

### Read a repository's parity.yaml [#read-a-repositorys-parityyaml]

<Endpoint method="GET" path="/v0/github/repos/{repo}/manifest" permission="projects.create · Admin+" />

Path: `repo`. 

## Sandboxes [#sandboxes]

### List sandboxes [#list-sandboxes]

<Endpoint method="GET" path="/v0/sandboxes" permission="logs.read · Viewer+" />

List the sandboxes this token can see, with status and expiry, a page at a time: while next_page_token is set, call again with it as page_token.

Arguments and behaviour match the MCP tool [`sandbox_list`](/reference/mcp#sandbox_list).

### Render a sandbox's objects [#render-a-sandboxs-objects]

<Endpoint method="POST" path="/v0/render" permission="sandbox.create · Developer+" />



### Upload source [#upload-source]

<Endpoint method="POST" path="/v0/sources" permission="sandbox.create · Developer+" />



### Create a sandbox [#create-a-sandbox]

<Endpoint method="POST" path="/v0/sandboxes" permission="sandbox.create · Developer+" />

Create a sandbox for one task: the app's services, database, mail and auth in their own namespace. Needs a project token. The sandbox's createdBy is the person the token was minted for. Returns the sandbox (id, status, domain, services[].public_urls) and its token at once: give that sandbox token to the agent doing the task. With wait (the default) it then waits up to about 50 seconds for ready, sending progress; if the sandbox is still starting it returns with next: call sandbox_status with wait until status is ready. A failed setup job is dependency_failed with the log tail. Pass idempotency_key to make a retry return the same sandbox and token.

Arguments and behaviour match the MCP tool [`sandbox_create`](/reference/mcp#sandbox_create).

### Sandbox status [#sandbox-status]

<Endpoint method="GET" path="/v0/sandboxes/{id}" permission="logs.read · Viewer+" />

Get a sandbox: status (starting, ready, failed, expiring), expires_at, services with public_urls and health, resources, lifecycle jobs and conditions. With wait, it waits up to about 50 seconds for ready (or failed), sending progress; call it again while status is starting. The app's URL is services[].public_urls.

Path: `id`. Arguments and behaviour match the MCP tool [`sandbox_status`](/reference/mcp#sandbox_status).

### Destroy the sandbox [#destroy-the-sandbox]

<Endpoint method="DELETE" path="/v0/sandboxes/{id}" permission="sandbox.create · Developer+" />

Destroy the sandbox and all its data. Its token stops working. Exported proofs and calls.jsonl are kept by Parity (GET /v0/proofs), but export the proof first: nothing can be exported after.

Path: `id`. Arguments and behaviour match the MCP tool [`sandbox_destroy`](/reference/mcp#sandbox_destroy).

### Roll onto a changed manifest or new images [#roll-onto-a-changed-manifest-or-new-images]

<Endpoint method="POST" path="/v0/sandboxes/{id}/sync" permission="sandbox.create · Developer+" />

Roll the sandbox onto a changed parity.yaml (manifest: its text), new prebuilt images (images: \{service: ref\}), or both; deploy jobs such as migrations run again. Waits up to about 50 seconds for ready unless wait is false. To run changed source code, use parity up from the working directory: it uploads the tree and Parity rebuilds the services that only have build:.

Path: `id`. Arguments and behaviour match the MCP tool [`sandbox_sync`](/reference/mcp#sandbox_sync).

### Extend the lifetime [#extend-the-lifetime]

<Endpoint method="POST" path="/v0/sandboxes/{id}/extend" permission="sandbox.create · Developer+" />

Push the sandbox's expiry back by a duration, such as 1h, up to the manifest's max_ttl. Returns the sandbox with the new expires_at.

Path: `id`. Arguments and behaviour match the MCP tool [`sandbox_extend`](/reference/mcp#sandbox_extend).

### Scale a service [#scale-a-service]

<Endpoint method="POST" path="/v0/sandboxes/{id}/services/{service}/scale" permission="sandbox.create · Developer+" />

Path: `id`, `service`. 

### Run a command in a service [#run-a-command-in-a-service]

<Endpoint method="POST" path="/v0/sandboxes/{id}/exec" permission="sandbox.create · Developer+" />

Run a command in a running service or resource container (such as psql in db, or a script in web) and return \{exit_code, stdout, stderr\}. Output is capped at 1 MiB per stream. The sandbox's generated values are replaced with [redacted] where they appear verbatim, as a courtesy: exec can read the env, so treat its output as secret-bearing.

Path: `id`. Arguments and behaviour match the MCP tool [`sandbox_exec`](/reference/mcp#sandbox_exec).

### Read logs [#read-logs]

<Endpoint method="GET" path="/v0/sandboxes/{id}/logs" permission="logs.read · Viewer+" />

Read logs as text: one service, resource or job, or the whole sandbox when neither is given. Several containers are prefixed with [pod/container]. Use since to see only what an action just caused.

Path: `id`. Arguments and behaviour match the MCP tool [`sandbox_logs`](/reference/mcp#sandbox_logs).

### Egress report [#egress-report]

<Endpoint method="GET" path="/v0/sandboxes/{id}/egress" permission="logs.read · Viewer+" />

Every outbound call the sandbox made: DNS queries for outside names and connections to outside hosts (HTTP Host, TLS server name), blocked or let through, with the service that tried and a count. A blocked host needs adding to the manifest's externals. sandbox_status lists the blocked hosts too.

Path: `id`. Arguments and behaviour match the MCP tool [`sandbox_egress`](/reference/mcp#sandbox_egress).

## Auth users [#auth-users]

### Auth users and sign-in links [#auth-users-and-sign-in-links]

<Endpoint method="GET POST PATCH DELETE" path="/v0/sandboxes/{id}/auth/{rest...}" permission="logs.read to read · sandbox.create to write" />

Path: `id`, `rest`. 

## Inbox [#inbox]

### List the inbox [#list-the-inbox]

<Endpoint method="GET" path="/v0/sandboxes/{id}/inbox" permission="logs.read · Viewer+" />

List the mail the sandbox received (every address at the sandbox's domains lands here), newest first: id, to, from, subject, received_at, snippet, and the links, codes and attachments extracted from each. Filter by recipient, subject text or regexp, since, or after (a cursor); q searches every message, not just one page. The answer's cursor is the newest message: pass it as inbox_wait's after to get the next mail once you have acted. inbox_read gives one message's text. While next_page_token is set, older mail is on the next page (page_token).

Path: `id`. Arguments and behaviour match the MCP tool [`inbox_list`](/reference/mcp#inbox_list).

### Wait for a message [#wait-for-a-message]

<Endpoint method="GET" path="/v0/sandboxes/{id}/inbox/wait" permission="logs.read · Viewer+" />

Wait for a message (to an address, with subject text or a subject regexp) and return it with its text, links, codes and attachments. Without after, it returns the newest match, even one that came before the call, so call it right after the action that sends mail. With after (a message id, or the cursor inbox_list gave before you acted), it returns the first match after that message, so old mail never answers. expect_none asserts that no match arrives in the window instead (signed evidence that something was not sent). Waits at most 50 seconds, sending progress; on timeout call again with the after the answer gives. Prefer links with internal: true.

Path: `id`. Arguments and behaviour match the MCP tool [`inbox_wait`](/reference/mcp#inbox_wait).

### Read a message [#read-a-message]

<Endpoint method="GET" path="/v0/sandboxes/{id}/inbox/{msg}" permission="logs.read · Viewer+" />

Read one message: its text, the extracted links and codes (one-time codes, verification links) and its attachments (part, name, content_type, size; inbox_attachment downloads one). The HTML part only with html: true.

Path: `id`, `msg`. Arguments and behaviour match the MCP tool [`inbox_read`](/reference/mcp#inbox_read).

### Download a mail attachment [#download-a-mail-attachment]

<Endpoint method="GET" path="/v0/sandboxes/{id}/inbox/{msg}/attachments/{part}" permission="logs.read · Viewer+" />

Download one attachment of a message, by its part or file name (inbox_read lists them), as an embedded resource with its content type; with parity mcp, save_to writes it to a local file. Without part, lists the attachments.

Path: `id`, `msg`, `part`. Arguments and behaviour match the MCP tool [`inbox_attachment`](/reference/mcp#inbox_attachment).

## Jobs [#jobs]

### Run a job [#run-a-job]

<Endpoint method="POST" path="/v0/sandboxes/{id}/jobs/{job}" permission="jobs.run · Developer+" />

Run one of the manifest's jobs now (a seed, a migration, a cron's task), from the app version the sandbox runs. Waits up to about 50 seconds, sending progress, and returns \{job, name, status, log_tail, duration_seconds\}; a failure is dependency_failed with the log tail. A job still running returns status running with next: call job_status with its name.

Path: `id`, `job`. Arguments and behaviour match the MCP tool [`job_run`](/reference/mcp#job_run).

### Job run status [#job-run-status]

<Endpoint method="GET" path="/v0/sandboxes/{id}/jobs/{job}/runs/{run}" permission="logs.read · Viewer+" />

The state of one job run (from job_run's name), waiting up to about 50 seconds for it to finish, with progress.

Path: `id`, `job`, `run`. Arguments and behaviour match the MCP tool [`job_status`](/reference/mcp#job_status).

## Proof and records [#proof-and-records]

### List proof files [#list-proof-files]

<Endpoint method="GET" path="/v0/sandboxes/{id}/proof/files" permission="logs.read · Viewer+" />

Path: `id`. 

### Attach to the proof [#attach-to-the-proof]

<Endpoint method="POST" path="/v0/sandboxes/{id}/proof/files" permission="sandbox.create · Developer+" />

Attach evidence to the sandbox's proof bundle: a screenshot, a test log, an API response. It lands in files/ of the export, with your note and its content type. Give text as content, bytes as content_base64 (or, with parity mcp, a local path); several files at once in files. Returns \{name, size, sha256, content_type\}, or \{files: [...]\} for several.

Path: `id`. Arguments and behaviour match the MCP tool [`proof_add`](/reference/mcp#proof_add).

### Export the proof [#export-the-proof]

<Endpoint method="POST" path="/v0/sandboxes/{id}/proof" permission="sandbox.create · Developer+" />

Export the proof bundle as a zip: proof.json (sandbox, commit, image digests, times, users created, your verdict), calls.jsonl (every API call this token made), inbox/*.eml, egress.json, logs/*.log and files/*. Fill claim, result and summary for the reviewer. Returns the list of entries and the zip as an embedded resource (or writes it to save_to with parity mcp).

Path: `id`. Arguments and behaviour match the MCP tool [`proof_export`](/reference/mcp#proof_export).

### Download a proof bundle [#download-a-proof-bundle]

<Endpoint method="GET" path="/v0/sandboxes/{id}/proof/{proof}" permission="logs.read · Viewer+" />

Path: `id`, `proof`. 

### List proofs [#list-proofs]

<Endpoint method="GET" path="/v0/proofs" permission="logs.read · Viewer+" />



### Get a proof [#get-a-proof]

<Endpoint method="GET" path="/v0/proofs/{proof}" permission="logs.read · Viewer+" />

Path: `proof`. 

### List records [#list-records]

<Endpoint method="GET" path="/v0/records" permission="logs.read · Viewer+" />



### Read a record's calls [#read-a-records-calls]

<Endpoint method="GET" path="/v0/records/{record}/calls" permission="logs.read · Viewer+" />

Path: `record`. 



## Public keys [#public-keys]

<Endpoint method="GET" path="/v0/keys" permission="No token" />

The ed25519 public keys Parity signs proof bundles with, as `{ "keys": [...] }`. `parity proof verify` checks bundles against them.
