@adcp/sdk 7.11.0 → 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/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/storyboard/default-invariants.js +23 -0
- 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/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +1 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
id: media_buy_seller/clicks_buy_flow
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Seller fulfills a media buy with a clicks optimization goal (target CPC)"
|
|
4
|
+
category: media_buy_seller
|
|
5
|
+
summary: "Verifies that a seller advertising clicks in supported_optimization_metrics can accept a media buy whose metric-kind optimization_goal targets cost-per-click and reports clicks + cost_per_click on delivery. Lightweight sibling to the performance scenarios on the click-optimization side: sellers that don't advertise clicks as an optimization metric (rare — most do; pure brand sellers like broadcast TV upper-funnel video are the not_applicable population) grade not_applicable."
|
|
6
|
+
track: media_buy
|
|
7
|
+
|
|
8
|
+
# Gate: scenario runs only when the seller declares clicks in
|
|
9
|
+
# media_buy.supported_optimization_metrics (proposed in #4669). Most
|
|
10
|
+
# adopters declare clicks (it is the most universal metric in advertising),
|
|
11
|
+
# but broadcast TV upper-funnel video and signal-only sellers honestly
|
|
12
|
+
# don't optimize for clicks and grade `not_applicable`. The gate is what
|
|
13
|
+
# keeps them from being marked failing. Requires runner support for the
|
|
14
|
+
# `contains:` matcher (adcp-client >= 7.70).
|
|
15
|
+
requires_capability:
|
|
16
|
+
path: media_buy.supported_optimization_metrics
|
|
17
|
+
contains: "clicks"
|
|
18
|
+
|
|
19
|
+
required_tools:
|
|
20
|
+
- get_products
|
|
21
|
+
- create_media_buy
|
|
22
|
+
- get_media_buy_delivery
|
|
23
|
+
- comply_test_controller
|
|
24
|
+
|
|
25
|
+
invariants:
|
|
26
|
+
- status.monotonic
|
|
27
|
+
|
|
28
|
+
narrative: |
|
|
29
|
+
A "clicks buy" is a media buy whose optimization_goal is metric-kind with
|
|
30
|
+
metric: clicks and a target_cpc (target.kind: cost_per, value:
|
|
31
|
+
target-cost-per-click in the buy currency). This is the most common
|
|
32
|
+
performance-shaped buy in advertising — link clicks, swipe-throughs, CTA
|
|
33
|
+
taps that navigate away — and the optimization shape is well-understood
|
|
34
|
+
across the industry. The scenario certifies that the click-optimization
|
|
35
|
+
path connects end-to-end when the seller advertises clicks as an
|
|
36
|
+
optimization metric.
|
|
37
|
+
|
|
38
|
+
This scenario is intentionally lightweight (no rejection arm) because
|
|
39
|
+
clicks is universal in semantics — there isn't an obvious unbound-id or
|
|
40
|
+
unsupported-value to reject. The seller either supports clicks as an
|
|
41
|
+
optimization metric or it doesn't (handled by the capability gate). The
|
|
42
|
+
three-phase shape — setup, create, delivery — is sufficient to certify
|
|
43
|
+
the click-optimization path without manufacturing artificial rejection
|
|
44
|
+
surfaces.
|
|
45
|
+
|
|
46
|
+
Discriminating behaviors this scenario verifies:
|
|
47
|
+
1. create_media_buy with metric-kind goal (metric: clicks, target.kind:
|
|
48
|
+
cost_per, target.value: target CPC) is accepted.
|
|
49
|
+
2. get_media_buy_delivery surfaces totals.clicks and totals.cost_per_click
|
|
50
|
+
— the discriminating output fields of click optimization. cost_per_click
|
|
51
|
+
is defined in delivery-metrics.json as spend / clicks; sellers
|
|
52
|
+
optimizing for clicks MUST populate both fields on delivery.
|
|
53
|
+
|
|
54
|
+
agent:
|
|
55
|
+
interaction_model: media_buy_seller
|
|
56
|
+
capabilities:
|
|
57
|
+
- sells_media
|
|
58
|
+
- supports_non_guaranteed
|
|
59
|
+
examples:
|
|
60
|
+
- "DSPs running click-optimized campaigns"
|
|
61
|
+
- "Social platforms (Meta link clicks, TikTok swipe-throughs)"
|
|
62
|
+
- "Search-adjacent / native sellers optimizing for CTA taps"
|
|
63
|
+
- "Retail-media performance products optimizing for product page visits"
|
|
64
|
+
|
|
65
|
+
caller:
|
|
66
|
+
role: buyer_agent
|
|
67
|
+
example: "Pinnacle Agency (buyer)"
|
|
68
|
+
|
|
69
|
+
prerequisites:
|
|
70
|
+
description: |
|
|
71
|
+
The seller must implement comply_test_controller with simulate_delivery
|
|
72
|
+
(already required for delivery_reporting). simulate_delivery injects
|
|
73
|
+
impressions, clicks, and spend so get_media_buy_delivery has something
|
|
74
|
+
to surface for the click-optimized buy.
|
|
75
|
+
|
|
76
|
+
The buyer fixture supplies a brand, an operator, and click optimization
|
|
77
|
+
parameters sufficient to exercise the cost_per target binding.
|
|
78
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
79
|
+
controller_seeding: true
|
|
80
|
+
|
|
81
|
+
fixtures:
|
|
82
|
+
products:
|
|
83
|
+
- product_id: "clicks_display_q2"
|
|
84
|
+
delivery_type: "non_guaranteed"
|
|
85
|
+
channels: ["display"]
|
|
86
|
+
format_ids:
|
|
87
|
+
- id: "display_300x250"
|
|
88
|
+
pricing_options:
|
|
89
|
+
- product_id: "clicks_display_q2"
|
|
90
|
+
pricing_option_id: "auction_cpm"
|
|
91
|
+
pricing_model: "cpm"
|
|
92
|
+
currency: "USD"
|
|
93
|
+
floor_price: 1.50
|
|
94
|
+
|
|
95
|
+
phases:
|
|
96
|
+
|
|
97
|
+
- id: setup
|
|
98
|
+
title: "Establish account and discover products"
|
|
99
|
+
steps:
|
|
100
|
+
- id: sync_accounts
|
|
101
|
+
title: "Establish account"
|
|
102
|
+
task: sync_accounts
|
|
103
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
104
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
105
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
106
|
+
stateful: true
|
|
107
|
+
expected: |
|
|
108
|
+
Return the account with account_id and status active.
|
|
109
|
+
sample_request:
|
|
110
|
+
accounts:
|
|
111
|
+
- brand:
|
|
112
|
+
domain: "acmeoutdoor.example"
|
|
113
|
+
operator: "pinnacle-agency.example"
|
|
114
|
+
billing: "operator"
|
|
115
|
+
idempotency_key: "$generate:uuid_v4#clicks_buy_flow_setup_sync_accounts"
|
|
116
|
+
validations:
|
|
117
|
+
- check: response_schema
|
|
118
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
119
|
+
- check: field_present
|
|
120
|
+
path: "accounts[0].account_id"
|
|
121
|
+
description: "Account has a platform-assigned ID"
|
|
122
|
+
|
|
123
|
+
- id: get_products_for_clicks
|
|
124
|
+
title: "Discover products that support click optimization"
|
|
125
|
+
task: get_products
|
|
126
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
127
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
128
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
129
|
+
stateful: false
|
|
130
|
+
expected: |
|
|
131
|
+
Return at least one product whose metric_optimization capabilities
|
|
132
|
+
include clicks as an optimization metric.
|
|
133
|
+
sample_request:
|
|
134
|
+
buying_mode: "brief"
|
|
135
|
+
brief: "Display performance, US adults 25-54. Q2 flight ~$15K, optimizing for clicks with a target CPC."
|
|
136
|
+
account:
|
|
137
|
+
brand:
|
|
138
|
+
domain: "acmeoutdoor.example"
|
|
139
|
+
operator: "pinnacle-agency.example"
|
|
140
|
+
validations:
|
|
141
|
+
- check: response_schema
|
|
142
|
+
description: "Response matches get-products-response.json schema"
|
|
143
|
+
- check: field_present
|
|
144
|
+
path: "products"
|
|
145
|
+
description: "Response contains products"
|
|
146
|
+
|
|
147
|
+
- id: create_clicks_buy
|
|
148
|
+
title: "Create a click-optimized buy with a target CPC"
|
|
149
|
+
narrative: |
|
|
150
|
+
The buyer creates a media buy whose package carries a metric-kind
|
|
151
|
+
optimization_goal with metric: clicks and target.kind: cost_per at
|
|
152
|
+
$2.50 per click. The seller should accept and return a media_buy_id
|
|
153
|
+
used for subsequent delivery checks.
|
|
154
|
+
|
|
155
|
+
steps:
|
|
156
|
+
- id: create_media_buy_clicks
|
|
157
|
+
title: "Create media buy with metric-kind clicks goal"
|
|
158
|
+
task: create_media_buy
|
|
159
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
160
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
161
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
162
|
+
stateful: true
|
|
163
|
+
expected: |
|
|
164
|
+
Create the media buy. Response carries a media_buy_id used for
|
|
165
|
+
subsequent get_media_buy_delivery calls.
|
|
166
|
+
sample_request:
|
|
167
|
+
brand:
|
|
168
|
+
domain: "acmeoutdoor.example"
|
|
169
|
+
account:
|
|
170
|
+
brand:
|
|
171
|
+
domain: "acmeoutdoor.example"
|
|
172
|
+
operator: "pinnacle-agency.example"
|
|
173
|
+
start_time: "2026-06-01T00:00:00Z"
|
|
174
|
+
end_time: "2026-06-30T23:59:59Z"
|
|
175
|
+
packages:
|
|
176
|
+
- product_id: "clicks_display_q2"
|
|
177
|
+
budget: 15000
|
|
178
|
+
pricing_option_id: "auction_cpm"
|
|
179
|
+
optimization_goals:
|
|
180
|
+
- kind: "metric"
|
|
181
|
+
metric: "clicks"
|
|
182
|
+
target:
|
|
183
|
+
kind: "cost_per"
|
|
184
|
+
value: 2.50
|
|
185
|
+
priority: 1
|
|
186
|
+
idempotency_key: "$generate:uuid_v4#clicks_buy_flow_create_clicks_buy_create_media_buy"
|
|
187
|
+
context_outputs:
|
|
188
|
+
- name: media_buy_id
|
|
189
|
+
path: "media_buy_id"
|
|
190
|
+
validations:
|
|
191
|
+
- check: response_schema
|
|
192
|
+
description: "Response matches create-media-buy-response.json schema"
|
|
193
|
+
- check: field_present
|
|
194
|
+
path: "media_buy_id"
|
|
195
|
+
description: "Media buy has a platform-assigned ID"
|
|
196
|
+
|
|
197
|
+
- id: clicks_delivery
|
|
198
|
+
title: "Delivery reporting carries clicks and cost_per_click"
|
|
199
|
+
narrative: |
|
|
200
|
+
The discriminating assertion of the click-optimization mode: delivery
|
|
201
|
+
reporting MUST surface clicks and cost_per_click — not just
|
|
202
|
+
impressions and spend. The runner injects simulated impressions,
|
|
203
|
+
clicks, and spend via the test controller, then verifies
|
|
204
|
+
get_media_buy_delivery returns clicks + cost_per_click on totals.
|
|
205
|
+
|
|
206
|
+
cost_per_click is defined in delivery-metrics.json as spend / clicks;
|
|
207
|
+
sellers optimizing for clicks at a cost_per target are committing to
|
|
208
|
+
populate both fields on delivery responses so the buyer can reconcile
|
|
209
|
+
effective CPC against the target.
|
|
210
|
+
|
|
211
|
+
steps:
|
|
212
|
+
- id: simulate_clicks_delivery
|
|
213
|
+
title: "Inject impressions + clicks + spend"
|
|
214
|
+
task: comply_test_controller
|
|
215
|
+
requires_tool: comply_test_controller
|
|
216
|
+
stateful: true
|
|
217
|
+
expected: |
|
|
218
|
+
The test controller acknowledges the simulated delivery.
|
|
219
|
+
sample_request:
|
|
220
|
+
account:
|
|
221
|
+
sandbox: true
|
|
222
|
+
scenario: "simulate_delivery"
|
|
223
|
+
params:
|
|
224
|
+
media_buy_id: "$context.media_buy_id"
|
|
225
|
+
impressions: 300000
|
|
226
|
+
clicks: 4800
|
|
227
|
+
reported_spend:
|
|
228
|
+
amount: 11000.00
|
|
229
|
+
currency: "USD"
|
|
230
|
+
validations:
|
|
231
|
+
- check: field_value
|
|
232
|
+
path: "success"
|
|
233
|
+
allowed_values: [true]
|
|
234
|
+
description: "Delivery simulation succeeds"
|
|
235
|
+
|
|
236
|
+
- id: get_clicks_delivery
|
|
237
|
+
title: "Get delivery and verify clicks + cost_per_click metrics"
|
|
238
|
+
task: get_media_buy_delivery
|
|
239
|
+
schema_ref: "media-buy/get-media-buy-delivery-request.json"
|
|
240
|
+
response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
|
|
241
|
+
doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
|
|
242
|
+
stateful: true
|
|
243
|
+
expected: |
|
|
244
|
+
Delivery response includes totals.clicks (the click count) and
|
|
245
|
+
totals.cost_per_click (effective CPC, spend / clicks). These are
|
|
246
|
+
the discriminating output fields of click optimization and are
|
|
247
|
+
required on click-optimized buys.
|
|
248
|
+
sample_request:
|
|
249
|
+
account:
|
|
250
|
+
brand:
|
|
251
|
+
domain: "acmeoutdoor.example"
|
|
252
|
+
operator: "pinnacle-agency.example"
|
|
253
|
+
media_buy_ids:
|
|
254
|
+
- "$context.media_buy_id"
|
|
255
|
+
include_package_daily_breakdown: true
|
|
256
|
+
validations:
|
|
257
|
+
- check: response_schema
|
|
258
|
+
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
259
|
+
- check: field_present
|
|
260
|
+
path: "media_buy_deliveries[0].totals.clicks"
|
|
261
|
+
description: "Click count surfaced at the buy level"
|
|
262
|
+
- check: field_present
|
|
263
|
+
path: "media_buy_deliveries[0].totals.cost_per_click"
|
|
264
|
+
description: "Effective CPC surfaced at the buy level (spend / clicks — the discriminating field of click-optimization with a cost_per target)"
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
id: media_buy_seller/completed_views_buy_flow
|
|
2
|
+
version: "1.0.0"
|
|
3
|
+
title: "Seller fulfills a video media buy with a completed_views optimization goal (target CPCV)"
|
|
4
|
+
category: media_buy_seller
|
|
5
|
+
summary: "Verifies that a seller advertising completed_views in supported_optimization_metrics can accept a media buy whose metric-kind optimization_goal targets completed views at a buyer-supplied view_duration_seconds, reject view_duration_seconds values not in the product's metric_optimization.supported_view_durations, and report completed_views + completion_rate on delivery. Sibling to reach_buy_flow on the video-completion side: sellers without video inventory (display-only DSPs, retail-media networks, audio-only sellers without video products) grade not_applicable."
|
|
6
|
+
track: media_buy
|
|
7
|
+
|
|
8
|
+
# Gate: scenario runs only when the seller declares completed_views in
|
|
9
|
+
# media_buy.supported_optimization_metrics (proposed in #4669). Sellers
|
|
10
|
+
# without video inventory or whose video products don't optimize for
|
|
11
|
+
# completion (display-only DSPs, retail-media networks, audio-only
|
|
12
|
+
# sellers without video) grade `not_applicable`, not failing. Gating
|
|
13
|
+
# on the explicit metric in supported_optimization_metrics avoids
|
|
14
|
+
# over-claiming against the broad delivery-tracking community.
|
|
15
|
+
# Requires runner support for the `contains:` matcher (adcp-client >= 7.70).
|
|
16
|
+
requires_capability:
|
|
17
|
+
path: media_buy.supported_optimization_metrics
|
|
18
|
+
contains: "completed_views"
|
|
19
|
+
|
|
20
|
+
required_tools:
|
|
21
|
+
- get_products
|
|
22
|
+
- create_media_buy
|
|
23
|
+
- get_media_buy_delivery
|
|
24
|
+
- comply_test_controller
|
|
25
|
+
|
|
26
|
+
invariants:
|
|
27
|
+
- status.monotonic
|
|
28
|
+
|
|
29
|
+
narrative: |
|
|
30
|
+
A "completed-views buy" (CPCV — cost per completed view) is a video or
|
|
31
|
+
audio media buy whose optimization_goal is metric-kind with metric:
|
|
32
|
+
completed_views, a buyer-supplied view_duration_seconds (e.g., 2 for
|
|
33
|
+
Snap/LinkedIn defaults, 6 for TikTok, 15 for Meta ThruPlay), and a
|
|
34
|
+
target.kind: cost_per target. The view_duration_seconds value MUST be
|
|
35
|
+
in the product's metric_optimization.supported_view_durations — silent
|
|
36
|
+
rounding to the seller's nearest supported duration would create
|
|
37
|
+
measurement discrepancies (a buyer targeting 6-second completion would
|
|
38
|
+
unknowingly be billed against 2-second or 15-second completion).
|
|
39
|
+
|
|
40
|
+
Discriminating behaviors this scenario verifies:
|
|
41
|
+
1. create_media_buy with metric: completed_views, a view_duration_seconds
|
|
42
|
+
value declared in the product's supported_view_durations, and a
|
|
43
|
+
target.kind: cost_per target is accepted.
|
|
44
|
+
2. create_media_buy with a view_duration_seconds value NOT in the
|
|
45
|
+
product's supported_view_durations is rejected with INVALID_REQUEST.
|
|
46
|
+
error.field points at the offending view_duration_seconds path.
|
|
47
|
+
optimization-goal.json:50-53 makes this requirement explicit:
|
|
48
|
+
"Sellers must reject goals with unsupported values — silent rounding
|
|
49
|
+
would create measurement discrepancies."
|
|
50
|
+
3. get_media_buy_delivery surfaces totals.completed_views and
|
|
51
|
+
totals.completion_rate on delivery. completion_rate is defined in
|
|
52
|
+
delivery-metrics.json as completed_views / impressions; sellers
|
|
53
|
+
optimizing for completed_views MUST populate both fields.
|
|
54
|
+
|
|
55
|
+
The 999-second view_duration is chosen for the rejection arm because
|
|
56
|
+
no honest video product will declare a 999-second duration in
|
|
57
|
+
supported_view_durations — common values are 2, 6, 15, and 30. A
|
|
58
|
+
seller that round-trips 999 as accepted is demonstrating they don't
|
|
59
|
+
validate against their product capability declarations.
|
|
60
|
+
|
|
61
|
+
agent:
|
|
62
|
+
interaction_model: media_buy_seller
|
|
63
|
+
capabilities:
|
|
64
|
+
- sells_media
|
|
65
|
+
- supports_non_guaranteed
|
|
66
|
+
examples:
|
|
67
|
+
- "CTV sellers optimizing for video completion"
|
|
68
|
+
- "Social platforms with video completion goals (Meta ThruPlay, TikTok 6-second views)"
|
|
69
|
+
- "Audio sellers optimizing for podcast/stream completion"
|
|
70
|
+
- "Online video DSPs with CPCV pricing"
|
|
71
|
+
|
|
72
|
+
caller:
|
|
73
|
+
role: buyer_agent
|
|
74
|
+
example: "Pinnacle Agency (buyer)"
|
|
75
|
+
|
|
76
|
+
prerequisites:
|
|
77
|
+
description: |
|
|
78
|
+
The seller must implement comply_test_controller with simulate_delivery
|
|
79
|
+
(already required for delivery_reporting). simulate_delivery injects
|
|
80
|
+
impressions and completed_views so get_media_buy_delivery has something
|
|
81
|
+
to surface for the completion-optimized buy.
|
|
82
|
+
|
|
83
|
+
The buyer fixture supplies a brand, an operator, and video-channel
|
|
84
|
+
targeting parameters sufficient to exercise the view_duration_seconds
|
|
85
|
+
binding contract and the unsupported-value rejection.
|
|
86
|
+
test_kit: "test-kits/acme-outdoor.yaml"
|
|
87
|
+
controller_seeding: true
|
|
88
|
+
|
|
89
|
+
fixtures:
|
|
90
|
+
products:
|
|
91
|
+
- product_id: "cpcv_video_q2"
|
|
92
|
+
delivery_type: "non_guaranteed"
|
|
93
|
+
channels: ["video"]
|
|
94
|
+
format_ids:
|
|
95
|
+
- id: "video_30s"
|
|
96
|
+
pricing_options:
|
|
97
|
+
- product_id: "cpcv_video_q2"
|
|
98
|
+
pricing_option_id: "auction_cpm"
|
|
99
|
+
pricing_model: "cpm"
|
|
100
|
+
currency: "USD"
|
|
101
|
+
floor_price: 12.00
|
|
102
|
+
|
|
103
|
+
phases:
|
|
104
|
+
|
|
105
|
+
- id: setup
|
|
106
|
+
title: "Establish account and discover products"
|
|
107
|
+
steps:
|
|
108
|
+
- id: sync_accounts
|
|
109
|
+
title: "Establish account"
|
|
110
|
+
task: sync_accounts
|
|
111
|
+
schema_ref: "account/sync-accounts-request.json"
|
|
112
|
+
response_schema_ref: "account/sync-accounts-response.json"
|
|
113
|
+
doc_ref: "/accounts/tasks/sync_accounts"
|
|
114
|
+
stateful: true
|
|
115
|
+
expected: |
|
|
116
|
+
Return the account with account_id and status active.
|
|
117
|
+
sample_request:
|
|
118
|
+
accounts:
|
|
119
|
+
- brand:
|
|
120
|
+
domain: "acmeoutdoor.example"
|
|
121
|
+
operator: "pinnacle-agency.example"
|
|
122
|
+
billing: "operator"
|
|
123
|
+
idempotency_key: "$generate:uuid_v4#completed_views_buy_flow_setup_sync_accounts"
|
|
124
|
+
validations:
|
|
125
|
+
- check: response_schema
|
|
126
|
+
description: "Response matches sync-accounts-response.json schema"
|
|
127
|
+
- check: field_present
|
|
128
|
+
path: "accounts[0].account_id"
|
|
129
|
+
description: "Account has a platform-assigned ID"
|
|
130
|
+
|
|
131
|
+
- id: get_products_for_cpcv
|
|
132
|
+
title: "Discover video products that support completed_views optimization"
|
|
133
|
+
task: get_products
|
|
134
|
+
schema_ref: "media-buy/get-products-request.json"
|
|
135
|
+
response_schema_ref: "media-buy/get-products-response.json"
|
|
136
|
+
doc_ref: "/media-buy/task-reference/get_products"
|
|
137
|
+
stateful: false
|
|
138
|
+
expected: |
|
|
139
|
+
Return at least one video product whose metric_optimization
|
|
140
|
+
capabilities include completed_views as an optimization metric and
|
|
141
|
+
declare supported_view_durations. The buyer selects a duration
|
|
142
|
+
from that list for the create_media_buy call below.
|
|
143
|
+
sample_request:
|
|
144
|
+
buying_mode: "brief"
|
|
145
|
+
brief: "Online video / CTV, US adults 25-54. Q2 flight ~$30K, optimizing for completed views at a 6-second threshold with target CPCV."
|
|
146
|
+
account:
|
|
147
|
+
brand:
|
|
148
|
+
domain: "acmeoutdoor.example"
|
|
149
|
+
operator: "pinnacle-agency.example"
|
|
150
|
+
validations:
|
|
151
|
+
- check: response_schema
|
|
152
|
+
description: "Response matches get-products-response.json schema"
|
|
153
|
+
- check: field_present
|
|
154
|
+
path: "products"
|
|
155
|
+
description: "Response contains products"
|
|
156
|
+
|
|
157
|
+
- id: create_cpcv_buy
|
|
158
|
+
title: "Create a completed-views buy at a supported view_duration"
|
|
159
|
+
narrative: |
|
|
160
|
+
The buyer creates a media buy whose package carries a metric-kind
|
|
161
|
+
optimization_goal with metric: completed_views, view_duration_seconds:
|
|
162
|
+
6 (a common supported value for online video — TikTok native, Meta
|
|
163
|
+
6-second qualifier), and target.kind: cost_per at $0.05 per completed
|
|
164
|
+
view. The seller should accept and return a media_buy_id used for
|
|
165
|
+
subsequent delivery checks.
|
|
166
|
+
|
|
167
|
+
steps:
|
|
168
|
+
- id: create_media_buy_cpcv
|
|
169
|
+
title: "Create media buy with metric-kind completed_views goal"
|
|
170
|
+
task: create_media_buy
|
|
171
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
172
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
173
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
174
|
+
stateful: true
|
|
175
|
+
expected: |
|
|
176
|
+
Create the media buy. Response carries a media_buy_id used for
|
|
177
|
+
subsequent get_media_buy_delivery calls.
|
|
178
|
+
sample_request:
|
|
179
|
+
brand:
|
|
180
|
+
domain: "acmeoutdoor.example"
|
|
181
|
+
account:
|
|
182
|
+
brand:
|
|
183
|
+
domain: "acmeoutdoor.example"
|
|
184
|
+
operator: "pinnacle-agency.example"
|
|
185
|
+
start_time: "2026-06-01T00:00:00Z"
|
|
186
|
+
end_time: "2026-06-30T23:59:59Z"
|
|
187
|
+
packages:
|
|
188
|
+
- product_id: "cpcv_video_q2"
|
|
189
|
+
budget: 30000
|
|
190
|
+
pricing_option_id: "auction_cpm"
|
|
191
|
+
optimization_goals:
|
|
192
|
+
- kind: "metric"
|
|
193
|
+
metric: "completed_views"
|
|
194
|
+
view_duration_seconds: 6
|
|
195
|
+
target:
|
|
196
|
+
kind: "cost_per"
|
|
197
|
+
value: 0.05
|
|
198
|
+
priority: 1
|
|
199
|
+
idempotency_key: "$generate:uuid_v4#completed_views_buy_flow_create_cpcv_buy_create_media_buy"
|
|
200
|
+
context_outputs:
|
|
201
|
+
- name: media_buy_id
|
|
202
|
+
path: "media_buy_id"
|
|
203
|
+
validations:
|
|
204
|
+
- check: response_schema
|
|
205
|
+
description: "Response matches create-media-buy-response.json schema"
|
|
206
|
+
- check: field_present
|
|
207
|
+
path: "media_buy_id"
|
|
208
|
+
description: "Media buy has a platform-assigned ID"
|
|
209
|
+
|
|
210
|
+
- id: rejection_unsupported_view_duration
|
|
211
|
+
title: "Reject a completed_views goal whose view_duration_seconds is not in supported_view_durations"
|
|
212
|
+
narrative: |
|
|
213
|
+
Silent acceptance of a view_duration_seconds value not declared in
|
|
214
|
+
the product's metric_optimization.supported_view_durations is a
|
|
215
|
+
façade — the seller either rounds to the nearest supported duration
|
|
216
|
+
(creating measurement discrepancies where the buyer thinks they're
|
|
217
|
+
paying for 999-second completion but is billed against the rounded
|
|
218
|
+
duration) or runs without a duration (delivery becomes uncomparable).
|
|
219
|
+
The seller MUST reject with INVALID_REQUEST and set error.field to
|
|
220
|
+
the offending view_duration_seconds path. Same shape as the
|
|
221
|
+
unsupported reach_unit rejection in reach_buy_flow.
|
|
222
|
+
|
|
223
|
+
optimization-goal.json:50-53 makes this requirement explicit:
|
|
224
|
+
"Sellers declare which durations they support in
|
|
225
|
+
metric_optimization.supported_view_durations. Sellers must reject
|
|
226
|
+
goals with unsupported values — silent rounding would create
|
|
227
|
+
measurement discrepancies."
|
|
228
|
+
|
|
229
|
+
The literal 999 is chosen because no honest video product will
|
|
230
|
+
declare a 999-second duration — common values are 2, 6, 15, and 30.
|
|
231
|
+
|
|
232
|
+
steps:
|
|
233
|
+
- id: create_media_buy_with_phantom_view_duration
|
|
234
|
+
title: "Submit a completed_views goal whose view_duration_seconds is not in supported_view_durations"
|
|
235
|
+
task: create_media_buy
|
|
236
|
+
schema_ref: "media-buy/create-media-buy-request.json"
|
|
237
|
+
response_schema_ref: "media-buy/create-media-buy-response.json"
|
|
238
|
+
doc_ref: "/media-buy/task-reference/create_media_buy"
|
|
239
|
+
expect_error: true
|
|
240
|
+
negative_path: payload_well_formed
|
|
241
|
+
stateful: false
|
|
242
|
+
expected: |
|
|
243
|
+
Reject with INVALID_REQUEST. error.field points at the offending
|
|
244
|
+
view_duration_seconds path. media_buy_id is not allocated.
|
|
245
|
+
sample_request:
|
|
246
|
+
brand:
|
|
247
|
+
domain: "acmeoutdoor.example"
|
|
248
|
+
account:
|
|
249
|
+
brand:
|
|
250
|
+
domain: "acmeoutdoor.example"
|
|
251
|
+
operator: "pinnacle-agency.example"
|
|
252
|
+
start_time: "2026-06-01T00:00:00Z"
|
|
253
|
+
end_time: "2026-06-30T23:59:59Z"
|
|
254
|
+
packages:
|
|
255
|
+
- product_id: "cpcv_video_q2"
|
|
256
|
+
budget: 5000
|
|
257
|
+
pricing_option_id: "auction_cpm"
|
|
258
|
+
optimization_goals:
|
|
259
|
+
- kind: "metric"
|
|
260
|
+
metric: "completed_views"
|
|
261
|
+
view_duration_seconds: 999
|
|
262
|
+
target:
|
|
263
|
+
kind: "cost_per"
|
|
264
|
+
value: 0.05
|
|
265
|
+
idempotency_key: "$generate:uuid_v4#completed_views_buy_flow_rejection_unsupported_view_duration"
|
|
266
|
+
validations:
|
|
267
|
+
- check: error_code
|
|
268
|
+
allowed_values: ["INVALID_REQUEST"]
|
|
269
|
+
description: "Seller rejects the unsupported view_duration_seconds with INVALID_REQUEST"
|
|
270
|
+
- check: field_value
|
|
271
|
+
path: "errors[0].field"
|
|
272
|
+
value: "packages[0].optimization_goals[0].view_duration_seconds"
|
|
273
|
+
description: "Error.field points at the offending view_duration_seconds path (core/error.json defines field as deterministic JSONPath-lite — literal equality)"
|
|
274
|
+
|
|
275
|
+
- id: cpcv_delivery
|
|
276
|
+
title: "Delivery reporting carries completed_views and completion_rate"
|
|
277
|
+
narrative: |
|
|
278
|
+
The discriminating assertion of the completed-views buy mode:
|
|
279
|
+
delivery reporting MUST surface completed_views and completion_rate
|
|
280
|
+
— not just impressions and spend. The runner injects simulated
|
|
281
|
+
impressions and completed_views via the test controller, then
|
|
282
|
+
verifies get_media_buy_delivery returns completed_views +
|
|
283
|
+
completion_rate on totals.
|
|
284
|
+
|
|
285
|
+
completion_rate is defined in delivery-metrics.json as
|
|
286
|
+
completed_views / impressions; sellers optimizing for completed_views
|
|
287
|
+
at a target view_duration_seconds are committing to populate both
|
|
288
|
+
fields on delivery responses.
|
|
289
|
+
|
|
290
|
+
steps:
|
|
291
|
+
- id: simulate_cpcv_delivery
|
|
292
|
+
title: "Inject impressions + completed_views + spend"
|
|
293
|
+
task: comply_test_controller
|
|
294
|
+
requires_tool: comply_test_controller
|
|
295
|
+
stateful: true
|
|
296
|
+
expected: |
|
|
297
|
+
The test controller acknowledges the simulated delivery.
|
|
298
|
+
sample_request:
|
|
299
|
+
account:
|
|
300
|
+
sandbox: true
|
|
301
|
+
scenario: "simulate_delivery"
|
|
302
|
+
params:
|
|
303
|
+
media_buy_id: "$context.media_buy_id"
|
|
304
|
+
impressions: 500000
|
|
305
|
+
completed_views: 350000
|
|
306
|
+
reported_spend:
|
|
307
|
+
amount: 18000.00
|
|
308
|
+
currency: "USD"
|
|
309
|
+
validations:
|
|
310
|
+
- check: field_value
|
|
311
|
+
path: "success"
|
|
312
|
+
allowed_values: [true]
|
|
313
|
+
description: "Delivery simulation succeeds"
|
|
314
|
+
|
|
315
|
+
- id: get_cpcv_delivery
|
|
316
|
+
title: "Get delivery and verify completed_views + completion_rate metrics"
|
|
317
|
+
task: get_media_buy_delivery
|
|
318
|
+
schema_ref: "media-buy/get-media-buy-delivery-request.json"
|
|
319
|
+
response_schema_ref: "media-buy/get-media-buy-delivery-response.json"
|
|
320
|
+
doc_ref: "/media-buy/task-reference/get_media_buy_delivery"
|
|
321
|
+
stateful: true
|
|
322
|
+
expected: |
|
|
323
|
+
Delivery response includes totals.completed_views (the completion
|
|
324
|
+
count at the declared view_duration_seconds threshold) and
|
|
325
|
+
totals.completion_rate (completed_views / impressions). These two
|
|
326
|
+
fields are the discriminating output of completed-views
|
|
327
|
+
optimization and are required on completion-optimized buys.
|
|
328
|
+
sample_request:
|
|
329
|
+
account:
|
|
330
|
+
brand:
|
|
331
|
+
domain: "acmeoutdoor.example"
|
|
332
|
+
operator: "pinnacle-agency.example"
|
|
333
|
+
media_buy_ids:
|
|
334
|
+
- "$context.media_buy_id"
|
|
335
|
+
include_package_daily_breakdown: true
|
|
336
|
+
validations:
|
|
337
|
+
- check: response_schema
|
|
338
|
+
description: "Response matches get-media-buy-delivery-response.json schema"
|
|
339
|
+
- check: field_present
|
|
340
|
+
path: "media_buy_deliveries[0].totals.completed_views"
|
|
341
|
+
description: "Completed-views count surfaced at the buy level (at the declared view_duration_seconds threshold)"
|
|
342
|
+
- check: field_present
|
|
343
|
+
path: "media_buy_deliveries[0].totals.completion_rate"
|
|
344
|
+
description: "Completion rate surfaced at the buy level (completed_views / impressions)"
|