@adcp/sdk 7.10.2 → 7.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compliance/cache/3.1.0-rc.2/domains/brand/index.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/distributed_brand_resolution.yaml +415 -0
- package/compliance/cache/3.1.0-rc.2/domains/brand/scenarios/single_side_trust_extension.yaml +454 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/index.yaml +339 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/billing_out_of_band.yaml +153 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/canonical_supported_formats.yaml +212 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
- package/compliance/cache/3.1.0-rc.2/domains/creative/scenarios/native_in_feed.yaml +543 -0
- package/compliance/cache/3.1.0-rc.2/domains/governance/index.yaml +682 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/index.yaml +789 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/audience_buy_flow.yaml +380 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/available_actions.yaml +565 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/canonical_formats.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/create_media_buy_async.yaml +234 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/creative_reception.yaml +247 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/delivery_reporting.yaml +357 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment.yaml +633 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/event_dedup_flow.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_approved.yaml +214 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_conditions.yaml +199 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied.yaml +204 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/invalid_transitions.yaml +289 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_accountability.yaml +244 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow.yaml +428 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/product_signal_targeting.yaml +373 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_enforcement.yaml +517 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/reach_buy_flow.yaml +823 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
- package/compliance/cache/3.1.0-rc.2/domains/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.1.0-rc.2/domains/signals/index.yaml +266 -0
- package/compliance/cache/3.1.0-rc.2/domains/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.1.0-rc.2/index.json +356 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/index.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/distributed_brand_resolution.yaml +415 -0
- package/compliance/cache/3.1.0-rc.2/protocols/brand/scenarios/single_side_trust_extension.yaml +454 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/index.yaml +339 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/billing_out_of_band.yaml +153 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/canonical_supported_formats.yaml +212 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/creative_lifecycle_webhooks.yaml +389 -0
- package/compliance/cache/3.1.0-rc.2/protocols/creative/scenarios/native_in_feed.yaml +543 -0
- package/compliance/cache/3.1.0-rc.2/protocols/governance/index.yaml +682 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/index.yaml +789 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/audience_buy_flow.yaml +380 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/available_actions.yaml +565 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/billing_finality_delivery.yaml +354 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/canonical_formats.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/clicks_buy_flow.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/completed_views_buy_flow.yaml +344 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/create_media_buy_async.yaml +234 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_fate_after_cancellation.yaml +419 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/creative_reception.yaml +247 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/delivery_reporting.yaml +357 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment.yaml +633 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/dependency_impairment_cardinality.yaml +800 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/event_dedup_flow.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/frequency_cap_enforcement.yaml +309 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_approved.yaml +214 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_conditions.yaml +199 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied.yaml +204 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/governance_denied_recovery.yaml +252 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/invalid_transitions.yaml +289 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_no_match.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/inventory_list_targeting.yaml +276 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_accountability.yaml +244 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/measurement_terms_rejected.yaml +203 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/package_correlation_legacy_fallback.yaml +113 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/pending_creatives_to_start.yaml +292 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/per_creative_conversion_attribution.yaml +500 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow.yaml +428 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/performance_buy_flow_roas.yaml +470 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/product_signal_targeting.yaml +373 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize.yaml +399 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_finalize_asap_timing.yaml +264 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/proposal_not_found_errors.yaml +257 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_audit_observation.yaml +333 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_enforcement.yaml +517 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/provenance_truth_of_claim.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/reach_buy_flow.yaml +823 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_finalize_exclusivity.yaml +360 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/refine_products.yaml +148 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_accountability.yaml +293 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_catalog_precondition.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/scenarios/vendor_metric_optimization_flow.yaml +576 -0
- package/compliance/cache/3.1.0-rc.2/protocols/media-buy/state-machine.yaml +442 -0
- package/compliance/cache/3.1.0-rc.2/protocols/signals/index.yaml +266 -0
- package/compliance/cache/3.1.0-rc.2/protocols/sponsored-intelligence/index.yaml +256 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/audience-sync/index.yaml +313 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/index.yaml +350 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/brand-rights/scenarios/governance_denied.yaml +226 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/collection-lists/index.yaml +359 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/content-standards/index.yaml +572 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-ad-server/index.yaml +409 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/generative-seller.yaml +807 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-generative/index.yaml +758 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/creative-template/index.yaml +510 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/index.yaml +143 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-aware-seller/scenarios/governance_multi_agent_rejected.yaml +117 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-delivery-monitor/index.yaml +441 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/denied.yaml +221 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/governance-spend-authority/index.yaml +330 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/property-lists/index.yaml +482 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-broadcast-tv/index.yaml +738 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-catalog-driven/index.yaml +840 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-guaranteed/index.yaml +601 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-non-guaranteed/index.yaml +546 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-proposal-mode/index.yaml +586 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sales-social/index.yaml +919 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/index.yaml +424 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-marketplace/scenarios/governance_denied.yaml +210 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/signal-owned/index.yaml +317 -0
- package/compliance/cache/3.1.0-rc.2/specialisms/sponsored-intelligence/index.yaml +59 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor-live.yaml +78 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/acme-outdoor.yaml +223 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/billing-gate-runner.yaml +115 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/bistro-oranje.yaml +126 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/distributed-brand-runner.yaml +281 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/nova-motors.yaml +262 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/osei-natural.yaml +126 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/parallel-dispatch-runner.yaml +196 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/rate-limit-trip-runner.yaml +172 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/signed-requests-runner.yaml +155 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/single-side-trust-runner.yaml +294 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/substitution-observer-runner.yaml +688 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/summit-foods.yaml +125 -0
- package/compliance/cache/3.1.0-rc.2/test-kits/webhook-receiver-runner.yaml +265 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/001-minimal-plan.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/002-full-plan.json +217 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/003-bookkeeping-stripped.json +60 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004a-human-review-omitted.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/004b-human-review-explicit-null.json +49 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005a-policy-categories-order-1.json +53 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/005b-policy-categories-order-2.json +57 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006a-ext-trace-v1.json +49 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/006b-ext-trace-v2.json +53 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/007-unicode-objectives.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/plan-hash/008-numeric-canonicalization.json +65 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/README.md +220 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/canonicalization.json +241 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/keys.json +60 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/001-no-signature-header.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/002-wrong-tag.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/003-expired-signature.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/004-window-too-long.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/005-alg-not-allowed.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/006-missing-covered-component.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/007-missing-content-digest.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/008-unknown-keyid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/009-key-ops-missing-verify.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/010-content-digest-mismatch.json +33 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/011-malformed-header.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/013-expires-le-created.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/014-missing-nonce-param.json +27 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/015-signature-invalid.json +28 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/016-replayed-nonce.json +35 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/017-key-revoked.json +38 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/018-digest-covered-when-forbidden.json +28 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/019-signature-without-signature-input.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/020-rate-abuse.json +34 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/021-duplicate-signature-input-label.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/022-multi-valued-content-type.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/023-multi-valued-content-digest.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/024-unquoted-string-param.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/025-jwk-alg-crv-mismatch.json +43 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/026-non-ascii-host.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/027-webhook-registration-authentication-unsigned.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/negative/028-unsigned-protocol-method-required.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/001-basic-post.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/002-post-with-content-digest.json +31 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/003-es256-post.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/004-multiple-signature-labels.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/005-default-port-stripped.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/006-dot-segment-path.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/007-query-byte-preserved.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/008-percent-encoded-path.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/009-percent-encoded-unreserved-decoded.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/010-percent-encoded-slash-preserved.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/011-ipv6-authority.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/request-signing/positive/012-ipv6-authority-default-port-stripped.json +30 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/README.md +211 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/keys.json +61 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/001-wrong-tag.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/002-expired-signature.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/003-window-too-long.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/004-alg-not-allowed.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/005-missing-authority-component.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/006-missing-content-digest.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/007-unknown-keyid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/008-wrong-adcp-use.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/009-content-digest-mismatch.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/010-malformed-signature-input.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/011-signature-without-input.json +25 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/012-missing-expires-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/013-expires-le-created.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/014-missing-nonce-param.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/015-signature-invalid.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/016-replayed-nonce.json +37 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/017-key-revoked.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/018-rate-abuse.json +33 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/019-revocation-stale.json +32 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/020-key-ops-missing-verify.json +41 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/negative/021-base64-alphabet-mixing.json +26 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/001-basic-post.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/002-es256-post.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/003-multiple-signature-labels.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/004-default-port-stripped.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/005-percent-encoded-path.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/006-query-byte-preserved.json +24 -0
- package/compliance/cache/3.1.0-rc.2/test-vectors/webhook-signing/positive/007-body-without-idempotency-key.json +25 -0
- package/compliance/cache/3.1.0-rc.2/universal/billing-gate-dispatch.yaml +450 -0
- package/compliance/cache/3.1.0-rc.2/universal/canonical-format-validate-input.yaml +640 -0
- package/compliance/cache/3.1.0-rc.2/universal/capability-discovery.yaml +125 -0
- package/compliance/cache/3.1.0-rc.2/universal/collection-lists-pagination-integrity.yaml +306 -0
- package/compliance/cache/3.1.0-rc.2/universal/comply-controller-mode-gate.yaml +141 -0
- package/compliance/cache/3.1.0-rc.2/universal/content-standards-pagination-integrity.yaml +326 -0
- package/compliance/cache/3.1.0-rc.2/universal/deterministic-testing.yaml +1430 -0
- package/compliance/cache/3.1.0-rc.2/universal/error-compliance-signals.yaml +377 -0
- package/compliance/cache/3.1.0-rc.2/universal/error-compliance.yaml +528 -0
- package/compliance/cache/3.1.0-rc.2/universal/fictional-entities.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/universal/get-media-buys-pagination-integrity.yaml +160 -0
- package/compliance/cache/3.1.0-rc.2/universal/get-signals-pagination-integrity.yaml +210 -0
- package/compliance/cache/3.1.0-rc.2/universal/idempotency.yaml +861 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-event-scope.yaml +119 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-lifecycle.yaml +337 -0
- package/compliance/cache/3.1.0-rc.2/universal/notification-config-rejections.yaml +107 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-creative-formats.yaml +265 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity-list-accounts.yaml +245 -0
- package/compliance/cache/3.1.0-rc.2/universal/pagination-integrity.yaml +263 -0
- package/compliance/cache/3.1.0-rc.2/universal/property-lists-pagination-integrity.yaml +307 -0
- package/compliance/cache/3.1.0-rc.2/universal/read-tool-idempotency.yaml +405 -0
- package/compliance/cache/3.1.0-rc.2/universal/runner-output-contract.yaml +1285 -0
- package/compliance/cache/3.1.0-rc.2/universal/schema-validation-signals.yaml +181 -0
- package/compliance/cache/3.1.0-rc.2/universal/schema-validation.yaml +548 -0
- package/compliance/cache/3.1.0-rc.2/universal/security.yaml +539 -0
- package/compliance/cache/3.1.0-rc.2/universal/signed-requests.yaml +217 -0
- package/compliance/cache/3.1.0-rc.2/universal/stale-response-advisory.yaml +295 -0
- package/compliance/cache/3.1.0-rc.2/universal/storyboard-schema.yaml +2194 -0
- package/compliance/cache/3.1.0-rc.2/universal/v3-envelope-integrity.yaml +117 -0
- package/compliance/cache/3.1.0-rc.2/universal/version-negotiation.yaml +130 -0
- package/compliance/cache/3.1.0-rc.2/universal/webhook-emission.yaml +411 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-bulk-webhooks.yaml +82 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-product-webhooks.yaml +83 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-products.yaml +151 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signal-webhooks.yaml +83 -0
- package/compliance/cache/3.1.0-rc.2/universal/wholesale-feed-signals.yaml +149 -0
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +9 -5
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/storyboard/default-invariants.js +30 -1
- package/dist/lib/testing/storyboard/default-invariants.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +84 -21
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/types.d.ts +21 -0
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/types.d.ts +9 -0
- package/dist/lib/testing/types.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.d.ts +6707 -12040
- package/dist/lib/types/schemas.generated.d.ts.map +1 -1
- package/dist/lib/types/schemas.generated.js +1 -1
- package/dist/lib/types/schemas.generated.js.map +1 -1
- package/dist/lib/utils/signal-id-builders.d.ts +19 -0
- package/dist/lib/utils/signal-id-builders.d.ts.map +1 -1
- package/dist/lib/utils/signal-id-builders.js +30 -0
- package/dist/lib/utils/signal-id-builders.js.map +1 -1
- package/dist/lib/utils/tool-request-schemas.d.ts.map +1 -1
- package/dist/lib/utils/tool-request-schemas.js +3 -0
- package/dist/lib/utils/tool-request-schemas.js.map +1 -1
- package/dist/lib/v2/projection/constants.d.ts +28 -0
- package/dist/lib/v2/projection/constants.d.ts.map +1 -0
- package/dist/lib/v2/projection/constants.js +31 -0
- package/dist/lib/v2/projection/constants.js.map +1 -0
- package/dist/lib/v2/projection/registry.d.ts.map +1 -1
- package/dist/lib/v2/projection/registry.js +9 -4
- package/dist/lib/v2/projection/registry.js.map +1 -1
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +1 -1
- package/skills/SHAPE-GOTCHAS.md +5 -0
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
id: media_buy_seller/per_creative_conversion_attribution
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Seller surfaces per-creative conversion attribution in delivery reporting"
|
|
4
|
+
category: media_buy_seller
|
|
5
|
+
summary: "Verifies that a seller advertising conversion_tracking.per_creative_attribution can register two creatives on a single package, accept a media buy with a CPA event-kind goal, ingest conversion events, and surface a populated by_package[].by_creative[] breakdown carrying conversions per creative in get_media_buy_delivery. Sibling to media_buy_seller/performance_buy_flow gated on the per_creative_attribution sub-capability: sellers that report attribution only at the line / package / placement / campaign granularity (retail-media, MMP-mediated mobile, CTV performance) grade not_applicable, not failing."
|
|
6
|
+
track: media_buy
|
|
7
|
+
|
|
8
|
+
# Gate: scenario runs only when the seller declares
|
|
9
|
+
# conversion_tracking.per_creative_attribution equals true. Sellers that
|
|
10
|
+
# attribute at coarser granularity (retail-media per-line, MMP per-campaign,
|
|
11
|
+
# broadcast/CTV per-placement) grade `not_applicable`, not failing.
|
|
12
|
+
# per_creative_attribution is a sub-capability of conversion_tracking — gating
|
|
13
|
+
# on this bit rather than on conversion_tracking presence is what keeps
|
|
14
|
+
# honest coarser-granularity implementations from failing on the per-creative
|
|
15
|
+
# breakdown that performance_buy_flow deliberately defers.
|
|
16
|
+
requires_capability:
|
|
17
|
+
path: media_buy.conversion_tracking.per_creative_attribution
|
|
18
|
+
equals: true
|
|
19
|
+
|
|
20
|
+
required_tools:
|
|
21
|
+
- get_products
|
|
22
|
+
- sync_event_sources
|
|
23
|
+
- sync_creatives
|
|
24
|
+
- create_media_buy
|
|
25
|
+
- log_event
|
|
26
|
+
- get_media_buy_delivery
|
|
27
|
+
- comply_test_controller
|
|
28
|
+
|
|
29
|
+
invariants:
|
|
30
|
+
- status.monotonic
|
|
31
|
+
|
|
32
|
+
narrative: |
|
|
33
|
+
Per-creative conversion attribution is the discriminating capability of
|
|
34
|
+
sellers whose attribution pipelines can route a logged conversion back to
|
|
35
|
+
the specific creative that drove it — typically via internal click-id or
|
|
36
|
+
view-through correlation that ties the event to the served impression. When
|
|
37
|
+
the seller advertises per_creative_attribution: true, buyers can rely on
|
|
38
|
+
the by_package[].by_creative[] breakdown in delivery reporting carrying
|
|
39
|
+
conversions per creative, not just aggregate package totals.
|
|
40
|
+
|
|
41
|
+
Most performance sellers cannot do this. Retail-media networks (Criteo,
|
|
42
|
+
Amazon Ads) typically expose conversions at the line level with creative
|
|
43
|
+
rotation opaque. MMP-mediated mobile (post-iOS-14) attributes at the
|
|
44
|
+
campaign / ad-set level. Broadcast and CTV performance products attribute
|
|
45
|
+
at the placement. Gating this scenario on the explicit sub-capability bit
|
|
46
|
+
is what keeps honest coarser-granularity implementations from failing on a
|
|
47
|
+
breakdown they truthfully don't produce.
|
|
48
|
+
|
|
49
|
+
This is the deferred half of performance_buy_flow. The CPA scenario
|
|
50
|
+
deliberately omits per-creative assertions for exactly this reason —
|
|
51
|
+
honest adopters report at differing granularities. The bit gates the
|
|
52
|
+
scenario; the scenario asserts the breakdown is populated end-to-end.
|
|
53
|
+
|
|
54
|
+
Discriminating behaviors this scenario verifies:
|
|
55
|
+
1. sync_creatives registers two distinct creatives on the buyer's account,
|
|
56
|
+
each with its own creative_id and shape-valid display assets.
|
|
57
|
+
2. create_media_buy accepts a package whose creative_assignments references
|
|
58
|
+
BOTH creatives and whose optimization_goal is event-kind with a CPA
|
|
59
|
+
target — the seller commits to rotating across both creatives AND
|
|
60
|
+
attributing conversions per creative.
|
|
61
|
+
3. log_event flows conversions back against the registered event source.
|
|
62
|
+
log_event does not carry creative_id on the event payload (core/event.json) —
|
|
63
|
+
the seller MUST attribute via its internal click / view-through
|
|
64
|
+
correlation. Two events with distinct event_ids are logged; the seller
|
|
65
|
+
spreads attributed conversions across the two creatives per its own
|
|
66
|
+
correlation, and simulate_delivery's conversions count drives the
|
|
67
|
+
totals.
|
|
68
|
+
4. get_media_buy_delivery returns the by_package[].by_creative[] breakdown
|
|
69
|
+
populated for BOTH creatives, each carrying creative_id and conversions.
|
|
70
|
+
The discriminating signal is the second row — a single-row breakdown
|
|
71
|
+
covering only one of the two assigned creatives would be a façade
|
|
72
|
+
(matching the impression rotation but not the conversion attribution).
|
|
73
|
+
|
|
74
|
+
Per-creative conversion_value / roas breakdown is intentionally NOT
|
|
75
|
+
asserted here. Sellers that compute ROAS at the creative level can declare
|
|
76
|
+
the per_creative_attribution bit and surface conversion_value on each
|
|
77
|
+
by_creative row, but the assertion target of this scenario is conversion
|
|
78
|
+
attribution (the field the bit names); per-creative value is a strict
|
|
79
|
+
superset that doesn't need an additional gate.
|
|
80
|
+
|
|
81
|
+
agent:
|
|
82
|
+
interaction_model: media_buy_seller
|
|
83
|
+
capabilities:
|
|
84
|
+
- sells_media
|
|
85
|
+
- supports_non_guaranteed
|
|
86
|
+
- conversion_tracking
|
|
87
|
+
examples:
|
|
88
|
+
- "Social platforms with per-ad conversion attribution (Meta, TikTok, Snap)"
|
|
89
|
+
- "DSPs operating their own attribution graph with creative-level resolution"
|
|
90
|
+
- "Walled-garden platforms with deterministic per-creative attribution"
|
|
91
|
+
|
|
92
|
+
caller:
|
|
93
|
+
role: buyer_agent
|
|
94
|
+
example: "Pinnacle Agency (buyer)"
|
|
95
|
+
|
|
96
|
+
prerequisites:
|
|
97
|
+
description: |
|
|
98
|
+
The seller must implement comply_test_controller with simulate_delivery
|
|
99
|
+
accepting a `conversions` param so the per-creative breakdown is
|
|
100
|
+
observable via get_media_buy_delivery without a real attribution run.
|
|
101
|
+
|
|
102
|
+
The buyer fixture supplies a brand, an operator, a conversion event
|
|
103
|
+
source definition, and two distinct display creatives sufficient to
|
|
104
|
+
exercise the per-creative breakdown.
|
|
105
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
106
|
+
controller_seeding: true
|
|
107
|
+
|
|
108
|
+
fixtures:
|
|
109
|
+
products:
|
|
110
|
+
- product_id: "performance_per_creative_q2"
|
|
111
|
+
delivery_type: "non_guaranteed"
|
|
112
|
+
channels: ["display"]
|
|
113
|
+
format_ids:
|
|
114
|
+
- id: "display_300x250"
|
|
115
|
+
pricing_options:
|
|
116
|
+
- product_id: "performance_per_creative_q2"
|
|
117
|
+
pricing_option_id: "auction_cpm"
|
|
118
|
+
pricing_model: "cpm"
|
|
119
|
+
currency: "USD"
|
|
120
|
+
floor_price: 1.50
|
|
121
|
+
|
|
122
|
+
phases:
|
|
123
|
+
|
|
124
|
+
- id: setup
|
|
125
|
+
title: "Establish account and discover products"
|
|
126
|
+
steps:
|
|
127
|
+
- id: sync_accounts
|
|
128
|
+
title: "Establish account"
|
|
129
|
+
task: sync_accounts
|
|
130
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
131
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
132
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
133
|
+
stateful: true
|
|
134
|
+
expected: |
|
|
135
|
+
Return the account with account_id and status active.
|
|
136
|
+
sample_request:
|
|
137
|
+
accounts:
|
|
138
|
+
- brand:
|
|
139
|
+
domain: "acmeoutdoor.example"
|
|
140
|
+
operator: "pinnacle-agency.example"
|
|
141
|
+
billing: "operator"
|
|
142
|
+
idempotency_key: "$generate:uuid_v4#per_creative_conversion_attribution_setup_sync_accounts"
|
|
143
|
+
validations:
|
|
144
|
+
- check: response_schema
|
|
145
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
146
|
+
- check: field_present
|
|
147
|
+
path: "accounts[0].account_id"
|
|
148
|
+
description: "Account has a platform-assigned ID"
|
|
149
|
+
|
|
150
|
+
- id: get_products_for_per_creative
|
|
151
|
+
title: "Discover products supporting per-creative conversion attribution"
|
|
152
|
+
task: get_products
|
|
153
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
154
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
155
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
156
|
+
stateful: false
|
|
157
|
+
expected: |
|
|
158
|
+
Return at least one product whose conversion_tracking capabilities
|
|
159
|
+
include per-creative attribution.
|
|
160
|
+
sample_request:
|
|
161
|
+
buying_mode: "brief"
|
|
162
|
+
brief: "Performance display, US, adults 25-54. Target CPA $35 on purchase events from acmeoutdoor.example. Two creative variants — need per-creative conversion breakdown in delivery reporting."
|
|
163
|
+
required_capabilities:
|
|
164
|
+
- "conversion_tracking"
|
|
165
|
+
account:
|
|
166
|
+
brand:
|
|
167
|
+
domain: "acmeoutdoor.example"
|
|
168
|
+
operator: "pinnacle-agency.example"
|
|
169
|
+
validations:
|
|
170
|
+
- check: response_schema
|
|
171
|
+
description: "Response matches get-products-response.json schema"
|
|
172
|
+
- check: field_present
|
|
173
|
+
path: "products"
|
|
174
|
+
description: "Response contains products"
|
|
175
|
+
|
|
176
|
+
- id: event_source_binding
|
|
177
|
+
title: "Register the conversion event source"
|
|
178
|
+
narrative: |
|
|
179
|
+
The performance buy cannot be created without a registered event
|
|
180
|
+
source. This phase exercises the binding — sync_event_sources returns
|
|
181
|
+
an event_source_id that the next phase's create_media_buy references on
|
|
182
|
+
the package's optimization_goal.
|
|
183
|
+
|
|
184
|
+
steps:
|
|
185
|
+
- id: sync_event_sources
|
|
186
|
+
title: "Register a website conversion source"
|
|
187
|
+
task: sync_event_sources
|
|
188
|
+
schema_ref: "media-buy/sync-event-sources-request.json"
|
|
189
|
+
response_schema_ref: "media-buy/sync-event-sources-response.json"
|
|
190
|
+
doc_ref: "/media-buy/task-reference/sync_event_sources"
|
|
191
|
+
stateful: true
|
|
192
|
+
expected: |
|
|
193
|
+
Return event_sources with event_source_id, setup.snippet, and
|
|
194
|
+
action: created. The id is captured for the create_media_buy phase.
|
|
195
|
+
sample_request:
|
|
196
|
+
account:
|
|
197
|
+
brand:
|
|
198
|
+
domain: "acmeoutdoor.example"
|
|
199
|
+
operator: "pinnacle-agency.example"
|
|
200
|
+
event_sources:
|
|
201
|
+
- event_source_id: "acmeoutdoor_website"
|
|
202
|
+
name: "Acme Outdoor Website"
|
|
203
|
+
event_types: ["purchase"]
|
|
204
|
+
allowed_domains: ["acmeoutdoor.example"]
|
|
205
|
+
idempotency_key: "$generate:uuid_v4#per_creative_conversion_attribution_event_source_binding_sync_event_sources"
|
|
206
|
+
validations:
|
|
207
|
+
- check: response_schema
|
|
208
|
+
description: "Response matches sync-event-sources-response.json schema"
|
|
209
|
+
- check: field_present
|
|
210
|
+
path: "event_sources[0].event_source_id"
|
|
211
|
+
description: "Event source has a platform-assigned ID"
|
|
212
|
+
# Anti-façade: an adapter that returns a shape-valid
|
|
213
|
+
# sync_event_sources response without forwarding the source
|
|
214
|
+
# definition upstream fails this check.
|
|
215
|
+
- check: upstream_traffic
|
|
216
|
+
description: "sync_event_sources caused upstream traffic registering the event source"
|
|
217
|
+
min_count: 1
|
|
218
|
+
endpoint_pattern: "POST *"
|
|
219
|
+
|
|
220
|
+
- id: register_two_creatives_and_create_buy
|
|
221
|
+
title: "Register two creatives and create a buy assigning both to one package"
|
|
222
|
+
narrative: |
|
|
223
|
+
The buyer pushes two distinct display creatives to the seller's
|
|
224
|
+
creative library via sync_creatives, then creates a media buy whose
|
|
225
|
+
single package's creative_assignments references BOTH creatives. The
|
|
226
|
+
package carries an event-kind optimization_goal binding to the
|
|
227
|
+
registered event source with a CPA target — the seller commits to
|
|
228
|
+
rotating delivery across both creatives AND attributing conversions
|
|
229
|
+
per creative.
|
|
230
|
+
|
|
231
|
+
steps:
|
|
232
|
+
- id: sync_two_creatives
|
|
233
|
+
title: "Push two distinct display creatives"
|
|
234
|
+
task: sync_creatives
|
|
235
|
+
schema_ref: "creative/sync-creatives-request.json"
|
|
236
|
+
response_schema_ref: "creative/sync-creatives-response.json"
|
|
237
|
+
doc_ref: "/creative/task-reference/sync_creatives"
|
|
238
|
+
stateful: true
|
|
239
|
+
expected: |
|
|
240
|
+
Accept both creatives and return them in the creatives array with
|
|
241
|
+
per-creative action (created) and platform-assigned status. Both
|
|
242
|
+
creative_ids are referenced in the next step's create_media_buy.
|
|
243
|
+
sample_request:
|
|
244
|
+
account:
|
|
245
|
+
brand:
|
|
246
|
+
domain: "acmeoutdoor.example"
|
|
247
|
+
operator: "pinnacle-agency.example"
|
|
248
|
+
creatives:
|
|
249
|
+
- creative_id: "creative_acme_1"
|
|
250
|
+
name: "Acme Outdoor — Trail Pro display 300x250 (variant A)"
|
|
251
|
+
format_id:
|
|
252
|
+
agent_url: "https://your-platform.example.com"
|
|
253
|
+
id: "display_300x250"
|
|
254
|
+
assets:
|
|
255
|
+
image:
|
|
256
|
+
asset_type: "image"
|
|
257
|
+
url: "https://test-assets.adcontextprotocol.org/acme-outdoor/trail-pro-a-300x250.jpg"
|
|
258
|
+
width: 300
|
|
259
|
+
height: 250
|
|
260
|
+
click_url:
|
|
261
|
+
asset_type: "url"
|
|
262
|
+
url: "https://acmeoutdoor.example/trail-pro?v=a"
|
|
263
|
+
- creative_id: "creative_acme_2"
|
|
264
|
+
name: "Acme Outdoor — Trail Pro display 300x250 (variant B)"
|
|
265
|
+
format_id:
|
|
266
|
+
agent_url: "https://your-platform.example.com"
|
|
267
|
+
id: "display_300x250"
|
|
268
|
+
assets:
|
|
269
|
+
image:
|
|
270
|
+
asset_type: "image"
|
|
271
|
+
url: "https://test-assets.adcontextprotocol.org/acme-outdoor/trail-pro-b-300x250.jpg"
|
|
272
|
+
width: 300
|
|
273
|
+
height: 250
|
|
274
|
+
click_url:
|
|
275
|
+
asset_type: "url"
|
|
276
|
+
url: "https://acmeoutdoor.example/trail-pro?v=b"
|
|
277
|
+
idempotency_key: "$generate:uuid_v4#per_creative_conversion_attribution_register_two_creatives_and_create_buy_sync_creatives"
|
|
278
|
+
validations:
|
|
279
|
+
- check: response_schema
|
|
280
|
+
description: "Response matches sync-creatives-response.json schema"
|
|
281
|
+
- check: field_present
|
|
282
|
+
path: "creatives[0].action"
|
|
283
|
+
description: "First creative has an action (created/updated)"
|
|
284
|
+
- check: field_present
|
|
285
|
+
path: "creatives[1].action"
|
|
286
|
+
description: "Second creative has an action (created/updated) — both must be registered for the per-creative breakdown to be meaningful"
|
|
287
|
+
|
|
288
|
+
- id: create_media_buy_two_creatives
|
|
289
|
+
title: "Create media buy assigning both creatives to one package with a CPA goal"
|
|
290
|
+
task: create_media_buy
|
|
291
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
292
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
293
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
294
|
+
stateful: true
|
|
295
|
+
expected: |
|
|
296
|
+
Create the media buy. Response carries a media_buy_id used for
|
|
297
|
+
subsequent log_event and get_media_buy_delivery calls. Both
|
|
298
|
+
creative_ids appear in the package's creative_assignments.
|
|
299
|
+
sample_request:
|
|
300
|
+
brand:
|
|
301
|
+
domain: "acmeoutdoor.example"
|
|
302
|
+
account:
|
|
303
|
+
brand:
|
|
304
|
+
domain: "acmeoutdoor.example"
|
|
305
|
+
operator: "pinnacle-agency.example"
|
|
306
|
+
start_time: "2026-06-01T00:00:00Z"
|
|
307
|
+
end_time: "2026-06-30T23:59:59Z"
|
|
308
|
+
packages:
|
|
309
|
+
- product_id: "performance_per_creative_q2"
|
|
310
|
+
budget: 25000
|
|
311
|
+
pricing_option_id: "auction_cpm"
|
|
312
|
+
creative_assignments:
|
|
313
|
+
- creative_id: "creative_acme_1"
|
|
314
|
+
- creative_id: "creative_acme_2"
|
|
315
|
+
optimization_goals:
|
|
316
|
+
- kind: "event"
|
|
317
|
+
event_sources:
|
|
318
|
+
- event_source_id: "acmeoutdoor_website"
|
|
319
|
+
event_type: "purchase"
|
|
320
|
+
target:
|
|
321
|
+
kind: "cost_per"
|
|
322
|
+
value: 35.00
|
|
323
|
+
priority: 1
|
|
324
|
+
idempotency_key: "$generate:uuid_v4#per_creative_conversion_attribution_register_two_creatives_and_create_buy_create_media_buy"
|
|
325
|
+
context_outputs:
|
|
326
|
+
- name: media_buy_id
|
|
327
|
+
path: "media_buy_id"
|
|
328
|
+
validations:
|
|
329
|
+
- check: response_schema
|
|
330
|
+
description: "Response matches create-media-buy-response.json schema"
|
|
331
|
+
- check: field_present
|
|
332
|
+
path: "media_buy_id"
|
|
333
|
+
description: "Media buy has a platform-assigned ID"
|
|
334
|
+
|
|
335
|
+
- id: log_conversions_against_both_creatives
|
|
336
|
+
title: "Log two purchase events against the bound event source"
|
|
337
|
+
narrative: |
|
|
338
|
+
The buyer logs two purchase events against the registered event source.
|
|
339
|
+
log_event's payload (core/event.json) does NOT carry creative_id —
|
|
340
|
+
attributing the event back to a specific creative is the seller's
|
|
341
|
+
internal click / view-through correlation responsibility, not the
|
|
342
|
+
buyer's. The buyer simply emits two events with distinct event_ids;
|
|
343
|
+
the seller is expected to spread attributed conversions across the
|
|
344
|
+
two assigned creatives per its own correlation, and simulate_delivery's
|
|
345
|
+
conversions count drives the totals that surface in by_creative[] in
|
|
346
|
+
the next phase.
|
|
347
|
+
|
|
348
|
+
Two events (rather than one) make the buyer's intent observable: the
|
|
349
|
+
buyer expects more than one conversion to surface, and the per-creative
|
|
350
|
+
breakdown should distribute them across creatives rather than
|
|
351
|
+
collapsing to a single row.
|
|
352
|
+
|
|
353
|
+
steps:
|
|
354
|
+
- id: log_purchase_event_1
|
|
355
|
+
title: "Log first purchase event"
|
|
356
|
+
task: log_event
|
|
357
|
+
schema_ref: "media-buy/log-event-request.json"
|
|
358
|
+
response_schema_ref: "media-buy/log-event-response.json"
|
|
359
|
+
doc_ref: "/media-buy/task-reference/log_event"
|
|
360
|
+
stateful: true
|
|
361
|
+
expected: |
|
|
362
|
+
Acknowledge the event with accepted status.
|
|
363
|
+
sample_request:
|
|
364
|
+
account:
|
|
365
|
+
brand:
|
|
366
|
+
domain: "acmeoutdoor.example"
|
|
367
|
+
operator: "pinnacle-agency.example"
|
|
368
|
+
event_source_id: "acmeoutdoor_website"
|
|
369
|
+
events:
|
|
370
|
+
- event_type: "purchase"
|
|
371
|
+
event_id: "evt_per_creative_001"
|
|
372
|
+
event_time: "2026-06-05T14:30:00Z"
|
|
373
|
+
user_match:
|
|
374
|
+
hashed_email: "a000000000000000000000000000000000000000000000000000000000000030"
|
|
375
|
+
custom_data:
|
|
376
|
+
order_total: 99.99
|
|
377
|
+
currency: "USD"
|
|
378
|
+
idempotency_key: "$generate:uuid_v4#per_creative_conversion_attribution_log_conversions_against_both_creatives_log_event_1"
|
|
379
|
+
validations:
|
|
380
|
+
- check: response_schema
|
|
381
|
+
description: "Response matches log-event-response.json schema"
|
|
382
|
+
|
|
383
|
+
- id: log_purchase_event_2
|
|
384
|
+
title: "Log second purchase event"
|
|
385
|
+
task: log_event
|
|
386
|
+
schema_ref: "media-buy/log-event-request.json"
|
|
387
|
+
response_schema_ref: "media-buy/log-event-response.json"
|
|
388
|
+
doc_ref: "/media-buy/task-reference/log_event"
|
|
389
|
+
stateful: true
|
|
390
|
+
expected: |
|
|
391
|
+
Acknowledge the event with accepted status. The seller is expected
|
|
392
|
+
to spread attributed conversions across the two assigned creatives
|
|
393
|
+
via internal click / view-through correlation; the discriminating
|
|
394
|
+
assertion is the populated by_creative[] breakdown in delivery, not
|
|
395
|
+
the per-event acknowledgement here.
|
|
396
|
+
sample_request:
|
|
397
|
+
account:
|
|
398
|
+
brand:
|
|
399
|
+
domain: "acmeoutdoor.example"
|
|
400
|
+
operator: "pinnacle-agency.example"
|
|
401
|
+
event_source_id: "acmeoutdoor_website"
|
|
402
|
+
events:
|
|
403
|
+
- event_type: "purchase"
|
|
404
|
+
event_id: "evt_per_creative_002"
|
|
405
|
+
event_time: "2026-06-06T10:15:00Z"
|
|
406
|
+
user_match:
|
|
407
|
+
hashed_email: "a000000000000000000000000000000000000000000000000000000000000031"
|
|
408
|
+
custom_data:
|
|
409
|
+
order_total: 149.99
|
|
410
|
+
currency: "USD"
|
|
411
|
+
idempotency_key: "$generate:uuid_v4#per_creative_conversion_attribution_log_conversions_against_both_creatives_log_event_2"
|
|
412
|
+
validations:
|
|
413
|
+
- check: response_schema
|
|
414
|
+
description: "Response matches log-event-response.json schema"
|
|
415
|
+
|
|
416
|
+
- id: assert_per_creative_breakdown_in_delivery
|
|
417
|
+
title: "Delivery reporting carries a populated per-creative conversion breakdown"
|
|
418
|
+
narrative: |
|
|
419
|
+
The discriminating assertion of per-creative attribution: delivery
|
|
420
|
+
reporting MUST surface conversions on each by_creative[] row, not just
|
|
421
|
+
at the package or buy level. The runner injects simulated impressions
|
|
422
|
+
+ conversions + spend via the test controller, then verifies
|
|
423
|
+
get_media_buy_delivery returns a by_package[].by_creative[] array with
|
|
424
|
+
at least two rows — one per assigned creative — each carrying
|
|
425
|
+
creative_id and conversions.
|
|
426
|
+
|
|
427
|
+
A single-row breakdown covering only one of the two assigned creatives
|
|
428
|
+
would be a façade (the seller is rotating impressions but collapsing
|
|
429
|
+
conversion attribution to whichever creative it tracked first). The
|
|
430
|
+
second-row assertion is what keeps honest per-creative implementations
|
|
431
|
+
separated from coarser-granularity ones — sellers that can't attribute
|
|
432
|
+
per creative don't advertise the bit and grade not_applicable.
|
|
433
|
+
|
|
434
|
+
steps:
|
|
435
|
+
- id: simulate_per_creative_delivery
|
|
436
|
+
title: "Inject impressions + conversions + spend"
|
|
437
|
+
task: comply_test_controller
|
|
438
|
+
requires_tool: comply_test_controller
|
|
439
|
+
stateful: true
|
|
440
|
+
expected: |
|
|
441
|
+
The test controller acknowledges the simulated delivery.
|
|
442
|
+
sample_request:
|
|
443
|
+
account:
|
|
444
|
+
sandbox: true
|
|
445
|
+
scenario: "simulate_delivery"
|
|
446
|
+
params:
|
|
447
|
+
media_buy_id: "$context.media_buy_id"
|
|
448
|
+
impressions: 200000
|
|
449
|
+
clicks: 4500
|
|
450
|
+
conversions: 90
|
|
451
|
+
reported_spend:
|
|
452
|
+
amount: 3000.00
|
|
453
|
+
currency: "USD"
|
|
454
|
+
validations:
|
|
455
|
+
- check: field_value
|
|
456
|
+
path: "success"
|
|
457
|
+
allowed_values: [true]
|
|
458
|
+
description: "Delivery simulation succeeds"
|
|
459
|
+
|
|
460
|
+
- id: get_per_creative_delivery
|
|
461
|
+
title: "Get delivery and verify the per-creative conversion breakdown"
|
|
462
|
+
task: get_media_buy_delivery
|
|
463
|
+
schema_ref: "media-buy/get-media-buy-delivery-request.json"
|
|
464
|
+
response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
|
|
465
|
+
doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
|
|
466
|
+
stateful: true
|
|
467
|
+
expected: |
|
|
468
|
+
Delivery response includes:
|
|
469
|
+
- totals.conversions at the buy level (still required, same as
|
|
470
|
+
performance_buy_flow)
|
|
471
|
+
- by_package[0].by_creative[] array with at least two rows, each
|
|
472
|
+
carrying creative_id and conversions — the discriminating
|
|
473
|
+
assertion that the per_creative_attribution bit commits to
|
|
474
|
+
|
|
475
|
+
Single-row by_creative[] coverage is a façade signal: the seller
|
|
476
|
+
is reporting at the package level and labelling it per-creative.
|
|
477
|
+
The second-row assertion is the asymmetry check.
|
|
478
|
+
sample_request:
|
|
479
|
+
account:
|
|
480
|
+
brand:
|
|
481
|
+
domain: "acmeoutdoor.example"
|
|
482
|
+
operator: "pinnacle-agency.example"
|
|
483
|
+
media_buy_ids:
|
|
484
|
+
- "$context.media_buy_id"
|
|
485
|
+
include_package_daily_breakdown: true
|
|
486
|
+
validations:
|
|
487
|
+
- check: response_schema
|
|
488
|
+
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
489
|
+
- check: field_present
|
|
490
|
+
path: "media_buy_deliveries[0].totals.conversions"
|
|
491
|
+
description: "Conversion count surfaced at the buy level"
|
|
492
|
+
- check: field_present
|
|
493
|
+
path: "media_buy_deliveries[0].by_package[0].by_creative[0].creative_id"
|
|
494
|
+
description: "First by_creative row carries creative_id — the breakdown is keyed"
|
|
495
|
+
- check: field_present
|
|
496
|
+
path: "media_buy_deliveries[0].by_package[0].by_creative[0].conversions"
|
|
497
|
+
description: "First by_creative row carries conversions — the discriminating assertion of per_creative_attribution"
|
|
498
|
+
- check: field_present
|
|
499
|
+
path: "media_buy_deliveries[0].by_package[0].by_creative[1].conversions"
|
|
500
|
+
description: "Second by_creative row carries conversions — confirms the breakdown isn't a single-row façade collapsing attribution to one creative when two were assigned"
|