Skip to content

Events V1 — Developer Guide

Reference: Events (V1) Endpoint Documentation


Events represent non-patient schedule blocks on the office calendar — team meetings, training sessions, closures, and similar items. They are distinct from AppointmentV1 records, which are tied to patients and clinical workflows.

All Events V1 endpoints require an Organization-ID header. Read operations require the model:read scope; write operations (POST, PUT, DELETE) require model:write.

⚠️ Rate Limited: Events endpoints are rate limited. See the rate limiting guide for details.


GET — Bulk List Events

Returns a paginated list of events matching the provided filter criteria.

Parameters

ParameterInRequiredTypeDescription
Organization-IDheaderYesstringYour organization identifier
filterqueryNostringFilter expression. See Filter Keys below
responseFieldsqueryNostringURL-encoded comma-delimited list of fields to return. Use ALL for all fields
pagequeryNostringPage number for offset-based pagination
pageSizequeryNostringNumber of records per page
lastIdqueryNostringThe largest eventId from the previous page — used for cursor-based pagination

Filter Keys

Filter KeySupported Operators
id->
title==, !=, ~=, <>=
start>, >=, <, <=
operatory.id==, !=, ->
location.id==, !=, ->
provider.id==, !=, ->
lastModified>, >=, <, <=
groupId==

Upcoming Breaking Change: location.id (as a list of IDs or ["ALL"]) will become a required filter. Omitting it currently defaults to all locations. See Location-Based API Billing.

Date-limiting filter: If you do not provide a date-limiting filter (lastModified, start, or createdDate), the server may automatically apply lastModified >= your organization's creation date or one year ago — whichever is more recent.

Ordering: When filtering by start or lastModified, results are returned in descending order (newest first). Use lastId with date filters for stable pagination.

Example Requests

Fetch events modified after a date at a specific location:

GET /api/v1/events?filter=lastModified>=2025-01-01T00:00:00Z,location.id->[64000000000004]

Fetch events for a provider within a date range:

GET /api/v1/events?filter=start>=2025-06-01,start<=2025-06-30,provider.id==789

Paginate using lastId:

GET /api/v1/events?lastId=9000000903375&pageSize=100&filter=lastModified>=2025-01-01T00:00:00Z,location.id->[64000000000004]

GET — Event by ID

Returns a single event by its ID.

Parameters

ParameterInRequiredTypeDescription
eventIdpathYesintegerThe ID of the event
Organization-IDheaderYesstringYour organization identifier
responseFieldsqueryNostringComma-delimited list of fields to return, or ALL

Example Request

GET /api/v1/events/9000000903375

GET — Events Async

GET /api/v1/events/async retrieves events asynchronously. It returns the first 10 matching results immediately in the HTTP response and streams all matching records to the Streaming API.

See the Async Endpoints V1 — Developer Guide for shared async mechanics, parameters, and pagination. Filter keys are the same as bulk list above.


GET — Events Total Count

Returns the total number of events matching a filter. Uses the same filter syntax as GET /v1/events.

Parameters

ParameterInRequiredTypeDescription
Organization-IDheaderYesstringYour organization identifier
filterqueryNostringFilter criteria — same keys as bulk GET

Example Request

GET /api/v1/events/totalcount?filter=lastModified>=2025-01-01,location.id==123

Response

FieldTypeDescription
data.totalintegerNumber of events matching the filter

POST — Create Event

Creates a new event. Supports one-time and recurring events (WEEKLY or MONTHLY patterns).

Parameters

ParameterInRequiredTypeDescription
Organization-IDheaderYesstringYour organization identifier

Request Body — EventV1

Required fields:

FieldTypeDescription
titlestringEvent title (max 60 characters)
startstring (date-time)Start time in ISO 8601 format (e.g. 2025-01-15T10:00:00.000Z)
locationobjectLinked model { "id": "<locationId>" }

Optional fields:

