Skip to main content

Event Feeds Workflows

Learn how to build common event features with step-by-step examples. These workflows show you how to fetch, filter, and display events from your feeds.

Building an Event Listing Page

Scenario: Display upcoming events for the next 30 days on your website.

Step 1: Fetch upcoming events

# Get events for the next 30 days
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"

Response:

{
"data": {
"items": [
{
"id": "660e8400-e29b-41d4-a716-446655440003",
"title": "Summer Music Festival",
"shortDescription": "Three-day outdoor music festival",
"occurrence": {
"nextOccurrence": {
"startDateTime": "2025-07-12T18:00:00.000Z",
"endDateTime": "2025-07-12T23:00:00.000Z",
"status": "scheduled"
},
"totalOccurrences": 3,
"upcomingOccurrences": 3
},
"time": {
"temporalPattern": "singular",
"timezone": "America/Los_Angeles",
"displayText": "Jul 12-14, 2025 at 6:00 PM PDT"
},
"location": {
"venue": {
"name": "City Park Amphitheater",
"address": "123 Main St, Portland, OR 97201"
},
"displayAddress": "City Park Amphitheater, Portland, OR"
},
"primaryImage": "https://example.com/festival.jpg",
"primaryUrl": "https://example.com/summer-festival"
}
],
"pagination": {
"limit": 20,
"offset": 0,
"total": 45,
"hasMore": true
}
}
}

Step 2: Display events by type

# One-time events: Check temporalPattern === "singular" and totalOccurrences === 1
# Multi-day events: Check temporalPattern === "singular" and totalOccurrences > 1
# Recurring events: Check temporalPattern === "recurring"

# Example display logic:
# - Title: event.title
# - When: event.time.displayText (human-readable)
# - Where: event.location.displayAddress
# - Image: event.primaryImage
# - Link: event.primaryUrl

Handling Different Event Patterns

One-Time Events

Single occurrence on a specific date.

curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"title": "Tech Conference 2025",
"occurrence": {
"nextOccurrence": {
"startDateTime": "2025-10-20T09:00:00.000Z",
"endDateTime": "2025-10-20T17:00:00.000Z",
"status": "scheduled"
},
"totalOccurrences": 1,
"upcomingOccurrences": 1
},
"time": {
"temporalPattern": "singular",
"displayText": "Oct 20, 2025 at 9:00 AM PST"
}
}

Display: "Tech Conference 2025 - Oct 20, 2025 at 9:00 AM PST"

Multi-Day Events

Single event spanning consecutive days.

{
"title": "Food & Wine Festival",
"occurrence": {
"nextOccurrence": {
"startDateTime": "2025-08-15T11:00:00.000Z",
"status": "scheduled"
},
"totalOccurrences": 3,
"occurrencesInRange": [
{ "startDateTime": "2025-08-15T11:00:00.000Z" },
{ "startDateTime": "2025-08-16T11:00:00.000Z" },
{ "startDateTime": "2025-08-17T11:00:00.000Z" }
]
},
"time": {
"temporalPattern": "singular",
"displayText": "Aug 15-17, 2025 at 11:00 AM PDT"
}
}

Display: "Food & Wine Festival - Aug 15-17, 2025 (3 days)"

Recurring Events

Events that repeat on a schedule.

{
"title": "Weekly Farmers Market",
"occurrence": {
"nextOccurrence": {
"startDateTime": "2025-11-23T09:00:00.000Z",
"status": "scheduled"
},
"totalOccurrences": 4,
"upcomingOccurrences": 4
},
"time": {
"temporalPattern": "recurring",
"displayText": "Every Sunday at 9:00 AM PST"
}
}

Display: "Weekly Farmers Market - Every Sunday at 9:00 AM PST (4 upcoming dates)"

Filtering by Date Range

Get events for a specific weekend:

# Weekend of December 20-22, 2025
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?since=2025-12-20T00:00:00Z&until=2025-12-22T23:59:59Z&limit=50" \
-H "Authorization: Bearer YOUR_API_KEY"

Get this month's events:

# December 2025 events
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?since=2025-12-01T00:00:00Z&until=2025-12-31T23:59:59Z&limit=100" \
-H "Authorization: Bearer YOUR_API_KEY"

Important: Date ranges are limited to:

  • Maximum 7 days in the past
  • Maximum 30 days in the future
  • Total window cannot exceed ~37 days

