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. Which of those events it carries is decided by its filters, which read the answers of processors.

Core Entities​

Feed​

A feed is your container for collected events. It holds configuration, its sources and its filters.

Source​

A source is what a feed's events come from. You add websites through the API ({ "type": "site", "url": … }, the whole domain); our team adds the other types on request. You can list, enable, disable and remove every source on your feeds. See Sources.

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
  • TikTok: Track events from a TikTok account
  • Twitter / X: Track events from a Twitter / X account

See Supported Source Types for detailed information about each source type.

When you add a source to an enabled feed, the feed begins receiving events from it, starting with the events the source brought in during the past 14 days. A new feed starts disabled and takes no events in (creating it with enabled: true is a 422); once it has an include filter you enable it, and it receives the past 14 days of events from each of its enabled sources. Each source brings in its past 14 days once.

Item​

Each item returned by the API represents an event in your feed.

Event Data​

Each event in your feed contains structured information. The API reference lists every field; this page explains what they mean.

Basic Information​

  • Title: Event name
  • Description: Full event description
  • Short description: One-sentence summary, when there is one
  • Status: active, or cancelled when the whole event was cancelled
  • Completeness: { score, missing[] }, how much we know about the event (see Completeness)

When: dates, times and recurrence​

The when object tells you when the event happens:

  • pattern: once (a date or a date range), recurring (repeats on a rule) or ongoing (runs continuously over a period)
  • timezone: IANA timezone such as America/New_York. The zone the source lists when it is a real region zone, otherwise the venue's. A fixed label from the source, such as EST, stays when the venue cannot be placed. Omitted only when the event has none of these. The clock of such a floating event is what its source gave, which for a Facebook event without a location is UTC
  • displayText: Human-readable schedule. One-time and ongoing events get text generated in English, for example Tue, Nov 3, 2026, 7:00 PM – 10:00 PM. A recurring event shows the source's description of its pattern, as stored (in English when extraction wrote English), with its times, for example Alternating Wednesdays, 9:00 AM – 9:45 AM. A date range with one pair of times can mean one continuous span (see below)
  • recurrence: For recurring events: a description, startDate, endDate, the exceptions (dates the series skips) and the patterns (iCalendar rules with local start and end times)
  • next: The earliest occurrence that has not ended, whatever your query window
  • occurrences: On the list, the occurrences that overlap your query window. On the single-item endpoint, up to 50 upcoming occurrences
  • upcomingCount: How many occurrences are upcoming, not limited by the window or the 50 cap

Each occurrence has start and end (UTC), allDay and status. Occurrences have no id. An occurrence whose local date is listed in recurrence.exceptions is left out of occurrences and next.

Reading a date range with times. On an ongoing event, Feb 14 – Feb 16, 2026, 6:00 PM – 9:00 PM (or Through Feb 16, 2026, 6:00 PM – 9:00 PM once it has started) does not always mean those hours each day. It can mean one continuous span, from 6:00 PM on the first day to 9:00 PM on the last: that is how a Facebook event running 24 hours or more reads. The occurrence's start and end give the span's exact instants.