FieldTypeDefaultDescription
durationinteger60Length in minutes. Valid range: 51440
descriptionstringFree-text description
allDaybooleanWhen true, start is normalized to location midnight and duration is set to 1439 minutes
colorstringbbbbbb6-character hexadecimal color code without # prefix (e.g. FF5733)
operatoryobjectLinked model { "id": "<operatoryId>" }. Must belong to the same location
providerobjectLinked model { "id": "<providerId>" }. Must be active with isNonPersonEntity: false

Recurrence fields (all required together when creating a recurring series):

FieldTypeNotes
recurrenceTypestringWEEKLY or MONTHLY
recurrenceStartstring (date)Start of recurrence range (YYYY-MM-DD)
recurrenceEndstring (date)End of recurrence range. Max 2 years after recurrenceStart
recurrenceFrequencyintegerInterval (1–52)
recurrenceDaysarrayRequired for WEEKLY. Values: SUNDAYSATURDAY
recurrenceWeekstringRequired for MONTHLY. Values: FIRST, SECOND, THIRD, FOURTH, LAST
recurrenceDaystringRequired for MONTHLY. Day of week (SUNDAYSATURDAY)

Example Request — One-time event

POST /api/v1/events
Content-Type: application/json

{
  "title": "Team Meeting",
  "start": "2025-01-15T10:00:00.000Z",
  "duration": 60,
  "location": { "id": "64000000000004" },
  "operatory": { "id": "9000000000338" },
  "color": "FF5733"
}

Example Request — Weekly recurring event

POST /api/v1/events
Content-Type: application/json

{
  "title": "Weekly Standup",
  "start": "2025-01-15T10:00:00.000Z",
  "duration": 30,
  "location": { "id": "64000000000004" },
  "recurrenceType": "WEEKLY",
  "recurrenceStart": "2025-01-15",
  "recurrenceEnd": "2025-06-15",
  "recurrenceFrequency": 1,
  "recurrenceDays": ["MONDAY", "WEDNESDAY", "FRIDAY"]
}

Returns 201 Created with the created EventV1 in data.


PUT — Update Event

Updates an existing event. The request body uses the EventV1 model with partial update semantics: only properties present in the JSON body are changed; omitted properties are left unchanged.

Parameters

ParameterInRequiredTypeDescription
eventIdpathYesintegerThe ID of the event to update
Organization-IDheaderYesstringYour organization identifier
recurrenceTargetqueryYesstringSERIES or OCCURRENCE (uppercase only)
responseFieldsqueryNostringComma-delimited list of fields to return, or ALL

recurrenceTarget Query Parameter

ValueBehavior
OCCURRENCEUpdates only the single event identified by eventId
SERIESUpdates the recurring series (required when modifying recurrence settings; propagates time changes across future occurrences)

Note: Although the EventV1 schema lists title, start, and location as required for create, none of these are required on PUT. Send only the fields you want to change.

Writable Body Properties

PropertyNotes
titlestring, max 60 characters
descriptionstring; send null to clear
startISO 8601 date-time
durationinteger, 5–1440 minutes; recomputes end
allDayboolean; when true, duration is forced to 1439 min and start is normalized to location midnight
color6-char hex, no # prefix
operatorylinked model { id }; send null to clear
providerlinked model { id }; send null to clear
recurrenceType, recurrenceStart, recurrenceEnd, recurrenceFrequencyrequire recurrenceTarget=SERIES
recurrenceDaysrequired for WEEKLY recurrence updates
recurrenceWeek, recurrenceDayrequired for MONTHLY recurrence updates

Not Writable on PUT

PropertyBehavior
locationRead-only after create — if sent, a warning is returned and the value is ignored
endRead-only — computed from start + duration; sending end has no effect
id, lastModified, groupId, typeRead-only response fields

Example Request

PUT /api/v1/events/9000000903375?recurrenceTarget=OCCURRENCE
Content-Type: application/json

{
  "title": "Updated Team Meeting",
  "duration": 90
}

Returns 200 OK with the updated EventV1 in data.


DELETE — Delete Event

Deletes an event by ID.

Parameters

