Skip to main content

Processors

What a feed carries is decided by processors and filters. You set both up through the API, for event feeds and news feeds alike.

  • Processor — looks at each item in your feeds and records answers ("outputs"); for example Event labels records age_restricted.confidence: 0.92. A processor never includes or excludes anything. Built-in processors are ours; you can create your own. A processor belongs to your organization, not to a feed.
  • Filter — a rule on one feed: include or exclude items whose processor outputs meet a condition. An item is in the feed when no exclude filter matches and at least one include filter does. A feed runs exactly the processors its filters read.

This page covers processors. Filters covers the rules, Opt-in filters our ready-made ones, Areas the area processors and Sources what a feed's items come from.

A processor's answers are read by filters only. They are not part of feed items, and the API never returns them.

Built-in processors​

Our built-ins are usable by every organization and editable by no one. A filter names a built-in by its key. GET /processors/{key} returns a built-in with every output, its range and what it means.

KeyRuns onOutputs
completenesseventsscore, 0 (bare) to 1 (everything present)
event_labelseventsFor each of 11 labels, <label>.answer (yes or no) and <label>.confidence (0 to 1). Labels: adult_content, age_restricted, promotional, not_an_occasion, virtual_only, fundraiser, religious_service, political_campaign, civic_government, business_professional, family_friendly
event_categoryeventsprimary (one of 17 categories), primaryConfidence (0 to 1), secondary (a category or none), secondaryConfidence (0 to 1)
has_covereventshasCover (true or false)
has_official_sourceeventshasOfficialSource (true or false)
priceeventsprice: free, paid or unknown
news_content_typenewsFor each of 14 content types, <type>.significance (0 to 10) and <type>.confidence (0 to 1)

The 17 event categories are music, performing_arts, visual_arts, film, food_drink, markets_fairs, festivals, sports_recreation, fitness_wellness, family_kids, education_talks, community_volunteering, civic_government, nightlife, business_networking, religious_spiritual and other. The 14 news content types are listed in News Feeds Concepts. How labels and categories are judged is in Event Feeds Concepts.

The safety floor is a processor too, but it is not listed and no filter of yours can read it: it applies to every feed and cannot be switched off.

Your processors​

You create a processor from a template:

TemplateWhat it answersOutputs
customA question of your own. A classifier answers yes or no; a scorer scores the item on your rubric.Classifier: answer (yes/no) and confidence (0 to 1). Scorer: score (1 to the number of rubric levels)
area_matchWhether the item's places fall inside an area, by their boundaries. No AI. See Areas.match: match, no_match or unknown
area_relevanceWhether the item takes place in or is about an area, judged by AI from its text. See Areas.answer and confidence
event_relevanceWhether an event belongs in a feed, from the feed's title, description and your rules. For a new question, prefer custom.answer and confidence
news_relevanceWhether a news item belongs in a feed, from the feed's title, description and your rules. For a new question, prefer custom.answer and confidence

confidence is how confident the processor is in a "yes", from 0 (not at all) to 1 (certain).

A processor belongs to your organization, so any of your feeds can use it. custom processors run on one item type (itemTypes: ["event"] or ["news"]), relevance processors on their own type, and area processors on both by default, so one area serves your event and news feeds.

We choose and run what is behind each processor. The API does not show or accept a provider or model.

Definitions​

Each template has its own definition:

  • custom: instructions (the question, up to 4,000 characters), the four rule and example lists (below) and, for a scorer only (and required for it), rubric: 2 to 10 levels { name, description }, lowest first. The score is the level the item reaches, from 1.
  • area_match: area: { name, places }. See Areas.
  • area_relevance: area as above, plus the four lists.
  • event_relevance and news_relevance: feed: { title, description }, geographyDecidedSeparately and the four lists.

The four lists are positiveRules (rules for a "yes"), negativeRules (rules for a "no"), positiveExamples and negativeExamples (example items of each), up to 50 entries of up to 1,000 characters each. A list left out is empty.

geographyDecidedSeparately says who judges where items take place. false (the default) and the relevance processor judges geography too, from the feed's title and description. true and it judges only the topic: an area decides where. Set it to true when a filter combines the relevance processor with an area, so geography is not decided twice. The relevance parameter of our opt-in filters requires it of an event_relevance or news_relevance processor; a custom classifier has no such flag and is taken as it is.

