*** title: Searching engagements subtitle: >- Common patterns for filtering engagements by CRM associations, contacts, companies, and transcript data slug: searching-engagements --------------------------- `GET /v2/engagements` is the main search surface for engagement discovery. Use it when you need to: * Find engagements linked to CRM records such as deals, companies, or contacts * Find engagements for known AskElephant `contact` or `company` IDs * Narrow results by time window, processing state, or engagement type * Load related engagement details before fetching transcript timelines If you specifically want CRM company, contact, or deal examples, see [Filter engagements by CRM object IDs](/filtering-engagements-by-crm-object-ids). ## What the endpoint supports The most common engagement search parameters are: | Parameter | What it does | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | `filter[crm_associations][eq]` | Matches engagements linked to one or more CRM objects. | | `filter[contact_ids][eq\|in]` | Matches engagements linked to AskElephant contact IDs. | | `filter[company_ids][eq\|in]` | Matches engagements linked to AskElephant company IDs. | | `filter[start_at][gt\|gte\|lt\|lte]` | Narrows by engagement start time. | | `filter[updated_at][gt\|gte\|lt\|lte]` | Narrows by last update time. | | `filter[processing_status][eq\|in]` | Filters by transcript or analysis processing state. | | `filter[engagement_type][eq\|in]` | Filters by engagement type such as `MEETING` or `CALL`. | | `expand` | Includes related fields like `companies`, `contacts`, `owner`, `signals`, `transcript`, `media_url`, or `tags`. | | `order_by` | Sorts by `updated_at:asc` or `updated_at:desc`. | ## Important behavior For readability, docs examples use indexed bracket syntax, but the equivalent object shape is: ```json [ { "id": "12345", "object_type": "company" }, { "id": "67890", "object_type": "contact" }, { "id": "deal_abc123", "object_type": "deal" } ] ``` Single-object examples: * CRM company ID: `{ "id": "12345", "object_type": "company" }` * CRM contact ID: `{ "id": "67890", "object_type": "contact" }` * CRM deal ID: `{ "id": "deal_abc123", "object_type": "deal" }` The CRM source is inferred from the workspace's connected CRM. You do not pass a separate `source` query parameter. Engagement filters combine like this: * Values in the same bucket use OR semantics * Populated buckets combine with AND semantics * AskElephant `company_ids` and CRM company associations share the company bucket * AskElephant `contact_ids` and CRM contact associations share the participant bucket * CRM deal associations populate a deal bucket That means you can search for: * Any engagement related to one of several contacts * Any engagement related to one of several CRM deals * Engagements that match both a company bucket and a participant bucket ## Search by CRM object ID Use `filter[crm_associations][eq]` when your system already knows the CRM record IDs and you want the related engagements. When using raw `filter[...]` query params with `curl`, add `--globoff` so `curl` does not interpret `[]` as URL globbing syntax. Example: find engagements linked to a CRM deal: ```bash curl --request GET \ --globoff \ --url 'https://app.askelephant.ai/api/v2/engagements?filter[crm_associations][eq][0][id]=deal_123&filter[crm_associations][eq][0][object_type]=deal&order_by=updated_at:desc&limit=25' \ --header 'Authorization: sk-apik_.' \ --header 'Accept: application/json' ``` Example: search by multiple CRM objects in one request: ```bash curl --request GET \ --globoff \ --url 'https://app.askelephant.ai/api/v2/engagements?filter[crm_associations][eq][0][id]=deal_123&filter[crm_associations][eq][0][object_type]=deal&filter[crm_associations][eq][1][id]=contact_456&filter[crm_associations][eq][1][object_type]=contact&order_by=updated_at:desc&limit=25' \ --header 'Authorization: sk-apik_.' \ --header 'Accept: application/json' ``` Use this pattern when your integration starts from Salesforce, HubSpot, or another CRM and you need to map back to AskElephant engagements. ## Search by AskElephant company IDs Use `filter[company_ids][eq]` or `filter[company_ids][in]` when you already have AskElephant company IDs. Example: ```bash curl --request GET \ --globoff \ --url 'https://app.askelephant.ai/api/v2/engagements?filter[company_ids][in]=cmp_01HQXVB4Y9Y0Q6P0QH5GX2CT7T,cmp_01HQXVB4Y9Y0Q6P0QH5GX2CT7U&expand=companies,owner&order_by=updated_at:desc&limit=25' \ --header 'Authorization: sk-apik_.' \ --header 'Accept: application/json' ``` This is useful when your app stores AskElephant company IDs directly and wants all engagement activity around one or more companies. ## Search by AskElephant contact IDs Use `filter[contact_ids][eq]` or `filter[contact_ids][in]` when you know the AskElephant contact IDs. Example: ```bash curl --request GET \ --globoff \ --url 'https://app.askelephant.ai/api/v2/engagements?filter[contact_ids][eq]=cnt_01HQY3JMS2QAXJGX6X7CH7CM6X&expand=contacts,owner&order_by=updated_at:desc&limit=25' \ --header 'Authorization: sk-apik_.' \ --header 'Accept: application/json' ``` This is the cleanest path when a user is already looking at a known AskElephant contact record and wants the related meetings, calls, emails, or notes. ## Combine company, contact, and CRM filters You can combine filters to narrow results further. Example: find engagements that are tied to a specific company, a specific contact, and a CRM deal: ```bash curl --request GET \ --globoff \ --url 'https://app.askelephant.ai/api/v2/engagements?filter[company_ids][eq]=cmp_01HQXVB4Y9Y0Q6P0QH5GX2CT7T&filter[contact_ids][eq]=cnt_01HQY3JMS2QAXJGX6X7CH7CM6X&filter[crm_associations][eq][0][id]=deal_123&filter[crm_associations][eq][0][object_type]=deal&filter[start_at][gte]=2026-03-01T00:00:00.000Z&order_by=updated_at:desc&limit=25' \ --header 'Authorization: sk-apik_.' \ --header 'Accept: application/json' ``` This is useful for account-level timeline views where you want only the subset of engagements that match a particular relationship context. ## Loading transcript-related data There are two distinct patterns: | Need | Recommended call | | ----------------------------------------------------------------- | --------------------------------------------------------- | | Include transcript-related data in the engagement payload | `GET /v2/engagements?...&expand=transcript` | | Retrieve the full transcript timeline entries with speaker timing | `GET /v2/engagements/{engagement_id}/transcript_timeline` | If you want full transcript timeline entries, first search engagements, then fetch timelines by the returned engagement IDs. Example: search engagements and include transcript expansion: ```bash curl --request GET \ --globoff \ --url 'https://app.askelephant.ai/api/v2/engagements?filter[contact_ids][eq]=cnt_01HQY3JMS2QAXJGX6X7CH7CM6X&filter[processing_status][eq]=COMPLETED&expand=transcript,contacts,companies&order_by=updated_at:desc&limit=10' \ --header 'Authorization: sk-apik_.' \ --header 'Accept: application/json' ``` Then fetch the transcript timeline for one engagement: ```bash curl --request GET \ --url 'https://app.askelephant.ai/api/v2/engagements/ngmt_01JWAS.../transcript_timeline' \ --header 'Authorization: sk-apik_.' \ --header 'Accept: application/json' ``` The transcript timeline endpoint requires the `transcript_timelines:read` scope. ## Recommended search recipes ### CRM-first integration 1. Start with `filter[crm_associations][eq]` 2. Add `filter[start_at][gte]` or `filter[updated_at][gte]` if you are narrowing to recent activity 3. Use `expand=contacts,companies,owner` if you want richer context in the search response 4. Fetch `/transcript_timeline` only for the engagement IDs you actually need ### Contact activity timeline 1. Use `filter[contact_ids][eq]` 2. Add `filter[processing_status][eq]=COMPLETED` if you only want engagements with completed processing 3. Sort with `order_by=updated_at:desc` 4. Fetch transcript timelines for the selected meetings or calls ### Company account review 1. Use `filter[company_ids][eq]` or `filter[company_ids][in]` 2. Add `filter[engagement_type][in]=MEETING,CALL` 3. Expand `companies,contacts,owner,tags` 4. Load transcript timelines for the specific engagements that matter ## Practical notes * `search` only matches engagement titles. It does not search transcript text, contact names, company names, descriptions, or CRM fields. * `filter[crm_associations][eq]` supports up to 20 CRM association objects. * `filter[company_ids][in]` and `filter[contact_ids][in]` support up to 25 values each. * `expand=contacts` additionally requires `contacts:read`. * `expand=owner` additionally requires `users:read`. * Use `next_cursor` to continue large result sets. See also: [Pagination and filtering](/pagination)