Documentation

← Docs

API reference

Programmatic access to projects, reports, and webhooks. Pro keys carry read scope; Team keys carry read + write. Generate keys at /dashboard/settings/api-keys.

Auth

Every request sends an Authorization: Bearer cp_live_<secret> header. Keys are SHA-256 hashed at rest; the plaintext shown at generation time is the only copy. Revoked keys are rejected immediately.

curl https://circuitproof.vercel.app/api/v1/projects \
  -H "Authorization: Bearer cp_live_<your-secret>"

Endpoints

GET/api/v1public

Discovery payload — endpoint list + auth format + tier matrix. No auth required.

Response

{
  "object": "circuitproof_api",
  "version": "1",
  "endpoints": { ... },
  "auth": "Bearer cp_live_<secret>",
  "tiers": { "read": ["pro","team"], "write": ["team"] }
}
GET/api/v1/projectsPro / Team (read)

List the caller's projects. Paginated; archived projects excluded by default.

Query

?limit=50&offset=0&archived=0

Response

{
  "object": "list",
  "data": [
    {
      "id": "uuid",
      "name": "Sprinter van 12V",
      "jurisdiction": "NEC_690_706_710",
      "archived": false,
      "created_at": "2026-05-26T...",
      "updated_at": "2026-05-28T..."
    }
  ],
  "has_more": false,
  "total": 1
}
GET/api/v1/projects/{id}Pro / Team (read)

Single project + computed report (summary / BOM / runs / issues).

Response

{
  "object": "project",
  "id": "uuid",
  "name": "...",
  "jurisdiction": "NEC_690_706_710",
  "codebase": "nec",
  "canvas_state": { "nodes": [...], "edges": [...] },
  "summary": { "systemVoltage": 12, "batteryWh": 2400, ... },
  "bom": [{ "label": "Battery", "manufacturer": "Battle Born", "sku": "BB10012", "spec": "...", "qty": 2 }],
  "runs": [{ "from": "Battery", "to": "Inverter", "length_ft": 5, "current_a": 180, "awg": "2", "vd": 1.62, ... }],
  "issues": [{ "severity": "warning", "code": "ABYC E-11.4", "message": "..." }]
}
POST/api/v1/projectsTeam (write)

Create a project. Returns 201 + the new project record.

Request body

{
  "name": "Off-grid cabin 48V",
  "jurisdiction": "NEC_690_706_710",
  "canvas_state": { "nodes": [], "edges": [] },
  "notes": "Optional"
}
PATCH/api/v1/projects/{id}Team (write)

Partial update. Send only the fields you want to change.

Request body

{
  "name": "Renamed",
  "archived": true
}
DELETE/api/v1/projects/{id}Team (write)

Hard delete. Returns { object: 'deleted', id }.

Error codes

HTTPBody codeMeaning
400invalid_jsonBody wasn't valid JSON.
400missing_namePOST /projects without a name.
400no_fields_to_updatePATCH with an empty body.
401unauthorizedMissing / malformed / revoked key.
403tier_lockedCaller's tier doesn't include API access.
403scope_requiredRead-only key on a write endpoint.
404not_foundProject ID unknown or owned by another user.
500insert_failed / update_failed / delete_failedDB error; the message field carries the underlying detail.

Webhooks

Team-tier endpoints can receive HTTP POSTs on project + report + share + AI events. Manage at /dashboard/settings/webhooks.

Every delivery carries a X-CircuitProof-Signature: t=<unix>,v1=<hex> header. The v1 hex is HMAC-SHA256(secret, `$${t}.$${rawBody}`). Verify on every receipt:

// Node receiver pseudo-code
const sig = req.headers["x-circuitproof-signature"]; // "t=...,v1=..."
const [t, v1] = sig.split(",").map(p => p.split("=")[1]);
const expected = crypto.createHmac("sha256", SECRET)
  .update(`${t}.${rawBody}`)
  .digest("hex");

if (expected !== v1) return reject();                           // signature mismatch
if (Date.now() / 1000 - Number(t) > 300) return reject();       // > 5 min old — replay

Event types currently shipped:

  • project.created
  • project.archived
  • project.deleted
  • report.pdf_generated
  • report.dxf_generated
  • share.link_created
  • ai.summary_requested
  • dfy.intake_submitted

Rate limits

Fair-use; no hard quota today. We log per-key request volume and will publish per-tier limits before surprising any caller. If you need higher sustained throughput than ~10 req/sec, reach the CircuitProof Team via any onboarding email and we'll raise it.

Stability

The /api/v1 surface is committed-stable: additive changes only, no breaking changes without a version bump. New endpoints will land at the same /api/v1 prefix; deprecations announced ≥90 days before removal.

Questions or missing capabilities? Reply to any onboarding email and the CircuitProof Team will get back to you. PRs against an OpenAPI spec (planned for v1.1) will be welcome on the public repo.