# Lead Scoring v2: Omni integration AI Platform publishes this provider contract; Omni implements its consumer. `openapi.json` is generated from backend routes. The JSON files under `fixtures/` are examples, not another validation schema. Cross-service acceptance still requires Omni to run them. ## Terminal notification When `AI_PLATFORM_WEBHOOK_URL` and `AI_PLATFORM_WEBHOOK_SIGNING_SECRET` are both configured, AI Platform sends `POST` to that one server-side URL with `Content-Type: application/json`. The raw UTF-8 body contains exactly `event_id` (stable across retries), `run_id`, `tenant_id`, `status` (`completed` or `failed`), and `occurred_at` (UTC ISO 8601). It contains no run result, snapshot, tenant key, V-Key, or AI evidence. `occurred_at` is the terminal event time; it is not the send time. `X-Webhook-Timestamp` is the UTC ISO 8601 time of **this delivery attempt**. `X-Webhook-Signature` is `sha256=` followed by the lowercase hex HMAC-SHA256 of the UTF-8 bytes `timestamp + "." + raw_request_body`, using the shared signing secret. Verify the signature over the raw body before parsing JSON, compare in constant time, and reject timestamps outside a five-minute window. The sample in `fixtures/webhook-delivery.json` uses the **test-only** secret `test-only-webhook-secret-32-characters-long` and fixes the exact bytes and signature. Omni must deduplicate by `event_id` and handle delivery retries without rescoring. Return any 2xx only after durably accepting the event; AI Platform retries non-2xx or network failures up to five total attempts, then marks the outbox event dead. The receiver uses its tenant key to `GET /v1/lead-scoring/runs/{run_id}`, checks tenant and terminal status, and applies its own latest-run-per-`(tenant, subject)` policy before writing to DotB EMS. The GET response is the result source of truth. Delivery may be repeated after a crash even if Omni previously replied 2xx. Only enable the integration after Omni verifies this fixture, timestamp/replay handling, duplicate delivery and GET/writeback against its consumer. The webhook URL, signing secret and tenant key belong in server-side configuration; never put them in browser code.