ParameterInRequiredTypeDescription
eventIdpathYesintegerThe ID of the event to delete
Organization-IDheaderYesstringYour organization identifier
recurrenceTargetqueryConditionalstringRequired when the event is part of a recurring series. SERIES or OCCURRENCE
recurrenceTargetBehavior
OCCURRENCEDeletes only the single occurrence
SERIESDeletes the target occurrence and all future occurrences in the series

Example Requests

Delete a one-time event:

DELETE /api/v1/events/9000000903375

Delete a single occurrence from a recurring series:

DELETE /api/v1/events/9000000903375?recurrenceTarget=OCCURRENCE

Returns 200 OK with { "data": { "id": <eventId> } }.


Response Structure

A successful response returns the following top-level structure:

FieldTypeDescription
dataobject or arrayThe event object (single) or array of events (bulk)
warningsarrayNon-fatal warnings (operation still succeeded)
errorsarrayField-level or structural errors

For bulk responses, data is an array and the response also includes meta.pagination with lastId for cursor pagination.

EventV1 Object Fields

FieldAccessDescription
idread-onlyUnique event identifier
typeread-onlyAlways "EventV1"
titleread/writeEvent title (max 60 characters)
descriptionread/writeFree-text description
startread/writeStart time (ISO 8601)
endread-onlyComputed from start + duration
durationread/writeLength in minutes (5–1440)
allDayread/writeAll-day event flag
colorread/write6-char hex color (defaults to bbbbbb)
lastModifiedread-onlyLast modification timestamp
groupIdread-onlyGroup identifier for recurring events (max 50 chars)
locationread/write on create; read-only on updateLinked model { id }
operatoryread/writeLinked model { id }; optional
providerread/writeLinked model { id }; optional
recurrenceTyperead/writeWEEKLY or MONTHLY; null for non-recurring
recurrenceStartread/writeRecurrence range start (YYYY-MM-DD)
recurrenceEndread/writeRecurrence range end (YYYY-MM-DD)
recurrenceFrequencyread/writeRecurrence interval (1–52)
recurrenceDaysread/writeDays of week for WEEKLY recurrence
recurrenceWeekread/writeWeek of month for MONTHLY recurrence
recurrenceDayread/writeDay of week for MONTHLY recurrence

Paginating with lastId

lastId is the recommended approach for iterating through large result sets. It uses the event's id as a cursor rather than an offset.

Step 1 — Initial Request

GET /api/v1/events?pageSize=100&filter=lastModified>=2025-01-01T00:00:00Z,location.id->[64000000000004]

Step 2 — Subsequent Requests

Pass the id of the last record in data as lastId:

GET /api/v1/events?lastId=9000000903375&pageSize=100&filter=lastModified>=2025-01-01T00:00:00Z,location.id->[64000000000004]

Step 3 — Repeat

Continue until data is empty.

⚠️ Not Recommended: Do not paginate large data sets using the page parameter. Use lastId instead.


Streaming API

Events are streamable via the Streaming API. Create, update, and delete operations emit stream messages. The async bulk GET endpoint also delivers matching records to the Streaming API.

See the Streaming API Webhooks Setup Guide for setup instructions.

Routing Key Format

organizationId.locationId.EventV1.operationType

Example Routing Keys

All event changes at a specific location:

66d22762060811049b50d085.64000000000004.EventV1.*

All CREATE events across all locations:

66d22762060811049b50d085.*.EventV1.CREATE

Operations Emitted

OperationWhen
CREATEA new event (or recurring series) is created
UPDATEAn event or series occurrence is updated
DELETEAn event or series occurrence is deleted

Errors & Warnings Reference

HTTP Status Code Errors — click to expand

These apply to all Events V1 endpoints.


400 — Bad Request

The request body or query parameters are invalid or cannot be processed. See Field-Level Validation Errors below.


401 — Unauthorized

MessageAuthentication is required and has failed or has not been provided.
WhyMissing, expired, or malformed Bearer token.
FixProvide a valid Bearer token in the Authorization header.

403 — Forbidden

MessageThe request is understood, but it has been refused or access is not allowed.
WhyThe token lacks the required scope. Read operations require model:read; write operations require model:write.
FixRequest a token with the appropriate scope.

