The criteria on this page are the id values you put in a filter constraint node. The node shape, the
operators for each data type, and the configuration block are covered in
Advanced Search Overview.
{
"type": "constraint",
"id": "birth_date",
"operator": "in_the_next",
"value": { "period": "day", "units": 30, "anniversary": true },
"invert": false
}
These criteria are for individual search onlyThey apply to
POST /search/individuals/results. The group, event-attendance, and scheduling
domains each have their own criteria set.
Get the live list for your integration
Criteria are filtered by the calling user's permissions and by the church's enabled modules, so the
set you can actually use is narrower than the full table below.
GET /search/individuals
Returns the criteria this caller may use, plus the search actions they may run. Call it once at
integration setup, or when a filter starts returning 412, instead of guessing from documentation.
It uses the same read:individuals scope as the results endpoint.
GET /search/criteria/individualsis the older form of the same call and is deprecated. Use
GET /search/individuals.
Reading the table
Type determines which operators are valid and what shape value takes. text, number,
date, date_parts, boolean, boolean_strict, currency, and time are documented in
Data Types and Operators.
special means the criterion takes a structured value object of its own. Every special
criterion has a section under Special criteria giving its exact shape.
Access is the permission the calling user needs. A user who does not have it gets 403, not a
filtered result set — a single unpermitted constraint fails the whole request.
| Access | Meaning |
|---|---|
| Any signed-in user | No specific people permission needed. |
| People read | Limited people-read in at least one campus. |
| Full people read | Full people-read in at least one campus. |
| Financial | Full financial access in at least one campus. |
| Notes | May view individual notes. |
| Virtus | May view Virtus data, and Virtus is connected for the church. |
| Significant events | Master administrator, or full people-read in at least one campus. |
| Sacrament admin | Sacrament admin in at least one campus. Falls back to People read when the church does not have sacrament visibility enabled. |
| Contextual | Checked per constraint against the specific event or group named in the value — guest-list or member-list visibility for that record. |
Master administrators and system users satisfy all of these.
Criteria
| Id | Type | Access | Notes |
|---|---|---|---|
ability | special | People read | shape |
age | number | People read | |
age_months | number | People read | |
allergies | text | People read | |
anniversary | date | People read | |
anniversary_date_parts | date_parts | People read | |
anniversary_month | number | People read | |
anointing_the_sick_sacrament | special | Full people read | shape · Requires the Sacraments module |
approval_status | text | People read | |
approval_status_date | date | People read | |
approval_status_modifier_id | number | People read | |
attendance_attendance_grouping | special | People read | shape |
attendance_department | special | People read | shape |
attendance_group | special | People read | shape |
attendance_single_event | special | People read | shape |
background_check_package_name | special | People read | shape |
baptism_sacrament | special | Full people read | shape · Requires the Sacraments module |
baptized_date | date | People read | |
baptized_date_parts | date_parts | People read | |
barcode | text | People read | |
birth_date | date | People read | |
birth_date_parts | date_parts | People read | |
birth_date_parts_anniversary_mode | date_parts | People read | |
birth_month | number | People read | |
campus | number | People read | |
child_work_approved_start_date | date_parts | People read | |
child_work_approved_start_month | number | People read | |
child_work_approved_stop_date | date_parts | People read | |
child_work_approved_stop_month | number | People read | |
church_service | number | People read | |
commitment_date | date | People read | |
commitment_date_parts | date_parts | People read | |
commitment_story | text | People read | |
confirmation_sacrament | special | Full people read | shape · Requires the Sacraments module |
contact_phone_number | text | People read | |
creator_first_name | text | People read | |
creator_last_name | text | People read | |
creator_name | special | People read | shape |
current_story | text | People read | |
custom_fields | special | People read | shape |
date_created | date | People read | |
date_created_month | number | People read | |
date_created_parts | date_parts | People read | |
date_deceased | date | People read | |
date_deceased_month | number | People read | |
date_deceased_parts | date_parts | People read | |
date_last_ran_own_giving_statement | date | People read | |
date_last_ran_own_giving_statement_parts | date_parts | People read | |
date_modified | date | People read | |
date_modified_month | number | People read | |
date_modified_parts | date_parts | People read | |
denied_status_reason | text | People read | |
department_admin | special | People read | shape |
discussion_posts | number | People read | |
duplicates | special | Full people read | shape |
email | text | People read | |
email_verification_date_opt_in_email_sent | special | People read | shape |
email_verification_date_verification_email_sent | special | People read | shape |
email_verification_date_verified | special | People read | shape |
email_verification_opt_in_date | special | People read | shape |
email_verification_opt_in_status | special | People read | shape |
emergency_contact_name | text | People read | |
emergency_contact_phone_number | text | People read | |
envelope_user_id | special | People read | shape |
ethnicity_id | number | People read | |
event | special | Contextual | shape |
event_attendance | special | Contextual | shape |
event_legacy | special | People read | shape |
event_rsvp | special | Contextual | shape |
external_diocesan_id | text | People read | Requires the Catholic vernacular module |
external_fundraising_id | text | People read | Requires the Catholic vernacular module |
external_safe_environment_id | text | People read | Requires the Catholic vernacular module |
family_child | special | People read | shape |
family_head | special | People read | shape |
family_household_mailing_name | text | People read | |
family_id | number | People read | |
family_other | special | People read | shape |
family_photo | text | People read | |
family_position | special | People read | shape |
family_spouse | special | People read | shape |
fax_phone_number | text | People read | |
first_attended_date | date | People read | |
first_communion_sacrament | special | Full people read | shape · Requires the Sacraments module |
first_name | text | People read | |
form_question_answer | special | People read | shape |
funeral_system_significant_event | special | Significant events | shape |
gender | text | People read | |
giving_number | text | People read | |
group | special | Contextual | shape |
group_custom_fields | special | People read | shape |
group_department | special | People read | shape |
group_interaction_type | special | People read | shape |
group_involvement | special | People read | shape |
group_member_start_date | special | People read | shape |
group_name | special | People read | shape |
group_relationship | special | People read | shape |
group_search | special | People read | shape |
group_status | special | People read | shape |
group_type | special | People read | shape |
group_udf_pulldown_1 | number | People read | |
group_udf_pulldown_2 | number | People read | |
group_udf_pulldown_3 | number | People read | |
has_requested_background_check | special | People read | shape |
holy_order_sacrament | special | Full people read | shape · Requires the Sacraments module |
home_address | special | People read | shape |
home_area | number | People read | |
home_city | text | People read | |
home_country | text | People read | |
home_phone_number | text | People read | |
home_state | text | People read | |
home_street | text | People read | |
home_zip | text | People read | |
homebound_ministry_id | number | People read | |
how_joined_church | number | Full people read | |
how_they_heard | number | Full people read | |
individual_id | number | Sacrament admin | |
is_baptized | boolean_strict | People read | |
is_confirmed_no_allergies | boolean_strict | People read | |
is_home_listed | boolean | People read | |
is_inactive | boolean | People read | |
is_limited_access_user | boolean | People read | |
is_listed | boolean | People read | |
is_other_listed | boolean | People read | |
is_work_listed | boolean | People read | |
last_attended_date | date_parts | People read | |
last_giving_date | date_parts | People read | |
last_login_date | date | People read | |
last_login_date_parts | date_parts | People read | |
last_name | text | People read | |
last_need_assigned_date | date_parts | People read | |
legal_name | text | People read | |
luna_assignment | special | People read | shape |
luna_assignment_date | date | People read | |
luna_assignment_date_parts | special | People read | shape |
luna_assignment_month | number | People read | |
luna_assignment_status | special | People read | shape |
luna_category | number | People read | |
luna_category_involvement | special | People read | shape |
luna_organizer | special | People read | shape |
luna_position | special | People read | shape |
luna_team | special | People read | shape |
mailing_address | special | People read | shape |
mailing_area | number | People read | |
mailing_carrier_route | text | People read | |
mailing_city | text | People read | |
mailing_country | text | People read | |
mailing_state | text | People read | |
mailing_street | text | People read | |
mailing_zip | text | People read | |
marital_status | text | People read | |
marriage_sacrament | special | Full people read | shape · Requires the Sacraments module |
membership_month | number | People read | |
membership_start_date | date | People read | |
membership_start_date_parts | date_parts | People read | |
membership_stop_date | date | People read | |
membership_stop_date_parts | date_parts | People read | |
membership_type | number | Full people read | |
micr_scan | special | Financial | shape |
middle_name | text | People read | |
military | text | People read | |
mobile_carrier | number | People read | |
mobile_phone_number | text | People read | |
modified_name | special | People read | shape |
modifier_first_name | text | People read | |
modifier_last_name | text | People read | |
name | special | Any signed-in user | shape |
name_fields | special | People read | shape |
new_giver | special | People read | shape |
note | special | Notes | shape |
other_address | special | People read | shape |
other_area | number | People read | |
other_city | text | People read | |
other_country | text | People read | |
other_id | text | People read | |
other_state | text | People read | |
other_street | text | People read | |
other_zip | text | People read | |
pager_phone_number | text | People read | |
passion | special | People read | shape |
personality_style | special | People read | shape |
phone_number | special | People read | shape |
photo | text | People read | |
pledge | number | People read | |
preferred_language_id | number | People read | |
privacy_settings | special | People read | shape |
process_queue | special | People read | shape |
process_queue_added_date | special | People read | shape |
process_queue_completed_date | special | People read | shape |
process_queue_due_date | special | People read | shape |
reason_left_church | number | Full people read | |
reconciliation_sacrament | special | Full people read | shape · Requires the Sacraments module |
religion_id | number | People read | Requires the Catholic vernacular module |
school | number | People read | |
school_grade | number | People read | |
significant_event | special | Full people read | shape |
significant_event_date | special | Full people read | shape |
spiritual_gift | special | People read | shape |
spiritual_maturity | number | Full people read | |
sync_id | number | People read | |
udf_date_1 | date | People read | |
udf_date_2 | date | People read | |
udf_date_3 | date | People read | |
udf_date_4 | date | People read | |
udf_date_5 | date | People read | |
udf_date_6 | date | People read | |
udf_pulldown_1 | number | People read | |
udf_pulldown_2 | number | People read | |
udf_pulldown_3 | number | People read | |
udf_pulldown_4 | number | People read | |
udf_pulldown_5 | number | People read | |
udf_pulldown_6 | number | People read | |
udf_text_1 | text | People read | |
udf_text_10 | text | People read | |
udf_text_11 | text | People read | |
udf_text_12 | text | People read | |
udf_text_2 | text | People read | |
udf_text_3 | text | People read | |
udf_text_4 | text | People read | |
udf_text_5 | text | People read | |
udf_text_6 | text | People read | |
udf_text_7 | text | People read | |
udf_text_8 | text | People read | |
udf_text_9 | text | People read | |
virtus_status | special | Virtus | shape |
virtus_status_expiration_time | special | Virtus | shape |
whos_included | inert | People read | Listed by GET /search/individuals but not queryable — see Non-queryable criteria |
work_address | special | People read | shape |
work_area | number | People read | |
work_city | text | People read | |
work_country | text | People read | |
work_job_title | text | People read | |
work_phone_number | text | People read | |
work_state | text | People read | |
work_street | text | People read | |
work_zip | text | People read |
Ids that changed
Earlier revisions of this page listed ids that the API does not accept, and typed several criteria in
a way that produces 412 or an empty result set. If your integration uses one of these, update it.
| Previously listed | Use instead | Why |
|---|---|---|
udf_pulldow_1 … udf_pulldow_6 | udf_pulldown_1 … udf_pulldown_6 | The old ids were misspelled and are rejected. |
area | home_area, work_area, other_area, mailing_area | There is no single area criterion; each address block has its own. |
emergency_contact_number | emergency_contact_phone_number | Rejected id. emergency_contact_name also exists. |
position | luna_position | Rejected id. See Scheduling (Luna). |
process_queue_date | process_queue_added_date, process_queue_completed_date, process_queue_due_date | Rejected id. The date type is chosen by the criterion, not by a date_type value. |
These are accepted, but were typed wrongly — the type in the table above is the one the API applies:
| Id | Was documented as | Actually |
|---|---|---|
child_work_approved_start_date, child_work_approved_stop_date | date | date_parts |
last_attended_date, last_giving_date, last_need_assigned_date | date | date_parts |
is_baptized | boolean | boolean_strict — is_not_set means explicitly not baptized, not "unknown". Use unknown for unset. |
ability, passion, personality_style, spiritual_gift | number | special — see My Fit |
family_head, family_spouse, family_child, family_other | text | special — see Family Members |
family_position | text | special, but a plain string still works — see Family Position |
group_name | text | special — the value is a group id under equal/not_equal |
group_relationship | number | special — see Group: Relationship |
virtus_status | text | special — see Virtus Status |
Special criteria
Each section gives the constraint's operator and the shape of value.
Where a section says the operator is ignored, send any string — the comparison logic lives
entirely inside value. invert still applies to the constraint as a whole.
Sub-operators inside a value (status_op, date_op, and so on) take the same operator names as the
matching data type. A sub-operator left null disables that part of the filter rather than failing.
Attendance
Covers attendance_attendance_grouping, attendance_department, and attendance_group. All three
share one value shape; type selects what id refers to.
Operator: ignored
{
"type": "grouping",
"id": 42,
"group_id": null,
"attended": "attended",
"total_by": "week",
"date_op": "in_the_last",
"period": "month",
"units": 3,
"number_of_times_op": "greater_than_or_equal",
"number_of_times_value": 4
}| Field | Type | Description |
|---|---|---|
type | string | grouping, group, department, or event. Determines what id means. event switches to per-event matching. |
id | number | The attendance grouping, group, or department id. 0 or omitted matches any. |
group_id | number | Optional, and only with type: "grouping" — narrows the grouping's events to one group. |
attended | string | attended, did_not_attend, did_not_attend_group, or pre_checked_did_not_attend. |
total_by | string | event, day, or week — what counts as one occurrence. week uses the church's engagement-week definition. |
date_op | string | A date operator. The date window itself is expressed with the sibling keys below. |
year, month, day | number | The date for equal, not_equal, greater_than. |
lbound, ubound | date string | The range for between / not_between. |
period, units | string, number | The window for the in_the_last / in_the_previous / in_the_current families. |
number_of_times_op | string | A number operator applied to the occurrence count. |
number_of_times_value | number | The occurrence count. |
from_date/to_dateandpresenceare not readEarlier revisions of this page showed
attendance_grouping_id,department_id,from_date,
to_date, andpresence. None of those keys are read. The id goes inid, the window goes in
date_opplus its sibling keys, and presence goes inattended.
Asking for "attended 0 times" is rewritten
attended: "attended"withnumber_of_times_op: "equal"andnumber_of_times_value: 0(or
less_than 1) is converted todid_not_attend_groupacross all occurrences. A negative
number_of_times_valueis clamped to0.
Attendance: Single Event (legacy)
attendance_single_event. One event on one date.
Operator: ignored
{
"presence": "present",
"event_id": 8123,
"event_date": "2026-08-16"
}| Field | Type | Description |
|---|---|---|
presence | string | present matches attendees. Any other value matches non-attendees. |
event_id | number | The event. |
event_date | date string | The occurrence date. |
total_byandnumber_of_times_*do nothing hereThis criterion reads only the three keys above. Sending count or grouping keys is silently
ignored — the result is a plain "did / did not attend that occurrence" match. For counted
attendance use Attendance.
Event
event. check_type selects one of two completely different value shapes.
Operator: ignored
Access: contextual — the caller must be able to view that event's guest list.
Registration status:
{
"check_type": "status",
"status_op": "in",
"status_value": [1, 2],
"event_op": "equal",
"event_id": 8123
}| Field | Type | Description |
|---|---|---|
check_type | "status" | Required. |
status_op | string | in, not_in, is, is_not, is_set, is_not_set, or is_not_any. |
status_value | number | [number] | Status id(s). Empty with in behaves as is_set; empty with not_in behaves as is_not_set. |
event_op | string | A number operator, or null to match across all events. |
event_id | number | The event. |
Attendance:
{
"check_type": "attendance",
"attended": "attended",
"event_op": "equal",
"event_id": 8123,
"date_op": "in_the_last",
"date_value": { "period": "month", "units": 1 }
}| Field | Type | Description |
|---|---|---|
check_type | "attendance" | Required. |
attended | string | attended, did_not_attend, or no_status. |
event_op, event_id | string, number | The event to look at. |
date_op, date_value | string, mixed | The occurrence-date window. |
The status key isstatus_value, notstatus_idA missing
status_valueis not a validation error — the constraint degrades to "has any status",
which quietly widens your result set.
Event (legacy)
event_legacy. The pre-event form. Prefer event with check_type: "status".
Operator: ignored
{
"status_op": "is",
"status_value": 2,
"event_op": "equal",
"event_id": 8123
}status_op is is, is_not, is_any, or is_not_any. As with event, the key is
status_value — not status_id.
Form Question and Answer
form_question_answer. Matches a response to one question on one form.
Operator: ignored — the real operators are question_op and value_op inside the value.
{
"form_id": 55,
"question_id": 912,
"question_op": "equal",
"question_type": "single",
"value": "Downtown",
"value_op": "contains"
}| Field | Type | Description |
|---|---|---|
form_id | number | Required. Omit question_id to match anyone who responded to the form at all. |
question_id | number | The question. |
question_op | string | equal to compare the answer, or is_set / is_not_set to test whether the person responded to the form. |
question_type | string | Required when comparing an answer — it selects how value is interpreted. Values below. |
value, value_op | mixed, string | The answer comparison. |
choice_value, choice_op | number, string | The choice comparison, for question types that need both a choice and a value. |
What value holds, by question_type:
question_type | value | Also needs |
|---|---|---|
single, paragraph | text | — |
checkbox, radio, select | choice id (number) | — |
scale | option id (number) | choice_value, choice_op |
prioritize, product | number | choice_value, choice_op |
number, donation_amount | number | — |
date | date parts | — |
file_upload | — | Existence only; no value or operator is used. |
form_question_id,option_value, andoption_opare not readThe question id key is
question_id. Forscale, the option id goes invalue/value_opand
the choice id inchoice_value/choice_op. An unrecognizedquestion_typeis an error, so
omitting it is not a safe default.
Group
group. Membership in one group, optionally narrowed by member status.
Operator: ignored
Access: contextual — the caller must be able to view that group's member list.
{
"group_id": 331,
"group_op": "equal",
"status_value": [1, 2],
"status_op": "in"
}| Field | Type | Description |
|---|---|---|
group_id | number | The group. 0 means any non-system group. |
group_op | string | A number operator. Defaults to equal. |
status_value | number | [number] | Relationship status. See Group statuses. |
status_op | string | Defaults to in. |
Group: Department
group_department. Membership in any group in a department.
Operator: ignored
{
"department_id": 12,
"department_op": "equal",
"status_value": ["LEADER"],
"status_op": "in"
}
The key isdepartment_id, notgrouping_id
grouping_idis the underlying column name, not the filter key.department_id: 0means any
group that is in a department and is not a system group.
Group: Type
group_type.
Operator: ignored
{
"type_id": 4,
"type_op": "equal",
"status_value": ["MEMBER"],
"status_op": "in"
}Group: Search
group_search. Combines group name, department, type, and member status in one constraint.
Operator: ignored
{
"group_name_value": "Youth",
"group_name_op": "contains",
"group_grouping_id": 12,
"group_grouping_op": "equal",
"group_type_id": 4,
"group_type_op": "equal",
"individual_status_id": ["LEADER", "MEMBER"],
"individual_status_op": "in"
}
group_name_op: "equal"changes whatgroup_name_valuemeansWith
equal,group_name_valueis treated as a group id and matched against the group id.
With any other operator it is matched as text against the group name. This is the single most
common source of "my group search returns nothing".
Group: Name
group_name. The value's meaning depends on the operator.
Operator: any text operator, plus equal / not_equal
| Operator | Value | Behaviour |
|---|---|---|
equal | group id (number) | In that group. 0 means in any group. |
not_equal | group id (number) | Not in that group. 0 means in no group at all. |
| any text operator | string | Matched against the group's name. |
Group: Relationship
group_relationship. Relationship status across all groups, with no group filter.
Operator: ignored
{ "status_value": ["LEADER", "COACH"], "status_op": "in" }Group: Interaction Type
group_interaction_type.
Operator: a number operator, applied to interaction_type
{ "interaction_type": 3, "status_value": ["MEMBER"], "status_op": "in" }Group: Status
group_status. Membership status with no group, type, or department filter.
Operator: a number operator
Value: the status value
Group: Member Start Date
group_member_start_date. When someone joined a specific group.
Operator: a date operator
Value: an object carrying group_id alongside the date parts the operator needs.
{ "group_id": 331, "year": 2026, "month": 1, "day": 15 }Group: Involvement
group_involvement. The composite group filter used by current People Search. Every sub-filter is
optional; supply only the pairs you want applied.
Operator: ignored
{
"group_name_selected_subfilter": "group_id",
"group_id_value": 331,
"group_id_op": "equal",
"member_status_value": ["LEADER"],
"member_status_op": "in",
"member_start_date_value": { "period": "year", "units": 1 },
"member_start_date_op": "in_the_last",
"group_active_value": "active"
}| Field pair | Filters on |
|---|---|
group_id_value / group_id_op | A specific group. |
group_term_value / group_term_op | Free text against the group name. |
group_type_value / group_type_op | Group type. |
group_department_value / group_department_op | Department. |
group_campus_value / group_campus_op | The group's campus. |
member_status_value / member_status_op | Relationship status. |
member_start_date_value / member_start_date_op | Join date. |
status_history_value / status_history_op | Past status, not just current. |
custom_field_id + custom_field_value / custom_field_op | A group custom field. |
group_active_value | active or inactive. |
group_name_selected_subfilter tells the filter which of the group-identifying pairs to honour.
Group statuses
status_value in the group criteria accepts these relationship values:
| Value | Meaning |
|---|---|
REQUESTING | Requested to join. |
LEADER | Main or assistant leader, or the group's owner. |
MEMBER | Member. |
INVITED | Invited. |
COACH | Group coach. |
DIRECTOR | Group director. |
DEPT_ADMIN | Administrator of the group's department. |
COACH,DIRECTOR, andDEPT_ADMINare leadership roles from a permissions standpoint but arenot included in
LEADER. Match them explicitly if you want every kind of leader.
Custom Fields
custom_fields for individual custom fields, group_custom_fields for group ones.
Operator: the operator for the field's own type
{ "field_id": "udf_text_3", "field_type": "TEXT", "field_value": "Alumni" }| Field | Type | Description |
|---|---|---|
field_id | string | The custom field's storage name, e.g. udf_text_3, udf_date_1, udf_pulldown_2. |
field_type | string | TEXT, DATE, or PULLDOWN. |
field_value | mixed | Text, or a pulldown id. |
For DATE, put the date parts on the value object itself alongside field_id and field_type:
{ "field_id": "udf_date_1", "field_type": "DATE", "year": 2026, "month": 3 }group_custom_fields takes field_id and field_value only.
Theudf_text_1…udf_text_12,udf_date_1…udf_date_6, andudf_pulldown_1…
udf_pulldown_6criteria in the table above target the same columns directly and are simpler.
Reach forcustom_fieldswhen your integration discovers field names at runtime.
Name
name. Fuzzy matching across first and last name. This is the criterion the quick-search box uses.
Operator: space_to_wildcard, space_to_wildcard_space, any_order_like, or legacy
Value: string
Access: any signed-in user
| Operator | Behaviour |
|---|---|
space_to_wildcard | Runs of whitespace become %, and the whole term is wrapped in %. Matched against first last. "jo sm" matches "John Smith". |
space_to_wildcard_space | Runs of whitespace become % % — wildcard, space, wildcard. Matched against first last. |
any_order_like | Splits on whitespace; every word must match first name or last name, in any order. "smith john" matches "John Smith". |
legacy | Prefix matching across first, last, legal, maiden, alternate name and primary email. With two words, also first-word-on-first-name and second-word-on-last-name. If the term is all digits and separators, home phone, mobile phone, mailing street, and giving number are searched too. |
The operator isspace_to_wildcard, with one underscoreEarlier revisions of this page printed
space_to__wildcard. An unrecognized name mode is an
error, not a fallback.
legacyis much broader than a name search — it will match on email and, for numeric input, onphone, street, and giving number. Use
any_order_likewhen you want names only.
Name Fields
name_fields. One specific name field, with normal text operators.
Operator: any text operator
{ "type": "last_name", "search_term": "Smith" }type is first_last_name (the default, which behaves like Name), first_name,
middle_name, last_name, legal_name, maiden_name, or alternate_name.
Address
home_address, work_address, mailing_address, other_address. One address block, one component.
Operator: any text operator
{ "type": "city", "search_term": "Colorado Springs" }type is street, city, state, zip, or country.
Thehome_city,work_zip,mailing_state-style criteria in the table target the same columnsand are simpler for a fixed query. The
*_addressform is useful when the component is chosen at
runtime.
Phone Number
phone_number. One phone field, or all of them.
Operator: any text operator
{ "type": "mobile", "search_term": "719-555-0134" }type is home, mobile, work, emergency, fax, pager, or any.
Formatting is handled for youPunctuation is stripped from both the search term and the stored value before comparison, and the
term is also matched in the campus's locale format. Withequalornot_equaland 10 or more
digits, the last 10 digits are matched as well, so a country code on either side does not break
the match.
My Fit: Ability, Passion, Spiritual Gift, Personality Style
ability, passion, spiritual_gift, personality_style.
Operator: in, not_in, is_set, or is_not_set
Value: an id, or an array of ids. Omit for is_set / is_not_set.
{ "type": "constraint", "id": "spiritual_gift", "operator": "in", "value": [3, 7], "invert": false }
Only those four operators workThese read as plain
numbercriteria but they are not.equal,between, and the rest raise an
error rather than falling back toin.
Family Members
family_head, family_spouse, family_child, family_other. Matches on the name of another
member of the individual's family, by that member's position.
Operator: any text operator
Value: string — the related person's name
Family Position
family_position. Accepts either form.
A plain string, with the constraint's own operator:
{ "type": "constraint", "id": "family_position", "operator": "equal", "value": "PRIMARY_CONTACT" }Or an object that pairs the position with a name, letting you ask "whose spouse is named Dana":
{
"family_position_value": "SPOUSE",
"family_position_op": "equal",
"individual_name_value": "Dana",
"individual_name_op": "contains"
}Created / Modified By Name
creator_name, modified_name. Matches the full name of the user who created or last modified the
profile, rather than first and last name separately.
Operator: any text operator
Value: string
The creator_first_name, creator_last_name, modifier_first_name, and modifier_last_name
criteria remain available for single-field matching.
Note
note. Text of individual notes.
Operator: any text operator
Value: string
Access: Notes
Duplicates
duplicates. Individuals flagged as possible duplicates of the ids you pass.
Operator: ignored
Value: an individual id, or an array of ids
Access: Full people read
Matches both sides of each duplicate pair, applies the church's duplicate-score threshold, and
excludes the master administrator's profile.
Privacy Settings
privacy_settings. The visibility level a person has set on one field.
Operator: a number operator
{ "type": "phone_home", "selection_values": [1, 2] }type names the field. email_primary checks the listed flag; every other value checks that
field's privacy level.
Process Queue
process_queue. Position in a process, by step and status.
Operator: ignored
{ "step_id": 17, "status_value": [1], "status_op": "in" }| Field | Type | Description |
|---|---|---|
step_id | number | The step. 0 inverts the test — it matches every step other than step 0. |
status_value | number | [number] | Status id(s). |
status_op | string | in, not_in, is_set, or is_not_set. Anything else is an error. |
Process Queue: Date
process_queue_added_date, process_queue_completed_date, process_queue_due_date. The criterion
id chooses the date; there is no date_type value.
Operator: a date_parts operator
Value: the date parts, plus the process and step ids
{
"process_name_id": 5,
"queue_name_id": 17,
"year": 2026,
"month": 8
}| Field | Type | Description |
|---|---|---|
process_name_id | number | The process. When set, both active and archived processes are searched. |
queue_name_id | number | The step. 0 matches every step in the process except step 0. |
year, month, day | number | Date parts, as required by the operator. |
is_not_set on the constraint drops the date comparison and inverts the match — it finds people who
have no such date on that step.
Significant Event
significant_event, and significant_event_date for a date-only query.
Operator: ignored (significant_event) · a date_parts operator (significant_event_date)
Access: Full people read
{
"significant_event_id": [4, 9],
"significant_event_op": "in",
"significant_event_date_value": { "period": "year", "units": 1 },
"significant_event_date_op": "in_the_last",
"significant_event_note_value": "hospital",
"significant_event_note_op": "contains"
}| Field | Type | Description |
|---|---|---|
significant_event_id | number | [number] | Event type id(s). |
significant_event_op | string | in, not_in, or is_not_set. Anything else leaves the event-type filter off. |
significant_event_date_value / _op | mixed, string | Date parts against when the event was recorded. |
significant_event_note_value / _op | string, string | Text search on the note. |
The date keys aresignificant_event_date_valueandsignificant_event_date_opNot
date_value/date_op. With the wrong keys the date filter is dropped and you get every
matching event type regardless of date.
Funeral
funeral_system_significant_event. Funerals recorded as system significant events.
Operator: ignored
Access: Significant events
Every pair below is optional; supply only what you want applied.
| Field pair | Filters on |
|---|---|
date_of_service_value / date_of_service_op | When the record was created. Date parts. |
date_of_death_value / date_of_death_op | Date of death. Date parts. |
cemetery_value / cemetery_op | Cemetery. |
location_of_funeral_service_value / _op | Service location. |
service_locations_value / _op | Service locations. |
primary_presider_value / _op | Primary presider. |
presider_name_value / _op | Presider name. |
remains_value / _op | Disposition of remains. |
note_value / note_op | Note text. |
Sacraments
baptism_sacrament, reconciliation_sacrament, first_communion_sacrament,
confirmation_sacrament, marriage_sacrament, holy_order_sacrament,
anointing_the_sick_sacrament.
Operator: ignored
Access: Sacrament admin. Requires the Sacraments module.
Deleted and archived sacraments are always excluded. Every pair is optional — an empty value matches
anyone with a sacrament of that type.
| Field pair | Filters on |
|---|---|
date_performed_value / date_performed_op | Date performed. |
diocese_value / diocese_op | Diocese of reception. |
subtype_value / subtype_op | Sacrament subtype. |
religion_status_value / religion_status_op | Religion status. |
status_value | Record status — verified values: COMPLETED, IN_PROGRESS, INCOMPLETE_PENDING. |
received_here, convalidation, ocia, profession_of_faith, last_rites | Boolean flags on the record. Which flags apply depends on the sacrament type — see the Sacraments MCP tool for the per-type field map. |
Not every pair is meaningful for every sacrament type
subtypeonly has values onbaptism_sacramentandholy_order_sacrament;religion_statusand
convalidationonly apply tomarriage_sacrament;last_ritesonly applies to
anointing_the_sick_sacrament. Sending a sub-filter that criterion doesn't carry data for simply
never matches anyone, rather than erroring.
Virtus Status
virtus_status, and virtus_status_expiration_time for the expiry date.
Operator: in or not_in (virtus_status) · a date_parts operator (virtus_status_expiration_time)
Access: Virtus
{
"type": "constraint",
"id": "virtus_status",
"operator": "in",
"value": ["CERTIFIED", "EXPIRED", "ID_ERROR", "INACTIVE", "NOT_CERTIFIED"],
"invert": false
}| Value | Meaning |
|---|---|
CERTIFIED | Active, certified, and not past its expiry. |
EXPIRED | Active and certified, but past its expiry. |
NOT_CERTIFIED | Active but not certified. |
INACTIVE | Not active. |
ID_ERROR | No Virtus id is stored on the profile. |
Don't usenot_inon this criterion at all — verified unreliable, even with one value
not_indoes not behave like a simple negation here. To exclude a set of statuses, always sendinwith that set and"invert": trueinstead — verified to return the correct count.
Virtus must be enabled and connected for the church. If it is not, the request returns
403 Forbidden.
New Giver
new_giver. Finds people by the date of their nth gift.
Operator: a date_parts operator
Value: the gift number in type, plus the date parts
{
"type": "constraint",
"id": "new_giver",
"operator": "in_the_last",
"value": { "type": 1, "period": "month", "units": 3 },
"invert": false
}| Field | Type | Description |
|---|---|---|
type | number | Which gift to look at. 1 is the person's first gift. |
year, month, day / period, units / lbound, ubound | — | The date window, matching the constraint's operator. |
The gift number key istype, and the operator is not ignoredEarlier revisions showed
gift_number,date_value, anddate_opwith an ignored operator. None
of those are read. The constraint's ownoperatordrives the date comparison.
Scheduling (Luna)
Scheduling criteria on the individual domain. For scheduling-first queries use the dedicated
scheduling search domains instead.
Operator: ignored, except where noted
| Id | Value |
|---|---|
luna_position | { position_id, position_op, status_value, status_op }. status_op takes in, not_in, is, is_not, is_any, is_not_any. |
luna_assignment | { status, status_op, date, date_op } |
luna_assignment_status | { status_value, position_id, position_op, date_value, date_op } |
luna_category_involvement | { category_id, position_value, position_op }. position_value is an array of involvement-role strings, not a position id — see below. |
luna_team | The team id. Uses the constraint's own operator. |
luna_organizer | The organizer's individual id. Uses the constraint's own operator, including is_set / is_not_set. |
luna_category | A number criterion — the category id. |
luna_assignment_date, luna_assignment_month | Plain date and number criteria. |
luna_assignment_date_parts | Date parts, using the constraint's own operator. |
luna_positionrequiresstatus_op— omit it and the whole request 500s
status_opis not an optional refinement here despite reading like one. Send it even if you only
want to filter byposition_id(any valid value, e.g."is_any", works) — without it the request
fails with a500regardless of what else is in the value object.position_iditself is
optional; omitting it (withstatus_oppresent) matches anyone holding any Luna position.
luna_category_involvement'sposition_valueis a role list, not an id — sending the wrong type 500s
position_valuetakes an array of involvement-role strings:VOLUNTEER,CATEGORY ORGANIZER,PLAN ORGANIZER,SCHEDULE ORGANIZER,TEAM ORGANIZER. Sending a position id (a
number) here — the natural-looking guess — crashes with a500, not a412, because the
criterion checks the array unconditionally regardless of operator.position_opisin/
not_in(matches if any listed role applies) oris_set/is_not_set(any / no category
involvement at all —position_valuecan be[]for these). Omittingcategory_id(or setting
it to0) also crashes unless the constraint node carries the separate
include_valuekey ({"include_value": ["ACTIVE", "ARCHIVED"]}) — with a specificcategory_id, that default is applied for you automatically.{ "type": "constraint", "id": "luna_category_involvement", "operator": "ignored", "value": { "category_id": 726, "position_op": "in", "position_value": ["VOLUNTEER"] }, "invert": false }
Department Admin
department_admin. Administrators of a department.
Operator: equal or not_equal
Value: the department id
Background Check Package Name
background_check_package_name matches people by their background checks — the package, and
optionally when the check completed, when it expires, who ordered it, and its report status.
has_requested_background_check distinguishes checks a person requested for themselves from checks
ordered on their behalf — send not_equal to match self-requested checks, anything else to match
checks ordered by someone else.
Operator: in — the node operator is not consulted; matching is controlled by the *_op keys
inside the value.
Checks expiring in the next 90 days under package 123:
{
"package_op": "in",
"package_value": [123],
"expiration_date_op": "in_the_next",
"expiration_date_value": { "period": "day", "units": 90 }
}| Field | Type | Description |
|---|---|---|
package_op | string | Number operator applied to the package id. is_not_set matches people with no background check at all; is_set matches a check of any package. |
package_value | number | [number] | Background check package id(s) — not the display name, despite the criterion's name. Package ids come from GET /individuals/background_check_types. |
completed_date_op / completed_date_value | date block | When the check completed (its status last changed). |
expiration_date_op / expiration_date_value | date block | When the check expires. |
ordered_by_op / ordered_by_value | string / number | [number] | Number operator on the id of the person who ordered the check. Ids come from GET /individuals/background_check_creators. |
report_status_op / report_status_value | string / string | [string] | Text operator on the report status. The supported statuses are PENDING, CLEAR, CONSIDER, DISPUTED, DISPUTED_CLEAR, SUSPENDED, CANCELED, CLEAR_CANCELED, CONSIDER_CANCELED, COMPLETE, PRE_ADVERSE_ACTION, POST_ADVERSE_ACTION — the same list for every integration, including vendor integrations; vendors do not define their own statuses. |
Every block except the package is optional — include only the *_op / *_value pairs you need.
Do not put acommentkey on this constraintThe optional
commentnode key documented under
Extra keys on a constraint node causes a
500 Internal Server Errorwhen sent on abackground_check_package_nameconstraint. The same
key on ordinary criteria in the same request works fine. Omit it here.
Date blocks. completed_date_* and expiration_date_* each accept four forms:
| Form | Operator | Value |
|---|---|---|
| Presence | is_set / is_not_set | none |
| Exact date | equal, not_equal, less_than, less_than_or_equal, greater_than, greater_than_or_equal | { "year": 2026, "month": 8, "day": 21 } — all three parts required, unlike a normal date_parts value. |
| Relative window | the in_the_* relative operators (e.g. in_the_last, in_the_next) | { "period": "day", "units": 90 } |
| Range | between / not_between | { "lbound": "2026-01-01", "ubound": "2026-03-31" } |
An incomplete date block is skipped, not rejectedA date value that fits none of the forms above — for example an exact date missing
day— drops
that date condition silently. The constraint still runs on its remaining conditions, typically
matching everyone with a live check of that package. Validate the date block yourself before
sending.
Only live checks are searchedThe criterion matches checks whose stored status is valid — pending, removed, and archived checks
are excluded. Date-expired checks still match, because expiry is derived fromexpiration_date
rather than the stored status, so both "expiring soon" (expiration_date_op: in_the_next) and
"lapsed" (in_the_last) filters work.
Email Verification
email_verification_opt_in_status, plus four date variants:
email_verification_opt_in_date, email_verification_date_verified,
email_verification_date_verification_email_sent, email_verification_date_opt_in_email_sent.
Operator: a text operator for the status · a date_parts operator for the dates
{ "type": "constraint", "id": "email_verification_opt_in_status", "operator": "in", "value": ["OPT_IN"] }| Value | Matches |
|---|---|
OPT_IN | Opted in. |
UNSUBSCRIBED | Opted out. |
SUBSCRIBED | Pre-opt-in or no response yet. |
The date variants share the status valueThe date criteria read the same
valuefor both the status list and the date parts, so the value
must contain at least one of the three status strings as well as the date parts. With no
recognized status, no condition is applied and the constraint matches everyone who has an
email-verification record.
MICR Scan
micr_scan. Matches a scanned check's MICR line.
Operator: ignored
Value: the MICR string
Access: Financial
Envelope User Id
envelope_user_id. Giving envelope number.
Operator: the constraint's own operator
Value: the envelope id
Non-queryable criteria
whos_included is returned by GET /search/individuals as a filtering option for the People Search
UI, but it is not backed by a query. Do not send it in a filter tree — it has no valid comparison
and will fail the request rather than being ignored. Use configuration.filter_profile_type and the
include_* keys documented in
Population selection instead.
Extra keys on a constraint node
Beyond type, id, operator, value, and invert, a constraint node accepts:
| Key | Type | Description |
|---|---|---|
comment | string | Free text. Carried into the generated query as a comment. Useful for tracing a slow or surprising search back to the integration that sent it. Does not affect results. Exception: on a background_check_package_name constraint it causes a 500 — omit it there. |
include_value | object | { "include_value": ["ACTIVE", "INACTIVE"] }. Read by the group criteria to decide whether inactive groups and archived processes count. Defaults to active only. |
value_type | string | Read by group_name and the *_address criteria to say whether value should be treated as a number (an id) or as text. |
Unrecognized keys are ignored.
Formula groups
A group node normally joins its children with a single and or or. A formula group lets you
express an arbitrary boolean expression over them instead, including NOT and parentheses, without
nesting groups by hand.
{
"type": "group",
"operator": "formula",
"formula": "set1 AND (NOT set2 OR set3)",
"invert": false,
"conditions": [
{ "type": "constraint", "id": "campus", "operator": "equal", "value": 1, "invert": false },
{ "type": "constraint", "id": "is_inactive", "operator": "is_set", "invert": false },
{ "type": "constraint", "id": "membership_type", "operator": "in", "value": [2, 3], "invert": false }
]
}| Field | Type | Required | Description |
|---|---|---|---|
type | "group" | yes | Formula groups are group nodes. |
operator | "formula" | yes | What marks the group as a formula. |
formula | string | yes | The expression. |
conditions | array | yes | The referenced nodes, in order. At least one. |
Grammar. SET<n>, AND, OR, NOT, and parentheses. Keywords are case-insensitive and
whitespace is ignored. set1 is the first entry in conditions, set2 the second, and so on —
the numbering is 1-based.
Each set may itself be a group node, so a formula can combine whole sub-trees rather than single
constraints.
A set number with no matching condition fails the request
set4against a three-entryconditionsarray is an error. Keep the formula and the array in
step when you build the filter programmatically.
ANDandORhave no precedence hereThe grammar binds left to right, so
set1 OR set2 AND set3is not the same as it would be in SQL.
Parenthesize anything non-trivial.
Examples
A single special criterion
Everyone whose mobile number contains a given exchange:
{
"configuration": { "return_search_results": true },
"filters": {
"type": "constraint",
"id": "phone_number",
"operator": "contains",
"value": { "type": "mobile", "search_term": "719555" },
"invert": false
}
}Attendance
Adults who attended a weekend service at least twice in the last three months:
{
"configuration": {
"return_search_results": true,
"order_by": [{ "column": "last_name", "direction": "asc" }]
},
"filters": {
"type": "group",
"operator": "and",
"invert": false,
"conditions": [
{
"type": "constraint",
"id": "age",
"operator": "greater_than_or_equal",
"value": 18,
"invert": false
},
{
"type": "constraint",
"id": "attendance_attendance_grouping",
"operator": "ignored",
"value": {
"type": "grouping",
"id": 42,
"attended": "attended",
"total_by": "week",
"date_op": "in_the_last",
"period": "month",
"units": 3,
"number_of_times_op": "greater_than_or_equal",
"number_of_times_value": 2
},
"invert": false
}
]
}
}Group leaders in a department
Everyone leading a group in department 12, including leaders of inactive groups:
{
"configuration": { "return_search_results": true },
"filters": {
"type": "constraint",
"id": "group_department",
"operator": "ignored",
"value": {
"department_id": 12,
"department_op": "equal",
"status_value": ["LEADER", "COACH", "DIRECTOR"],
"status_op": "in"
},
"include_value": { "include_value": ["ACTIVE", "INACTIVE"] },
"invert": false
}
}A form response
Everyone who answered question 912 on form 55 with a specific choice:
{
"configuration": { "return_search_results": true },
"filters": {
"type": "constraint",
"id": "form_question_answer",
"operator": "ignored",
"value": {
"form_id": 55,
"question_id": 912,
"question_op": "equal",
"question_type": "select",
"value": 4471,
"value_op": "equal"
},
"invert": false
}
}To find everyone who responded to the form at all, drop question_id and keep only form_id.
First-time givers this quarter
{
"configuration": {
"return_search_results": true,
"order_by": [{ "column": "last_name", "direction": "asc" }]
},
"filters": {
"type": "constraint",
"id": "new_giver",
"operator": "in_the_previous",
"value": { "type": 1, "period": "quarter", "units": 1 },
"invert": false
}
}Excluding a set of Virtus statuses
Everyone who is neither expired nor uncertified — written as in plus invert, because not_in
with multiple statuses does not exclude the way it reads:
{
"configuration": { "return_search_results": true },
"filters": {
"type": "constraint",
"id": "virtus_status",
"operator": "in",
"value": ["EXPIRED", "NOT_CERTIFIED"],
"invert": true
}
}A formula group
Members of campus 1 who are either leading a group or have a background check on file, but are not
inactive:
{
"configuration": {
"return_search_results": true,
"filter_profile_type": ["active", "inactive"]
},
"filters": {
"type": "group",
"operator": "formula",
"formula": "set1 AND NOT set2 AND (set3 OR set4)",
"invert": false,
"conditions": [
{ "type": "constraint", "id": "campus", "operator": "equal", "value": 1, "invert": false },
{ "type": "constraint", "id": "is_inactive", "operator": "is_set", "invert": false },
{
"type": "constraint",
"id": "group_relationship",
"operator": "ignored",
"value": { "status_value": ["LEADER"], "status_op": "in" },
"invert": false
},
{
"type": "constraint",
"id": "background_check_package_name",
"operator": "is_set",
"invert": false
}
]
}
}When a filter is rejected
| Response | Cause |
|---|---|
412 with "<id> is not valid" | The id is not a criterion on this domain, or is misspelled. Compare against GET /search/individuals. |
412 with "id not currently set" | A constraint node is missing id. |
403 | The caller lacks the permission for one of the criteria used, or the OAuth token lacks the scope for the endpoint. Every criterion in the tree is checked before any results are produced. |
403 on a Virtus criterion | Virtus is not connected for the church. |
POST /search/individuals/resultsrequires theread:individualsscopeThe reference page for the endpoint currently lists
read:advanced_searches. That scope covers the
saved-search endpoints; the results endpoint itself is gated onread:individuals. Request both if
your integration reads saved searches as well as running them.
