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, orcancelledwhen 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) orongoing(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 asEST, 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 exampleAlternating 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, theexceptions(dates the series skips) and thepatterns(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 plannedcancelled: Cancelledpostponed: Delayed (check for new dates)rescheduled: Moved to a different datecompleted: 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,countryandcountryCode - geo:
lat,lngandprecision - online:
urlandplatform, for virtual and hybrid events - multipleVenues:
truewhen the event takes place at several venues.venue,addressandgeoare 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 exampleMain Library, 310 North Tryon Street, Charlotte, NC 28202) when the street is known; for a town-level point (geo.precisionlocality) 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 exampleTrips for Kids Charlotte, 812 Atando Avenue, Charlotte, NC 28206); else the text as stated, orOnline
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, orin_areawithoutareaRelevance, the feed leaves it out; with area relevance, that processor judges it from its text. An own filter can keep such events withmatch != "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 optionalsecondary, each with a confidence. Without a second category,secondaryisnone. - 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: the pages about the event
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_profileorother),official(published by the organizer, venue or a performer),relation, thepublisherandpublishedAtwhen known - links.best: the recommended "more info" link, with a
reason.nullwhen 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
| Role | Meaning | Official |
|---|---|---|
organizer | Runs the event | yes |
venue | Hosts the event | yes |
performer | Performs at the event | yes |
ticketing | Sells tickets or lists events | no |
curator | Writes about or collects events (a guide, a listing site) | no |
media | News or magazine coverage | no |
unknown | Could not be determined | no |
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.
Picking the more-info link
Use links.best. It is the first link of the ranking that qualifies, in this order:
- An official event page (
official_event_page) - An official tickets or registration page (
official_tickets) - An official social post (
official_social_post) - A ticketing site's page: an event page or tickets link whose publisher has the
ticketingrole or is on a known ticketing site (ticketing_page) - Any other event page or post, unless a curator or media site published it (
event_page) - 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 benulleven whenimageshas 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:
usage | Where the image came from | What you may do |
|---|---|---|
cover_eligible | An official website: the organizer, venue, performer or tickets | Show it as the event image |
display_with_attribution | An official social post | Show it with its source beside it |
reference_only | A curator, a media outlet or a site we could not identify | It 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.
updatedSinceis 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.updatedAtis 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 byidandupdatedAt.
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.occurrenceslists the occurrences that overlap the range - An occurrence already in progress at
sinceis 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.nextis 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
sinceanduntilmust be between 7 days in the past and 30 days in the futuresincemust be beforeuntil
Filtering and Sorting
| Filter | What it does |
|---|---|
status | Only items with an occurrence of this status |
addedSince | Only items added to the feed at or after this time |
updatedSince | Only items whose updatedAt is at or after this time |
pattern | once, recurring or ongoing |
hasOfficialLink | true: only items with an official link; false: only items without |
hasCover | true: only items with a cover; false: only items without |
minCompleteness | Only 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 firstorderBy=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
| Feature | News Feeds | Event Feeds |
|---|---|---|
| Time relevance | Publication date | Occurrence dates (future-focused) |
| Filtering | By publish date | By occurrence date range |
| Status tracking | None | Event status on each occurrence |
| Recurring content | No | Yes (multiple occurrences) |
How It Works
- Create a feed - Your container for events (it starts disabled)
- Add sites - The websites your events come from
- Decide what it carries - Create an area and add filters, your own or our opt-in filters, then enable the feed
- Automatic discovery - Events from sources flow into your feed when they pass its filters
- Query the items - Use date ranges, status filters, and sorting
- 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
- API Reference: Complete endpoint documentation
- Quickstart Guide: Build a feed end to end
- Feed Configuration: Processors, filters, opt-in filters, areas and sources
- Event Feed Overview: Use cases and implementation examples
- Event Delivery Concepts: How deliveries, destinations, and subscriptions work