Coperniq accounts API
The accounts API from Coperniq — 3 operation(s) for accounts.
The accounts API from Coperniq — 3 operation(s) for accounts.
openapi: 3.1.0
info:
title: API Key accounts API
version: 1.0.0
servers:
- url: https://api.coperniq.io/v1
description: Production server
tags:
- name: accounts
paths:
/accounts:
get:
operationId: list-accounts
summary: List Accounts
description: 'Retrieve a paginated list of accounts.
Supports:
- Pagination (`page_size`, `page`)
- Date filtering (`updated_after`, `updated_before`)
- Sorting (`order_by`, default: desc)
- Field search (`title`, `address`, `primaryName`, `primaryPhone`, `primaryEmail`)
- Full text search (`q`)
**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.
'
tags:
- accounts
parameters:
- name: page_size
in: query
description: Number of items per page (max 100)
required: false
schema:
type: integer
default: 20
- name: page
in: query
description: Page number (1-based)
required: false
schema:
type: integer
default: 1
- name: updated_after
in: query
description: Filter items updated after this timestamp (ISO 8601)
required: false
schema:
type: string
format: date-time
- name: updated_before
in: query
description: Filter items updated before this timestamp (ISO 8601)
required: false
schema:
type: string
format: date-time
- name: order_by
in: query
description: Sort order for results
required: false
schema:
$ref: '#/components/schemas/AccountsGetParametersOrderBy'
- name: include_virtual_properties
in: query
description: Whether to include virtual properties in the response. Defaults to false unless explicitly set to true.
required: false
schema:
type: boolean
default: false
- name: include_contacts
in: query
description: Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.
required: false
schema:
type: boolean
default: false
- name: include_archived
in: query
description: Whether to include archived (inactive) records in the response. By default only active records are returned.
required: false
schema:
type: boolean
default: false
- name: q
in: query
description: Full text search query
required: false
schema:
type: string
- name: title
in: query
description: Title search query
required: false
schema:
type: string
- name: address
in: query
description: Address search query
required: false
schema:
type: string
- name: primaryName
in: query
description: Contact name search query
required: false
schema:
type: string
- name: primaryPhone
in: query
description: Contact phone search query
required: false
schema:
type: string
- name: primaryEmail
in: query
description: Contact email search query
required: false
schema:
type: string
- name: x-api-key
in: header
required: true
schema:
type: string
responses:
'200':
description: List of accounts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Account'
'401':
description: Authentication failed
content:
application/json:
schema:
$ref: '#/components/schemas/ListAccountsRequestUnauthorizedError'
post:
operationId: create-account
summary: Create Account
description: 'Create a new account with required and optional fields.
Required fields:
- `title`: Account name
- `address`: Account location
Optional fields:
- `accountType`: Account type (RESIDENTIAL/COMMERCIAL)
- `value`: Account value
- `size`: Account size
- `primaryEmail`/`primaryPhone`: Contact information
- `contacts`: Contact IDs only (no name, email, phone, etc.). **The contacts must be created first via POST /contacts.**
- `custom`: Custom fields object
Note: If primaryEmail or primaryPhone is provided and no contacts are provided, a contact will be automatically created or matched.
**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.
'
tags:
- accounts
parameters:
- name: allow_new_options
in: query
description: Whether to allow creation of new dropdown options during record creation
required: false
schema:
type: boolean
default: false
- name: match_by
in: query
description: Field to use for matching existing records
required: false
schema:
$ref: '#/components/schemas/AccountsPostParametersMatchBy'
- name: match_found_strategy
in: query
description: Strategy to use when a match is found
required: false
schema:
$ref: '#/components/schemas/AccountsPostParametersMatchFoundStrategy'
- name: x-api-key
in: header
required: true
schema:
type: string
responses:
'200':
description: Matching account found
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAccountRequestBadRequestError'
'401':
description: Authentication failed
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAccountRequestUnauthorizedError'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AccountUpsert'
/accounts/search:
get:
operationId: search-accounts
summary: Search Accounts
description: "Search accounts using up to two filters (prop1/op1/value1 and optionally prop2/op2/value2), combined with `logic` (AND/OR).\n\nProperties:\n- `propX` can be a standard field (e.g., `status`, `title`, `city`, `type`, `accountId`, etc.) or a custom property key name.\n- Use the `property key` from your company settings.\n- Filter by parent account with `accountId`. `clientId` is accepted as a deprecated alias for backwards compatibility.\n\nOperators (`opX`):\n- Equality: `eq`, `neq`\n- Numeric/datetime comparisons: `gt`, `gte`, `lt`, `lte`\n- Text/string matching: `contains` (case-insensitive)\n- Lists: `in`, `nin` (CSV list in `valueX`)\n- Ranges: `between` (use `valueX` as `from,to`)\n- Existence: `exists` is not supported for custom properties due to performance limitations. Use `eq` or `neq` instead.\n\nValue formats:\n- `in`/`nin`: lists can be provided as:\n - Plain CSV: `value1=OPEN,ACTIVE`\n - Quoted CSV (to include commas inside a value): `value1=\"Last, First\",Other`\n - JSON array: `value1=[\"Last, First\",\"Other\"]`\n- `between`: `from,to` (e.g., `value1=2025-01-01,2025-12-31` or `value1=10,20`)\n- Dates should be ISO 8601 strings; numeric-like values on custom properties are matched against both numeric and text representations.\n\nExamples:\n- status equals ACTIVE: `?prop1=status&op1=eq&value1=ACTIVE`\n- custom id equals 1234: `?prop1=legacy_tool_project_id&op1=eq&value1=1234`\n- title contains \"Solar\": `?prop1=name&op1=contains&value1=Solar`\n- status IN (ACTIVE, ON_HOLD) AND city = Austin: `?prop1=status&op1=in&value1=ACTIVE,ON_HOLD&logic=and&prop2=city&op2=eq&value2=Austin`\n\n**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.\n"
tags:
- accounts
parameters:
- name: prop1
in: query
description: First field to filter (standard or custom keyName)
required: true
schema:
type: string
- name: op1
in: query
description: Operator for prop1
required: true
schema:
$ref: '#/components/schemas/AccountsSearchGetParametersOp1'
- name: value1
in: query
description: Value for prop1 (comma-separated values for in/nin or between)
required: true
schema:
type: string
- name: logic
in: query
description: Logical combination when both prop1 and prop2 are provided
required: false
schema:
$ref: '#/components/schemas/AccountsSearchGetParametersLogic'
- name: prop2
in: query
description: Optional second field to filter
required: false
schema:
type: string
- name: op2
in: query
description: Operator for prop2
required: false
schema:
$ref: '#/components/schemas/AccountsSearchGetParametersOp2'
- name: value2
in: query
description: Value for prop2 (comma-separated values for in/nin or between)
required: false
schema:
type: string
- name: page_size
in: query
description: Number of items per page (max 100)
required: false
schema:
type: integer
default: 20
- name: page
in: query
description: Page number (1-based)
required: false
schema:
type: integer
default: 1
- name: order_by
in: query
description: Sort order for results
required: false
schema:
$ref: '#/components/schemas/AccountsSearchGetParametersOrderBy'
- name: include_archived
in: query
description: Whether to include archived (inactive) records in the response. By default only active records are returned.
required: false
schema:
type: boolean
default: false
- name: x-api-key
in: header
required: true
schema:
type: string
responses:
'200':
description: List of accounts matching filters
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Account'
'400':
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/SearchAccountsRequestBadRequestError'
'401':
description: Authentication failed
content:
application/json:
schema:
$ref: '#/components/schemas/SearchAccountsRequestUnauthorizedError'
/accounts/{accountId}:
get:
operationId: get-account
summary: Get Account
description: 'Retrieve a specific account by ID
**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.
'
tags:
- accounts
parameters:
- name: accountId
in: path
description: Account identifier
required: true
schema:
type: integer
- name: include_virtual_properties
in: query
description: Whether to include virtual properties in the response. Defaults to false unless explicitly set to true.
required: false
schema:
type: boolean
default: false
- name: include_contacts
in: query
description: Whether to include associated contacts in the response. Defaults to false unless explicitly set to true.
required: false
schema:
type: boolean
default: false
- name: include_archived
in: query
description: Whether to include archived (inactive) records in the response. By default only active records are returned.
required: false
schema:
type: boolean
default: false
- name: x-api-key
in: header
required: true
schema:
type: string
responses:
'200':
description: Account details
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'401':
description: Authentication failed
content:
application/json:
schema:
$ref: '#/components/schemas/GetAccountRequestUnauthorizedError'
'404':
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/GetAccountRequestNotFoundError'
patch:
operationId: update-account
summary: Update Account
description: 'Update an existing account. Supports partial updates.
Updatable fields:
- Standard fields (title, description, address, accountType, isActive)
- Contact information (primaryEmail, primaryPhone)
- `contacts`: Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts.
- Custom fields (through custom object)
Note: Updates are atomic - either all fields update or none do.
**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.
'
tags:
- accounts
parameters:
- name: accountId
in: path
description: Account identifier
required: true
schema:
type: integer
- name: allow_new_options
in: query
description: Whether to allow creation of new dropdown options during record creation
required: false
schema:
type: boolean
default: false
- name: x-api-key
in: header
required: true
schema:
type: string
responses:
'200':
description: Account updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Account'
'400':
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateAccountRequestBadRequestError'
'401':
description: Authentication failed
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateAccountRequestUnauthorizedError'
'404':
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateAccountRequestNotFoundError'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AccountUpdate'
delete:
operationId: delete-account
summary: Delete Account
description: 'Delete a specific account by ID
**Note:** The `/clients` path is an alias for `/accounts` and will continue to work until users are individually notified and migrated.
'
tags:
- accounts
parameters:
- name: accountId
in: path
description: Account identifier
required: true
schema:
type: integer
- name: x-api-key
in: header
required: true
schema:
type: string
responses:
'200':
description: Successful response
'401':
description: Authentication failed
content:
application/json:
schema:
$ref: '#/components/schemas/DeleteAccountRequestUnauthorizedError'
'404':
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/DeleteAccountRequestNotFoundError'
components:
schemas:
AccountsSearchGetResponsesContentApplicationJsonSchemaCode:
type: string
enum:
- UNAUTHORIZED
title: AccountsSearchGetResponsesContentApplicationJsonSchemaCode
GetAccountRequestNotFoundError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsAccountIdGetResponsesContentApplicationJsonSchemaCode'
title: GetAccountRequestNotFoundError
UpdateAccountRequestBadRequestError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode'
field:
type: string
description: Field that caused the validation error (if applicable)
title: UpdateAccountRequestBadRequestError
Account:
type: object
properties:
id:
type: integer
description: Unique identifier
createdAt:
type: string
format: date-time
description: Creation timestamp
updatedAt:
type: string
format: date-time
description: Last update timestamp
title:
type: string
description: Record title/name
description:
type:
- string
- 'null'
description: Record description
address:
type: array
items:
type: string
description: Record location/address
isActive:
type: boolean
description: Whether the record is active
primaryEmail:
type:
- string
- 'null'
format: email
description: Primary contact email
primaryPhone:
type:
- string
- 'null'
description: Primary contact phone
number:
type: integer
description: Record number (e.g., 1234)
createdBy:
oneOf:
- $ref: '#/components/schemas/UserSummary'
- type: 'null'
description: User who created the record. Null when the record was created by a non-user actor (e.g. automation or a contact).
updatedBy:
oneOf:
- $ref: '#/components/schemas/UserSummary'
- type: 'null'
description: User who last edited a field on the record, derived from the changelog. Null when the record has never been edited or the last edit was made by a non-user actor.
custom:
type: object
additionalProperties:
description: Any type
description: Custom fields
accountType:
oneOf:
- $ref: '#/components/schemas/AccountAccountType'
- type: 'null'
description: Type of account (residential or commercial)
contacts:
type: array
items:
$ref: '#/components/schemas/AccountContactsItems'
title: Account
AccountUpdateAccountType:
type: string
enum:
- RESIDENTIAL
- COMMERCIAL
description: Account type
title: AccountUpdateAccountType
AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode:
type: string
enum:
- NOT_FOUND
title: AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode
DeleteAccountRequestUnauthorizedError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsAccountIdDeleteResponsesContentApplicationJsonSchemaCode'
title: DeleteAccountRequestUnauthorizedError
UpdateAccountRequestNotFoundError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode'
title: UpdateAccountRequestNotFoundError
AccountsSearchGetParametersOp2:
type: string
enum:
- eq
- neq
- gt
- gte
- lt
- lte
- contains
- in
- nin
- between
title: AccountsSearchGetParametersOp2
CreateAccountRequestUnauthorizedError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsPostResponsesContentApplicationJsonSchemaCode'
title: CreateAccountRequestUnauthorizedError
AccountUpdate:
type: object
properties:
title:
type: string
description: Account name
description:
type:
- string
- 'null'
description: Account description
address:
type: array
items:
type: string
description: An array containing a single string, which represents the primary account location/address.
accountType:
oneOf:
- $ref: '#/components/schemas/AccountUpdateAccountType'
- type: 'null'
description: Account type
primaryEmail:
type:
- string
- 'null'
format: email
description: Primary contact email
primaryPhone:
type:
- string
- 'null'
description: Primary contact phone
contacts:
type:
- array
- 'null'
items:
type: integer
description: Contact IDs to associate with this account. The contacts must be created first via POST /contacts.
isActive:
type: boolean
description: Whether the account is active
custom:
type: object
additionalProperties:
description: Any type
description: Custom fields
description: Partial update payload for an account. All fields are optional.
title: AccountUpdate
SearchAccountsRequestBadRequestError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsSearchGetResponsesContentApplicationJsonSchemaCode'
field:
type: string
description: Field that caused the validation error (if applicable)
title: SearchAccountsRequestBadRequestError
AccountUpsert:
type: object
properties:
title:
type: string
description: Account name
description:
type:
- string
- 'null'
description: Account description
address:
type: array
items:
type: string
description: An array containing a single string, which represents the primary account location/address.
accountType:
$ref: '#/components/schemas/AccountUpsertAccountType'
description: Account type
primaryEmail:
type: string
format: email
description: Primary contact email
primaryPhone:
type: string
description: Primary contact phone
contacts:
type:
- array
- 'null'
items:
type: integer
description: Contact IDs only (no name, email, phone, etc.). The contacts must be created first via POST /contacts.
custom:
type: object
additionalProperties:
description: Any type
description: Custom fields
required:
- title
- address
title: AccountUpsert
AccountsGetResponsesContentApplicationJsonSchemaCode:
type: string
enum:
- UNAUTHORIZED
title: AccountsGetResponsesContentApplicationJsonSchemaCode
CreateAccountRequestBadRequestError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsPostResponsesContentApplicationJsonSchemaCode'
field:
type: string
description: Field that caused the validation error (if applicable)
title: CreateAccountRequestBadRequestError
AccountsAccountIdGetResponsesContentApplicationJsonSchemaCode:
type: string
enum:
- NOT_FOUND
title: AccountsAccountIdGetResponsesContentApplicationJsonSchemaCode
AccountsSearchGetParametersOrderBy:
type: string
enum:
- asc
- desc
default: asc
title: AccountsSearchGetParametersOrderBy
AccountsPostParametersMatchBy:
type: string
enum:
- title
- primaryEmail
- primaryPhone
- address
default: title
title: AccountsPostParametersMatchBy
AccountsPostParametersMatchFoundStrategy:
type: string
enum:
- skip
- replace
- enrich
default: skip
description: '- skip: Return existing record without changes
- replace: Replace existing record with new data
- enrich: Update only empty fields in existing record
'
title: AccountsPostParametersMatchFoundStrategy
AccountUpsertAccountType:
type: string
enum:
- RESIDENTIAL
- COMMERCIAL
description: Account type
title: AccountUpsertAccountType
SearchAccountsRequestUnauthorizedError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsSearchGetResponsesContentApplicationJsonSchemaCode'
title: SearchAccountsRequestUnauthorizedError
DeleteAccountRequestNotFoundError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsAccountIdDeleteResponsesContentApplicationJsonSchemaCode'
title: DeleteAccountRequestNotFoundError
AccountsAccountIdDeleteResponsesContentApplicationJsonSchemaCode:
type: string
enum:
- NOT_FOUND
title: AccountsAccountIdDeleteResponsesContentApplicationJsonSchemaCode
AccountsGetParametersOrderBy:
type: string
enum:
- asc
- desc
default: asc
title: AccountsGetParametersOrderBy
AccountsPostResponsesContentApplicationJsonSchemaCode:
type: string
enum:
- UNAUTHORIZED
title: AccountsPostResponsesContentApplicationJsonSchemaCode
AccountAccountType:
type: string
enum:
- RESIDENTIAL
- COMMERCIAL
description: Type of account (residential or commercial)
title: AccountAccountType
GetAccountRequestUnauthorizedError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsAccountIdGetResponsesContentApplicationJsonSchemaCode'
title: GetAccountRequestUnauthorizedError
UserSummary:
type: object
properties:
id:
type: integer
firstName:
type:
- string
- 'null'
lastName:
type:
- string
- 'null'
email:
type:
- string
- 'null'
format: email
avatarUrl:
type:
- string
- 'null'
description: Minimal user representation used in responses
title: UserSummary
UpdateAccountRequestUnauthorizedError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsAccountIdPatchResponsesContentApplicationJsonSchemaCode'
title: UpdateAccountRequestUnauthorizedError
AccountsSearchGetParametersLogic:
type: string
enum:
- and
- or
default: and
title: AccountsSearchGetParametersLogic
ListAccountsRequestUnauthorizedError:
type: object
properties:
message:
type: string
code:
$ref: '#/components/schemas/AccountsGetResponsesContentApplicationJsonSchemaCode'
title: ListAccountsRequestUnauthorizedError
AccountsSearchGetParametersOp1:
type: string
enum:
- eq
- neq
- gt
- gte
- lt
- lte
- contains
- in
- nin
- between
title: AccountsSearchGetParametersOp1
AccountContactsItems:
type: object
properties:
id:
type: integer
emails:
type: array
items:
type: string
phones:
type: array
items:
type: string
title: AccountContactsItems
securitySchemes:
BasicAuth:
type: http
scheme: basic