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
contactorcompanyIDs - 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.
Every engagement object now includes is_private so your integration can see the privacy state of the engagements it is allowed to read.
What the endpoint supports
The most common engagement search parameters are:
Use the canonical filter names exactly as shown in the table. Legacy top-level aliases such as
company_id, top-level processing_status, sort, and order are rejected with 400
responses.
Important behavior
For readability, docs examples use indexed bracket syntax, but the equivalent object shape is:
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_idsand CRM company associations share the company bucket - AskElephant
contact_idsand 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:
Example: search by multiple CRM objects in one request:
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:
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:
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:
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 three distinct patterns:
expand=transcript returns an aggregated engagement text string (or null when no text is available). Depending on the engagement, it can include Markdown or HTML plus extracted text from completed attachments, so it is not guaranteed to contain only spoken transcript. It does not include speaker identity, timing, or sentence boundaries. Use it only for quick previews or full-text search over a single engagement.
For speaker-aware ingest — joining transcript text to workspace users or contacts, building per-speaker timelines, or exporting timed entries — use expand=transcript_timeline for paginated bulk reads or GET /v2/engagements/{engagement_id}/transcript_timeline for one engagement. Do not use expand=transcript as your primary ingest path.
expand=transcript_timeline returns the same structured transcript_timeline object as the per-engagement endpoint, embedded on each engagement in the list response. Engagements without a primary timeline return transcript_timeline: null. This expand requires transcript_timelines:read in addition to engagements:read. Each list request counts as one read against workspace rate limits. Pages with this expand are capped at 25 engagements, even when a larger limit is supplied.
For large backfills, paginate engagements with expand=transcript_timeline and limit=25 instead of issuing one timeline GET per engagement. See Bulk exports and incremental syncs for checkpoint and pagination guidance.
Example: search engagements and include plaintext transcript expansion:
Example: bulk-fetch structured timelines for a page of engagements:
To fetch a single engagement’s timeline without listing, use the dedicated endpoint:
Structured timeline reads require the transcript_timelines:read scope. If the engagement is private, they also require engagements:read and engagements:private:read.
Recommended search recipes
CRM-first integration
- Start with
filter[crm_associations][eq] - Add
filter[start_at][gte]orfilter[updated_at][gte]if you are narrowing to recent activity - Use
expand=contacts,companies,ownerif you want richer context in the search response - Use
expand=transcript_timelinewhen you need structured timelines for many engagements, or fetch/transcript_timelinefor individual engagement IDs
Contact activity timeline
- Use
filter[contact_ids][eq] - Add
filter[processing_status][eq]=COMPLETEDif you only want engagements with completed processing - Sort with
order_by=updated_at:desc - Use
expand=transcript_timelineto load structured timelines for the selected meetings or calls
Company account review
- Use
filter[company_ids][eq]orfilter[company_ids][in] - Add
filter[engagement_type][in]=MEETING,CALL - Expand
companies,contacts,owner,tags - Use
expand=transcript_timelineto load structured timelines for the specific engagements that matter
Practical notes
searchonly 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]andfilter[contact_ids][in]support up to 25 values each.expand=contactsadditionally requirescontacts:read.expand=owneradditionally requiresusers:read.engagements:readreturns only non-private engagements; includeengagements:private:readif your integration must read private engagements too.- Use
next_cursorto continue large result sets.
See also: Pagination and filtering