Skip to content
Pathbound DOCS

Batch & Aggregate

When you need to look up many contacts at once, or roll events up by some dimension, paginating the list endpoints is wasteful. Use the batch and aggregate endpoints instead — both perform the work server-side and return a single response.

POST /v1/batch/details

Required scope: contacts:read (works for both contacts and companies).

Fetch up to 25 contacts or companies by ID in one request.

FieldTypeRequiredDescription
entity_typestringyescontacts or companies.
idsstring[]yesArray of 1–25 IDs.
Terminal window
curl -X POST https://api.pathbound.ai/v1/batch/details \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_type": "contacts",
"ids": ["ct_abc", "ct_def", "ct_ghi"]
}'
{
"status": "success",
"contacts": [ /* up to 25 contact objects */ ]
}

IDs that don’t exist (or belong to a different tenant) are silently dropped from the response.


POST /v1/batch/activity

Required scope: contacts:read.

Fetch recent events for up to 25 contacts in one request — without one busy contact starving the others. Each contact gets up to events_limit events independently.

FieldTypeRequiredDescription
contact_idsstring[]yesArray of 1–25 contact IDs.
events_limitnumbernoMax events per contact (1–20, default 5).
date_afterstringnoISO 8601 lower bound on timestamp.
date_beforestringnoISO 8601 upper bound on timestamp.
{
"status": "success",
"contact_count": 3,
"activity": {
"ct_abc": {
"events": [
{ "id": "evt_1", "event": "page_view", "url": "https://example.com/pricing", "timestamp": "...", "title": "Pricing" }
],
"total_events": 18
},
"ct_def": { "events": [], "total_events": 0 },
"ct_ghi": { "events": [ /* … */ ], "total_events": 4 }
}
}

Empty arrays are returned for contacts with no events in the window.


POST /v1/aggregate

Required scope: depends on entitycontacts:read, companies:read, or events:read.

Group-by aggregation across contacts, companies, or events, with optional filters and metrics. This is the engine behind dashboard charts and aggregate_data in MCP.

FieldTypeRequiredDescription
entitystringyescontacts, companies, or events.
group_bystringyesField to group on (e.g. lifecycle_stage, industry, country, event_type, domain, day).
filtersobjectnoEntity-specific filters applied before grouping.
metricstringnocount (default), avg, sum, min, max.
metric_fieldstringnoRequired for non-count metrics — the field to aggregate.
limitnumbernoMax buckets returned (1–50, default 25).
  • Contacts: lifecycle_stage, lead_status, country, industry, city, state, job_title, company_id, created_day, has_linkedin.
  • Companies: industry, country, lifecycle_stage, employee_band.
  • Events: event_type, domain, day, contact_id.
  • Contacts: lifecycle_stage, industry, country, created_after, created_before, segment_id, contact_ids (capped at 100).
  • Events: event_type, domain, date_after, date_before, identified_only, contact_id.

Example — events per day for the last 30 days

Section titled “Example — events per day for the last 30 days”
Terminal window
curl -X POST https://api.pathbound.ai/v1/aggregate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity": "events",
"group_by": "day",
"filters": {
"event_type": "page_view",
"date_after": "2026-03-30T00:00:00Z"
},
"metric": "count",
"limit": 30
}'
{
"status": "success",
"entity": "events",
"group_by": "day",
"metric": "count",
"buckets": [
{ "key": "2026-04-29", "value": 432 },
{ "key": "2026-04-28", "value": 511 }
],
"total": 11_900
}