Exergy Lab
Browse developer guides
API guide·10 min read·Private beta

Workspace API and integrations

Use the current same-origin workspace endpoints and understand what is—and is not—available as a public API today.

Current API status

The application has an authenticated JSON API used by the web workspace. It supports project creation, file upload, durable agent runs, polling, and server-sent run events.

External API keys, service accounts, published SDKs, and a versioned public base URL are not self-serve yet. Treat the routes below as same-origin workspace endpoints, not a stable third-party contract. Organizations can contact the team about private-beta integration planning.

Do not expose a browser session cookie

Current endpoints authenticate with the signed-in web session or an anonymous trial cookie. Do not copy those cookies into a server, mobile app, repository, or third-party automation.

Same-origin example

A custom component running inside the Exergy Lab web origin can create a project and start a run with the existing session. The server remains authoritative for ownership, account status, tier, quota, and minimum reasoning budget.

Create a projectjavascript
const projectResponse = await fetch("/api/projects", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "North loop heat recovery",
    domain: "district_heating",
    description: "Screen an 88 °C source against the winter load.",
    goal: "Decide whether to fund a site study."
  })
});

if (!projectResponse.ok) throw await projectResponse.json();
const project = await projectResponse.json();
Start a durable runjavascript
const runResponse = await fetch(`/api/projects/${project.id}/runs`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID()
  },
  body: JSON.stringify({
    message: "Assess technical fit, show the governing calculation, and state what is not proven.",
    mode: "implement",
    document_ids: []
  })
});

// 202 means the durable run was accepted, not that analysis is complete.
const { run, events } = await runResponse.json();

Workspace endpoint reference

GET
/api/projects

List projects owned by the current actor.

Project summaries

POST
/api/projects

Create an account or anonymous-trial project.

201 + project

GET
/api/projects/{project_id}

Read one owned project and its current records.

Project, documents, artifacts, actions, runs

PATCH
/api/projects/{project_id}

Update the project name, description, or goal.

200 + ok

POST
/api/projects/{project_id}/documents

Upload one multipart file under the 25 MB ceiling.

201 + document and extraction status

POST
/api/projects/{project_id}/runs

Create and enqueue a durable agent run.

202 + run and initial events

GET
/api/projects/{project_id}/runs/{run_id}

Poll authoritative run state and events.

Run and events

GET
/api/projects/{project_id}/runs/{run_id}/events

Stream ordered run events over SSE.

text/event-stream

Errors and safe retries

  • 400: invalid request input. Fix the request before retrying.
  • 401: no usable identity. Sign in or establish an anonymous trial session in the browser.
  • 403: the account tier or lifecycle state does not authorize the feature. Read code, required_tier, and upgrade_url when present.
  • 404: missing or inaccessible project/run. Ownership failures intentionally use the same response to prevent enumeration.
  • 429: quota exhausted. Do not retry until the stated window resets or the account changes plan.
  • 503: account, usage, storage, or verifier state could not be checked safely. No work should be assumed complete or charged.
Structured lock examplejson
{
  "error": "Report exports requires Plus or Pro.",
  "code": "upgrade_required",
  "feature": "report_export",
  "current_tier": "free",
  "required_tier": "plus",
  "upgrade_url": "/pricing"
}