Retrieve public notifications, request a specific current notification version, and record notification views.
This reference documents the current version 1 public API. All requests require an InsideHOA API key associated with a specific HOA.
Getting Started
https://services.insidehoa.com/api/public/v1
All production requests must use HTTPS.
Security
Include the API key in the X-IHOA-API-Key request header.
X-IHOA-API-Key: YOUR_API_KEY
API keys must be stored in secure server-side configuration and must not be exposed in public browser JavaScript.
public.notifications.read
The current notification endpoints require this scope.
/api/public/v1/pingConfirms that the API key is valid and returns the integration name and assigned scopes.
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL =>
'https://services.insidehoa.com' .
'/api/public/v1/ping',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-IHOA-API-Key: YOUR_API_KEY'
]
]);
$response = curl_exec($curl);
curl_close($curl);
{
"name": "Community Website",
"scopes": [
"public.notifications.read"
]
}
/api/public/v1/notificationsReturns the latest public notification versions available to the HOA associated with the API key. By default, all public notification types are returned. Use type=General for general notifications or type=Event for event notifications only. All date-time values are returned in UTC, the response includes hoaTimeZone for local display conversion, and older event notifications may return event.details as null.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
integer | No | Number of results to return. Defaults to 20. Minimum 1 and maximum 100. |
type |
string | No | Filters notifications by type. Supported values are General and Event. Omit this parameter to return all notification types. |
cursor |
string | No | Opaque paging cursor returned by a previous response. |
since |
ISO 8601 date-time | No | Requests notifications updated after the supplied timestamp. |
cursor and since cannot be used together.
When using cursor, preserve the same query settings used for the first page, including limit and type. Changing those values while continuing a cursor-based result set can produce invalid or inconsistent paging behavior.
Results are already ordered for display: pinned notifications first, then newest notification versions first within each group. Clients should preserve the returned order.
All date-time values are UTC. Use the response-level hoaTimeZone value to convert timestamps into the HOA's local display time.
For older event notifications, event.details may be null. Use the legacy event summary fields when structured details are unavailable.
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL =>
'https://services.insidehoa.com' .
'/api/public/v1/notifications?limit=20&type=Event',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-IHOA-API-Key: YOUR_API_KEY'
]
]);
$response = curl_exec($curl);
curl_close($curl);
{
"items": [
{
"notificationPk":
"cd9f775f7ce3468297ad7b6e59751215",
"notificationId":
"8877fb91a1b143dcad87ca4c5df28829",
"notificationType":
"Event",
"title":
"Board Meeting",
"contentText":
"The board will meet Thursday evening.",
"contentHtml":
"<p>The board will meet Thursday evening.</p>",
"isPinned":
false,
"author":
"Community News",
"created":
"2026-07-29T14:55:00Z",
"modified":
null,
"images":
[],
"event": {
"startDateTime":
"2026-10-01T23:30:00Z",
"endDateTime":
"2026-10-02T01:30:00Z",
"isAllDay":
false,
"details": {
"eventType":
"BoardMeeting",
"additionalInformation":
null,
"occurrences": [
{
"id":
"95f0ab4b54704d0d90f736df060cb293",
"location":
"Remote",
"url":
null,
"notes":
"Regular board meeting.",
"startDateTime":
"2026-10-01T23:30:00Z",
"endDateTime":
"2026-10-02T01:30:00Z",
"isAllDay":
false
}
],
"meeting": {
"agendaContent":
"Review prior minutes and new business.",
"meetingProvider":
"Zoom",
"meetingUrl":
"https://example.com/meeting",
"meetingId":
"123 456 789",
"meetingPassword":
null,
"dialIn":
null
}
}
}
}
],
"nextCursor":
null,
"hasMore":
false,
"hoaTimeZone":
"Mountain Standard Time"
}
Display Behavior
Notifications are returned in their intended display order. Clients should preserve the order returned by the API.
created, newest first.Clients should not re-sort notifications by date alone, because doing so can move non-pinned notifications ahead of pinned notifications.
ORDER BY
isPinned DESC,
created DESC
created is the creation timestamp of the returned notification version. A later edit may therefore move a notification higher within its pinned or non-pinned group.
Temporal Data
All date-time values returned by the Public Notifications API are expressed in UTC. Clients should convert those values to an appropriate display time zone before presenting them to users.
The following values are returned in UTC:
createdmodifiedstartDateTime and endDateTimeexpires{
"startDateTime":
"2026-10-01T23:30:00Z"
}
A trailing Z or an offset of +00:00 indicates UTC.
hoaTimeZoneThe response includes the HOA's configured display time zone:
{
"hoaTimeZone":
"Mountain Standard Time"
}
The current value is a Windows time-zone identifier. Platforms that use IANA identifiers may need to map values such as Mountain Standard Time to America/Denver.
Backward Compatibility
Notifications created before structured event details were introduced remain available through version 1. For those records, event.details may be null.
event.details is present, use details.occurrences.event.details is null, use the legacy event.startDateTime, event.endDateTime, and event.isAllDay fields.{
"event": {
"startDateTime":
"2026-07-25T21:00:00Z",
"endDateTime":
"2026-07-26T00:00:00Z",
"isAllDay":
false,
"details":
null
}
}
details = null indicates a valid legacy event record, not a failed or incomplete API response.
/api/public/v1/notifications/{notificationPk}/{notificationId}Returns the notification document identified by the permanent notification root identifier and its current version identifier. The wrapped response also includes hoaTimeZone, all date-time values are UTC, and older event notifications may return event.details as null.
| Parameter | Type | Description |
|---|---|---|
notificationPk |
string | Permanent root identifier for the notification. It remains unchanged across edits. |
notificationId |
string | Identifier of the current notification version returned by the list endpoint. |
For an unedited notification, notificationPk and notificationId may be identical. After a published notification is edited, notificationPk remains unchanged while notificationId identifies the latest version.
$notification_pk =
'cd9f775f7ce3468297ad7b6e59751215';
$notification_id =
'8877fb91a1b143dcad87ca4c5df28829';
$url =
'https://services.insidehoa.com' .
'/api/public/v1/notifications/' .
rawurlencode($notification_pk) .
'/' .
rawurlencode($notification_id);
$response = wp_remote_get(
$url,
[
'headers' => [
'X-IHOA-API-Key' =>
INSIDEHOA_API_KEY
]
]
);
/api/public/v1/notifications/{notificationPk}/viewRecords engagement for a notification. Duplicate views are permitted.
| Parameter | Type | Description |
|---|---|---|
notificationPk |
string | Permanent notification root identifier. |
A request body is not required. A successful request returns 204 No Content.
$notification_pk =
'cd9f775f7ce3468297ad7b6e59751215';
$response = wp_remote_post(
'https://services.insidehoa.com' .
'/api/public/v1/notifications/' .
rawurlencode($notification_pk) .
'/view',
[
'headers' => [
'X-IHOA-API-Key' =>
INSIDEHOA_API_KEY
],
'timeout' => 10
]
);
Record a view after at least 50% of the notification has remained visible for approximately one second. Browser JavaScript should call a secure server-side endpoint, which then calls InsideHOA using the API key.
Result Navigation
The notification-list endpoint uses cursor-based pagination. When hasMore is true, pass nextCursor back using the cursor query parameter to retrieve the next page.
GET /api/public/v1/notifications?limit=20&type=Event
{
"items": [
...
],
"nextCursor": "PROTECTED_CURSOR_VALUE",
"hasMore": true,
"hoaTimeZone": "Mountain Standard Time"
}
GET /api/public/v1/notifications?limit=20&type=Event&cursor=PROTECTED_CURSOR_VALUE
Each cursor belongs to the exact result set created by the original request. Subsequent requests using that cursor must preserve the same query settings, including:
limittypecursor and since cannot be used together.
Treat nextCursor as opaque. Do not parse, alter, or generate cursor values. Continue requesting pages until hasMore is false and nextCursor is null.
Response Model
The following models describe the notification-list and specific-notification responses.
| Property | Type | Nullable | Description |
|---|---|---|---|
items |
PublicNotification[] | No | Public notifications returned by the request. |
nextCursor |
string | Yes | Cursor used to retrieve the next result page. Null when no additional page exists. |
hasMore |
boolean | No | Indicates whether another page is available. Equivalent to checking whether nextCursor contains a value. |
hoaTimeZone |
string | No | HOA display time zone. The current value is a Windows time-zone identifier, such as Mountain Standard Time. Use it to convert UTC date-time values for display. |
| Property | Type | Nullable | Description |
|---|---|---|---|
notificationPk |
string | No | Permanent root identifier for the notification. |
notificationId |
string | No | Identifier of the returned current notification version. |
notificationType |
string | No | Notification classification. Current public values are None for a general notification and Event for an event notification. The list filter uses the friendlier value type=General to select notifications whose response value is None. |
title |
string | Yes | Public notification title. |
contentText |
string | Yes | Plain-text notification content. |
contentHtml |
string | Yes | HTML-formatted notification content. |
isPinned |
boolean | No | Indicates whether the notification is pinned. |
author |
string | Yes | Display name of the original/root notification author. This remains the original author even when the returned document is a later edit. |
created |
ISO 8601 date-time | No | UTC creation timestamp for the returned notification version. This value is used for newest-first ordering within the pinned and non-pinned groups. |
modified |
ISO 8601 date-time | Yes | UTC modification timestamp when present. |
images |
PublicNotificationImage[] | Yes | Public images associated with the notification. |
event |
PublicNotificationEvent | Yes | Event information for Event notifications. Structured details are available in event.details for newer records; older records may expose only the legacy summary fields. |
| Property | Type | Nullable | Description |
|---|---|---|---|
id |
string | No | Image identifier. |
ordinal |
integer | No | Display ordering value. |
url |
string | No | Public image URL. |
altText |
string | Yes | Optional image alternative text. |
expires |
ISO 8601 date-time | Yes | Optional UTC expiration timestamp for the image URL. |
| Property | Type | Nullable | Description |
|---|---|---|---|
startDateTime |
ISO 8601 date-time | Yes | Legacy-compatible primary event start in UTC. New integrations should use details.occurrences. |
endDateTime |
ISO 8601 date-time | Yes | Legacy-compatible primary event end in UTC. |
isAllDay |
boolean | No | Legacy-compatible all-day flag. |
details |
PublicNotificationEventDetails | Yes | Structured event type, occurrences, meeting information, and additional information. May be null for legacy event notifications created before structured event details were introduced. |
When details is null, use startDateTime, endDateTime, and isAllDay. New integrations should prefer details.occurrences whenever it is available.
| Property | Type | Nullable | Description |
|---|---|---|---|
eventType |
string | No | Structured event classification, such as None, BoardMeeting, or AnnualMeeting. |
additionalInformation |
string | Yes | Additional public event information. |
occurrences |
PublicNotificationEventOccurrence[] | No | One or more event dates and times. |
meeting |
PublicNotificationMeeting | Yes | Meeting-specific information for supported meeting event types. |
| Property | Type | Nullable | Description |
|---|---|---|---|
id |
string | Yes | Stable occurrence identifier. |
location |
string | Yes | Physical or descriptive location. |
url |
string | Yes | Optional occurrence-specific URL. |
notes |
string | Yes | Public notes for the occurrence. |
startDateTime |
ISO 8601 date-time | Yes | Occurrence start date and time in UTC. |
endDateTime |
ISO 8601 date-time | Yes | Occurrence end date and time in UTC. |
isAllDay |
boolean | No | Indicates whether the occurrence is an all-day event. |
| Property | Type | Nullable | Description |
|---|---|---|---|
agendaContent |
string | Yes | Meeting agenda content. |
meetingProvider |
string | Yes | Meeting service, such as Zoom, Teams, or Webex. |
meetingUrl |
string | Yes | Public meeting URL. |
meetingId |
string | Yes | Meeting identifier. |
meetingPassword |
string | Yes | Optional meeting password. |
dialIn |
string | Yes | Phone number or dial-in instructions. |
Responses
| Status | Meaning |
|---|---|
200 OK |
The request completed successfully. |
204 No Content |
The notification view was recorded. |
400 Bad Request |
Request parameters are invalid, including using cursor and since together. |
401 Unauthorized |
The API key is missing, invalid, expired, or does not identify a valid API client. |
403 Forbidden |
The API key does not include the required scope. |
404 Not Found |
The requested notification could not be found. |
500 Internal Server Error |
The request could not be completed because of an unexpected server error. |
Integration Guide
Store the API key in server-side configuration and use the WordPress HTTP API to request notifications. Support both structured and legacy event records, and convert UTC timestamps using the returned hoaTimeZone before displaying them.
define(
'INSIDEHOA_API_KEY',
'YOUR_API_KEY'
);
function insidehoa_get_notifications(): array
{
if (!defined('INSIDEHOA_API_KEY')) {
return [];
}
$response = wp_remote_get(
'https://services.insidehoa.com' .
'/api/public/v1/notifications?limit=20&type=Event',
[
'headers' => [
'X-IHOA-API-Key' =>
INSIDEHOA_API_KEY
],
'timeout' => 10
]
);
if (is_wp_error($response)) {
error_log(
'InsideHOA API error: ' .
$response->get_error_message()
);
return [];
}
$status_code =
wp_remote_retrieve_response_code(
$response
);
if ($status_code !== 200) {
error_log(
'InsideHOA API returned HTTP ' .
$status_code
);
return [];
}
$body =
wp_remote_retrieve_body(
$response
);
$result =
json_decode(
$body,
true
);
return is_array($result)
? $result
: [];
}
$windows_to_iana = [
'Mountain Standard Time' =>
'America/Denver'
];
$utc = new DateTime(
$notification['event']['details']
['occurrences'][0]['startDateTime'],
new DateTimeZone('UTC')
);
$utc->setTimezone(
new DateTimeZone(
$windows_to_iana[
$result['hoaTimeZone']
]
)
);
$display_time =
$utc->format(
'F j, Y \a\t g:i A T'
);
PHP uses IANA time-zone identifiers, so map the Windows identifier returned by hoaTimeZone to the corresponding IANA identifier used by the integration.
$event =
$notification['event'] ?? null;
if (!empty($event['details'])) {
$occurrences =
$event['details']['occurrences'] ?? [];
} elseif ($event !== null) {
$occurrences = [[
'startDateTime' =>
$event['startDateTime'] ?? null,
'endDateTime' =>
$event['endDateTime'] ?? null,
'isAllDay' =>
$event['isAllDay'] ?? false
]];
} else {
$occurrences = [];
}
The Public Notifications API is currently in beta. Existing version 1 contracts will be treated carefully, but documentation and available capabilities may expand as feedback is gathered from integration partners.
Contact InsideHOA for API access, WordPress integration guidance, or help designing a custom implementation.