Skip to main content

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 starts
  • endDateTime - When it ends (if specified)
  • status - Current status (see below)

Status values:

  • 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

Structured Event Details

Events include machine-readable structured data:

Time Information (time):

  • temporalPattern - Type of event:
    • singular: One-time event
    • recurring: 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 name
  • venue.address - Street address
  • coordinates.lat/lng - Geographic coordinates
  • online.platform - Platform for online events (e.g., "Zoom")
  • online.url - Event URL
  • displayAddress - 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 capacity
  • available - Currently available spots
  • unlimited - Whether capacity is unlimited

Organizer Information (organizer):

  • name - Organizer name
  • url - Organizer website
  • contact - Contact information (email/phone)
  • 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 happens
    • RELEVANCE_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
  • nextOccurrence always shows the earliest occurrence in your range

Default Date Range

If you don't specify dates, the API defaults to:

  • since: Current date/time
  • until: 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

FeatureNews FeedsEvent Feeds
Source modelInline definitionReference by ID
Time relevancePublication dateOccurrence dates (future-focused)
FilteringBy publish dateBy occurrence date range
Status trackingNonePer-occurrence status
Recurring contentNoYes (multiple occurrences)
Geographic dataSimpleMultiple locations with relevance scores

How It Works

  1. Create a feed - Your container for events
  2. Add source references - Reference existing source IDs
  3. Automatic discovery - Events from sources flow into your feed
  4. Query with filters - Use date ranges, status filters, and sorting
  5. 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