Skip to main content

Event Feed API Reference

Complete API reference for Helix Event Feeds. All endpoints require authentication via API key.

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:


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:

NameTypeRequiredDescription
namestringYesFeed name. Minimum 1 character.
descriptionstringYesFeed description. Minimum 1 character.
enabledbooleanNoWhether the feed is enabled. Defaults to true.
configobjectNoFeed configuration options.
config.versionnumberNoConfig 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:

FieldTypeDescription
idstring (UUID)Unique feed identifier
namestringFeed name
descriptionstringFeed description
enabledbooleanWhether the feed is active
enabledSourcestringWho enabled/disabled the feed (system, admin, api)
enabledReasonstring|nullOptional reason for enabled status
configobjectFeed configuration
createdAtstring (ISO 8601)Feed creation timestamp
updatedAtstring (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:

NameTypeDescription
idstring (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:

NameTypeDescription
idstring (UUID)Event feed ID

Body:

{
"name": "Updated Events Feed",
"description": "Updated description",
"enabled": false,
"config": {
"version": 1
}
}

Parameters:

NameTypeRequiredDescription
namestringNoNew feed name. Minimum 1 character.
descriptionstringNoNew feed description. Minimum 1 character.
enabledbooleanNoEnable or disable the feed.
configobjectNoUpdated 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:

NameTypeDescription
idstring (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:

NameTypeDescription
idstring (UUID)Event feed ID

Body:

{
"sourceType": "site",
"sourceId": "550e8400-e29b-41d4-a716-446655440001"
}

Parameters:

NameTypeRequiredDescription
sourceTypestringYesType of source: site, sitemap, siteIndexPage, instagram, or facebook
sourceIdstring (UUID)YesID 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:

FieldTypeDescription
idstring (UUID)Unique feed source association ID
eventFeedIdstring (UUID)Parent event feed ID
sourceTypestringType of source
sourceIdstring (UUID)Referenced source ID
createdAtstring (ISO 8601)When source was added to feed

What happens after adding a source:

  1. A 14-day backfill workflow is automatically triggered
  2. Recent events from the source are added to your feed
  3. 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:

NameTypeDescription
idstring (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:

NameTypeDescription
idstring (UUID)Event feed ID
sourceIdstring (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 with advanced filtering, date range querying, and flexible sorting options.

GET /feeds/events/:id/items

Request

Headers:

Authorization: Bearer YOUR_API_KEY

Path Parameters:

NameTypeDescription
idstring (UUID)Event feed ID

Query Parameters:

NameTypeRequiredDefaultDescription
limitintegerNo20Number of items to return. Min: 1, Max: 100.
offsetintegerNo0Number of items to skip. Min: 0.
sincedate (ISO 8601)NonowStart of date range for event occurrences.
untildate (ISO 8601)Nosince + 30 daysEnd of date range for event occurrences.
statusstringNoallFilter by instance status: scheduled, cancelled, postponed, rescheduled, completed
orderBystringNooccurrenceSort order: occurrence, created

Date Range Behavior:

The API automatically handles date range logic to provide a sensible default experience:

  1. No dates provided: Returns events with occurrences from now until 30 days in the future
  2. Only since provided: Returns events from since until since + 30 days
  3. Both since and until provided: 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
  • since must be before until
  • 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 first
  • created: 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",
"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": "[email protected]"
},
"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",
"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": "[email protected]"
},
"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",
"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",
"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": "[email protected]"
},
"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",
"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": "[email protected]"
},
"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",
"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",
"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": "[email protected]"
},
"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:

FieldTypeDescription
itemsarrayArray of event feed items (see Event Feed Item fields below)
totalnumberTotal number of events matching the query
paginationobjectPagination metadata
pagination.limitnumberNumber of items per page
pagination.offsetnumberCurrent offset in results
pagination.hasMorebooleanWhether more items are available

Event Feed Item Fields:

Metadata:

FieldTypeDescription
idstring (UUID)Unique feed item identifier
eventIdstring (UUID)Event identifier (same event can appear in multiple feeds)
addedToFeedAtstring (ISO 8601)When event was added to this feed
publishedAtstring (ISO 8601)|nullWhen event was originally published (currently always null - extraction pending)

Core Event Data:

FieldTypeDescription
titlestringEvent title (may contain HTML)
descriptionstringFull event description (may contain HTML)
shortDescriptionstring|nullBrief 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:

FieldTypeDescription
nextOccurrenceobject|nullEarliest occurrence in the query date range
nextOccurrence.idstring (UUID)Occurrence identifier
nextOccurrence.instanceIdstring (UUID)Parent instance identifier
nextOccurrence.startDateTimestring (ISO 8601)When the occurrence starts
nextOccurrence.endDateTimestring (ISO 8601)|nullWhen the occurrence ends
nextOccurrence.statusstringInstance status: scheduled, cancelled, postponed, rescheduled, completed
occurrencesInRangearrayAll occurrences matching the query date range (same structure as nextOccurrence)
totalOccurrencesnumberTotal number of occurrences in the query range
upcomingOccurrencesnumberNumber of future occurrences (from current time)

Understanding Occurrences:

  • For a one-time event: totalOccurrences = 1, single entry in occurrencesInRange
  • 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
  • nextOccurrence always 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):

FieldTypeDescription
temporalPatternstringEvent pattern: singular (one-time), recurring (repeats), ongoing (continuous)
timezonestringIANA timezone identifier (e.g., America/Los_Angeles)
displayTextstringHuman-readable time description (e.g., "Oct 20, 2025 at 7:00 PM PST")

Location Information (location object|null):

FieldTypeDescription
venueobject|undefinedPhysical venue information
venue.namestringVenue name
venue.addressstring|undefinedStreet address
coordinatesobject|undefinedGeographic coordinates
coordinates.latnumberLatitude
coordinates.lngnumberLongitude
onlineobject|undefinedOnline event information
online.platformstringPlatform name (e.g., "Zoom", "YouTube Live")
online.urlstringEvent URL/link
displayAddressstringHuman-readable address for display

Capacity Information (capacity object|null):

FieldTypeDescription
totalnumber|undefinedTotal capacity/seats
availablenumber|undefinedCurrently available seats
unlimitedbooleanWhether capacity is unlimited

Organizer Information (organizer object|null):

FieldTypeDescription
namestringOrganizer name
urlstring|undefinedOrganizer website
contactstring|undefinedContact information (email/phone)

Media & Links:

FieldTypeDescription
primaryImagestring|nullMain event image URL
supportingImagesstring[]Additional image URLs
primaryUrlstring|nullMain event URL/website
urlsstring[]All related URLs

Geographic Relevance:

The geoLocations array contains all geographic locations associated with the event across all instances:

FieldTypeDescription
idstring (UUID)Geographic location identifier
descriptionstringLocation description (e.g., venue name, city name)
relationTypestringLOCATION (specific point/venue) or RELEVANCE_REGION (broader area)
scorenumberRelevance 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/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/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/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/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/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/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/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/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/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 planned
  • cancelled: Event has been cancelled
  • postponed: Event delayed (check for new dates)
  • rescheduled: Event moved to different date
  • completed: Event is over

Common Scenarios Quick Reference

"Show me this weekend's events"

curl "https://api.feeds.onhelix.ai/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/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/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/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/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/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/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": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}

Common causes:

  • Missing Authorization header
  • 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>;
}

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