Skip to main content

Opt-in Filters

Opt-in filters are our ready-made filters. You add one to a feed, or a whole set at once, and remove it when you no longer want it.

  • They follow our latest definition. An opt-in's condition is ours, and when we change it (a threshold, say), the change applies to every feed that has it, going forward: to new items, and to items already in the feed when they next change.
  • You cannot edit them. A PATCH of an opt-in filter is refused with 403 OPT_IN_NOT_EDITABLE. To use a different threshold, remove the opt-in and write your own filter with the condition you want.
  • On the feed, an opt-in is a filter like any other. It is listed with type: "opt_in" and its current condition, and it counts in the include/exclude rule like your own filters: an opt-in include widens the feed, an opt-in exclude leaves out what it matches.

A new event feed starts with the completeness opt-in.

The catalog​

KeyFeedActionNameConditionTakes
completenesseventexcludeCompleteness below 0.5completeness.score < 0.5nothing
age_restrictedeventexcludeAge restrictedevent_labels.age_restricted.confidence >= 0.8nothing
promotionaleventexcludePromotionalevent_labels.promotional.confidence >= 0.95nothing
not_an_occasioneventexcludeNot an occasionevent_labels.not_an_occasion.confidence >= 0.9nothing
in_areaeventincludeIn the areathe area part, and relevance.answer = "yes" when givenareaMatch (required), areaRelevance, relevance
sponsored_or_advertorialnewsexcludeSponsored or advertorialnews_content_type.sponsored_or_advertorial.significance >= 3nothing
self_promotionnewsexcludeSelf-promotionnews_content_type.self_promotion.significance >= 3nothing
newsnewsincludeNewseditorial_news.significance >= 6 or opinion_editorial.significance >= 6; and the area part, and relevance.answer = "yes", each when givenareaMatch, areaRelevance, relevance
creator_postsnewsincludeCreator postsany of behind_the_scenes, daily_life, life_milestone, personal_interest, professional_update, fan_directed, celebrity_interaction at significance >= 5; and the area and relevance parts, each when givenareaMatch, areaRelevance, relevance

The area part is areaMatch.match = "match", or, with areaRelevance, any(areaMatch.match = "match", areaRelevance.answer = "yes"): an item is in the area when it lies inside the area's boundaries, or the area relevance processor judges it to be about the area. See Areas.

What each one leaves out or lets in:

  • completeness: events missing too much of what a listing needs.
  • age_restricted: age-restricted events: 21+ and 18+ venues, bar crawls, gambling.
  • promotional: "events" that are mainly a sale or brand activation.
  • not_an_occasion: listings that are not an occasion people can attend: deals and specials, broadcasts, giveaways, permanent exhibits.
  • in_area: events in the area. With relevance, the event must also be relevant.
  • sponsored_or_advertorial: paid or sponsored placements.
  • self_promotion: authors promoting their own work, product or event.
  • news: editorial news and opinion pieces; with an area, only those in it; with relevance, only relevant ones.
  • creator_posts: creators' posts about their lives and work; with an area, only those in it; with relevance, only relevant ones.

Parameters​

Some opt-ins take your processors as parameters, by name, in with:

ParameterTakes
areaMatchAn area_match processor: the area
areaRelevanceAn area_relevance processor, OR-ed with the area match. Needs areaMatch
relevanceA classifier that must also say yes: a custom classifier, or an event_relevance / news_relevance processor with geographyDecidedSeparately: true

Each must be one of your organization's processors, run on the feed's item type and not be archived. A part of the condition that reads a parameter you leave out is dropped: news with no areaMatch lets in news from anywhere. Give the area relevance processor the same places as the area match (see Areas).

A relevance processor given as relevance must have geographyDecidedSeparately: true, or it would still judge geography from the feed's description and the area would be decided twice.

