AdCP interop
Why
AdCP is an MCP-based standard for agentic advertising. Buy-side agents speak its measurement vocabulary. adscapi covers the measurement side — not media-buy. You still fire conversions with track; these helpers translate what came back.
Schema pin: dist/schemas/3.1.13 (provide-performance-feedback-request.json). Taxonomy: AdCP measurement taxonomy.
Measurements
toAdcpMeasurements emits one (metric_id, value) tuple per present finite number. Absent fields are omitted. 0 is present.
import { toAdcpMeasurements } from 'adscapi';
const rows = await getReport('meta', secrets, { since: '2026-04-01', until: '2026-04-08' });
const totals = rows.reduce(
(acc, r) => ({
conversions: (acc.conversions ?? 0) + (r.conversions ?? 0),
conversionValue: (acc.conversionValue ?? 0) + (r.conversionValue ?? 0),
spend: (acc.spend ?? 0) + r.spend,
impressions: (acc.impressions ?? 0) + r.impressions,
roas: r.roas,
}),
{} as { conversions?: number; conversionValue?: number; spend?: number; impressions?: number; roas?: number },
);
const measurements = toAdcpMeasurements(totals);
// [{ metric_id: 'conversions', value }, { metric_id: 'spend', value }, …]Accepted input keys: conversions, conversionValue (→ conversion_value), spend, impressions, clicks, roas, cpa.
One destination result
conversionToAdcpEvent represents a single track result as a conversion measurement. value is always 1. occurred is true only on a real successful send — dryRun and errors are occurred: false.
import { conversionToAdcpEvent } from 'adscapi';
const results = await ads.conversions.track(event);
const mapped = results.map((r) => conversionToAdcpEvent(r, event));event_id is copied from event.eventId when present, otherwise omitted.
Performance feedback
toPerformanceFeedback shapes the AdCP provide_performance_feedback request body. Required: idempotencyKey, mediaBuyId, measurementPeriod, performanceIndex. Defaults adcp_version to 3.1 and feedback_source to buyer_attribution.
import { toPerformanceFeedback } from 'adscapi';
const body = toPerformanceFeedback({
mediaBuyId: 'mb-9',
idempotencyKey: 'adscapi-feedback-01',
measurementPeriod: { start: '2026-04-01T00:00:00Z', end: '2026-04-08T00:00:00Z' },
performanceIndex: 1.2,
});Optional: packageId, creativeId, metricType, feedbackSource, adcpVersion, adcpMajorVersion, context, ext. This emits the request body. You POST it on the AdCP transport yourself.
Notes
- Measurement interop only. adscapi does not place or mutate media buys.
toAdcpMeasurements/conversionToAdcpEventdo not invent extra wire fields.metric_typeon the feedback request is the legacy enum from schema 3.1.13 (overall_performance,conversion_rate, …) and is marked deprecated in-schema.
Related
- Reporting —
getReportis the usual input totoAdcpMeasurements - conversions.track() — map each destination result with
conversionToAdcpEvent