# HVAKR API Cloud HVAC design platform for mechanical engineers. This is the public v0 REST API. All numeric values are in data units: airflows in CFM, loads in BTU/h, lengths in inches, temperatures in °F. ## Auth Send an access token as `Authorization: Bearer `. Create tokens in your HVAKR account settings. Firebase ID tokens are also accepted for first-party callers. ## Base URL https://api.hvakr.com/v0 ## Errors Every error response uses the envelope: { "error": { "code": "", "message": "", "details"?: }, "requestId": "" } `requestId` matches the `X-Request-Id` response header. `code` is one of: invalid_request, validation_failed, unauthenticated, permission_denied, not_found, method_not_allowed, conflict, rate_limited, internal. ## Rate limiting & idempotency Responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`. The per-minute limit is set by your plan: Enterprise 1200, all other paid plans 120. A 429 includes `Retry-After`. Retry POSTs safely by sending an `Idempotency-Key` header. API access requires a paid plan; Pay-Per-Project does not include API access (403). Official SDKs send `X-HVAKR-Client: /`; if your client is outdated the response includes an `X-HVAKR-Client-Warning` header telling you to upgrade. ## Endpoints - GET /me — the authenticated caller: identity, organizations, plan, and rate-limit budget. A good first call. - GET /projects?limit&cursor&search&status&projectType — list accessible projects (paginated). search filters name/number/address; status and projectType are exact filters - POST /projects — create a project (Idempotency-Key supported) - GET /projects/{id}?expand — get a project. expand: absent/false = base; true = all subcollections; or a comma list (e.g. spaces,zones,exports). exports are returned in the public export shape (id, status, downloadUrl when completed) - PATCH /projects/{id} — deep-merge update (null values delete) - DELETE /projects/{id} — soft-delete (OWNER only) - GET /projects/{id}/calculations?include — run the calculator once and return the requested sections. include: comma list of loads, register_schedule, dryside_graph, ventilation, equipment, checksums, airflows (omit for all — the response can be large) - POST /projects/{id}/jobs — create a job (Idempotency-Key supported). body.type: export | auto-group | check | auto-takeoff. auto-group/check run synchronously and return status "completed" with a result; export/auto-takeoff return "queued". export definitions: load-calculation, basis-of-design, ventilation-csv, hourly-loads-csv - POST /projects/{id}/sheet-files — multipart upload exactly one application/pdf file (maximum 30 MiB; optional display-name field name; Idempotency-Key supported). Returns a sheet-upload job. Do not set the multipart boundary manually in SDK clients. - GET /projects/{id}/jobs/{jobId} — poll a job; export jobs report their linked export's status + downloadUrl, and sheet-upload jobs report extracted pages, active placement, and readyForTakeoff - GET /products?search&limit&cursor — list accessible catalog products (org + public, paginated); search filters name/manufacturer/model - GET /products/{id} — get a single catalog product ## Revit ingestion (versioned independently, not under /v0) - POST https://api.hvakr.com/revit/v0/projects — create a project from a Revit plugin payload (Idempotency-Key supported) - PATCH https://api.hvakr.com/revit/v0/projects/{id} — merge a Revit plugin payload into a project (imports new Revit spaces) ## Machine-readable spec OpenAPI 3 JSON: https://api.hvakr.com/v0/docs/openapi.json Interactive docs: https://api.hvakr.com/v0/docs/ ## Sheet upload workflow Upload a PDF with POST /projects/{id}/sheet-files, then poll its returned jobId through GET /projects/{id}/jobs/{jobId}. A completed job can have readyForTakeoff:false when no extracted page is actively placed; repair placement with PATCH /projects/{id} using its sheets subcollection, then run POST /projects/{id}/jobs with {"type":"auto-takeoff"}. Auto-takeoff is project-wide: it runs every active placed sheet and eligible map, not only this upload.