Refusals name the parameter (with.<parameter>) in details.problems:

  • A required processor left out, or areaRelevance without areaMatch: 422 MISSING_OPT_IN_PARAM.
  • A processor the opt-in cannot take (unknown, another organization's, archived, the wrong template or item type, a relevance processor that judges geography) or a parameter it does not take: 422 INVALID_OPT_IN_PARAM.

Adding an opt-in​

POST /feeds/{type}/{id}/filters
{
"optIn": "in_area",
"with": {
"areaMatch": "5c0e8f9a-3b1d-4f6e-9a2c-7d4b1e0f8a63",
"areaRelevance": "0a7d2c4e-9f1b-4e3a-8c6d-1b2e3f4a5c6d"
}
}

The response is the new filter (see Filters).

If the feed already has a filter that decides the same (same action and, once generated, the same condition, whether yours or an opt-in), the request is refused with 409 FILTER_ALREADY_PRESENT; details.equalTo is that filter's id.

Sets​

A set adds several opt-ins in one request:

KeyFeedNameMembers
community_eventseventCommunity eventscompleteness, age_restricted, promotional, not_an_occasion, in_area
standard_newsnewsStandard newssponsored_or_advertorial, self_promotion, news
creator_socialnewsCreator socialsponsored_or_advertorial, self_promotion, creator_posts
POST /feeds/{type}/{id}/filter-sets/{setKey}
{
"with": {
"areaMatch": "5c0e8f9a-3b1d-4f6e-9a2c-7d4b1e0f8a63",
"areaRelevance": "0a7d2c4e-9f1b-4e3a-8c6d-1b2e3f4a5c6d"
}
}

setKey must be a set of the feed's type: a set of the other feed type (for example standard_news on an event feed) is a 400 INVALID_PARAMS. Each member gets the parameters it takes from with. Members the feed already has a filter for (same action and condition, yours or an opt-in) are skipped, and the response says which were added and which were skipped:

{
"success": true,
"data": {
"added": [
{
"id": "7f3c2b1a-6e5d-4c4b-9a3f-2e1d0c9b8a71",
"name": "In the area",
"action": "include",
"type": "opt_in",
"optIn": {
"key": "in_area",
"with": {
"areaMatch": "5c0e8f9a-3b1d-4f6e-9a2c-7d4b1e0f8a63",
"areaRelevance": "0a7d2c4e-9f1b-4e3a-8c6d-1b2e3f4a5c6d"
}
},
"condition": {
"any": [
{
"processor": "5c0e8f9a-3b1d-4f6e-9a2c-7d4b1e0f8a63",
"output": "match",
"op": "=",
"value": "match"
},
{
"processor": "0a7d2c4e-9f1b-4e3a-8c6d-1b2e3f4a5c6d",
"output": "answer",
"op": "=",
"value": "yes"
}
]
},
"createdAt": "2026-10-28T14:05:00.000Z",
"updatedAt": "2026-10-28T14:05:00.000Z"
}
],
"skipped": [
{
"optIn": "completeness",
"equalTo": "3e9a1c7b-2d4f-4a8e-b6c5-9f0e1d2c3b4a"
}
]
}
}

A set is added in one change: when a member's parameters are refused (MISSING_OPT_IN_PARAM, INVALID_OPT_IN_PARAM), nothing is added. The feed is not linked to the set afterwards: each member is an ordinary opt-in filter you can remove on its own, and a later change to the set's members does not reach your feed.

Reading the catalog​

GET /opt-in-filters and GET /opt-in-filter-sets return the catalog and the sets, for every API key. A catalog condition shows each parameter's processor as a placeholder ({areaMatch}) and every optional part, as if every parameter were given:

{
"key": "in_area",
"feedType": "event",
"action": "include",
"name": "In the area",
"description": "Includes events in the area: the area match finds them inside it, or the area relevance processor says yes. With relevance, the event must also be relevant.",
"parameters": [
{ "name": "areaMatch", "required": true, "processor": "area_match" },
{
"name": "areaRelevance",
"required": false,
"processor": "area_relevance"
},
{ "name": "relevance", "required": false, "processor": "classifier" }
],
"condition": {
"all": [
{
"any": [
{
"processor": "{areaMatch}",
"output": "match",
"op": "=",
"value": "match"
},
{
"processor": "{areaRelevance}",
"output": "answer",
"op": "=",
"value": "yes"
}
]
},
{
"processor": "{relevance}",
"output": "answer",
"op": "=",
"value": "yes"
}
]
}
}
{
"key": "community_events",
"feedType": "event",
"name": "Community events",
"members": [
"completeness",
"age_restricted",
"promotional",
"not_an_occasion",
"in_area"
]
}

Both lists come in { "success": true, "data": [ … ] }.