Guide

Filtering events

How search_events conditions join, which fields take a reference, and how to read what comes back.

One condition

A condition is a field, an operator and a value. The operator defaults to EQUAL, so the shortest useful filter is one line.

Every move
{
  "conditions": [
    {
      "field": "EventType",
      "value": "move"
    }
  ],
  "limit": 15
}

Joining conditions

Each condition after the first carries a join of AND or OR, which says how it attaches to the conditions before it. Leave it out and it's AND.

Departures from one company
{
  "conditions": [
    {
      "field": "EventType",
      "value": "move"
    },
    {
      "field": "MoveType",
      "value": "Departure",
      "join": "AND"
    },
    {
      "field": "Organisation",
      "value": "3f2a9c1e-7b4d-4e8a-9c21-5d6e7f8a9b01",
      "join": "AND"
    }
  ],
  "limit": 15
}

Precedence

AND binds tighter than OR, as in SQL. The list below reads as (Hire at Halberd) OR (any Appointment), which is rarely what anyone means.

Binds as (A AND B) OR C
{
  "conditions": [
    {
      "field": "MoveType",
      "value": "Hire"
    },
    {
      "field": "Organisation",
      "value": "3f2a9c1e-7b4d-4e8a-9c21-5d6e7f8a9b01",
      "join": "AND"
    },
    {
      "field": "MoveType",
      "value": "Appointment",
      "join": "OR"
    }
  ],
  "limit": 15
}

There are no brackets, and moving the OR pair to the front doesn't help: AND still binds first. To get hires or appointments at Halberd, repeat the shared condition on each side of the OR.

(Hire AND Halberd) OR (Appointment AND Halberd)
{
  "conditions": [
    {
      "field": "MoveType",
      "value": "Hire"
    },
    {
      "field": "Organisation",
      "value": "3f2a9c1e-7b4d-4e8a-9c21-5d6e7f8a9b01",
      "join": "AND"
    },
    {
      "field": "MoveType",
      "value": "Appointment",
      "join": "OR"
    },
    {
      "field": "Organisation",
      "value": "3f2a9c1e-7b4d-4e8a-9c21-5d6e7f8a9b01",
      "join": "AND"
    }
  ],
  "limit": 15
}

Fields that need a reference

Organisation, Profile and Occupation take a UUID reference, never a name. Resolve the name first with resolve_search_terms (companies and job titles) or search_people (people). Each suggestion comes back with a field and a value you can drop straight into a condition.

Date ranges

PublishedDate is the only field that takes >, <, >= and <=. Two conditions make a range.

CFO moves in August 2026
{
  "conditions": [
    {
      "field": "EventType",
      "value": "move"
    },
    {
      "field": "Occupation",
      "value": "7d0e1f2a-b4c5-4d6e-9f8a-b9c0d1e2f3d1",
      "join": "AND"
    },
    {
      "field": "PublishedDate",
      "operator": ">=",
      "value": "2026-08-01",
      "join": "AND"
    },
    {
      "field": "PublishedDate",
      "operator": "<=",
      "value": "2026-08-31",
      "join": "AND"
    }
  ],
  "limit": 15
}

Invalid conditions are refused

An unknown field, an ordering operator on a field other than PublishedDate, a name where a UUID belongs, or a value outside a field's allowed list comes back as a tool error naming the condition. Nothing is quietly dropped, so a result set always matches every condition you gave.

A refused condition
{
  "error": "condition 2 (Organisation) needs a UUID, got \"Halberd\". Use resolve_search_terms to turn a company name into its UUID."
}

Reading the response

KeyWhat it holds
eventsA short projection of each event. Pass detail: "full" for whole payloads, or open one with get_event
paginationtotal and total_pages, corrected from the page itself when a short page proves the end
applied.conditionsThe conditions exactly as they were applied
applied.date_windowAny history window your plan imposes, stated in words

Paging

Keep limit small (the default is 15, the maximum 50) and page with page. Stop when a page returns fewer events than limit. On very broad filters the total can be an estimate for the whole table, so a short page is the reliable end signal.

Related