Welcome to the Coperniq API release notes. This section highlights noteworthy changes across endpoints, schemas, and docs.

Recent highlights

  • New: AHJs — GET /ahjs (search, filter, and lat+lng geo lookup), GET /ahjs/{id}, and PATCH /ahjs/{id} to update custom property values. v2 mirrors these under /v2 with the standard success envelope.
  • Updated: GET /properties — now documents the ahj record type (custom AHJ properties only) and adds an isCustom boolean to every property to distinguish custom columns from built-in standard ones.
  • New: Sections — line items on projects, invoices, and bills can now be grouped into named sections (matching quotes and work orders); read responses expose sectionName per line item.
  • New: Vendors — full CRUD via GET/POST /vendors, GET/PATCH/DELETE /vendors/{vendorId}, GET /vendors/search, and many-to-many project linking via POST/DELETE /projects/{projectId}/vendors/{vendorId}. Vendor-specific fields: vendorType (enum), website, and projectIds.
  • New: Labels — GET /labels (filter by type), POST /labels, GET /labels/{labelId}. type is WORK (work orders) or ASSET. v2 mirrors these under /v2 with the standard success envelope.
  • New: Assets — GET /assets (filter by account_id), POST /assets, GET/PATCH /assets/{assetId} (set isArchived: true via PATCH to archive). v2 mirrors these under /v2 with the standard success envelope.

Looking for a specific date? See the entries below.

Project & opportunity title fallback

When a project or opportunity has no title of its own (empty string or whitespace-only), the API now returns the parent account’s title in the title field instead of the blank value.

This applies to all read endpoints that return project or opportunity records:

  • GET /projects, GET /projects/search, GET /projects/{projectId}
  • GET /opportunities, GET /opportunities/search, GET /opportunities/{opportunityId}

Behavior

Record titleParent account titleResponse title
"Roof replacement""Acme Co""Roof replacement"
"" (empty)"Acme Co""Acme Co"
" " (whitespace)"Acme Co""Acme Co"
"""" or no parent""

The underlying stored record is not modified — this is a read-time fallback only. Write endpoints (POST, PATCH) continue to accept and persist titles exactly as provided.

Why

Many integrations rely on title being a meaningful, human-readable label (list views, search results, downstream syncs). Projects that were created without a title were surfacing as blank rows, which was confusing. Falling back to the parent account’s title gives consumers a sensible default without changing the source of truth.