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.

Sites endpoints

Full CRUD support for site records via the public API.

Sites are address/location records that belong to an account. A single account may have multiple sites.

Endpoints

MethodPathDescription
GET/sitesList all sites. Optionally filter by accountId.
POST/sitesCreate a new site.
GET/sites/{siteId}Get a site by ID.
PATCH/sites/{siteId}Update a site.
DELETE/sites/{siteId}Delete a site.
POST/sites/{siteId}/moveMove a site to a different account.

Create a site

accountId is required. Either fullAddress or geoLocation must also be provided. The backend automatically geocodes fullAddress and checks for duplicate addresses — if a site with the same address already exists for the same account, the existing site is returned (200) instead of creating a duplicate.

POST /sites
1{
2 "accountId": 714570,
3 "fullAddress": "123 Main St, San Francisco, CA 94105",
4 "title": "Main Office",
5 "timezone": "America/Los_Angeles"
6}

List sites by account

GET /sites?accountId=714570

Update a site

All fields are optional. Updating fullAddress triggers re-geocoding. To move a site to a different account, use POST /sites/{siteId}/move.

PATCH /sites/9876
1{
2 "title": "Updated Office Name",
3 "fullAddress": "456 Oak Ave, San Francisco, CA 94107"
4}

Move a site to a different account

Moves the site and all associated records to a different account. The original site is permanently deleted and a new site is created on the target account. ⚠️ This operation is irreversible.

POST /sites/9876/move
1{
2 "accountId": 789224
3}