---
title: "Lookup Crm Account Sessionless"
method: POST
path: "/integrations/crm/lookup"
tags: ["integrations", "crm"]
---

# Lookup Crm Account Sessionless

`POST /integrations/crm/lookup`

## Request

- Base URL: `https://dev.whispa.net` (the document declares no server; this is the origin it was published from)
- URL: `https://dev.whispa.net/integrations/crm/lookup`
- Auth: one of:
  - OAuth 2
    - Password
    - Token URL: `auth/bearer/login`
  - API key in cookie `access_token`

Read-only account lookup that needs no call session.

Backs pre-call tools (the payment calculator's loan-id lookup) so an agent
can pull account context before dialing. It never mutates state.

Because this path is not tied to a call the agent owns, it is deliberately
restricted to *exact record identifiers* (account number / customer id).
Broad demographic criteria (phone, email, name, DOB) and the creditor-wide
``client_id`` are rejected here: they turn a targeted pre-call lookup into a
tool for sweeping the customer book by matching partial PII. Those criteria
remain available on the session-scoped ``/sessions/{id}/crm/lookup`` route,
which is gated to a call the agent is actually handling. Every call is
audit-logged with the caller so bulk enumeration is attributable.

## Request body

- CrmLookupRequest
  - `phone` string, nullable: Phone number to match
  - `email` string, nullable: Email address to match
  - `name` string, nullable: Customer name to match
  - `dob` string, date, nullable: Date of birth to match
  - `account_number` string, nullable: Provider-side account number to match
  - `customer_id` string, nullable: Provider-side customer id to match
  - `client_id` string, nullable: Owning creditor / client id to match

## Response `200`

Successful Response

- CrmLookupResponse
  - `candidates` CrmAccountSummary[]
    - `provider` string, required
    - `id` string, required
    - `display_name` string, required
    - `phones` string[]
    - `address` string, nullable
    - `dob` string, date, nullable
    - `email` string, nullable
    - `ssn_last4` string, nullable
    - `postal_code` string, nullable
    - `account_number` string, nullable
    - `customer_id` string, nullable
    - `client_id` string, nullable
    - `matched_contact_type` string, nullable
    - `context` AccountContextRead: Wire shape for domain-shared account context (debt-collection state). Mirrors `src.crm.base.AccountContext`. Every field is optional because providers expose different subsets, and within a single provider some fields are only present when the underlying record has them set.
      - `product_name` string, nullable
      - `account_status` string, nullable
      - `account_status_disposition` 'workable' | 'not_workable' | 'resolved' | 'unknown': Provider-neutral meaning of a CRM's native account status. Providers keep their raw status in ``AccountContext.account_status`` for display and audit, then map it onto this small contract for autonomous outbound policy. Adding another CRM means adding its native-code mapping in that provider; the compliance gate never needs vendor status strings.
      - `collection_stage` 'open' | 'arrangement' | 'broken_arrangement' | 'paid' | 'settled' | 'excluded' | 'unknown': Provider-neutral collections-funnel position of a CRM's native status. Orthogonal to :class:`AccountStatusDisposition`, which answers "may the autonomous scheduler dial this account". The stage answers "where does this debt sit in the collections funnel" for reporting: an arrangement in place and a broken arrangement are both not-workable, but they are opposite outcomes on a performance dashboard. ``EXCLUDED`` marks accounts whose balance can move without money being collected (disputed, deceased, bankrupt, statute-barred), so recovery metrics can leave them out rather than count adjustments as payments.
      - `arrears_amount` number, nullable
      - `arrears_days` integer, nullable
      - `outstanding_amount` number, nullable
      - `original_balance` number, nullable
      - `amount_paid` number, nullable
      - `last_payment_date` string, date, nullable
      - `principal_outstanding` number, nullable
      - `referred_date` string, date, nullable
      - `interest_overdue` number, nullable
      - `interest_rate` number, nullable
      - `late_fees` number, nullable
      - `dishonour_fees` number, nullable
      - `settled_date` string, date, nullable
      - `cycle_day` integer, nullable
      - `repayment_amount` number, nullable
      - `repayment_frequency` string, nullable
      - `next_installment_amount` number, nullable
      - `next_installment_date` string, date, nullable
      - `has_hardship` boolean, nullable
      - `hardship_requested` boolean, nullable
      - `hardship_status` string, nullable
      - `hardship_notice_date` string, date, nullable
      - `active_arrangement_summary` string, nullable
      - `active_arrangement_status` string, nullable
      - `active_arrangement_next_amount` number, nullable
      - `active_arrangement_next_date` string, date, nullable
      - `collection_statuses` string[]
      - `risk_segmentation` string, nullable
      - `num_active_loans` integer, nullable
      - `num_broken_arrangements_last_6_months` integer, nullable
      - `num_dishonours_last_6_months` integer, nullable
      - `num_contacts_last_30_days` integer, nullable
      - `third_party_authority` boolean, nullable
      - `is_staff_account` boolean, nullable
      - `is_outsourced` boolean, nullable
      - `outsource_partner` string, nullable
      - `is_written_off` boolean, nullable
      - `joint_parties` JointPartyRead[]
        - `customer_id` string, nullable
        - `display_name` string, nullable
        - `relationship` string, nullable
      - `recent_transactions` LedgerEntryRead[]
        - `occurred_on` string, date, nullable
        - `description` string, nullable
        - `amount` number, nullable
        - `balance_after` number, nullable
        - `kind` string, nullable
      - `recent_contacts` ContactEventRead[]
        - `occurred_on` string, date, nullable
        - `description` string, nullable
        - `channel` string, nullable
        - `completed` boolean, nullable
        - `done_date` string, date, nullable
      - `recent_successful_contact_dates` string[]: Provider-classified successful contacts for outbound frequency caps; duplicate dates represent separate contacts.
      - `days_past_section_88` integer, nullable
      - `days_past_information_request` integer, nullable
      - `days_past_six_q` integer, nullable
  - `total_matched` integer
  - `truncated` boolean

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/whispa/apis/whispa-api.md) - [All operations](https://skmtc.dev/whispa/apis/whispa-api/llms.txt) - [OpenAPI document](https://skmtc.dev/whispa/apis/whispa-api/revisions/12c2e4aca43c?raw)