Changing a processor​

PATCH /processors/{id} changes name, description or definition. The template, kind and item types cannot change.

  • definition replaces the whole definition. Send every rule and example list you want to keep: a list you leave out becomes empty. Only geographyDecidedSeparately keeps its value when you leave it out.
  • A changed definition makes a new version. It applies going forward only: to new items, and to items already in a feed when they next change. Items are not re-judged when you save. A name or description change makes no version.
  • An edit that would break a filter is refused. If a filter reading the processor would no longer be valid (for example, a scorer's rubric shrinking from 5 levels to 3 under a filter score >= 4), the PATCH is a 409 PROCESSOR_EDIT_BREAKS_FILTERS naming those filters and what is wrong with each. Nothing is saved.
  • A definition its template or kind refuses is a 422 VALIDATION_FAILED (for example a scorer without a rubric), with each problem in details.problems[{ path, code, message }], as on create. Nothing is saved. (A filter's condition that does not check out is a different code, 422 INVALID_CONDITION; see Filters.)
  • Built-ins cannot be changed: 403 BUILT_IN_PROCESSOR.

Archiving a processor​

DELETE /processors/{id} archives the processor. It stays readable, with archivedAt, but runs for no filter and cannot be changed (409 PROCESSOR_ARCHIVED). Archiving is refused while any filter reads the processor, including an opt-in filter that takes it as a parameter: 409 PROCESSOR_READ_BY_FILTERS, with the filters in details.filters. Remove those filters, or change them to read another processor, first.

{
"success": false,
"error": {
"code": "PROCESSOR_READ_BY_FILTERS",
"message": "Processor '5d1c7a2e-9b4f-4c3e-8a6d-1f2e3d4c5b6a' is read by 1 filter(s); remove them or change them to read another processor first.",
"details": {
"filters": [
{
"feedType": "event",
"feedId": "550e8400-e29b-41d4-a716-446655440000",
"filterId": "7f3c2b1a-6e5d-4c4b-9a3f-2e1d0c9b8a71",
"name": "In the area"
}
]
}
}
}

API reference​

RouteDoes
GET /processorsOur built-ins, then your processors by name. ?itemType=event or news; ?includeArchived=true
GET /processors/{id}One processor, archived or not. A built-in also by its key: /processors/event_labels
POST /processorsCreate one of your processors
PATCH /processors/{id}Change its name, description or definition
DELETE /processors/{id}Archive it

Every route needs your API key. Another organization's processor is a 404.

The processor​

FieldDescription
idStable identifier: what a filter's condition names. Built-ins are named by key.
keyBuilt-ins only: the key, e.g. event_labels.
ownerplatform (ours) or organization (yours)
nameUnique in your organization, archived processors included
descriptionWhat the processor is for
itemTypesevent, news or both
kindclassifier (records answers) or scorer (records a score on a scale)
templateYours only: the template
definitionYours only: the definition, an area with its places resolved
versionThe version of its definition, from 1
outputsWhat a filter can read: each with name, type (number, boolean or enum), min and max or values, and description
createdAt, updatedAt, archivedAtISO 8601; archivedAt is null unless archived

Create a processor​

POST /processors
{
"template": "area_match",
"name": "Charlotte metro",
"definition": {
"area": {
"name": "Charlotte metro",
"places": [
{ "name": "Mecklenburg County, North Carolina" },
{ "name": "Gaston County, North Carolina" },
{ "name": "Rock Hill, South Carolina", "level": "place" }
]
}
}
}
FieldRequiredDescription
templateYescustom, area_match, area_relevance, event_relevance or news_relevance
nameYesUp to 200 characters, unique in your organization
descriptionNoUp to 1,000 characters. An area processor gets one written for it when left out
kindcustom onlyclassifier or scorer
itemTypescustom only["event"] or ["news"]. Area processors take ["event"], ["news"] or both (the default); relevance processors take none
definitionYesThe template's definition (see Definitions)

Response 200 OK:

{
"success": true,
"data": {
"id": "5d1c7a2e-9b4f-4c3e-8a6d-1f2e3d4c5b6a",
"name": "Charlotte metro",
"description": "Whether the item's places fall inside Charlotte metro",
"itemTypes": ["event", "news"],
"kind": "classifier",
"owner": "organization",
"template": "area_match",
"definition": {
"area": {
"name": "Charlotte metro",
"places": [
{
"type": "place",
"id": "mbx_WyJkWEp1T20xaWVIQnNZenBCVmtKdk4xRSIsImRpc3RyaWN0IiwiTWVja2xlbmJ1cmcgQ291bnR5LCBOb3J0aCBDYXJvbGluYSwgVW5pdGVkIFN0YXRlcyJd",
"name": "Mecklenburg County",
"level": "district",
"displayText": "Mecklenburg County, North Carolina, United States",
"geo": {
"center": { "lat": 35.247, "lng": -80.833 },
"bbox": [-81.058, 35.002, -80.55, 35.515]
}
},
{
"type": "place",
"id": "mbx_WyJkWEp1T20xaWVIQnNZenBCVkhCdk4xRSIsImRpc3RyaWN0IiwiR2FzdG9uIENvdW50eSwgTm9ydGggQ2Fyb2xpbmEsIFVuaXRlZCBTdGF0ZXMiXQ",
"name": "Gaston County",
"level": "district",
"displayText": "Gaston County, North Carolina, United States",
"geo": {
"center": { "lat": 35.294, "lng": -81.178 },
"bbox": [-81.456, 35.152, -80.957, 35.416]
}
},
{
"type": "place",
"id": "mbx_WyJkWEp1T20xaWVIQnNZenBHUmxOdk4xRSIsInBsYWNlIiwiUm9jayBIaWxsLCBTb3V0aCBDYXJvbGluYSwgVW5pdGVkIFN0YXRlcyJd",
"name": "Rock Hill",
"level": "place",
"displayText": "Rock Hill, South Carolina, United States",
"geo": {
"center": { "lat": 34.925, "lng": -81.025 },
"bbox": [-81.12, 34.87, -80.94, 34.99]
}
}
]
}
},
"version": 1,
"outputs": [
{
"name": "match",
"type": "enum",
"values": ["match", "no_match", "unknown"],
"description": "Whether the item is inside the area: match, no_match (outside it), or unknown (no known location)."
}
],
"createdAt": "2026-10-28T14:05:00.000Z",
"updatedAt": "2026-10-28T14:05:00.000Z",
"archivedAt": null
}
}

A custom classifier, for comparison:

{
"template": "custom",
"name": "Family friendly",
"kind": "classifier",
"itemTypes": ["event"],
"definition": {
"instructions": "Is this event suitable for families with young children?"
}
}

Update a processor​

PATCH /processors/{id}

Send only the fields to change. definition is the whole new definition.

{
"name": "Charlotte metro",
"definition": {
"area": {
"name": "Charlotte metro",
"places": [
{
"id": "mbx_WyJkWEp1T20xaWVIQnNZenBCVmtKdk4xRSIsImRpc3RyaWN0IiwiTWVja2xlbmJ1cmcgQ291bnR5LCBOb3J0aCBDYXJvbGluYSwgVW5pdGVkIFN0YXRlcyJd"
},
{ "name": "Union County, North Carolina" }
]
}
}
}

Returns the processor, as on create.

Archive a processor​

DELETE /processors/{id}

Returns { "success": true }. Archiving an archived processor changes nothing.

Errors​

StatusCodeWhen
400INVALID_BODYThe body does not match the template's shape
403BUILT_IN_PROCESSORA PATCH or DELETE of a built-in
404NOT_FOUNDNo such processor, or another organization's
409ALREADY_EXISTSYour organization already has a processor with that name, archived ones included
409PROCESSOR_ARCHIVEDA PATCH of an archived processor
409PROCESSOR_READ_BY_FILTERSArchiving while filters read it. details.filters[{ feedType, feedId, filterId, name }]
409PROCESSOR_EDIT_BREAKS_FILTERSThe new definition would make filters reading it invalid. details.filters as above, and details.problems[{ filterId, path, code, message }]
422AREA_PLACES_UNRESOLVEDA place name is not exactly one place. See Areas
422VALIDATION_FAILEDThe definition does not suit its template or kind (for example a scorer without a rubric). details.problems[{ path, code, message }]
429RATE_LIMITEDMore than 30 requests that search places in a minute by your organization. See Areas
503SERVICE_UNAVAILABLEPlace search is down, or its requests cannot be counted against the limit. Retry after the Retry-After header's seconds