Reference: Providers (V1) Endpoint Documentation
Providers represent dentists, hygienists, and other clinical staff in your organization. Use these endpoints to list providers, retrieve individual records, create new providers, and update existing ones. Providers are referenced by linked model { id } on appointments, clinical notes, and other resources.
There is no REST DELETE endpoint for providers.
GET — Bulk List Providers — click to expand
Returns a paginated list of providers filtered by the provided criteria.
⚠️ Rate Limited: This endpoint is rate limited. See the rate limiting guide for details.
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
Organization-ID | header | Yes | string | The organization ID |
filter | query | No | string | Filter criteria (see filter keys below). If omitted, a default date-limiting filter may be applied automatically. |
responseFields | query | No | string | Comma-delimited list of fields to include, or ALL |
pageSize | query | No | string | Number of records per page (default 100, maximum 500) |
lastId | query | No | string | Largest provider id from the previous page, used for cursor pagination |
✅ Recommended: Use
lastIdcursor pagination for large result sets (see below). Combine withlastModifiedfilters to scope changes over time.
| Filter Key | Operators | Example |
|---|---|---|
id | -> | ?filter=id->[1000000020702,1000000020703] |
location.id | ==, -> | ?filter=location.id==64000000000004 |
user.id | ==, -> | ?filter=user.id==12000006542062 |
lastModified | >, >=, <, <= | ?filter=lastModified>=2025-01-01T00:00:00.000Z |
When filtering by lastModified, results are returned in descending order (newest first). Use lastId with date filters for stable cursor pagination.
Combine filters with commas, for example: filter=location.id==64000000000004,lastModified>2025-01-01T00:00:00.000Z.
Note: A very wide
lastModifiedrange with no other scoping can return 408 (timeout) on large tenants. Narrow your filter and retry.
Fetch providers modified since a date:
GET /api/v1/providers?filter=lastModified>=2025-01-01T00:00:00.000ZFetch providers at a specific location:
GET /api/v1/providers?filter=location.id==64000000000004Fetch specific providers by ID:
GET /api/v1/providers?filter=id->[1000000020702,1000000020703]Paginating with `lastId` — click to expand
lastId uses the provider's id as a cursor. Pass the largest id from the previous page as lastId for the next request.
When lastId is present, meta.pagination.total is not included in the response. Use GET /v1/providers/totalcount when you need a record count. See also Bulk GET — Total Count Behavior.
Send the first request without lastId:
GET /api/v1/providers?pageSize=500&filter=lastModified>2025-01-01T00:00:00.000ZUse the id of the last object in the data array as lastId:
GET /api/v1/providers?lastId=1000000020703&pageSize=500&filter=lastModified>2025-01-01T00:00:00.000ZContinue until data is empty or you have retrieved all records you need.
GET — Total Count — click to expand
Returns the number of provider records matching a filter.
GET /api/v1/providers/totalcountUses the same filter syntax and filter keys as bulk GET. Only Organization-ID and filter apply — pagination query parameters are not used on this endpoint.
GET /api/v1/providers/totalcount?filter=lastModified>=2025-01-01T00:00:00.000Z,location.id==64000000000004| Field | Type | Description |
|---|---|---|
data.totalCount | integer | Number of providers matching the filter |
{
"data": {
"totalCount": 42
},
"warnings": [],
"errors": []
}GET — Provider by ID — click to expand
Returns a single provider by its ID.
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
providerId | path | Yes | integer | The ID of the provider |
Organization-ID | header | Yes | string | The organization ID |
responseFields | query | No | string | Comma-delimited list of fields to include, or ALL |
GET /api/v1/providers/1000000020702A provider that does not exist in your organization returns 404 with ProviderV1 not found.
POST — Create Provider — click to expand
Creates a new provider. Returns 201 with the created resource in data.
All create requests require:
| Field | Type | Description |
|---|---|---|
firstName | string | 1–25 characters |
lastName | string | 1–50 characters |
shortName | string | 3–6 characters |
specialty | string | Provider specialty enum (see below) |
isPrimaryProvider | boolean | Whether this provider is the primary provider |
address1 | string | Street address, max 50 characters |
city | string | Max 30 characters |
state | string | US state or territory code (e.g. CA, TX) |
postalCode | string | 5–10 characters |
When isPrimaryProvider is true, or when specialty is not HYGIENIST, these fields are also required:
| Field | Type | Description |
|---|---|---|
npi | string | National Provider Identifier, max 10 characters |
stateId | string | State license number, 1–20 characters |
tin | string | Tax identification number, exactly 9 numeric digits |
DENTALPUBLICHEALTH, DENTALSPECIALTY, DENTIST, DENTAL, ENDODONTICS, FEDERALLYQUALIFIEDHEALTHCENTER, GENERALPRACTICE, HYGIENIST, MULTISPECIALTY, ORTHODONTICS, ORALMAXILLOFACIALPATHOLOGY, ORALMAXILLOFACIALRADIOLOGY, ORALMAXILLOFACIALSURGERY, PEDIATRICDENTISTRY, PERIODONTICS, PROSTHODONTICS, SINGLESPECIALTY
Scenario 1 — POST: Create a Primary Dentist — click to expand
Use when creating a dentist who is the primary provider. Requires npi, stateId, and tin.
{
"firstName": "John",
"lastName": "Doe",
"shortName": "JD-DDS",
"specialty": "DENTIST",
"isPrimaryProvider": true,
"npi": "1234567893",
"stateId": "DDS-12345",
"tin": "123456789",
"color": "ffffff",
"address1": "123 Main St",
"address2": "Suite 100",
"city": "Salt Lake City",
"state": "UT",
"postalCode": "84103"
}Scenario 2 — POST: Create a Hygienist Without Identifiers — click to expand
Use when creating a hygienist who is not the primary provider. npi, stateId, and tin can be omitted.
{
"firstName": "Jane",
"lastName": "Smith",
"shortName": "J-HYG",
"specialty": "HYGIENIST",
"isPrimaryProvider": false,
"color": "ffffff",
"address1": "123 Main St",
"city": "Salt Lake City",
"state": "UT",
"postalCode": "84103"
}Scenario 3 — POST: Create a Provider With a Linked User — click to expand
Use when creating a provider and assigning an existing user account. The user must not already be assigned to another provider.
{
"firstName": "John",
"lastName": "Doe",
"shortName": "JD-DDS",
"specialty": "DENTIST",
"isPrimaryProvider": true,
"npi": "1234567893",
"stateId": "DDS-12345",
"tin": "123456789",
"address1": "123 Main St",
"city": "Salt Lake City",
"state": "UT",
"postalCode": "84103",
"user": {
"id": 12000006542062
}
}PUT — Update Provider — click to expand
Updates an existing provider. Only fields included in the request body are changed; omitted fields remain unchanged.
Returns 200 with the updated resource. By default, the response includes only modified fields (responseFields=MODIFIED). Use ?responseFields=ALL when you need the full resource after update.
PUT /api/v1/providers/1000000020702?responseFields=ALLScenario 1 — PUT: Assign a User (First Time) — click to expand
Use when a provider has no user assigned yet. Once assigned, the user cannot be changed or removed via the API.
{
"user": {
"id": 12000006542062
}
}Scenario 2 — PUT: Update Address — click to expand
{
"address1": "456 Oak Ave",
"address2": null,
"city": "Provo",
"state": "UT",
"postalCode": "84604"
}Note: When
responseFieldsis omitted (defaultMODIFIED), unchanged fields such asstatemay not appear in the response even if sent in the request.
Scenario 3 — PUT: Link Insurance Carriers — click to expand
{
"insuranceCarriers": [
{ "id": 1000000020702 },
{ "id": 1000000020703 }
]
}Pass an empty array to clear all linked carriers: "insuranceCarriers": [].
Scenario 4 — PUT: Toggle Signature on File — click to expand
{
"signatureOnFile": true
}| Constraint | Behavior |
|---|---|
active: false | Not supported — returns 400. Contact support to deactivate a provider. |
Change assigned user | Not supported once a user is assigned |
user: null | Not supported — cannot unassign a user via API |
| Provider assigned to a location | firstName, lastName, address1, address2, city, state, postalCode, and user are read-only |
isPrimaryProvider: false | Not allowed when the provider has patients assigned |
location in request body | Ignored with a read-only warning — location assignment is not writable via API |
isNonPersonEntity | Read-only — ignored if sent on create or update |
Providers emit StreamAPI events on CREATE (POST) and UPDATE (PUT). For real-time sync, use StreamAPI webhooks (SNS) instead of polling bulk GET. Setup is covered in Creating and Setting Up Webhooks for the StreamAPI.
There is no REST DELETE endpoint for providers.
organizationId.locationId.ProviderV1.operationTypeWhen no location is associated, locationId is -1.
All provider events:
66d22762060811049b50d085.*.ProviderV1.*Creates only:
66d22762060811049b50d085.*.ProviderV1.CREATEUpdates only:
66d22762060811049b50d085.*.ProviderV1.UPDATE| Operation | Public payload |
|---|---|
CREATE | Full provider resource (public fields only) |
UPDATE | Changed fields only (public fields only) |
Public stream payloads exclude internal-only fields and follow the same field visibility as REST GET responses.
A successful 200/201 response returns:
| Field | Type | Description |
|---|---|---|
data | object | The created or retrieved provider |
warnings | array | Non-fatal warnings (e.g. read-only fields ignored) |
errors | array | Field-level errors |
For bulk GET, data is an array and includes meta.pagination.
| Field | Type | Description |
|---|---|---|
limit | integer | Page size used for this response |
offset | integer | Offset for this page |
total | integer | Total matching records — omitted when using lastId cursor pagination |
| Field | Type | Read-Only | Description |
|---|---|---|---|
id | integer | Yes | Unique provider ID |
type | string | Yes | Always "ProviderV1" |
firstName | string | No | First name (1–25 characters) |
middleInitial | string | No | Middle initial (max 1 character) |
lastName | string | No | Last name (1–50 characters) |
shortName | string | No | Short display name (3–6 characters) |
specialty | string | No | Provider specialty enum |
npi | string | No | National Provider Identifier |
stateId | string | No | State license number |
tin | string | No | Tax identification number (9 digits) |
color | string | No | Hex color (fff or ffffff) |
active | boolean | No | Whether the provider is active |
isPrimaryProvider | boolean | No | Primary provider flag |
isNonPersonEntity | boolean | Yes | Whether the provider is a non-person entity (e.g. equipment) |
signatureOnFile | boolean | No | Signature-on-file flag |
title | string | No | Title (max 50 characters) |
isLocumTenens | boolean | No | Locum tenens flag |
address1 | string | No | Street address line 1 |
address2 | string | No | Street address line 2 (nullable) |
city | string | No | City |
state | string | No | US state or territory code |
postalCode | string | No | Postal code |
feeSchedule | object | No | Linked model { id, type, url } when assigned |
user | object | No | Linked model { id, type, url } when assigned |
insuranceCarriers | array | No | Array of linked models { id, type, url } when assigned |
location | object | Yes | Linked model { id, type, url } when provider is assigned to a location |
stateIdExpiration | string | No | State ID expiration date (YYYY-MM-DD) when set |
lastModified | string | Yes | Last modification timestamp (ISO 8601) |
HTTP Status Code Errors — click to expand
The request body or parameters are invalid. See field-level errors below.
| Message | Authentication is required and has failed or has not been provided. |
| Fix | Provide a valid Bearer token in the Authorization header. |
| Message | The request is understood, but it has been refused or access is not allowed. |
| Why | The caller is not allowed to perform this operation for the organization or resource. |
| Fix | Confirm your integration credentials and that the organization has enabled the capabilities needed for this API. See the API Consumer Guide. |
| Message | The requested resource is either missing or does not exist. |
| Why | No provider exists for the given providerId within your organization. |
| Fix | Confirm the providerId is correct and belongs to your organization. |
| Message | The server timed out while processing the request. |
| Why | Often caused by an overly broad filter on a large tenant. |
| Fix | Narrow filter criteria (add location.id, user.id, or a tighter lastModified range) and retry. |
| Message | Rate limit exceeded. |
| Fix | Implement exponential backoff. See the rate limiting guide. |
| Message | An unexpected error occurred. |
| Fix | Retry. If the issue persists, contact support. |
Field-Level Validation Errors — click to collapse
Error: firstName must be longer than or equal to 1 characters (or same for lastName).
| Why | The field was set to null or an empty string on PUT. |
| Fix | Provide a non-empty string within the length limits. |
Error: specialty must have a value in [...]
| Why | The specialty was set to null or an unrecognized value. |
| Fix | Use one of the supported specialty enum values. |
Error: You cannot make provider primary without setting his npi (and similar for stateId, tin).
| Why | isPrimaryProvider is true but one or more identifiers are missing on create or update. |
| Fix | Include all three fields when the provider is primary. |
Error: You cannot make provider non-HYGIENIST without setting his npi (and similar for stateId, tin).
| Why | Specialty is not HYGIENIST but identifiers are missing or were cleared. |
| Fix | Include npi, stateId, and tin for non-hygienist specialties. |
Error: Linked model for property 'user' should be plain object with id of UserV1
| Why | The user value is not a valid linked model object. |
| Fix | Send { "id": <userId> } with a valid user ID. |
Error: Linked model with id '<id>' of type 'UserV1' not found
| Why | No user exists with the given ID in your organization. |
| Fix | Confirm the user ID is correct. |
Error: userId <id> is incorrect. This user is already assigned to another provider
| Why | The user is already linked to a different provider. |
| Fix | Choose a user that is not assigned, or update the existing provider instead. |
Error: You cannot change user for provider
| Why | Attempted to change the user on a provider that already has one assigned. |
| Fix | User assignment is permanent via the API. Contact support if reassignment is required. |
Error: You cannot unassign user from provider for now, please contact support in case of need
| Why | Attempted to set user: null. |
| Fix | User unassignment is not supported via the API. Contact support if needed. |
Error: Linked model for property 'feeSchedule' should be plain object with id of FeeScheduleV1
| Why | Invalid linked model shape for feeSchedule. |
| Fix | Send { "id": <feeScheduleId> } with a valid fee schedule ID. |
Error: You cannot deactivate a provider for now, please contact support in case of need
| Why | Attempted to set active: false. |
| Fix | Provider deactivation is not supported via the API. Contact support. |
Error: You cannot set isPrimaryProvider to false because he has patients
| Why | The provider has patients assigned and cannot be demoted from primary. |
| Fix | Reassign patients before changing the primary provider flag. |
Error: Provider is assigned to location. Field <fieldName> is readonly
| Why | The provider is assigned to a location and the field cannot be updated via API. |
| Fix | Affected fields: firstName, lastName, address1, address2, city, state, postalCode, user. |
Error: insuranceCarriers must be an array
| Why | insuranceCarriers was set to null. |
| Fix | Send an array (use [] to clear). |
Error: Each element in array should be an object and contain 'id' key...
| Why | An array element is missing a valid id. |
| Fix | Each entry must be { "id": <insuranceCarrierId> }. |
Error: Linked models with ids [...] of type 'InsuranceCarrierV1' not found
| Why | One or more insurance carrier IDs do not exist. |
| Fix | Confirm carrier IDs belong to your organization. |
Error: Validation errors when required address fields are nulled or emptied.
| Why | Address fields cannot all be cleared — at least address1, city, state, and postalCode must remain valid. |
| Fix | Provide valid address values within length and enum constraints. |
Error: Invalid hex color value.
| Why | color is not a valid 3- or 6-character hex string. |
| Fix | Use formats like "fff" or "ffffff". |
Warning: Property 'location' is read-only. Assignment is ignored.
| Why | location was included in a POST or PUT body. |
| Fix | Omit location from write requests. It appears on GET responses when the provider is assigned to a location. |
Warning: Property 'isNonPersonEntity' is read-only. Assignment is ignored.
| Why | isNonPersonEntity was included in a POST or PUT body. |
| Fix | Omit this field from write requests. It is returned on GET responses. |