---
title: "Search Accounts"
method: GET
path: "/accounts/search"
tags: ["accounts"]
---

# Search Accounts

`GET /accounts/search`

## 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/accounts/search`
- Auth: one of:
  - OAuth 2
    - Password
    - Token URL: `auth/bearer/login`
  - API key in cookie `access_token`

Paginated, filterable working set of the active CRM provider (admin
only). Backs the Accounts table and the campaign add-accounts picker.

## Query parameters

- `sort_by` 'display_name' | 'account_number' | 'phone' | 'account_status' | 'outstanding_amount' | 'arrears_amount' | 'last_activity_at' | 'synced_at' | 'created_at': Column to sort by: display_name, account_number, phone, account_status, outstanding_amount, arrears_amount, last_activity_at, synced_at, created_at.
- `sort_order` 'asc' | 'desc': Sort direction: asc or desc.
- `page` integer
- `size` integer
- `demo_market` 'au' | 'us', nullable
- `q` string, nullable: Free-text search (case-insensitive) across display name, account number, email, external id and phone.
- `status` string[], nullable: Provider status values to include (case-insensitive, repeatable). Omit for every status.
- `campaign_id` string, uuid, nullable: Only accounts with a membership in this campaign.
- `campaign_assignment` 'assigned' | 'unassigned' | 'multiple' | 'review', nullable: Filter by current campaign assignment count, or 'review' for accounts waiting on an operator decision.
- `timezone_status` 'unknown' | 'manual', nullable: 'unknown': no timezone, so the gate will not call the account. 'manual': an operator set the timezone.
- `called` 'account' | 'customer' | 'never', nullable: 'account': a call is linked to this account. 'customer': a call is linked to this account or another account of the same customer. 'never': neither.
- `min_balance` number, nullable: Inclusive lower bound on outstanding amount.
- `max_balance` number, nullable: Inclusive upper bound on outstanding amount.
- `min_arrears` number, nullable: Inclusive lower bound on arrears amount.
- `max_arrears` number, nullable: Inclusive upper bound on arrears amount.

## Response `200`

Successful Response

- PageAccountSearchRead
  - `items` AccountSearchRead[], required
    - `id` string, uuid, required
    - `provider` string, required
    - `external_id` string, required
    - `display_name` string, required
    - `account_number` string, nullable
    - `email` string, nullable
    - `address` string, nullable
    - `dob` string, date, nullable
    - `customer_id` string, nullable
    - `client_id` string, nullable
    - `phone` string, nullable
    - `phones` string[]
    - `state` string, nullable
    - `timezone` string, nullable
    - `manual_timezone` string, nullable
    - `manual_timezone_set_by` string, uuid, nullable
    - `manual_timezone_set_by_email` string, nullable
    - `manual_timezone_set_at` string, date-time, nullable
    - `status` string, nullable
    - `balance` number, nullable
    - `arrears_amount` number, nullable
    - `original_balance` number, nullable
    - `amount_paid` number, nullable
    - `collection_stage` 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
    - `data_source` 'crm' | 'csv'
    - `source_filename` string, nullable
    - `source_data` object, nullable
    - `suppression_reason` string, nullable
    - `suppressed_at` string, date-time, nullable
    - `suppression_released_reason` string, nullable
    - `suppression_released_by` string, uuid, nullable
    - `suppression_released_by_email` string, nullable
    - `suppression_released_at` string, date-time, nullable
    - `synced_at` string, date-time, required
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
    - `last_activity_at` string, date-time, nullable
    - `customer_last_activity_at` string, date-time, nullable
    - `can_call_now` boolean, required
    - `next_callable_at` string, date-time, nullable
    - `callability_reason` string, nullable
    - `callability_detail` string, nullable
    - `campaign_memberships` AccountCampaignMembershipRead[]
      - `id` string, uuid, required
      - `campaign_id` string, uuid, required
      - `campaign_name` string, required
      - `campaign_status` string, required
      - `account_status` string, required
      - `archived_at` string, date-time, nullable
    - `suppression_releasable` boolean, required: Whether an operator may clear the hold: a creditor file's is the file's to lift.
  - `total` integer, required
  - `page` integer, required
  - `size` integer, required
  - `pages` integer, required

## 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)