Filtering by Event Status

Show only active events (excludes cancelled, postponed, completed):

curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?status=scheduled&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"

Handle cancelled events in your display:

{
"title": "Annual Gala",
"occurrence": {
"nextOccurrence": {
"startDateTime": "2025-12-05T19:00:00.000Z",
"status": "cancelled"
}
}
}

Display logic:

# Pseudo-code for display:
if status === "cancelled":
show_badge("CANCELLED")
apply_strikethrough_styling()
elif status === "postponed":
show_badge("POSTPONED")
show_message("New date TBA")
elif status === "rescheduled":
show_badge("RESCHEDULED")
# Look for new occurrence with status === "scheduled"
else:
# Normal display

Handling Different Location Types

Physical Events

{
"title": "Community Meetup",
"location": {
"venue": {
"name": "Downtown Library",
"address": "456 Oak St, Seattle, WA 98101"
},
"coordinates": {
"lat": 47.6062,
"lng": -122.3321
},
"displayAddress": "Downtown Library, 456 Oak St, Seattle, WA"
}
}

Display: "📍 Downtown Library, Seattle, WA" + [Show on map button]

Online Events

{
"title": "Virtual Workshop",
"location": {
"online": {
"platform": "Zoom",
"url": "https://zoom.us/j/123456789"
},
"displayAddress": "Online via Zoom"
}
}

Display: "💻 Online via Zoom" + [Join meeting button]

Hybrid Events

{
"title": "Tech Conference",
"location": {
"venue": {
"name": "Convention Center",
"address": "789 Pine St, San Francisco, CA 94102"
},
"online": {
"platform": "StreamYard",
"url": "https://streamyard.com/watch/xyz"
},
"displayAddress": "Convention Center, San Francisco + Online"
}
}

Display: "🏢 Convention Center, SF + 💻 Virtual attendance available"

Sorting Events

By occurrence date (default - soonest first):

curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?orderBy=occurrence&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"

By recently added:

curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?orderBy=created&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"

Pagination

Load More Events (Infinite Scroll)

# Initial load
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"

# Returns: { pagination: { offset: 0, limit: 20, total: 150, hasMore: true } }

# Load next page
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?limit=20&offset=20" \
-H "Authorization: Bearer YOUR_API_KEY"

# Returns: { pagination: { offset: 20, limit: 20, total: 150, hasMore: true } }

# Continue until hasMore === false

Get Complete Dataset

# Fetch all events in batches
OFFSET=0
LIMIT=100

