Event Feeds Concepts
Core concepts and terminology for understanding the Event Feeds API.
What is an Event Feed?
An event feed aggregates events from multiple sources into a single stream. Unlike news feeds, event feeds use a reference-based source model where sources are managed separately and referenced by ID.
Core Entities
Feed
A feed is your container for collected events. It holds configuration and aggregates content from referenced sources.
Source Reference
Event feeds reference sources by their ID rather than defining them inline. Sources are created separately and can be shared across multiple feeds.
Supported source types:
- Site: Monitor an entire domain for event pages
- Sitemap: Track a specific XML sitemap for event URLs
- Index Page: Watch a calendar or events listing page
- Instagram: Monitor an Instagram account for event announcements
- Facebook: Track events from Facebook pages
See Supported Source Types for detailed information about each source type.
When you add a source reference to your feed, the feed begins receiving events from that source.
Item
Each item returned by the API represents an event in your feed.
Event Data
Each event in your feed contains rich, structured information:
Basic Information
- Title: Event name/headline
- Description: Full event description (may contain HTML)
- Short Description: Brief summary
Occurrence Information
The occurrence object tells you when the event happens:
- nextOccurrence: The earliest date/time in your query range
- occurrencesInRange: All dates the event happens (for multi-day or recurring events)
- totalOccurrences: How many times the event occurs
- upcomingOccurrences: How many future occurrences remain
Each occurrence includes:
startDateTime- When it startsendDateTime- When it ends (if specified)status- Current status (see below)
Status values:
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
Structured Event Details
Events include machine-readable structured data:
Time Information (time):
temporalPattern- Type of event:singular: One-time eventrecurring: Repeats on a schedule (weekly, monthly, etc.)ongoing: Continuous/always-available
timezone- IANA timezone (e.g.,America/Los_Angeles)displayText- Human-readable time (e.g., "Oct 20, 2025 at 7:00 PM PST")
Location Information (location):
venue.name- Venue namevenue.address- Street addresscoordinates.lat/lng- Geographic coordinatesonline.platform- Platform for online events (e.g., "Zoom")online.url- Event URLdisplayAddress- Formatted address for display
Events can be:
- Physical: Has venue and/or coordinates
- Online: Has platform and URL
- Hybrid: Both physical and online
Capacity Information (capacity):
total- Total capacityavailable- Currently available spotsunlimited- Whether capacity is unlimited
Organizer Information (organizer):
name- Organizer nameurl- Organizer websitecontact- Contact information (email/phone)
Media & Links
- primaryImage: Main event image
- supportingImages: Additional images
- primaryUrl: Main event website
- urls: All related URLs
Geographic Information
The geoLocations array contains geographic data:
description- Location name (e.g., "Downtown Community Park", "San Francisco")relationType:LOCATION- Specific venue where event happensRELEVANCE_REGION- Broader geographic area
score- Relevance score (0-100)
Common Event Patterns
One-Time Event
Single occurrence on a specific date.
Example: Concert on October 20, 2025
{
"occurrence": {
"totalOccurrences": 1,
"nextOccurrence": {
"startDateTime": "2025-10-20T19:00:00Z",
"endDateTime": "2025-10-20T22:00:00Z",
"status": "scheduled"
}
},
"time": {
"temporalPattern": "singular"
}
}
Multi-Day Event
Single event spanning multiple consecutive days.
Example: 3-day music festival
{
"occurrence": {
"totalOccurrences": 3,
"nextOccurrence": {
"startDateTime": "2025-07-12T18:00:00Z", // Friday
"status": "scheduled"
},
"occurrencesInRange": [
{ "startDateTime": "2025-07-12T18:00:00Z" }, // Friday
{ "startDateTime": "2025-07-13T18:00:00Z" }, // Saturday
{ "startDateTime": "2025-07-14T18:00:00Z" } // Sunday
]
},
"time": {
"temporalPattern": "singular", // Still one event
"displayText": "Jul 12-14, 2025 at 6:00 PM PDT"
}
}
Recurring Event
Event that repeats on a schedule.
Example: Weekly farmers market
{
"occurrence": {
"totalOccurrences": 4, // 4 weeks in query range
"upcomingOccurrences": 4,
"nextOccurrence": {
"startDateTime": "2025-11-17T09:00:00Z", // This week
"status": "scheduled"
},
"occurrencesInRange": [
{ "startDateTime": "2025-11-17T09:00:00Z", "status": "scheduled" },
{ "startDateTime": "2025-11-24T09:00:00Z", "status": "scheduled" },
{ "startDateTime": "2025-12-01T09:00:00Z", "status": "cancelled" }, // Holiday
{ "startDateTime": "2025-12-08T09:00:00Z", "status": "scheduled" }
]
},
"time": {
"temporalPattern": "recurring",
"displayText": "Every Sunday at 9:00 AM PST"
}
}
Cancelled or Rescheduled Event
Event status changes are reflected in the occurrence data.
Cancelled:
{
"occurrence": {
"nextOccurrence": {
"status": "cancelled"
}
}
}
Rescheduled:
Check for occurrences with status: "rescheduled" and look for new occurrences with status: "scheduled".
Working with Date Ranges
How Date Filtering Works
When you query events with since and until parameters, the API returns events that have at least one occurrence in that date range.
Important behaviors:
- An event added months ago will appear if it has an occurrence in your query range
- For recurring events, you see all occurrences within the range
- For multi-day events, all days overlapping the range are included
nextOccurrencealways shows the earliest occurrence in your range
Default Date Range
If you don't specify dates, the API defaults to:
since: Current date/timeuntil: 30 days in the future
This gives you upcoming events by default.
Date Range Limits
- Maximum 7 days in the past
- Maximum 30 days in the future
- Total window cannot exceed ~37 days
Filtering and Sorting
By Status
Filter events by their current status:
// Get only scheduled (active) events
GET /feeds/events/{feedId}/items?status=scheduled
// Excludes cancelled, postponed, and completed events
Sorting Options
By Occurrence (default): Events sorted by earliest occurrence date (soonest first).
GET /feeds/events/{feedId}/items?orderBy=occurrence
By Created: Events sorted by when added to feed (newest first).
GET /feeds/events/{feedId}/items?orderBy=created
Reference-Based Source Model
Event feeds differ from news feeds in how sources are managed:
News Feeds: Sources are defined inline when adding to a feed
{
"type": "site",
"url": "https://example.com"
}
Event Feeds: Sources are referenced by ID
{
"sourceType": "site",
"sourceId": "770e8400-e29b-41d4-a716-446655440001"
}
Practical Examples
Displaying Event Dates
function formatEventDates(event) {
const { occurrence, time } = event;
if (!occurrence.nextOccurrence) {
return 'No upcoming occurrences';
}
// Single occurrence
if (occurrence.totalOccurrences === 1) {
return (
time?.displayText ||
new Date(occurrence.nextOccurrence.startDateTime).toLocaleDateString()
);
}
// Multiple occurrences
const dates = occurrence.occurrencesInRange.map((occ) =>
new Date(occ.startDateTime).toLocaleDateString()
);
return `${dates.length} dates: ${dates.slice(0, 3).join(', ')}${
dates.length > 3 ? '...' : ''
}`;
}
Checking Event Status
function getEventStatus(event) {
const status = event.occurrence.nextOccurrence?.status;
switch (status) {
case 'scheduled':
return { badge: '✓', color: 'green', text: 'Happening' };
case 'cancelled':
return { badge: '✗', color: 'red', text: 'Cancelled' };
case 'postponed':
return { badge: '⏸', color: 'yellow', text: 'Postponed' };
case 'completed':
return { badge: '✓', color: 'gray', text: 'Completed' };
default:
return { badge: '?', color: 'gray', text: 'Unknown' };
}
}
Working with Location Data
function getEventLocation(event) {
const { location } = event;
if (!location) return 'Location TBD';
// Online event
if (location.online && !location.venue) {
return `Online via ${location.online.platform}`;
}
// Physical event
if (location.venue) {
return location.displayAddress;
}
// Hybrid event
if (location.venue && location.online) {
return `${location.venue.name} + Online via ${location.online.platform}`;
}
return location.displayAddress;
}
Handling Time Zones
function formatEventTime(event) {
const { occurrence, time } = event;
if (!occurrence.nextOccurrence || !time) {
return 'Time TBD';
}
const startTime = new Date(occurrence.nextOccurrence.startDateTime);
// Convert to event's timezone
return startTime.toLocaleString('en-US', {
timeZone: time.timezone,
weekday: 'long',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
timeZoneName: 'short',
});
}
Finding Events in a Specific City
function findEventsInCity(events, cityName) {
return events.filter((event) => {
return event.geoLocations.some((geo) =>
geo.description.toLowerCase().includes(cityName.toLowerCase())
);
});
}
// Usage
const sfEvents = findEventsInCity(allEvents, 'San Francisco');
Key Differences from News Feeds
| Feature | News Feeds | Event Feeds |
|---|---|---|
| Source model | Inline definition | Reference by ID |
| Time relevance | Publication date | Occurrence dates (future-focused) |
| Filtering | By publish date | By occurrence date range |
| Status tracking | None | Per-occurrence status |
| Recurring content | No | Yes (multiple occurrences) |
| Geographic data | Simple | Multiple locations with relevance scores |
How It Works
- Create a feed - Your container for events
- Add source references - Reference existing source IDs
- Automatic discovery - Events from sources flow into your feed
- Query with filters - Use date ranges, status filters, and sorting
- Receive structured data - Get events with occurrence info, locations, and details
When you add a source, events from the past 14 days are automatically added to provide immediate context.
Next Steps
- API Reference: Complete endpoint documentation
- Quickstart Guide: Create your first feed in 5 minutes
- Event Feed Overview: Use cases and implementation examples
- Webhooks: Set up webhook notifications