profile-investigator
Profile Investigator
Purpose
Deep diagnostic profile exploration. Answers questions like:
- "Why is this user in segment X?"
- "Why isn't this user in segment Y?"
- "What happened to this user?" (data lineage)
- "What does this user look like?" (full profile + memberships)
Goes beyond basic profile lookup by cross-referencing profile data against segment FilterQL to show exactly which conditions match or fail.
Environment
Requires authenticated API access. See ../references/auth.md for credential resolution.
Inputs
- Identity field and value (e.g.,
email,user@example.com) - Segment name or ID (for membership diagnosis)
- Or a diagnostic question in natural language
Diagnostic Flows
Flow A: "Why is/isn't this user in segment X?"
Step 1: Look Up the Profile
Fetch the full profile with segment memberships:
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/api/entity/user/${FIELD}/${VALUE}?segments=true&allsegments=true" \
-H "Authorization: ${LYTICS_API_TOKEN}"
This returns:
- All profile fields and their values
segments-- list of segment names the user belongs tosegments_all-- list of all segment IDs
Check immediately: is the target segment in the membership list?
Step 2: Fetch the Segment's FilterQL
Get the segment with its fully resolved FilterQL (all INCLUDE directives inlined):
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/v2/segment/${SEGMENT_ID}?inline=true" \
-H "Authorization: ${LYTICS_API_TOKEN}"
The ql_resolved field contains the complete filter expression with nested segments expanded.
Step 3: Evaluate Each Condition Against the Profile
Parse the FilterQL into individual conditions and check each one against the profile's actual field values.
For each condition in the FilterQL, report:
If the user IS in the segment:
## Why user@example.com IS in "High Value Customers"
FilterQL: FILTER AND (visit_count >= 5, email_engagement > 0.3, country = "US") FROM user
All conditions PASS:
visit_count >= 5 PASS (actual: 12)
email_engagement > 0.3 PASS (actual: 0.72)
country = "US" PASS (actual: "US")
If the user is NOT in the segment:
## Why user@example.com is NOT in "High Value Customers"
FilterQL: FILTER AND (visit_count >= 5, email_engagement > 0.3, country = "US") FROM user
Condition results:
visit_count >= 5 PASS (actual: 12)
email_engagement > 0.3 FAIL (actual: 0.15, required: > 0.3)
country = "US" PASS (actual: "US")
The user fails the email_engagement condition. Their value (0.15) is below
the threshold (0.3). This is the reason they are excluded from the segment.
Step 4: Check Included Segments
If the FilterQL references other segments via INCLUDE, check those memberships too:
Segment "High Value Customers" includes "Email Subscribers":
Email Subscribers membership: YES
Combined evaluation:
INCLUDE Email Subscribers PASS
visit_count >= 5 PASS (actual: 12)
last_purchase > "now-90d" FAIL (actual: 2025-01-15, ~63 days ago -- outside 90d window)
Flow B: "What happened to this user?" (Data Lineage)
Step 1: Fetch Entity with Explain Mode
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/api/entity/user/${FIELD}/${VALUE}?explain=true" \
-H "Authorization: ${LYTICS_API_TOKEN}"
This returns:
entity-- the resolved profilefragments-- array of data fragments showing where each piece of data came fromkeys-- source references (fragment aliases)
Step 2: Present Data Lineage
## Data Lineage: user@example.com
### Identity Resolution
Linked identities:
email: user@example.com
_uid: abc-def-123
user_id: 98765
### Data Sources (N fragments)
Fragment 1: stream "web_events" (last seen: 2026-03-18)
-> visit_count, pages_viewed, last_visit, referrer
Fragment 2: stream "salesforce_contacts" (last seen: 2026-03-15)
-> first_name, last_name, company, phone
Fragment 3: stream "email_events" (last seen: 2026-03-19)
-> email_engagement, newsletters, last_email_open
Flow C: Full Profile Summary
Step 1: Fetch Profile + Segments
curl -s "${LYTICS_API_URL:-https://api.lytics.io}/api/entity/user/${FIELD}/${VALUE}?segments=true&allsegments=true&meta=true" \
-H "Authorization: ${LYTICS_API_TOKEN}"
Step 2: Present Structured Summary
## Profile: user@example.com
### Identity
email: user@example.com
_uid: abc-def-123
### Key Attributes
Name: Jane Smith
Country: US
Created: 2024-01-15
Last Active: 2026-03-18
Visit Count: 12
### Segment Memberships (5 segments)
- High Value Customers (segment)
- Email Subscribers (aspect)
- US Users (aspect)
- Q1 Campaign (list)
- Active Last 30 Days (segment)
### NOT in these commonly-checked segments
[If the user asks about specific segments, show which they're not in and why]
Condition Evaluation
When cross-referencing FilterQL conditions against profile data, handle each operator type:
| FilterQL Condition | How to Check |
|---|---|
field = "value" |
Compare profile's field value to literal |
field > N |
Numeric comparison against profile value |
field > "now-Nd" |
Compare profile's date field to calculated threshold |
EXISTS field |
Check if field exists and has a non-empty value in profile |
NOT EXISTS field |
Check if field is missing or empty |
field INTERSECTS ("a", "b") |
Check if profile's set field contains any listed values |
field NOT INTERSECTS ("a") |
Check if profile's set field contains none of the listed values |
field CONTAINS "substr" |
Check if profile's string field contains the substring |
field IN ("a", "b") |
Check if profile's value is in the list |
INCLUDE segment_slug |
Check if user is a member of the referenced segment |
For each condition, always show:
- The condition itself
- PASS or FAIL
- The actual value from the profile (or "field not present" if missing)
- For FAIL: what value would be needed to pass
Error Handling
- Profile not found: Try alternative identity fields, suggest checking spelling. URL-encode values with special characters.
- Segment not found: List segments with similar names, suggest checking the slug.
- Complex FilterQL: For deeply nested expressions, evaluate the top-level conditions first, then drill into failing branches.
- Missing fields: If a profile field referenced in FilterQL doesn't exist on the profile, report it clearly -- this is often the root cause.
Dependencies
- Composes:
entity-lookup skill,segment-manager skill - References:
../references/filterql-grammar.md,../references/auth.md,../references/api-client.md
More from lytics/agent-skills
entity-lookup
Look up user profiles by identity field and value. Use when the user wants to find or look up a specific user profile by email, user ID, or other identity field.
29audience-advisor
Strategic audience guidance -- helps users build the right audience for their business goal or improve an existing segment. Use when the user needs help choosing the right audience strategy, wants advice on segment design, or needs to improve an existing segment.
29integration-setup
Guided setup for data integrations -- connection, auth, and job creation. Use when the user wants to set up, configure, or connect a new data integration end-to-end.
29audience-snapshot
Analyze what an audience looks like -- demographic breakdowns, top field values, coverage rates, and distributions. Use when the user wants to understand audience composition, view segment demographics, or analyze field coverage for a segment.
29data-health-monitor
Single-command data health check -- streams, jobs, schema, and quota status in one report. Use when the user wants to check data health, view system status, or get an overview of streams, jobs, and schema health.
29schema-manager
Browse and modify schema fields, mappings, identity config, and field rankings. Use when the user wants to list, view, create, or modify schema fields, mappings, identity configuration, or field rankings.
28