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

Recent highlights

  • 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.
  • New: Invoice payments — GET /invoices/{invoiceId}/payments, GET /invoices/{invoiceId}/payments/{paymentId}, and POST /invoices/{invoiceId}/payments (optional paymentReference on create).
  • New: Quotes — full CRUD via GET/POST /quotes, GET/PATCH/DELETE /quotes/{quoteId}, GET /quotes/{quoteId}/pdf, POST /quotes/{quoteId}/send, and GET /opportunities/{opportunityId}/quotes.
  • New: Work order line items — PUT /work-orders/{workOrderId}/line-items replaces line items on service work orders (account type). GET /work-orders/{workOrderId} now includes lineItems when present.
  • New: Taxes — GET /taxes lists company tax rates with pagination and archived filtering.
  • New: Bills — full CRUD for project bills via GET/POST /bills, GET/PATCH/DELETE /bills/{billId}, and GET /projects/{projectId}/bills. Supports LINE_ITEMS and PERCENTAGE calculation methods.
  • Improvement: Nullable fields on PATCH /projects/{projectId}, PATCH /accounts/{accountId}, and PATCH /clients/{clientId} — pass null to clear a field (e.g. description, ownerId, primaryEmail) or any custom property.

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}