Searching engagements

Common patterns for filtering engagements by CRM associations, contacts, companies, and transcript data
View as Markdown

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.

What the endpoint supports

The most common engagement search parameters are:

ParameterWhat 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.
expandIncludes related fields like companies, contacts, owner, signals, transcript, media_url, or tags.
order_bySorts by updated_at:asc or updated_at:desc.

Important behavior

For readability, docs examples use indexed bracket syntax, but the equivalent object shape is:

1[
2 { "id": "12345", "object_type": "company" },
3 { "id": "67890", "object_type": "contact" },
4 { "id": "deal_abc123", "object_type": "deal" }
5]

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:

$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_<id>.<secret>' \
> --header 'Accept: application/json'

Example: search by multiple CRM objects in one request:

$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_<id>.<secret>' \
> --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:

$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_<id>.<secret>' \
> --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:

$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_<id>.<secret>' \
> --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:

$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_<id>.<secret>' \
> --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.

There are two distinct patterns:

NeedRecommended call
Include transcript-related data in the engagement payloadGET /v2/engagements?...&expand=transcript
Retrieve the full transcript timeline entries with speaker timingGET /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:

$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_<id>.<secret>' \
> --header 'Accept: application/json'

Then fetch the transcript timeline for one engagement:

$curl --request GET \
> --url 'https://app.askelephant.ai/api/v2/engagements/ngmt_01JWAS.../transcript_timeline' \
> --header 'Authorization: sk-apik_<id>.<secret>' \
> --header 'Accept: application/json'

The transcript timeline endpoint requires the transcript_timelines:read scope.

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