Build on the supported package contract
Use @absolutejs/engagement through its supported public entry points.
@absolutejs/engagementv0.0.8alphaCommerce & GrowthOne EngagementSource contract normalizing sales-engagement providers into enrichment plus outreach-activity data.
The EngagementSource contract plus normalized types for sales-engagement adapters. A platform like Apollo, Outreach, or Salesloft is two things at once — an enrichment source (who is this person or company) and an activity source (what outreach actually happened: emails sent, opened, replied; LinkedIn touches; calls) — and each adapter normalizes one provider to this single contract so a consuming app can pull both onto a unified deal timeline without knowing which vendor is behind it.
bun add @absolutejs/engagementProvider-neutral contracts for sales enrichment and outreach activity in AbsoluteJS. Applications depend on one EngagementSource; provider packages such as @absolutejs/engagement-apollo implement that contract.
The package manifest exposes a required engagement/source slot. The hosted AbsoluteJS.ai platform uses that slot to present compatible providers as configuration choices while keeping credentials in the environment and provider response shapes behind the shared contract.
@absolutejs/engagement-apollo
— Apollo person and company enrichment, role-based people search, and outreach activity.
One EngagementSource type covers enrichPerson, enrichCompany, searchPeople, and listActivities; every capability is optional so an adapter implements only what its provider and plan support.
NormalizedPerson and NormalizedCompany make every possibly-missing field explicitly null rather than optional, and preserve the untyped provider payload on raw.
EngagementActivity keeps the provider event name verbatim in kind while normalizing channel (call, email, linkedin, meeting, other) and direction as reliable axes.
searchPeople returns PersonSearchResult with revealsAttempted and searchRequests counts, so a metered caller bills the paid work that actually happened.
Adapters throw RateLimitError on an explicit provider rate limit so consumers can defer and retry; every other failure resolves to null or an empty list.
Outcomes
Use @absolutejs/engagement through its supported public entry points.
Hardening checklist
Follow in order
# @absolutejs/engagement
import type { EngagementSource } from "@absolutejs/engagement";
export const enrichLead = async (engagement: EngagementSource, email: string) =>
engagement.enrichPerson?.({ email });Consume a provider through the contract: enrich a person, then pull their normalized outreach activity — capabilities are optional, so check before calling.
import type { EngagementSource } from '@absolutejs/engagement';
import { apolloSource } from '@absolutejs/engagement-apollo';
const source: EngagementSource = apolloSource({
apiKey: process.env.APOLLO_API_KEY ?? ''
});
const person = await source.enrichPerson?.({
domain: 'acme.com',
name: 'Jane Doe'
});
const activities = await source.listActivities?.({
contactEmail: person?.emails[0],
since: '2026-01-01T00:00:00Z'
});
// → normalized touchpoints: channel, direction, kind
// ('email_sent', 'email_opened', 'email_replied', …)Provider adapters live in the engagement-adapters monorepo (Apache-2.0). Add a provider by implementing EngagementSource in a new workspace publishing as @absolutejs/engagement-<name> — the same shape as every other adapter monorepo in the ecosystem.
Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.
Thrown by an adapter when the provider reports a rate limit (e.g. HTTP 429), so a consumer can DEFER (retry when the window resets) instead of mistaking it for "no results found". Other failures still resolve to null/[] — only an explicit rate limit throws, because only it is meaningfully retryable-later.
class RateLimitError extends Error {
readonly provider: string;
constructor(provider: string);
}@absolutejs/engagement