Status values (every occurrence of an event carries the event's status):

  • scheduled: Happening as planned
  • cancelled: Cancelled
  • postponed: Delayed (check for new dates)
  • rescheduled: Moved to a different date
  • completed: Over

What "upcoming" means. An occurrence is upcoming until it ends. A date with no time of day stays upcoming until that date is over everywhere. A time with no known zone (neither listed nor from the venue) is shown as its source gave it, when.timezone is omitted, and the occurrence stays upcoming until its listed date is over. when.next and when.upcomingCount use this rule.

Where: venue, address and coordinates​

The where object is omitted when nothing is known about the location:

  • venue: { name }
  • address: display (the full normalized address) and, when known, street, city, region, postcode, country and countryCode
  • geo: lat, lng and precision
  • online: url and platform, for virtual and hybrid events
  • multipleVenues: true when the event takes place at several venues. venue, address and geo are omitted then
  • displayText: A ready-to-show location: venue and short address (venue, street, city, region postcode, a US state as its two-letter code, for example Main Library, 310 North Tryon Street, Charlotte, NC 28202) when the street is known; for a town-level point (geo.precision locality) the venue, city and state (Town Hall, Charlotte, NC); else the venue and the stored address without its country, a US state shortened to its code (for example Trips for Kids Charlotte, 812 Atando Avenue, Charlotte, NC 28206); else the text as stated, or Online

precision says how exact the point is. address means a street address or a building; locality means a town, neighborhood or postcode area, so do not drop a pin on it as if it were the door. The street, postcode, country code and precision appear as venues are (re)geocoded, so older events may lack them.

An event can be physical (venue, address, geo), online (online) or hybrid (both).

How geography decides what a feed carries​

A feed can be limited to an area. An area is a list of places, at any level and anywhere in the world (a city, a county, a state, a country), and circles (a point and a radius). You create it as an area match processor, and optionally an area relevance processor, and read them in your feed's filters: see Areas.

An area match records match (in the area), no_match (outside it) or unknown for each event, like this:

  • It has a venue: the venue decides. The event is in the area when the venue is inside one of its places or inside one of its circles, and not in it otherwise. Wider regions the event is about do not count when there is a venue. Where our map data does not say whether the venue is in a place (for example, a city that belongs to no county), the venue's position on the map is compared with the place's bounding box instead. A bounding box is a rough rectangle around the place; it can also cover land outside it.
  • It has no venue but names a region: the event is in the area when that region is one of the area's places, lies inside one, or overlaps a circle. A region that only contains one of the area's places, such as a whole state or country, is not in the area by place; a feed that also has an area relevance processor judges it from its text.
  • It has no location at all: area match records unknown, so the event is not in the area by place. With area match alone, or in_area without areaRelevance, the feed leaves it out; with area relevance, that processor judges it from its text. An own filter can keep such events with match != "no_match".

A feed can also ask whether an event is in its area using the event's own description, with an area relevance processor. It usually catches an event whose venue the map placed in a town of the same name elsewhere (for example in another state), because it judges from the place the event names, unless something else in the event's text (a state, a street or a venue) points to that other place; it is not guaranteed to. It does not do this for a venue just over the area's edge whose postal town lies inside: there the venue's own address decides. It keeps to the area: a town just outside it is not in it.

If an event's location cannot be read at the moment it is checked, the check waits and is retried; an event already in the feed stays in it meanwhile.

Geography can be checked on its own, apart from the topic the feed is about: give your relevance processor geographyDecidedSeparately: true. The topic check then judges every event as if it took place in the area, even when the feed's name or description names a place, so an event is never kept or dropped for what it says about location beyond the area check. When a feed's rules leave out online events, an event that takes place only online is always left out, even if it is tied to a place in the area.

How labels and categories are judged​

When a feed uses labels or a category, each event is judged from its text and, where the model it runs on supports images, its cover image.

  • Labels are yes/no judgements. Each comes with a confidence, which is the model's probability that the answer is yes. A feed that excludes an event for a label acts when that confidence reaches the label's cut-off, so a higher cut-off is stricter about what it drops. Cut-offs differ by label, each chosen so that the events it drops really are that label. They are set from measurements on real events and approved by our team. A label we have not yet seen often enough on real events to measure has no cut-off, so none of our opt-in filters excludes on it. In your own filters you choose the cut-off.
  • Category is one of 17 fixed categories, the best fit as primary, and an optional secondary, each with a confidence. Without a second category, secondary is none.
  • Checks need no model: whether the event serves a cover, whether it has an official source (the page we found the event on, or another page confirming the same event, published by the event's organizer, venue, performer or ticket seller, as we identify the publisher; a page that only mentions the event does not count) and whether it is free, paid or unknown.

A feed filters on a label's confidence and on the primary or secondary category, through our opt-in filters or your own filters. The answers are read by filters only and are not part of the feed item.

links holds every URL we know for the event:

  • links.all: every URL once, ranked, best first. Each entry has a kind (event_page, tickets, registration, streaming, calendar, social_post, social_profile or other), official (published by the organizer, venue or a performer), relation, the publisher and publishedAt when known
  • links.best: the recommended "more info" link, with a reason. null when the event has no URL, or none worth recommending

relation says how we know the page: origin (the document the event was found in), confirmed (a page we read and judged to be about this event), supporting (a related page we read) or mentioned (a URL stated on a page we read, not read itself).

publisher says who published the page: name, domain (websites) or handle (social accounts), platform (web, instagram, facebook, tiktok or twitter), role and roleConfidence.

Publisher roles​

RoleMeaningOfficial
organizerRuns the eventyes
venueHosts the eventyes
performerPerforms at the eventyes
ticketingSells tickets or lists eventsno
curatorWrites about or collects events (a guide, a listing site)no
mediaNews or magazine coverageno
unknownCould not be determinedno

roleConfidence is verified when a link confirms the role (the publisher's profile links to the page, or the page links back to the publisher) and inferred otherwise. It is almost always inferred, so treat role as a good guess, not a guarantee.

Use links.best. It is the first link of the ranking that qualifies, in this order:

  1. An official event page (official_event_page)
  2. An official tickets or registration page (official_tickets)
  3. An official social post (official_social_post)
  4. A ticketing site's page: an event page or tickets link whose publisher has the ticketing role or is on a known ticketing site (ticketing_page)
  5. Any other event page or post, unless a curator or media site published it (event_page)
  6. A page by a curator or media site (curator_or_media_page)

Within a tier, a verified role comes before an inferred one, then by relation: confirmed, origin, mentioned, supporting. A curator's or media page is best only when nothing else exists, and reason: "curator_or_media_page" says so: you may prefer to label it, or to show nothing. Streaming links, calendars, social profiles, other URLs, and tickets or registration links that are not official and not on a ticketing site are in links.all but are never best.

const link = item.links.best;
if (link) {
const label =
link.reason === 'curator_or_media_page'
? 'Read more (third-party page)'
: 'More info';
show(label, link.url);
}

If you want an official-only link, use links.all.find((l) => l.official). Every URL is http or https.

Media​

  • cover: The chosen event image, or null. It can be null even when images has entries; show no event image then and do not promote another image
  • images: Every image we found for the event and serve, in rank order, official images first

Each image has usage, a kind (flyer, photo, social_slide or video_thumbnail), width and height, and a source with the original imageUrl (provenance only, do not display it), the pageUrl and the publisher.

usage tells you what you may do with the image:

usageWhere the image came fromWhat you may do
cover_eligibleAn official website: the organizer, venue, performer or ticketsShow it as the event image
display_with_attributionAn official social postShow it with its source beside it
reference_onlyA curator, a media outlet or a site we could not identifyIt is shown for reference: credit the source, do not republish it as your own

The cover prefers official images: a reference_only image is the cover only when no official image shows the event.

Image URLs​

Image URLs in feed items are private, signed and temporary: each carries expiresAt. Use them to show the event's images in your own product, but do not share, publish or store the links themselves. Fetch the item again whenever you need a current link.

Completeness​

completeness.score is 0 to 1. completeness.missing lists what we do not know, from a closed list: startDate, startTime, venue, address, endTime, description, officialUrl, ticketUrl, image. Filter with minCompleteness. It is omitted for events that have not been scored.

Polling for changes​

updatedAt is when the item last changed in a way subscribers are notified of: the same moments an event.item.updated webhook is sent. Poll with updatedSince to fetch only what changed, or use Event Delivery to be notified. Use addedSince to fetch only new items.

  • updatedSince is combined with the occurrence window (since/until), so an item whose dates moved out of the window, or whose last occurrence has ended, is not returned. For complete change tracking, including removals, use webhooks.
  • updatedAt is stamped just before the change is committed, so poll from a few seconds before your last poll time (for example 10 seconds) and de-duplicate by id and updatedAt.

Common Event Patterns​

One-time event​

when.pattern is once, with one occurrence.

{
"when": {
"pattern": "once",
"timezone": "America/New_York",
"displayText": "Tue, Nov 3, 2026, 7:00 PM – 10:00 PM",
"next": {
"start": "2026-11-04T00:00:00.000Z",
"end": "2026-11-04T03:00:00.000Z",
"allDay": false,
"status": "scheduled"
},
"occurrences": [
{
"start": "2026-11-04T00:00:00.000Z",
"end": "2026-11-04T03:00:00.000Z",
"allDay": false,
"status": "scheduled"
}
],
"upcomingCount": 1
}
}

Multi-day event​

A festival over three days is one event with pattern: "once". It usually has one occurrence per day, but a date range can also be stored as one spanning occurrence. Read when.displayText for the range.

Recurring event​

pattern is recurring and recurrence describes the rule. occurrences holds the dates that overlap your window; upcomingCount tells you how many more there are. Skipped dates are in recurrence.exceptions and are left out of occurrences and next; upcomingCount can still count one stored before the exception was recorded. See the example in the API reference.

Cancelled or rescheduled event​

A cancelled event has top-level status: "cancelled", and every one of its occurrences is cancelled. A single cancelled date of a series is not represented: the item shows only whole-event cancellation. For a rescheduled event, look for new occurrences with status: "scheduled".

Working with Date Ranges​

How date filtering works​

When you query with since and until, the API returns events that have at least one occurrence that overlaps that range: it starts at or before until, and it has not ended by since.

  • An event added months ago appears if it has an occurrence that overlaps your query range
  • For recurring events, when.occurrences lists the occurrences that overlap the range
  • An occurrence already in progress at since is listed. That includes today's event once it has started, and an ongoing exhibition stored as one long occurrence
  • "Has not ended" is the same rule as when.next: an occurrence ends at its end time, or at its start when it has none; a date with no time lasts until that date is over everywhere; a time given without a timezone lasts until its listed date is over
  • when.next is the earliest occurrence that has not ended, whatever the range, so it can be an occurrence that lies after the range

Default date range​

If you don't specify dates, the API uses since = now and until = 30 days from now. With only since, the window runs from since for 30 days, at most until 30 days from now. With only until, since is now; when until is already past, the window starts 7 days ago.

Date range limits​

  • since and until must be between 7 days in the past and 30 days in the future
  • since must be before until

Filtering and Sorting​

FilterWhat it does
statusOnly items with an occurrence of this status
addedSinceOnly items added to the feed at or after this time
updatedSinceOnly items whose updatedAt is at or after this time
patternonce, recurring or ongoing
hasOfficialLinktrue: only items with an official link; false: only items without
hasCovertrue: only items with a cover; false: only items without
minCompletenessOnly items with completeness.score at least this value

Filters combine with AND. An invalid value (a bad pattern, an orderBy other than occurrence or created) returns 400 with code INVALID_QUERY.

Sorting​

  • orderBy=occurrence (default): soonest first
  • orderBy=created: newest added first

There is no relevance ordering.

Practical Examples​

Displaying event dates​

function formatEventDates(item) {
const { when } = item;

if (item.status === 'cancelled') return 'Cancelled';
if (!when.next) return 'No upcoming dates';
if (when.upcomingCount === 1) return when.displayText;

const next = new Date(when.next.start).toLocaleDateString();
return `${when.displayText} (next: ${next})`;
}

Showing the location​

function formatLocation(item) {
const { where } = item;
if (!where) return 'Location to be announced';
return where.displayText;
}

// Put a pin on the map only when the point is an exact address
const pin = item.where?.geo?.precision === 'address' ? item.where.geo : null;

Handling time zones​

function formatEventTime(item) {
const { when } = item;
if (!when.next || !when.timezone) return when.displayText;

return new Date(when.next.start).toLocaleString('en-US', {
timeZone: when.timezone,
weekday: 'long',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
timeZoneName: 'short',
});
}

When when.timezone is omitted, the times are what the source gave (UTC for a Facebook event without a location): show when.displayText.

Finding events in a specific city​

function findEventsInCity(items, cityName) {
return items.filter(
(item) =>
item.where?.address?.city?.toLowerCase() === cityName.toLowerCase()
);
}

Key Differences from News Feeds​

FeatureNews FeedsEvent Feeds
Time relevancePublication dateOccurrence dates (future-focused)
FilteringBy publish dateBy occurrence date range
Status trackingNoneEvent status on each occurrence
Recurring contentNoYes (multiple occurrences)

How It Works​

  1. Create a feed - Your container for events (it starts disabled)
  2. Add sites - The websites your events come from
  3. Decide what it carries - Create an area and add filters, your own or our opt-in filters, then enable the feed
  4. Automatic discovery - Events from sources flow into your feed when they pass its filters
  5. Query the items - Use date ranges, status filters, and sorting
  6. Receive structured data - Get events with their schedule, location, ranked links and images

When you enable a feed, add a source to an enabled feed, or enable a source of an enabled feed, the events that source brought in during the past 14 days that pass the feed's filters are added to provide immediate context, once per source.

Next Steps​