Event Feed API Reference
Complete API reference for Helix Event Feeds. All endpoints require authentication via API key.
An interactive OpenAPI playground is available at api.feeds.onhelix.ai/docs. The spec is generated from the live route validators, so it cannot drift from the running implementation — useful for testing requests, inspecting response shapes, and generating client SDKs.
Base URL: https://api.feeds.onhelix.ai
Authentication
Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
See the Authentication Guide for details on obtaining and managing API keys.
Quick Start
Get your first events in 3 simple steps:
1. Create an Event Feed
curl -X POST https://api.feeds.onhelix.ai/feeds/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My Events",
"description": "Events I want to track"
}'
Save the returned id - you'll need it for the next steps.
2. Add Source References
Add sources to your feed (sites, sitemaps, index pages, Instagram accounts, or Facebook pages):
# Example: Add a site source
curl -X POST https://api.feeds.onhelix.ai/feeds/events/{feedId}/sources \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sourceType": "site",
"sourceId": "770e8400-e29b-41d4-a716-446655440001"
}'
Note: Sources must be created separately before adding them to a feed. See the Event Feed Overview for source creation details.
3. Get Your Events
Retrieve events from your feed:
# Get upcoming events (next 30 days by default)
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items" \
-H "Authorization: Bearer YOUR_API_KEY"
Common Query Patterns:
# Events in a specific date range
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?since=2025-12-01T00:00:00Z&until=2025-12-31T23:59:59Z" \
-H "Authorization: Bearer YOUR_API_KEY"
# Only scheduled events (exclude cancelled)
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?status=scheduled" \
-H "Authorization: Bearer YOUR_API_KEY"
# Sort by when added to feed (newest first)
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?orderBy=created" \
-H "Authorization: Bearer YOUR_API_KEY"
Next Steps:
- See Event Feed Concepts to understand the event data model
- Review Get Feed Items below for all query options and response examples
- Set up Webhooks to receive real-time notifications
Event Feed Endpoints
Create an Event Feed
Creates a new event feed to organize events from multiple sources.
POST /feeds/events
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Body:
{
"name": "Community Events",
"description": "Local community happenings and activities",
"enabled": true,
"config": {
"version": 1
}
}
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Feed name. Minimum 1 character. |
description | string | Yes | Feed description. Minimum 1 character. |
enabled | boolean | No | Whether the feed is enabled. Defaults to true. |
config | object | No | Feed configuration options. |
config.version | number | No | Config schema version. Defaults to 1. |
Response
Status: 201 Created
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Community Events",
"description": "Local community happenings and activities",
"enabled": true,
"enabledSource": "system",
"enabledReason": null,
"config": {
"version": 1
},
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
}
Response fields:
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique feed identifier |
name | string | Feed name |
description | string | Feed description |
enabled | boolean | Whether the feed is active |
enabledSource | string | Who enabled/disabled the feed (system, admin, api) |
enabledReason | string|null | Optional reason for enabled status |
config | object | Feed configuration |
createdAt | string (ISO 8601) | Feed creation timestamp |
updatedAt | string (ISO 8601) | Last update timestamp |
Example
curl -X POST https://api.feeds.onhelix.ai/feeds/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "City Events",
"description": "Events happening around the city"
}'
List Event Feeds
Retrieves all event feeds.
GET /feeds/events
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Response
Status: 200 OK
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Community Events",
"description": "Local community happenings",
"enabled": true,
"enabledSource": "system",
"config": {
"version": 1
},
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
]
}
Example
curl https://api.feeds.onhelix.ai/feeds/events \
-H "Authorization: Bearer YOUR_API_KEY"
Get Event Feed
Retrieves a specific event feed by ID.
GET /feeds/events/:id
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Path Parameters:
| Name | Type | Description |
|---|---|---|
id | string (UUID) | Event feed ID |
Response
Status: 200 OK
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Community Events",
"description": "Local community happenings",
"enabled": true,
"enabledSource": "system",
"config": {
"version": 1
},
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}
}
Example
curl https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY"
Update Event Feed
Updates an existing event feed. All fields are optional.
PATCH /feeds/events/:id
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Path Parameters:
| Name | Type | Description |
|---|---|---|
id | string (UUID) | Event feed ID |
Body:
{
"name": "Updated Events Feed",
"description": "Updated description",
"enabled": false,
"config": {
"version": 1
}
}
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
name | string | No | New feed name. Minimum 1 character. |
description | string | No | New feed description. Minimum 1 character. |
enabled | boolean | No | Enable or disable the feed. |
config | object | No | Updated feed configuration. |
Response
Status: 200 OK
Returns the updated feed object (same structure as Get Event Feed).
Example
curl -X PATCH https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Events Feed",
"enabled": true
}'
Delete Event Feed
Permanently deletes an event feed and all its sources and items.
DELETE /feeds/events/:id
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Path Parameters:
| Name | Type | Description |
|---|---|---|
id | string (UUID) | Event feed ID |
Response
Status: 200 OK
{
"success": true
}
Example
curl -X DELETE https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY"
Event Feed Source Endpoints
Add Source to Feed
Adds an existing source to an event feed. The source must already exist in the system.
POST /feeds/events/:id/sources
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Path Parameters:
| Name | Type | Description |
|---|---|---|
id | string (UUID) | Event feed ID |
Body:
{
"sourceType": "site",
"sourceId": "550e8400-e29b-41d4-a716-446655440001"
}
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
sourceType | string | Yes | Type of source: site, sitemap, siteIndexPage, instagram, facebook, tiktok, or twitter |
sourceId | string (UUID) | Yes | ID of the existing source to add |
Response
Status: 201 Created
{
"success": true,
"data": {
"id": "660e8400-e29b-41d4-a716-446655440002",
"eventFeedId": "550e8400-e29b-41d4-a716-446655440000",
"sourceType": "site",
"sourceId": "550e8400-e29b-41d4-a716-446655440001",
"createdAt": "2024-01-15T11:00:00.000Z"
}
}
Response fields:
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique feed source association ID |
eventFeedId | string (UUID) | Parent event feed ID |
sourceType | string | Type of source |
sourceId | string (UUID) | Referenced source ID |
createdAt | string (ISO 8601) | When source was added to feed |
What happens after adding a source:
- A 14-day backfill workflow is automatically triggered
- Recent events from the source are added to your feed
- The source is monitored for new events going forward
Example
curl -X POST https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000/sources \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sourceType": "site",
"sourceId": "550e8400-e29b-41d4-a716-446655440001"
}'
List Feed Sources
Retrieves all sources associated with an event feed.
GET /feeds/events/:id/sources
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Path Parameters:
| Name | Type | Description |
|---|---|---|
id | string (UUID) | Event feed ID |
Response
Status: 200 OK
{
"success": true,
"data": [
{
"id": "660e8400-e29b-41d4-a716-446655440002",
"eventFeedId": "550e8400-e29b-41d4-a716-446655440000",
"sourceType": "site",
"sourceId": "550e8400-e29b-41d4-a716-446655440001",
"createdAt": "2024-01-15T11:00:00.000Z"
},
{
"id": "660e8400-e29b-41d4-a716-446655440003",
"eventFeedId": "550e8400-e29b-41d4-a716-446655440000",
"sourceType": "sitemap",
"sourceId": "550e8400-e29b-41d4-a716-446655440004",
"createdAt": "2024-01-15T11:30:00.000Z"
}
]
}
Example
curl https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000/sources \
-H "Authorization: Bearer YOUR_API_KEY"
Remove Source from Feed
Removes a source from an event feed. Events from this source will no longer appear in the feed.
DELETE /feeds/events/:id/sources/:sourceId
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Path Parameters:
| Name | Type | Description |
|---|---|---|
id | string (UUID) | Event feed ID |
sourceId | string (UUID) | Feed source association ID (not the original source ID) |
Response
Status: 200 OK
{
"success": true
}
Example
curl -X DELETE https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000/sources/660e8400-e29b-41d4-a716-446655440002 \
-H "Authorization: Bearer YOUR_API_KEY"
Event Feed Items Endpoint
Get Feed Items
Retrieves events from a feed in a normalized, source-agnostic response shape — sourceType is no longer at the root; strip-null semantics omit absent optional scalars; arrays remain present. This is the canonical endpoint for new integrations.
GET /feeds/events/{feedId}/items
A legacy endpoint at /v0/feeds/events/{feedId}/items returns the previous response shape (root sourceType, nulls emitted). See Get Feed Items (v0, legacy) below.
Request
Path parameters, query parameters (limit, offset, since, until, status, orderBy), and headers are identical to v0, plus:
| Name | Type | Default | Description |
|---|---|---|---|
include | string | - | Comma-separated list of optional response sections. Currently supported: source. Unknown tokens return 400. |
Response shape
The root of each event is source-agnostic — sourceType is no longer present at the root. Optional scalars are omitted when null/undefined; arrays remain present (empty arrays are not omitted, since iterating consumers treat an empty array differently from a missing field).
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | Stable feed-item identifier (per-feed). Use this for feedback and per-feed dedup. |
eventId | string | yes | Underlying event identifier (the same event may appear in multiple feeds; use for cross-feed dedup). |
title | string | yes | Event title. |
description | string | yes | Event description. |
shortDescription | string | no | Short summary (omitted when not available). |
relevanceScore | number | no | Feed relevance score (omitted when not scored). |
addedToFeedAt | string (ISO 8601) | yes | When the event was added to this feed. |
publishedAt | string (ISO 8601) | no | Original publish time on the source platform (omitted when unknown). |
occurrence | object | yes | Occurrence summary. nextOccurrence is omitted (rather than null) when absent. |
time | object | no | Time-display info (omitted when not derivable). |
location | object | no | Location info (omitted when not available). |
capacity | object | no | Capacity info (omitted when not available). |
organizer | object | no | Organizer info (omitted when not available). |
primaryImage | string | no | Hero image URL (omitted when not available). |
supportingImages | string[] | yes | Array — empty when no supporting images. |
primaryUrl | string | no | Primary external URL for the event (omitted when not available). |
urls | string[] | yes | Array — empty when no associated URLs. |
geoLocations | object[] | yes | Array of geo associations. Empty when no geo data. |
source | object | no | Per-platform detail block, present only when the request used ?include=source. See Source block below. |
The shapes of occurrence, time, location, capacity, organizer, and geoLocations are identical to the v0 endpoint — see the legacy section below for those details.
Strip-null semantics: optional scalar fields whose underlying value is null, undefined, or empty-after-trim are omitted from the response. Arrays are always present (empty when no data).
?include=source block
The source block is identical to the news endpoint — same discriminator, same per-platform shapes, same omission rules. See the Get Feed Items section in the news API reference for the per-platform field tables.
For events specifically, the subtype of a Facebook source is most often event, since event feeds typically pull from FB Events. Site events expose only { type: "site", url }.
Examples
Default response (site event, no include):
{
"id": "770e8400-e29b-41d4-a716-446655440005",
"eventId": "880e8400-e29b-41d4-a716-446655440006",
"title": "Community Art Fair",
"description": "<p>Annual art fair featuring local artists and craftspeople...</p>",
"shortDescription": "Annual community art fair with local artists",
"addedToFeedAt": "2024-01-15T12:00:00.000Z",
"occurrence": {
"nextOccurrence": {
"id": "aa0e8400-e29b-41d4-a716-446655440008",
"instanceId": "990e8400-e29b-41d4-a716-446655440007",
"startDateTime": "2024-06-15T10:00:00.000Z",
"endDateTime": "2024-06-15T18:00:00.000Z",
"status": "scheduled"
},
"occurrencesInRange": [],
"totalOccurrences": 1,
"upcomingOccurrences": 1
},
"primaryImage": "https://example.com/images/art-fair-2024.jpg",
"supportingImages": [],
"primaryUrl": "https://example.com/events/art-fair-2024",
"urls": ["https://example.com/events/art-fair-2024"],
"geoLocations": []
}
Note: no sourceType at the root, no null fields. relevanceScore, publishedAt, time, location, capacity, organizer are simply absent because they were not available for this event.
With ?include=source (Facebook event):
{
"id": "770e8400-e29b-41d4-a716-44665544000c",
"eventId": "880e8400-e29b-41d4-a716-44665544000d",
"title": "Summer Concert in the Park",
"description": "Free outdoor concert featuring local bands.",
"addedToFeedAt": "2024-05-20T08:00:00.000Z",
"publishedAt": "2024-05-15T12:00:00.000Z",
"occurrence": {
"occurrencesInRange": [],
"totalOccurrences": 1,
"upcomingOccurrences": 1
},
"supportingImages": [],
"urls": [],
"geoLocations": [],
"source": {
"type": "facebook",
"subtype": "event",
"permalinkUrl": "https://www.facebook.com/events/987654321098765",
"publisher": {
"type": "page",
"name": "City Events FB",
"username": "cityeventsfb",
"avatarUrl": "https://cdn.example.com/fb/avatar.jpg"
}
}
}
curl:
# Default shape
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"
# With per-platform source block
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?limit=20&include=source" \
-H "Authorization: Bearer YOUR_API_KEY"
What changed from v0
v0 (/v0/feeds/events/...) | Current (/feeds/events/...) | |
|---|---|---|
| Root shape | Carries sourceType discriminator at the root. | Source-agnostic — sourceType removed; the discriminator moves to source.type and is only present with ?include=source. |
| Null scalars | Emitted as null. | Omitted from response. |
| Empty arrays | Emitted as []. | Same — arrays remain present (empty arrays are semantically meaningful for iterators). |
?include | not supported. | Supported. Currently allows source. |
The envelope ({ items, total, pagination }), the date-range behavior, the status and orderBy query parameters, and the occurrence / time / location / capacity / organizer / geoLocations shapes are identical between versions.
Get a Single Feed Item
Returns a single item from an event feed by its itemId. The response wraps one item in the same shape returned by Get Feed Items per element — including occurrences, time, location, capacity, organizer, and geo locations. Use this when you already have an item id and want to refetch the latest version of just that event without scanning the feed.
GET /feeds/events/{feedId}/items/{itemId}
Request
Path parameters:
| Name | Type | Description |
|---|---|---|
feedId | string (UUID) | Event feed identifier |
itemId | string (UUID) | Feed item identifier (from the id field) |
Query parameters:
| Name | Type | Default | Description |
|---|---|---|---|
include | string | - | Comma-separated list of optional response sections to include. Currently supported: source. Unknown tokens return 400. |
Headers:
Authorization: Bearer YOUR_API_KEY
Response
Status: 200 OK
The response body wraps a single event item in the same per-item shape as Get Feed Items, including the opt-in ?include=source block. See Get Feed Items above for the full field reference.
Unlike the list endpoint, this endpoint returns all instances and occurrences for the event — there is no since/until filter to apply, since the consumer asked for everything we know about a single item.
Examples
Default:
curl "https://api.feeds.onhelix.ai/feeds/events/feed_2aKj39dkD/items/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_API_KEY"
With per-platform source block:
curl "https://api.feeds.onhelix.ai/feeds/events/feed_2aKj39dkD/items/550e8400-e29b-41d4-a716-446655440000?include=source" \
-H "Authorization: Bearer YOUR_API_KEY"
Errors
400: Unknownincludetoken, or malformed UUID.401: Missing or invalid API key.404: Feed or item not found, the item belongs to a different feed, or your organization has no access to the feed.
Get Feed Items (v0, legacy)
Returns events in the original verbose response shape: root sourceType discriminator, nulls emitted, no source-block support. Kept for backwards compatibility — new integrations should use Get Feed Items above.
GET /v0/feeds/events/:id/items
Request
Headers:
Authorization: Bearer YOUR_API_KEY
Path Parameters:
| Name | Type | Description |
|---|---|---|
id | string (UUID) | Event feed ID |
Query Parameters:
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
limit | integer | No | 20 | Number of items to return. Min: 1, Max: 100. |
offset | integer | No | 0 | Number of items to skip. Min: 0. |
since | date (ISO 8601) | No | now | Start of date range for event occurrences. |
until | date (ISO 8601) | No | since + 30 days | End of date range for event occurrences. |
status | string | No | all | Filter by instance status: scheduled, cancelled, postponed, rescheduled, completed |
orderBy | string | No | occurrence | Sort order: occurrence, created |
Date Range Behavior:
The API automatically handles date range logic to provide a sensible default experience:
- No dates provided: Returns events with occurrences from now until 30 days in the future
- Only
sinceprovided: Returns events fromsinceuntilsince+ 30 days - Both
sinceanduntilprovided: Returns events in that exact date range
Date Range Validation:
- Dates must be within 7 days in the past and 30 days in the future from current date
sincemust be beforeuntil- Dates must be in ISO 8601 format (e.g.,
2025-12-01T00:00:00Z)
Sort Order Details:
occurrence: Sort by earliest occurrence date (ascending) - events happening soonest appear firstcreated: Sort by when added to feed (descending) - newest additions first
Response
Status: 200 OK
{
"success": true,
"data": {
"items": [
{
"id": "770e8400-e29b-41d4-a716-446655440005",
"eventId": "880e8400-e29b-41d4-a716-446655440006",
"sourceType": "site",
"addedToFeedAt": "2024-01-15T12:00:00.000Z",
"publishedAt": null,
"title": "Community Art Fair",
"description": "<p>Annual art fair featuring local artists and craftspeople...</p>",
"shortDescription": "Annual community art fair with local artists",
"occurrence": {
"nextOccurrence": {
"id": "aa0e8400-e29b-41d4-a716-446655440008",
"instanceId": "990e8400-e29b-41d4-a716-446655440007",
"startDateTime": "2024-06-15T10:00:00.000Z",
"endDateTime": "2024-06-15T18:00:00.000Z",
"status": "scheduled"
},
"occurrencesInRange": [
{
"id": "aa0e8400-e29b-41d4-a716-446655440008",
"instanceId": "990e8400-e29b-41d4-a716-446655440007",
"startDateTime": "2024-06-15T10:00:00.000Z",
"endDateTime": "2024-06-15T18:00:00.000Z",
"status": "scheduled"
},
{
"id": "aa0e8400-e29b-41d4-a716-446655440009",
"instanceId": "990e8400-e29b-41d4-a716-446655440007",
"startDateTime": "2024-06-16T10:00:00.000Z",
"endDateTime": "2024-06-16T18:00:00.000Z",
"status": "scheduled"
}
],
"totalOccurrences": 2,
"upcomingOccurrences": 2
},
"time": {
"temporalPattern": "singular",
"timezone": "America/Los_Angeles",
"displayText": "Jun 15-16, 2024 at 10:00 AM - 6:00 PM PDT"
},
"location": {
"venue": {
"name": "Downtown Community Park",
"address": "123 Main St, San Francisco, CA 94102"
},
"coordinates": {
"lat": 37.7749,
"lng": -122.4194
},
"displayAddress": "Downtown Community Park, 123 Main St, San Francisco, CA 94102"
},
"capacity": {
"total": 500,
"available": 350,
"unlimited": false
},
"organizer": {
"name": "SF Arts Council",
"url": "https://sfartscouncil.org",
"contact": "events@sfartscouncil.org"
},
"primaryImage": "https://example.com/images/art-fair-2024.jpg",
"supportingImages": [
"https://example.com/images/art-fair-booth1.jpg",
"https://example.com/images/art-fair-booth2.jpg"
],
"primaryUrl": "https://example.com/events/art-fair-2024",
"urls": [
"https://example.com/events/art-fair-2024",
"https://sfartscouncil.org/community-fair"
],
"geoLocations": [
{
"id": "cc0e8400-e29b-41d4-a716-44665544000a",
"description": "Downtown Community Park",
"relationType": "LOCATION",
"score": 95
}
]
}
],
"total": 42,
"pagination": {
"limit": 20,
"offset": 0,
"hasMore": true
}
}
}
Response Examples for Different Event Types
The response structure adapts to different types of events. Here are realistic examples:
Example 1: Simple One-Time Event (Concert)
Minimal event with basic information:
{
"id": "item_001",
"eventId": "evt_concert_2025",
"sourceType": "site",
"addedToFeedAt": "2025-11-17T10:00:00.000Z",
"publishedAt": null,
"title": "Jazz Night at Blue Note",
"description": "<p>An evening of smooth jazz featuring local artists.</p>",
"shortDescription": "Jazz concert with local musicians",
"occurrence": {
"nextOccurrence": {
"id": "occ_001",
"instanceId": "inst_001",
"startDateTime": "2025-12-20T20:00:00.000Z",
"endDateTime": "2025-12-20T23:00:00.000Z",
"status": "scheduled"
},
"occurrencesInRange": [
{
"id": "occ_001",
"instanceId": "inst_001",
"startDateTime": "2025-12-20T20:00:00.000Z",
"endDateTime": "2025-12-20T23:00:00.000Z",
"status": "scheduled"
}
],
"totalOccurrences": 1,
"upcomingOccurrences": 1
},
"time": {
"temporalPattern": "singular",
"timezone": "America/New_York",
"displayText": "Dec 20, 2025 at 8:00 PM EST"
},
"location": {
"venue": {
"name": "Blue Note Jazz Club",
"address": "131 W 3rd St, New York, NY 10012"
},
"coordinates": {
"lat": 40.7308,
"lng": -74.0005
},
"displayAddress": "Blue Note Jazz Club, 131 W 3rd St, New York, NY 10012"
},
"capacity": {
"total": 200,
"available": 45,
"unlimited": false
},
"organizer": {
"name": "Blue Note Entertainment",
"url": "https://bluenote.net",
"contact": "bookings@bluenote.net"
},
"primaryImage": "https://example.com/images/jazz-night.jpg",
"supportingImages": [],
"primaryUrl": "https://bluenote.net/events/jazz-night-dec",
"urls": ["https://bluenote.net/events/jazz-night-dec"],
"geoLocations": [
{
"id": "geo_001",
"description": "Blue Note Jazz Club",
"relationType": "LOCATION",
"score": 100
},
{
"id": "geo_002",
"description": "New York, NY",
"relationType": "RELEVANCE_REGION",
"score": 95
}
]
}
Example 2: Multi-Day Festival
Event spanning multiple consecutive days:
{
"id": "item_002",
"eventId": "evt_summerfest_2025",
"sourceType": "site",
"addedToFeedAt": "2025-11-17T10:00:00.000Z",
"publishedAt": null,
"title": "Summer Music Festival",
"description": "<p>Three days of live music featuring 50+ artists across 5 stages.</p>",
"shortDescription": "3-day outdoor music festival",
"occurrence": {
"nextOccurrence": {
"id": "occ_fri",
"instanceId": "inst_festival",
"startDateTime": "2025-07-18T14:00:00.000Z",
"endDateTime": "2025-07-18T23:00:00.000Z",
"status": "scheduled"
},
"occurrencesInRange": [
{
"id": "occ_fri",
"instanceId": "inst_festival",
"startDateTime": "2025-07-18T14:00:00.000Z",
"endDateTime": "2025-07-18T23:00:00.000Z",
"status": "scheduled"
},
{
"id": "occ_sat",
"instanceId": "inst_festival",
"startDateTime": "2025-07-19T12:00:00.000Z",
"endDateTime": "2025-07-19T23:00:00.000Z",
"status": "scheduled"
},
{
"id": "occ_sun",
"instanceId": "inst_festival",
"startDateTime": "2025-07-20T12:00:00.000Z",
"endDateTime": "2025-07-20T22:00:00.000Z",
"status": "scheduled"
}
],
"totalOccurrences": 3,
"upcomingOccurrences": 3
},
"time": {
"temporalPattern": "singular",
"timezone": "America/Chicago",
"displayText": "Jul 18-20, 2025"
},
"location": {
"venue": {
"name": "Lakefront Park",
"address": "1234 Lake Shore Drive, Chicago, IL"
},
"coordinates": {
"lat": 41.8781,
"lng": -87.6298
},
"displayAddress": "Lakefront Park, Chicago, IL"
},
"capacity": {
"unlimited": true
},
"organizer": {
"name": "Chicago Music Events",
"url": "https://chicagomusicfest.com"
},
"primaryImage": "https://example.com/summer-fest-2025.jpg",
"supportingImages": [
"https://example.com/stage-setup.jpg",
"https://example.com/lineup-poster.jpg"
],
"primaryUrl": "https://chicagomusicfest.com/summer-2025",
"urls": [
"https://chicagomusicfest.com/summer-2025",
"https://tickets.example.com/summerfest"
],
"geoLocations": [
{
"id": "geo_park",
"description": "Lakefront Park",
"relationType": "LOCATION",
"score": 100
},
{
"id": "geo_chicago",
"description": "Chicago, IL",
"relationType": "RELEVANCE_REGION",
"score": 98
}
]
}
Example 3: Recurring Event (Weekly Meetup)
Event that repeats on a schedule:
{
"id": "item_003",
"eventId": "evt_python_meetup",
"sourceType": "instagram",
"addedToFeedAt": "2025-11-17T10:00:00.000Z",
"publishedAt": null,
"title": "Python Developers Meetup",
"description": "<p>Weekly gathering for Python enthusiasts. Share projects, learn new techniques, and network.</p>",
"shortDescription": "Weekly Python developer meetup",
"occurrence": {
"nextOccurrence": {
"id": "occ_nov24",
"instanceId": "inst_nov24",
"startDateTime": "2025-11-24T19:00:00.000Z",
"endDateTime": "2025-11-24T21:00:00.000Z",
"status": "scheduled"
},
"occurrencesInRange": [
{
"id": "occ_nov24",
"instanceId": "inst_nov24",
"startDateTime": "2025-11-24T19:00:00.000Z",
"endDateTime": "2025-11-24T21:00:00.000Z",
"status": "scheduled"
},
{
"id": "occ_dec01",
"instanceId": "inst_dec01",
"startDateTime": "2025-12-01T19:00:00.000Z",
"endDateTime": "2025-12-01T21:00:00.000Z",
"status": "scheduled"
},
{
"id": "occ_dec08",
"instanceId": "inst_dec08",
"startDateTime": "2025-12-08T19:00:00.000Z",
"endDateTime": "2025-12-08T21:00:00.000Z",
"status": "scheduled"
},
{
"id": "occ_dec15",
"instanceId": "inst_dec15",
"startDateTime": "2025-12-15T19:00:00.000Z",
"endDateTime": "2025-12-15T21:00:00.000Z",
"status": "scheduled"
}
],
"totalOccurrences": 4,
"upcomingOccurrences": 4
},
"time": {
"temporalPattern": "recurring",
"timezone": "America/Los_Angeles",
"displayText": "Every Monday at 7:00 PM PST"
},
"location": {
"venue": {
"name": "TechHub Coworking",
"address": "456 Market St, San Francisco, CA 94105"
},
"coordinates": {
"lat": 37.7749,
"lng": -122.4194
},
"displayAddress": "TechHub Coworking, 456 Market St, San Francisco, CA"
},
"capacity": {
"total": 50,
"available": 12,
"unlimited": false
},
"organizer": {
"name": "SF Python User Group",
"url": "https://sfpython.org",
"contact": "organizers@sfpython.org"
},
"primaryImage": null,
"supportingImages": [],
"primaryUrl": "https://sfpython.org/meetups",
"urls": ["https://sfpython.org/meetups"],
"geoLocations": [
{
"id": "geo_techhub",
"description": "TechHub Coworking",
"relationType": "LOCATION",
"score": 100
},
{
"id": "geo_sf",
"description": "San Francisco, CA",
"relationType": "RELEVANCE_REGION",
"score": 95
}
]
}
Example 4: Online-Only Event (Webinar)
Virtual event with no physical location:
{
"id": "item_004",
"eventId": "evt_webinar_security",
"sourceType": "site",
"addedToFeedAt": "2025-11-17T10:00:00.000Z",
"publishedAt": null,
"title": "Cybersecurity Best Practices 2025",
"description": "<p>Learn the latest cybersecurity techniques from industry experts.</p>",
"shortDescription": "Online cybersecurity training webinar",
"occurrence": {
"nextOccurrence": {
"id": "occ_webinar",
"instanceId": "inst_webinar",
"startDateTime": "2025-12-05T18:00:00.000Z",
"endDateTime": "2025-12-05T19:30:00.000Z",
"status": "scheduled"
},
"occurrencesInRange": [
{
"id": "occ_webinar",
"instanceId": "inst_webinar",
"startDateTime": "2025-12-05T18:00:00.000Z",
"endDateTime": "2025-12-05T19:30:00.000Z",
"status": "scheduled"
}
],
"totalOccurrences": 1,
"upcomingOccurrences": 1
},
"time": {
"temporalPattern": "singular",
"timezone": "UTC",
"displayText": "Dec 5, 2025 at 6:00 PM UTC"
},
"location": {
"online": {
"platform": "Zoom",
"url": "https://zoom.us/j/123456789"
},
"displayAddress": "Online via Zoom"
},
"capacity": {
"total": 500,
"available": 234,
"unlimited": false
},
"organizer": {
"name": "SecureIT Training",
"url": "https://secureit-training.com",
"contact": "info@secureit-training.com"
},
"primaryImage": "https://example.com/security-webinar.jpg",
"supportingImages": [],
"primaryUrl": "https://secureit-training.com/webinars/best-practices-2025",
"urls": [
"https://secureit-training.com/webinars/best-practices-2025",
"https://zoom.us/j/123456789"
],
"geoLocations": []
}
Example 5: Cancelled Event
Event that has been cancelled:
{
"id": "item_005",
"eventId": "evt_outdoor_concert",
"sourceType": "facebook",
"addedToFeedAt": "2025-11-17T10:00:00.000Z",
"publishedAt": null,
"title": "Outdoor Summer Concert",
"description": "<p>Annual outdoor concert series - CANCELLED due to venue construction.</p>",
"shortDescription": "Outdoor concert (CANCELLED)",
"occurrence": {
"nextOccurrence": {
"id": "occ_cancelled",
"instanceId": "inst_cancelled",
"startDateTime": "2025-08-15T19:00:00.000Z",
"endDateTime": "2025-08-15T22:00:00.000Z",
"status": "cancelled"
},
"occurrencesInRange": [
{
"id": "occ_cancelled",
"instanceId": "inst_cancelled",
"startDateTime": "2025-08-15T19:00:00.000Z",
"endDateTime": "2025-08-15T22:00:00.000Z",
"status": "cancelled"
}
],
"totalOccurrences": 1,
"upcomingOccurrences": 0
},
"time": {
"temporalPattern": "singular",
"timezone": "America/Denver",
"displayText": "Aug 15, 2025 at 7:00 PM MDT"
},
"location": {
"venue": {
"name": "City Park Amphitheater",
"address": "789 Park Ave, Denver, CO"
},
"coordinates": {
"lat": 39.7392,
"lng": -104.9903
},
"displayAddress": "City Park Amphitheater, Denver, CO"
},
"capacity": null,
"organizer": {
"name": "Denver Parks & Recreation"
},
"primaryImage": null,
"supportingImages": [],
"primaryUrl": "https://denverparks.org/events",
"urls": ["https://denverparks.org/events"],
"geoLocations": [
{
"id": "geo_amphitheater",
"description": "City Park Amphitheater",
"relationType": "LOCATION",
"score": 100
}
]
}
Example 6: Hybrid Event (Physical + Online)
Event available both in-person and remotely:
{
"id": "item_006",
"eventId": "evt_tech_conference",
"sourceType": "site",
"addedToFeedAt": "2025-11-17T10:00:00.000Z",
"publishedAt": null,
"title": "TechWorld Conference 2025",
"description": "<p>Join us in person or online for the premier technology conference of the year.</p>",
"shortDescription": "Hybrid tech conference with 100+ speakers",
"occurrence": {
"nextOccurrence": {
"id": "occ_day1",
"instanceId": "inst_conf",
"startDateTime": "2025-09-10T09:00:00.000Z",
"endDateTime": "2025-09-10T18:00:00.000Z",
"status": "scheduled"
},
"occurrencesInRange": [
{
"id": "occ_day1",
"instanceId": "inst_conf",
"startDateTime": "2025-09-10T09:00:00.000Z",
"endDateTime": "2025-09-10T18:00:00.000Z",
"status": "scheduled"
},
{
"id": "occ_day2",
"instanceId": "inst_conf",
"startDateTime": "2025-09-11T09:00:00.000Z",
"endDateTime": "2025-09-11T18:00:00.000Z",
"status": "scheduled"
}
],
"totalOccurrences": 2,
"upcomingOccurrences": 2
},
"time": {
"temporalPattern": "singular",
"timezone": "America/Los_Angeles",
"displayText": "Sep 10-11, 2025 at 9:00 AM PST"
},
"location": {
"venue": {
"name": "Moscone Center",
"address": "747 Howard St, San Francisco, CA 94103"
},
"coordinates": {
"lat": 37.7842,
"lng": -122.4016
},
"online": {
"platform": "Virtual Event Platform",
"url": "https://techworld2025.virtual.com"
},
"displayAddress": "Moscone Center, San Francisco, CA + Online"
},
"capacity": {
"total": 5000,
"available": 1200,
"unlimited": false
},
"organizer": {
"name": "TechWorld Events Inc",
"url": "https://techworld.events",
"contact": "info@techworld.events"
},
"primaryImage": "https://example.com/techworld-2025.jpg",
"supportingImages": [
"https://example.com/speakers-lineup.jpg",
"https://example.com/venue-map.jpg"
],
"primaryUrl": "https://techworld2025.com",
"urls": [
"https://techworld2025.com",
"https://tickets.techworld2025.com",
"https://techworld2025.virtual.com"
],
"geoLocations": [
{
"id": "geo_moscone",
"description": "Moscone Center",
"relationType": "LOCATION",
"score": 100
},
{
"id": "geo_sf",
"description": "San Francisco, CA",
"relationType": "RELEVANCE_REGION",
"score": 95
}
]
}
Response Fields
Top-level Response:
| Field | Type | Description |
|---|---|---|
items | array | Array of event feed items (see Event Feed Item fields below) |
total | number | Total number of events matching the query |
pagination | object | Pagination metadata |
pagination.limit | number | Number of items per page |
pagination.offset | number | Current offset in results |
pagination.hasMore | boolean | Whether more items are available |
Event Feed Item Fields:
Metadata:
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique feed item identifier |
eventId | string (UUID) | Event identifier (same event can appear in multiple feeds) |
sourceType | string | Source that produced the event: site, sitemap, siteIndexPage, instagram, facebook, tiktok, or twitter |
addedToFeedAt | string (ISO 8601) | When event was added to this feed |
publishedAt | string (ISO 8601)|null | When event was originally published (currently always null - extraction pending) |
Core Event Data:
| Field | Type | Description |
|---|---|---|
title | string | Event title (may contain HTML) |
description | string | Full event description (may contain HTML) |
shortDescription | string|null | Brief summary of the event |
Occurrence Information (occurrence object):
The occurrence object aggregates all instances and occurrences of an event into a single, easy-to-consume format:
| Field | Type | Description |
|---|---|---|
nextOccurrence | object|null | Earliest occurrence in the query date range |
nextOccurrence.id | string (UUID) | Occurrence identifier |
nextOccurrence.instanceId | string (UUID) | Parent instance identifier |
nextOccurrence.startDateTime | string (ISO 8601) | When the occurrence starts |
nextOccurrence.endDateTime | string (ISO 8601)|null | When the occurrence ends |
nextOccurrence.status | string | Instance status: scheduled, cancelled, postponed, rescheduled, completed |
occurrencesInRange | array | All occurrences matching the query date range (same structure as nextOccurrence) |
totalOccurrences | number | Total number of occurrences in the query range |
upcomingOccurrences | number | Number of future occurrences (from current time) |
Understanding Occurrences:
- For a one-time event:
totalOccurrences= 1, single entry inoccurrencesInRange - For a multi-day event (e.g., festival):
totalOccurrences> 1, each day is a separate occurrence - For recurring events (e.g., weekly meetup): Multiple instances, each with their own occurrences
nextOccurrencealways points to the earliest occurrence in your query range, making it easy to display "next event date"
Event Details (Structured Data):
Time Information (time object|null):
| Field | Type | Description |
|---|---|---|
temporalPattern | string | Event pattern: singular (one-time), recurring (repeats), ongoing (continuous) |
timezone | string | IANA timezone identifier (e.g., America/Los_Angeles) |
displayText | string | Human-readable time description (e.g., "Oct 20, 2025 at 7:00 PM PST") |
Location Information (location object|null):
| Field | Type | Description |
|---|---|---|
venue | object|undefined | Physical venue information |
venue.name | string | Venue name |
venue.address | string|undefined | Street address |
coordinates | object|undefined | Geographic coordinates |
coordinates.lat | number | Latitude |
coordinates.lng | number | Longitude |
online | object|undefined | Online event information |
online.platform | string | Platform name (e.g., "Zoom", "YouTube Live") |
online.url | string | Event URL/link |
displayAddress | string | Human-readable address for display |
Capacity Information (capacity object|null):
| Field | Type | Description |
|---|---|---|
total | number|undefined | Total capacity/seats |
available | number|undefined | Currently available seats |
unlimited | boolean | Whether capacity is unlimited |
Organizer Information (organizer object|null):
| Field | Type | Description |
|---|---|---|
name | string | Organizer name |
url | string|undefined | Organizer website |
contact | string|undefined | Contact information (email/phone) |
Media & Links:
| Field | Type | Description |
|---|---|---|
primaryImage | string|null | Main event image URL |
supportingImages | string[] | Additional image URLs |
primaryUrl | string|null | Main event URL/website |
urls | string[] | All related URLs |
Geographic Relevance:
The geoLocations array contains all geographic locations associated with the event across all instances:
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Geographic location identifier |
description | string | Location description (e.g., venue name, city name) |
relationType | string | LOCATION (specific point/venue) or RELEVANCE_REGION (broader area) |
score | number | Relevance score (0-100) indicating confidence/importance |
Query Examples
Example 1: Get upcoming events (default behavior)
Returns events happening from now until 30 days in the future:
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items" \
-H "Authorization: Bearer YOUR_API_KEY"
Example 2: Get events in December 2025
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items?since=2025-12-01T00:00:00Z&until=2025-12-31T23:59:59Z" \
-H "Authorization: Bearer YOUR_API_KEY"
Example 3: Get only scheduled events (exclude cancelled)
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items?status=scheduled" \
-H "Authorization: Bearer YOUR_API_KEY"
Example 4: Get events happening next week
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items?since=2025-11-17T00:00:00Z&until=2025-11-24T23:59:59Z" \
-H "Authorization: Bearer YOUR_API_KEY"
Example 5: Pagination - get second page
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items?limit=20&offset=20" \
-H "Authorization: Bearer YOUR_API_KEY"
Example 6: Get events added to feed recently (newest first)
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items?orderBy=created" \
-H "Authorization: Bearer YOUR_API_KEY"
Pagination
Use limit and offset to paginate through results:
# Get first page (items 1-20)
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items?limit=20&offset=0" \
-H "Authorization: Bearer YOUR_API_KEY"
# Get second page (items 21-40)
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items?limit=20&offset=20" \
-H "Authorization: Bearer YOUR_API_KEY"
# Get third page (items 41-60)
curl "https://api.feeds.onhelix.ai/v0/feeds/events/550e8400-e29b-41d4-a716-446655440000/items?limit=20&offset=40" \
-H "Authorization: Bearer YOUR_API_KEY"
Check pagination.hasMore in the response to determine if more pages are available.
Understanding Query Behavior
Date Filtering:
The API filters events based on their occurrence dates, not when they were added to the feed:
- An event added months ago will appear if it has an occurrence in your query range
- Recurring events appear if any occurrence falls within the range
- Multi-day events appear if any day overlaps with the range
Status Filtering:
The status parameter filters events by their current status:
scheduled: Event is happening as plannedcancelled: Event has been cancelledpostponed: Event delayed (check for new dates)rescheduled: Event moved to different datecompleted: Event is over
Common Scenarios Quick Reference
"Show me this weekend's events"
curl "https://api.feeds.onhelix.ai/v0/feeds/events/{feedId}/items?since=2025-11-22T00:00:00Z&until=2025-11-24T23:59:59Z" \
-H "Authorization: Bearer YOUR_API_KEY"
"What events were just added to my feed?"
curl "https://api.feeds.onhelix.ai/v0/feeds/events/{feedId}/items?orderBy=created&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"
"Show me only virtual/online events"
// Get all events, then filter in your application:
const events = await fetch(
`https://api.feeds.onhelix.ai/v0/feeds/events/{feedId}/items`,
{
headers: { Authorization: 'Bearer YOUR_API_KEY' },
}
).then((r) => r.json());
const onlineEvents = events.data.items.filter(
(event) => event.location?.online && !event.location?.venue
);
"Which events are selling out soon?"
// Get all events, then filter by capacity:
const events = await fetch(
`https://api.feeds.onhelix.ai/v0/feeds/events/{feedId}/items`,
{
headers: { Authorization: 'Bearer YOUR_API_KEY' },
}
).then((r) => r.json());
const lowAvailability = events.data.items.filter((event) => {
const capacity = event.capacity;
if (!capacity || capacity.unlimited) return false;
const availablePercent = (capacity.available / capacity.total) * 100;
return availablePercent < 20; // Less than 20% available
});
"Get all recurring events"
// Filter by temporalPattern:
const events = await fetch(
`https://api.feeds.onhelix.ai/v0/feeds/events/{feedId}/items`,
{
headers: { Authorization: 'Bearer YOUR_API_KEY' },
}
).then((r) => r.json());
const recurringEvents = events.data.items.filter(
(event) => event.time?.temporalPattern === 'recurring'
);
"Show me events in San Francisco"
// Filter by geoLocations:
const events = await fetch(
`https://api.feeds.onhelix.ai/v0/feeds/events/{feedId}/items`,
{
headers: { Authorization: 'Bearer YOUR_API_KEY' },
}
).then((r) => r.json());
const sfEvents = events.data.items.filter((event) =>
event.geoLocations.some((geo) =>
geo.description.toLowerCase().includes('san francisco')
)
);
"Get the next occurrence of each event"
// Use nextOccurrence for easy access:
const events = await fetch(
`https://api.feeds.onhelix.ai/v0/feeds/events/{feedId}/items`,
{
headers: { Authorization: 'Bearer YOUR_API_KEY' },
}
).then((r) => r.json());
events.data.items.forEach((event) => {
if (event.occurrence.nextOccurrence) {
console.log(
`${event.title}: ${event.occurrence.nextOccurrence.startDateTime}`
);
}
});
"Handle cancelled events gracefully"
// Check status before displaying:
function getEventStatus(event) {
const status = event.occurrence.nextOccurrence?.status;
if (status === 'cancelled') {
return { show: false, reason: 'Event cancelled' };
}
if (status === 'postponed') {
return { show: true, notice: 'Event postponed - check for new dates' };
}
return { show: true, notice: null };
}
Error Responses
All endpoints may return the following error responses:
400 Bad Request
Invalid request parameters or body.
{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "Invalid request parameters",
"details": {
"field": "since",
"issue": "Dates must be within 7 days in the past and 30 days in the future"
}
}
}
Common causes:
- Missing required fields
- Invalid field types or formats
- Validation failures (date ranges, limits, etc.)
- Date range exceeds allowed window
401 Unauthorized
Missing or invalid API key.
{
"success": false,
"error": "Authentication failed for strategy: api-key",
"code": "AUTHENTICATION_FAILED"
}
Common causes:
- Missing
Authorizationheader - Invalid API key format
- Expired or revoked API key
404 Not Found
Requested resource doesn't exist.
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Event feed not found"
}
}
Common causes:
- Invalid feed ID
- Feed was deleted
- Source ID doesn't exist
500 Internal Server Error
Unexpected server error.
{
"success": false,
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "An unexpected error occurred"
}
}
Solution: Retry the request. If the error persists, contact support.
Best Practices
Date Range Queries
Use specific date ranges for better performance:
// Good: Specific date range
const thisWeekend = await fetch(
`https://api.feeds.onhelix.ai/feeds/events/${feedId}/items?since=2025-11-22T00:00:00Z&until=2025-11-24T23:59:59Z`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
// Also good: Let API calculate default 30-day range
const upcoming = await fetch(
`https://api.feeds.onhelix.ai/feeds/events/${feedId}/items`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
Remember date range limits:
- Maximum 7 days in the past
- Maximum 30 days in the future
- Total window cannot exceed ~37 days
Working with Occurrences
Understanding the occurrence data structure:
// Single occurrence event
{
"occurrence": {
"nextOccurrence": { /* occurrence details */ },
"totalOccurrences": 1,
"upcomingOccurrences": 1
}
}
// Multi-day festival
{
"occurrence": {
"nextOccurrence": { /* first day */ },
"occurrencesInRange": [
{ /* day 1 */ },
{ /* day 2 */ },
{ /* day 3 */ }
],
"totalOccurrences": 3,
"upcomingOccurrences": 3
}
}
// Weekly recurring meetup (showing occurrences in 30-day window)
{
"occurrence": {
"nextOccurrence": { /* this week's meeting */ },
"occurrencesInRange": [
{ /* week 1 */ },
{ /* week 2 */ },
{ /* week 3 */ },
{ /* week 4 */ }
],
"totalOccurrences": 4,
"upcomingOccurrences": 4
}
}
Displaying event dates:
function formatEventDates(event) {
const { occurrence, time } = event;
if (!occurrence.nextOccurrence) {
return 'No upcoming occurrences';
}
// For single occurrence
if (occurrence.totalOccurrences === 1) {
return `${new Date(
occurrence.nextOccurrence.startDateTime
).toLocaleDateString()} at ${time?.displayText || 'TBD'}`;
}
// For multiple occurrences
const firstDate = new Date(
occurrence.nextOccurrence.startDateTime
).toLocaleDateString();
const lastDate = new Date(
occurrence.occurrencesInRange[
occurrence.occurrencesInRange.length - 1
].startDateTime
).toLocaleDateString();
return `${firstDate} - ${lastDate} (${occurrence.totalOccurrences} dates)`;
}
Pagination
When retrieving large numbers of events, use pagination:
async function getAllFeedEvents(feedId, dateRange) {
const allEvents = [];
let offset = 0;
const limit = 100; // Maximum allowed
while (true) {
const url = new URL(
`https://api.feeds.onhelix.ai/feeds/events/${feedId}/items`
);
url.searchParams.set('limit', limit);
url.searchParams.set('offset', offset);
if (dateRange.since) url.searchParams.set('since', dateRange.since);
if (dateRange.until) url.searchParams.set('until', dateRange.until);
const response = await fetch(url, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const result = await response.json();
if (result.data.items.length === 0) break;
allEvents.push(...result.data.items);
// Check if more items available
if (!result.data.pagination.hasMore) break;
offset += result.data.items.length;
}
return allEvents;
}
Filtering by Status
Get only active events:
const activeEvents = await fetch(
`https://api.feeds.onhelix.ai/feeds/events/${feedId}/items?status=scheduled`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
Handle cancelled events in UI:
function EventCard({ event }) {
if (event.occurrence.nextOccurrence?.status === 'cancelled') {
return (
<div className="event-card cancelled">
<h3>{event.title}</h3>
<p className="status-badge">CANCELLED</p>
{/* Show event details but mark as cancelled */}
</div>
);
}
return <div className="event-card">{/* Normal event display */}</div>;
}
Submit Item Feedback
Submits feedback for a specific event feed item. Use this to indicate whether an event was relevant or useful.
POST /feeds/events/{feedId}/items/{itemId}/feedback
Request
Path parameters:
| Name | Type | Description |
|---|---|---|
feedId | string (UUID) | Event feed identifier |
itemId | string (UUID) | Event feed item identifier (from id field) |
Headers:
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Body:
{
"rating": "positive",
"comment": "This event was exactly what I was looking for."
}
Parameters:
| Name | Type | Required | Description |
|---|---|---|---|
rating | string | Yes | Feedback rating: positive, negative, or neutral |
comment | string | No | Optional comment explaining the feedback. Maximum 5000 characters. |
Response
Status: 200 OK
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440099"
}
}
Response fields:
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique feedback identifier |
Examples
Positive feedback with comment:
curl -X POST https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000/items/770e8400-e29b-41d4-a716-446655440005/feedback \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rating": "positive",
"comment": "Perfect event for our community calendar!"
}'
Negative feedback without comment:
curl -X POST https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000/items/770e8400-e29b-41d4-a716-446655440005/feedback \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rating": "negative"
}'
Neutral feedback:
curl -X POST https://api.feeds.onhelix.ai/feeds/events/550e8400-e29b-41d4-a716-446655440000/items/770e8400-e29b-41d4-a716-446655440005/feedback \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rating": "neutral",
"comment": "Event was okay but not quite what we needed."
}'
Errors
400: Invalid rating value, invalid UUID format, or comment exceeds maximum length401: Missing or invalid API key404: Feed or item not found, or you don't have access to this feed
Notes
- Feedback is additive: you can submit multiple feedback entries for the same item
- You can only submit feedback for items in feeds you own or are subscribed to
- Feedback helps improve event relevance recommendations over time
Source ID Management
Keep track of source IDs for reuse across multiple feeds:
// Source IDs can be shared across feeds
const venueSourceIds = {
'Main Theater': '770e8400-e29b-41d4-a716-446655440001',
'Community Center': '770e8400-e29b-41d4-a716-446655440006',
'City Park': 'siteIndexPage_ghi789',
};
// Create multiple feeds using the same sources
async function createVenueFeed(name, sourceIds) {
// Create feed
const feedResponse = await createEventFeed({ name, description: name });
const feedId = feedResponse.data.id;
// Add sources
for (const sourceId of sourceIds) {
await addSourceToFeed(feedId, sourceId);
}
return feedId;
}
// Different feeds can use the same sources
await createVenueFeed('All Venues', Object.values(venueSourceIds));
await createVenueFeed('Main Events', [venueSourceIds['Main Theater']]);
Next Steps
- Event Feed Overview: Understand event feeds and source types
- Event Feed Concepts: Learn about the event data model and occurrence aggregation
- Quickstart Guide: Create your first feed in 5 minutes
- Webhooks: Set up webhook notifications for new events
- Authentication: API key best practices