Skip to main content
A client in OnboardMe is an entity. entityKey is the id you store. It does not change when a lead becomes an Active client, and it is the foreign key for contacts, eForms, proposals, bills, and onboardings. This guide is the read path. Creating a client is at the end. Creating a lead with a source, status, and opening note is Leads and deals.

Before you call

  1. Use the practice region for every request. There is no cross-region routing. See Regions.
  2. Call GET /api/v1/auth/validate once during setup. Read canWrite. Listing clients works with read-only credentials. POST /api/v1/entities does not.
  3. Store three identifiers per client:

Full import

GET /api/v1/entities/list is paged. pageNumber is 1-based, up to 10000. Keep requesting the next page until the page is empty.
List rows are the sync record. Fields you will use:
  • fullEntityName, entityEmail, entityMobile, entityTelephone
  • entityType (the practice’s type name, such as Individual or Company)
  • entityTerminated
  • partnerName, managerName, inChargeName (display names, not user keys)
  • updatedOn (UTC). This is the value you compare with your watermark.
Optional filters are case-insensitive substrings and AND together: name, otherName, surname, email. Use them for a lookup, not for the full import.
List does not return addresses or integration ids. Load those per client, below, and only for the clients you actually map.

Detail, then integrations

GET /api/v1/entities/{key} is the full client: addresses, tax and registration numbers, and custom field values that are populated. GET /api/v1/entities/{key}/integrations is the cross-system map. A null or empty id means that product is not linked for this client. Match on these ids when your product already has the client. Match on externalSystemID when you created the client from your system.

People on the client

Contacts are a separate object. A contact is a person tied to one entityKey.
  • Full sync: GET /api/v1/contacts/list with pageNumber, then lastUpdated.
  • One client: GET /api/v1/entities/{entityKey}/contacts, or GET /api/v1/contacts/list?entityKey=.
  • Soft-deleted contacts are hidden unless includeDeleted=true.
Write access is required to add or update a contact (POST and PUT on /api/v1/entities/{entityKey}/contacts).

Incremental sync

After the first import, store the greatest updatedOn you successfully persisted, in UTC. Next run:
Rules that keep the watermark honest:
  • Send UTC. A future timestamp is rejected.
  • Do not move the watermark forward until every page of that run is stored. A crash mid-page should retry the same lastUpdated.
  • The same pattern works on contacts, leads, deals, groups, and users. Bills do not use lastUpdated. They filter on bill date. See Bills.
  • lastUpdated returns rows changed on or after that time. Overlap by a minute if your clock and ours can disagree, and upsert on entityKey.
Run contacts on their own watermark. A contact can change when the client row does not.

Create a client

POST /api/v1/entities needs canWrite: true.
  1. GET /api/v1/settings/entity-types and send entityType as the code or display name (Company, Individual, Trust). entityTypeID is the numeric alternative. If both are sent, entityType wins.
  2. clientStatus is Active for a client you can bill and propose to, or Lead if they are not a client yet. For a real lead (source, status, value, opening note) use POST /api/v1/leads instead.
  3. Naming depends on type. Individuals and sole traders: entityName is the given name and entitySurname is the family name. They are not split for you. Companies: entityName is the legal or trading name, and entitySurname stays unset.
  4. Send externalSystemID if you want the client to round-trip to your id on later list and get calls.
Store the returned entityKey immediately. That is the id for every later call.

What usually goes wrong

Endpoint reference

List, get, create, integrations, and the contact routes.