while true; do
RESPONSE=$(curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?limit=$LIMIT&offset=$OFFSET" \
-H "Authorization: Bearer YOUR_API_KEY")

# Process events from RESPONSE

HAS_MORE=$(echo $RESPONSE | jq -r '.data.pagination.hasMore')
if [ "$HAS_MORE" != "true" ]; then
break
fi

OFFSET=$((OFFSET + LIMIT))
done

Building a Calendar View

Scenario: Display events in a monthly calendar.

# Step 1: Get all events for the month
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?since=2025-12-01T00:00:00Z&until=2025-12-31T23:59:59Z&limit=100" \
-H "Authorization: Bearer YOUR_API_KEY"

# Step 2: Group by date
# For each event:
# - Extract occurrence.occurrencesInRange[]
# - Group events by startDateTime date
# - Display on corresponding calendar day

# Step 3: Handle multi-occurrence events
# - One-time: Show on single date
# - Multi-day: Show on all dates in range
# - Recurring: Show on each occurrence date

Display logic:

# Pseudo-code:
calendar = {}

for event in events:
for occurrence in event.occurrence.occurrencesInRange:
date = occurrence.startDateTime.split('T')[0] # Get YYYY-MM-DD

if date not in calendar:
calendar[date] = []

calendar[date].append({
'title': event.title,
'time': format_time(occurrence.startDateTime),
'status': occurrence.status,
'url': event.primaryUrl
})

# Render calendar with events grouped by date

Showing Event Capacity

Display ticket availability:

{
"title": "Concert",
"capacity": {
"total": 500,
"available": 50,
"unlimited": false
}
}

Display logic:

# Calculate availability percentage
available_percent = (capacity.available / capacity.total) * 100

if capacity.unlimited:
show_message("Tickets available")
elif available_percent < 10:
show_badge("Almost sold out!")
show_message("Only {capacity.available} tickets left")
elif available_percent < 30:
show_message("Limited availability")
else:
show_message("{capacity.available} tickets available")

Geographic Filtering

Find Events Near a Location

# Step 1: Fetch events with location data
curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?limit=100" \
-H "Authorization: Bearer YOUR_API_KEY"

# Step 2: Filter by geographic location
# Events include geoLocations array with descriptions:
# - "relationType": "LOCATION" - Specific venue
# - "relationType": "RELEVANCE_REGION" - Broader area

# Example: Find events in San Francisco
# Filter where geoLocations[].description contains "San Francisco"

Using Coordinates (Client-Side Filtering)

# Events with coordinates can be filtered by distance
# Each event.location.coordinates has {lat, lng}

# Pseudo-code for distance filtering:
user_location = {lat: 37.7749, lng: -122.4194} # San Francisco

nearby_events = events.filter(event => {
if (!event.location?.coordinates) return false

distance = calculate_distance(
user_location,
event.location.coordinates
)

return distance < 10 # Within 10 miles
})

Building a "This Weekend" Widget

Complete example:

#!/bin/bash

# Calculate this weekend's dates
FRIDAY=$(date -d "next friday" +%Y-%m-%dT00:00:00Z)
SUNDAY=$(date -d "next sunday" +%Y-%m-%dT23:59:59Z)

# Fetch weekend events
EVENTS=$(curl "https://api.feeds.onhelix.ai/feeds/events/{feedId}/items?since=$FRIDAY&until=$SUNDAY&status=scheduled&limit=50" \
-H "Authorization: Bearer YOUR_API_KEY")

# Display formatted output
echo "$EVENTS" | jq -r '.data.items[] |
"• \(.title)
When: \(.time.displayText)
Where: \(.location.displayAddress)
\(.primaryUrl)
"'

Output:

• Summer Concert Series
When: Fri, Jul 12, 2025 at 7:00 PM PDT
Where: City Park, Portland, OR
https://example.com/summer-concerts

• Food Truck Festival
When: Sat, Jul 13, 2025 at 11:00 AM PDT
Where: Downtown Plaza, Portland, OR
https://example.com/food-trucks

• Farmers Market
When: Sun, Jul 14, 2025 at 9:00 AM PDT
Where: Market Square, Portland, OR
https://example.com/farmers-market

Best Practices

1. Use Appropriate Date Ranges

# ✓ Good: 30-day window for general event browsing
?since=2025-12-01T00:00:00Z&until=2025-12-30T23:59:59Z

# ✓ Good: Specific weekend
?since=2025-12-20T00:00:00Z&until=2025-12-22T23:59:59Z

# ✗ Bad: Exceeds 30-day future limit
?since=2025-12-01T00:00:00Z&until=2026-02-01T23:59:59Z

2. Filter by Status for User-Facing Displays

# ✓ Always use status=scheduled for public listings
?status=scheduled

# This automatically excludes cancelled, postponed, and completed events

3. Handle Pagination Properly

# ✓ Good: Check hasMore before requesting next page
if (response.data.pagination.hasMore) {
fetchNextPage(response.data.pagination.offset + limit)
}

# ✗ Bad: Assuming fixed total pages
for (let page = 1; page <= 10; page++) { ... }

4. Use displayText for Dates When Available

# ✓ Good: Use pre-formatted display text
event.time.displayText // "Oct 20, 2025 at 7:00 PM PST"

# ✓ Acceptable: Format startDateTime yourself
new Date(event.occurrence.nextOccurrence.startDateTime).toLocaleString()

# ✓ Best: Combine both for consistency
event.time?.displayText || formatDate(event.occurrence.nextOccurrence.startDateTime)

5. Show Event Type Indicators

if (event.time.temporalPattern === 'recurring'):
show_icon('🔄') // Recurring
elif (event.occurrence.totalOccurrences > 1):
show_icon('📅') // Multi-day
else:
show_icon('📍') // One-time

6. Cache and Refresh Strategically

# ✓ Good: Cache for reasonable duration
cache_duration = 5 minutes # For frequently updated feeds
cache_duration = 1 hour # For stable event listings

# ✓ Good: Refresh on user action
# Provide manual refresh button for users who want latest data

Next Steps