Production-safe Apify Pay-Per-Event (PPE) monetization, added without any
change to V1 scoring or calibration.
- New billing unit
source-post-analyzed, charged once per run by
summary.postsAfterDeduplication — every distinct post that actually
entered analysis, including baseline-only posts that never reach the ranked
output. Never driven by topResults or postsReturned. No price is
hardcoded in source; prices are configured entirely in Apify Console.
- Budget pre-flight (
src/monetization/ppe.ts): before any paid Instagram
child Actor starts, verifies pay-per-event pricing is correctly configured
(a valid, finite, strictly-positive price for source-post-analyzed) and
that the run's maximum total charge covers its worst-case event count.
A misconfiguration or insufficient budget fails the run immediately, with
zero child Actors started.
- Idempotent charging: reads
getChargedEventCount before charging, so
charging is always the exact delta to the target count and can never
double-charge across retries or repeated calls.
- Structured monetization failures with machine-readable codes
(
MONETIZATION_CONFIG_INVALID, MAX_TOTAL_CHARGE_TOO_LOW,
MONETIZATION_LIMIT_REACHED, MONETIZATION_INVARIANT_VIOLATION,
MONETIZATION_CHARGE_FAILED), reusing the existing FAILED OUTPUT contract.
A charge-API failure surfaces as a structured failure rather than being
silently swallowed, and never exposes the underlying exception message,
stack, or any pricing object.
- Non-PPE usage (FREE Actor pricing, local workflows,
dry-run) is
completely unaffected — monetization is a strict no-op outside PPE mode.
- No scoring, calibration, baseline, provider, or pipeline logic changed.
calibrationVersion remains V1_LIVE_ROUND_1; weights, saturation
constants, and classification thresholds are unchanged from V1.0.0.
Initial validated V1 baseline: deterministic Instagram viral-content scoring,
live-calibrated weights and thresholds, and full production hardening
(release packaging, public input/output contract, paid-run cost safety).