404 — Not Found

MessageThe requested resource is either missing or does not exist.
WhyNo event exists for the given eventId within your organization, or the ID is invalid.
FixConfirm the eventId is correct and belongs to your organization.

408 — Request Timeout

MessageThe server timed out while processing the request.
WhyHigh server load or an overly broad filter.
FixNarrow filter criteria and retry.

429 — Too Many Requests

MessageRate limit exceeded.
WhyToo many requests in a short period.
FixImplement exponential backoff. See the rate limiting guide.

500 — Internal Server Error

MessageAn unexpected error occurred.
FixRetry. If the issue persists, contact support with the request details and timestamp.

Field-Level Validation Errors — click to collapse

title

Error: title must be longer than or equal to 1 characters / title must be a string

Whytitle was omitted, empty, or not a string.
FixProvide a non-empty string up to 60 characters.

start

Error: 'undefined' is not a valid date in the format 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'.

Whystart was omitted or not a valid ISO 8601 date-time.
FixProvide a valid date-time, e.g. 2025-01-15T10:00:00.000Z.

Error: start and end should be at the same day

WhyFor non-allDay events, the computed end time falls on a different calendar day than start (in the location's timezone).
FixAdjust start or duration so the event fits within a single day.

duration

Error: duration must be an integer between 5 and 1440.

WhyDuration is outside the allowed range.
FixProvide a value between 5 and 1440 inclusive.

location

Error: Linked model for property 'location' should be plain object with id of LocationV1

Whylocation was omitted on create or not a valid linked model.
FixProvide { "id": "<locationId>" } with a valid location ID.

Warning: Property 'location' is read-only. Assignment is ignored.

Whylocation was included in a PUT request body.
FixOmit location from update requests. Location cannot be changed after create.

operatory

Error: Location of Event and Location of Operatory should be the same

WhyThe operatory belongs to a different location than the event.
FixAssign an operatory at the same location as the event.

provider

Error: Provider should have 'isNonPersonEntity: false' to be assigned to the appointment

WhyThe provider is a non-person entity.
FixAssign a person provider.

Error: Provider should have 'active: true' to be assigned to the appointment

WhyThe provider is inactive.
FixUse an active provider or reactivate the provider first.

color

Error: color must be a 6-character hexadecimal color code without # prefix

WhyInvalid color format (e.g. includes #, wrong length, non-hex characters).
FixUse exactly 6 hex characters, e.g. FF5733 or aabbcc.

recurrenceTarget

Error: recurrenceTarget must have a value in [SERIES,OCCURRENCE]

WhyrecurrenceTarget was omitted on PUT, or an invalid value was provided (including lowercase).
FixProvide recurrenceTarget=SERIES or recurrenceTarget=OCCURRENCE in uppercase.

Error: recurrenceTarget should be SERIES if fields for modifying recurrence settings are provided

WhyRecurrence fields were sent in the body with recurrenceTarget=OCCURRENCE.
FixUse recurrenceTarget=SERIES when modifying recurrence settings.

Error: recurrenceTarget cannot be SERIES because event doesn't have recurrence settings

WhyrecurrenceTarget=SERIES was used on DELETE for a non-recurring event.
FixOmit recurrenceTarget for one-time events, or use OCCURRENCE.

Recurrence fields

Error: recurrenceStart cannot be after the recurrenceEnd

FixEnsure recurrenceStart is on or before recurrenceEnd.

Error: range between recurrenceStart and recurrenceEnd cannot be bigger than 2 years

FixLimit the recurrence range to 2 years or less.

Error: No events can be created for provided recurrence settings

WhyThe recurrence configuration produces zero event dates.
FixAdjust recurrence days, frequency, or date range so at least one occurrence is generated.

Error: recurrenceDays should not be empty / recurrenceFrequency must not be less than 1 / recurrenceFrequency must not be greater than 52

WhyIncomplete or out-of-range recurrence configuration.
FixProvide all required recurrence fields for the chosen recurrenceType. See POST — Create Event.