---
title: "Privacy-conscious person lookup with journey tracking"
method: POST
path: "/crm/lookup/person"
tags: ["CRM Service Calls"]
---

# Privacy-conscious person lookup with journey tracking

`POST /crm/lookup/person`

Search for a person by email, phone, internal ID, or external ID and retrieve their complete journey
through the sales pipeline (lead → contact → opportunity).

## Search Options

Provide at least one of:
- **email**: Search by email address
- **phone**: Search by phone number
- **id**: Search by internal CRM record ID (lead or contact)
- **external_id**: Search by external/partner reference ID

## Privacy Notice

This endpoint returns **only aggregate activity metrics**. It does NOT expose:

- Names, IDs, or any identifying information
- Actual comment content or details
- Owner/assigned user information
- Deal values or commission-sensitive data
- Tags or custom fields

## Rate Limits

- **60 requests per minute** per auth token
- Rate limited to prevent abuse

## Search Logic

1. If `id` or `external_id` provided, searches directly by ID (takes priority)
2. Falls back to email/phone search if no ID match or no ID provided
3. Searches contacts first (prioritizes existing relationships)
4. Searches leads (for new prospects)
5. If a contact is found, searches for associated opportunities
6. Returns the complete journey with activity metrics at each stage

## Use Cases

- **Duplicate Detection**: Check if a person already exists before creating a new lead
- **Journey Tracking**: Understand where a person is in the sales pipeline
- **Commission Attribution**: Verify activity within inactivity period for commission eligibility
- **Direct Lookup**: Retrieve journey info for a known record by ID

## Inactivity Period

The `inactivity_days` parameter (default: 30) determines whether activity is considered
"recent". The `has_recent_activity` response field indicates if the most recent
activity falls within this threshold.

## Query parameters

- `inactivity_days` integer — Number of days to consider for inactivity threshold. Activity within this period sets has_recent_activity=true.

## Request body

- PersonLookupRequest — Request for privacy-conscious person lookup. At least one of email, phone, id, or external_id must be provided. Used by third-party integrations to check for duplicate leads and track lead journey without exposing sensitive data.
  - `email` string, nullable — Email address to search for
  - `phone` string, nullable — Phone number to search for (various formats accepted)
  - `id` string, nullable — Internal CRM record ID to search for (lead or contact)
  - `external_id` string, nullable — External/partner reference ID to search for

## Response `200`

Lookup successful

- PersonLookupResponse — Privacy-conscious response for person lookup with full journey tracking. Returns the complete lead → contact → opportunity journey without exposing sensitive business data like names, IDs, values, or specific statuses. **Privacy Notice**: This response does NOT expose: - Names, IDs, or any identifying information - Actual comment content - Owner/assigned user information - Deal values or commission-sensitive data - Tags or custom fields
  - `exists` boolean, required — Whether any matching record was found (lead or contact)
  - `matched_on` 'email' | 'phone' | 'both' | 'id' | 'external_id', nullable — Which identifier matched (email, phone, both, id, or external_id)
  - `has_recent_activity` boolean — True if person has activity within the configured threshold (default 30 days)
  - `lead` LeadJourneyInfo, required — Privacy-safe lead information for journey tracking. Exposes only aggregate activity metrics without PII.
    - `exists` boolean, required — Whether a matching lead record was found
    - `is_active` boolean — Whether the lead is in an active state (not disqualified/inactive)
    - `is_converted` boolean — Whether the lead has been converted to a contact
    - `has_activity` boolean — Whether there has been any activity on this lead
    - `comment_count` integer — Number of comments/touchpoints on the lead
    - `days_since_last_activity` integer, nullable — Days since last activity, null if no activity
    - `activity_summary` string, nullable — Human-readable activity summary
    - `created_date` string, nullable — Date the lead was created (ISO 8601)
  - `contact` ContactJourneyInfo, required — Privacy-safe contact information for journey tracking. Exposes only aggregate activity metrics without PII.
    - `exists` boolean, required — Whether a matching contact record was found
    - `is_active` boolean — Whether the contact is in an active state
    - `has_activity` boolean — Whether there has been any activity on this contact
    - `comment_count` integer — Number of comments/touchpoints on the contact
    - `days_since_last_activity` integer, nullable — Days since last activity, null if no activity
    - `activity_summary` string, nullable — Human-readable activity summary
    - `created_date` string, nullable — Date the contact was created (ISO 8601)
    - `converted_from_lead` boolean — Whether this contact was converted from a lead
  - `opportunity` OpportunityJourneyInfo, required — Privacy-safe opportunity information for journey tracking. Exposes stage and dates only - no values or sensitive details.
    - `exists` boolean, required — Whether an opportunity exists for this person
    - `stage` string, nullable — Current opportunity stage (e.g., discovery, negotiation, closed_won)
    - `is_closed` boolean — Whether the opportunity is in a closed state
    - `is_won` boolean — Whether the opportunity was won (closed_won)
    - `created_date` string, nullable — Date the opportunity was created (ISO 8601)
    - `expected_close_date` string, nullable — Expected close date (ISO 8601)
    - `close_date` string, nullable — Actual close date if closed (ISO 8601)
    - `opportunity_count` integer — Total number of opportunities for this person
  - `journey_stage` 'lead' | 'contact' | 'opportunity' | 'closed', nullable — Current stage in the journey (furthest stage reached)
  - `total_touchpoints` integer — Total touchpoints across all stages
  - `first_seen_date` string, nullable — Earliest date this person entered the system (ISO 8601)

## Other responses

- `401` — Missing or invalid authorization token
- `422` — Validation error (invalid email/phone format or missing both)
- `429` — Rate limit exceeded
- `500` — Internal server error

---

[API](https://skmtc.net/ambivo/apis/ambivo-api.md) · [All operations](https://skmtc.net/ambivo/apis/ambivo-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/ambivo/ambivo-api/revisions/165a6d16a9a0/schema)
