Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

- Added source-build `Client.analytics.metrics` for scoped Prometheus/OpenMetrics gauges, including denominators, observation times and coverage. Uses Analytics opt-in and `sessions:read`.

- `Client.analytics.get` reads WhatsApp number activity, completed 24-hour read and reply cohorts, response times and connection vitals. Requires `sessions:read` and Analytics enabled by a team owner or admin. Missing coverage returns null rates.

- Hybrid Link tier transitions. `Client.sessions.quoteTierChange` accepts
`hybridResolution` (`keep` one connection or `split` into two Numbers) for a
Hybrid Link Number leaving Pro, or `hybridMerge` to merge a same-number pair
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -936,3 +936,28 @@ or Number authority. Writes require the exact `expectedRevision`, `prefer`, and
## License

MIT

### WhatsApp analytics

`client.analytics.get({projectId, sessionId, start, end})` reads activity,
completed 24-hour direct-chat delivery/read/reply cohorts, response times and
connection vitals. Times are Unix milliseconds and the range is at most 366
days. A project-bound client confines the request to its own project. Requires
`sessions:read` and Analytics enabled by a team owner or admin in the Console.
Disabled results contain no business data. Missing coverage has null rates;
read receipts do not prove an app open. `measured` distinguishes observed zero
activity from a number without telemetry. No contact identities or message
content are returned. See the [Analytics guide](https://docs.polymorfa.com/console/analytics).

### Collector metrics

`client.analytics.metrics({windowHours: 24, format: "openmetrics", segments: true})` returns Prometheus/OpenMetrics text with HTTP metadata, on root and project clients.
Counts are overlapping-window gauges, with denominators, measurement coverage and observation times.
Requires `sessions:read` and the same Analytics opt-in. Disabled exports contain only
enablement and window metadata. [Collector configuration](https://docs.polymorfa.com/console/analytics-collectors).

Analytics responses also expose completed observed phone activity spans and
quiet gaps, duration sums, sample counts and weighted averages. Ranges up to
48 hours use hourly activity buckets; longer ranges and call series use daily
UTC buckets. These signals do not establish phone online/offline or power state.
See the [measurement definitions](https://docs.polymorfa.com/console/analytics#phone-polymorfa-and-customer-activity).
52 changes: 35 additions & 17 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,24 @@ published SDK package before updating their pinned dependency.

## Full snapshots

The current snapshots are byte-identical copies of Messaging and Platform
contracts at API implementation commit `ac1c7010d5c3cdf0262f1b5deb2c4d7ce6a249a5` on
`t3code/project-billing-dashboard`. This branch is unmerged. Seven financial
operations cover limits, priorities, complete ordering and one-resource combined
read/save. Project priority takes precedence. Numbers inherit customer priority;
a higher number priority overrides it within the project. Customer limits still
include all assigned numbers.
Initial real QuickLink creation accepts optional billing controls before admission.
This integrated source inherits five private Console operations: Settings
Activity, the retained-log calendar, project logging reads, sampling writes and
HTTPS drain writes. All require dashboard identity and remain excluded from
server SDK authority. The already-excluded `logsInsight` fingerprint changes
only for its server-side `filters` and `search` parameters. All public and other
existing operation fingerprints remain unchanged. The ledger contains 574
operations: 429 covered and 145 excluded. The financial methods operate actual
monthly credit-debit limits; the separate nested included-usage/overage quota
model remains an unshipped prototype outside those methods.
The current snapshots are byte-identical copies of the Messaging and Platform
contracts at API dev merge commit `171a9683ff45d11a4b5d3917dc428ad2722b0d99`.
The full revision contains the inherited Logs and Usage contracts and all four
public Analytics reads. The ledger contains 579 operations: 433 covered and
146 excluded, with no missing, partial or changed fingerprints. Six reviewed
Console changes cover analytics projections, consent preferences, operational
error vitals and shared drains. They require dashboard identity and remain
excluded from server SDK authority.

The seven financial operations cover limits, priorities, complete ordering and
one-resource combined read/save. Project priority takes precedence. Numbers
inherit customer priority; a higher number priority overrides it within the
project. Customer limits include all assigned numbers. Initial real QuickLink
creation accepts optional billing controls before admission. These methods
operate actual monthly credit-debit limits; the separate nested included-usage
quota prototype remains outside those methods. Reads require `billing:read`;
writes require `billing:manage`, live team authority and Pay-As-You-Go.
SDK publication and API deployment remain separate gates.

The preceding repin at `b8fa167e47c901131d3bd9865e6479b153ad5157`
added only the private Console `listConsoleNumberOptions` operation,
Expand Down Expand Up @@ -286,6 +287,9 @@ exported `ContactOptPayload`. The unproduced `bansafe.health_changed`,
`bansafe.risk_changed`, and `bansafe.enforcement` names are retired. Historical
signed events with these names still decode as unknown events.

The base contract snapshot below excludes the four WhatsApp business analytics
reads described at the end of this document.

| Status | Operations |
| ------------------- | ---------: |
| Covered | 422 |
Expand Down Expand Up @@ -467,3 +471,17 @@ spec while the beta has no audience. The full snapshots stay pinned to
coverage ledger as `Client.campaigns.recordConversion` and
`Client.campaigns.conversions`. `campaign-conversions-contract.test.ts`
compares the exported types with the supplement.

## WhatsApp business analytics contract

`Client.analytics.get` covers the team and project Analytics reads.
The strict response contains number/project-scoped messaging aggregates,
retained-call outcomes, measured timings, quality, failure categories,
missed-call follow-up and daily call series. `Client.analytics.metrics` covers
the two collector reads and returns Prometheus/OpenMetrics text rather than
a JSON envelope. All four use scoped reader authority and Analytics opt-in.

The full Platform snapshot, each Analytics operation and `source.json` pin the
same API source revision. Reconciliation tests check exact snapshot hashes and
strict operation fingerprints. Counts do not establish package publication or
customer access.
79 changes: 73 additions & 6 deletions contracts/coverage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"sourceCommit": "ac1c7010d5c3cdf0262f1b5deb2c4d7ce6a249a5",
"sourceCommit": "171a9683ff45d11a4b5d3917dc428ad2722b0d99",
"excludedContracts": [
{
"family": "graph",
Expand Down Expand Up @@ -2956,7 +2956,7 @@
"method": "GET",
"path": "/console/insights/analytics",
"operationId": "analyticsInsight",
"fingerprint": "6574426025ecc2f85e5cb33c616ea91170789fb3834f7dbc4a609358df4e79a6",
"fingerprint": "09f2d7ba74398a51e05102ab22bb7e137f6e6019825574615b9a095a9005976c",
"typescript": {
"status": "excluded",
"reason": "Console-only operation requires dashboard identity; not available to SDK credentials."
Expand Down Expand Up @@ -3000,7 +3000,7 @@
"method": "GET",
"path": "/console/insights/preferences",
"operationId": "getInsightPreferences",
"fingerprint": "7bfc1895f88c744415f0e1db6915e7afcad8414c1debeaf0ff5e154f2aa7e01e",
"fingerprint": "6e65a8a39cf4e9952e71073ee9c0446be4a3e02ba3d70a67471092f8c2be0851",
"typescript": {
"status": "excluded",
"reason": "Console-only operation requires dashboard identity; not available to SDK credentials."
Expand Down Expand Up @@ -3088,7 +3088,7 @@
"method": "GET",
"path": "/console/projects/{projectId}/logging",
"operationId": "getProjectLogging",
"fingerprint": "ee09b8d569d9b33bd5e65c1ead0bb2b71ee4b8e8e766627bb97a99e24f78fc19",
"fingerprint": "00ccc14321453e8653c1cde355a42bdea78d7d3bace5b7a95bbc13d4f82d5b3a",
"typescript": {
"status": "excluded",
"reason": "Console-only operation requires dashboard identity; organization API keys and project tokens are not accepted."
Expand Down Expand Up @@ -6033,7 +6033,7 @@
"method": "PUT",
"path": "/console/insights/preferences",
"operationId": "updateInsightPreferences",
"fingerprint": "987095e182ff41ca660e7531f0343ad0e22a5c59f39ec730cd56a7feb7e78565",
"fingerprint": "596ecaa4a34cc9c991aa33aabadf76670f970291a15f721bb8567076c3fb6048",
"typescript": {
"status": "excluded",
"reason": "Console-only operation requires dashboard identity; not available to SDK credentials."
Expand Down Expand Up @@ -6077,7 +6077,7 @@
"method": "PUT",
"path": "/console/projects/{projectId}/logging/drains",
"operationId": "saveProjectDrain",
"fingerprint": "d6464828734345de6640155503d469531741f527bcb1bcd24d28ecdc15d39aae",
"fingerprint": "d8de37aca07f8b8b24c4ed5444896dfd7458c3b248a010750ac445a096f28f33",
"typescript": {
"status": "excluded",
"reason": "Console-only operation requires dashboard identity; organization API keys and project tokens are not accepted."
Expand Down Expand Up @@ -6335,6 +6335,73 @@
"status": "covered",
"method": "Client.sessions.updateSafeMode"
}
},
{
"family": "platform",
"method": "GET",
"path": "/platform/analytics",
"operationId": "getWhatsAppAnalytics",
"fingerprint": "1ac8b2438ef13263289d71f0d956fd3f7b60b44ac0999151bc96f30d31798b91",
"typescript": {
"status": "covered",
"method": "Client.analytics.get"
},
"sourceContractSha256": "71454ab4bb66d844aeedd325d9a62086cd6b6ba39a135197fd4f5ca29ef089e8",
"sourceCommit": "171a9683ff45d11a4b5d3917dc428ad2722b0d99",
"sdkContractSha256": "71454ab4bb66d844aeedd325d9a62086cd6b6ba39a135197fd4f5ca29ef089e8"
},
{
"family": "platform",
"method": "GET",
"path": "/platform/projects/{projectId}/analytics",
"operationId": "getProjectWhatsAppAnalytics",
"fingerprint": "dc6ab3ff0e56d2e97c26fb64c2090b8b8f900a0f09c86e221f84932e9fb0a36f",
"typescript": {
"status": "covered",
"method": "Client.analytics.get"
},
"sourceContractSha256": "71454ab4bb66d844aeedd325d9a62086cd6b6ba39a135197fd4f5ca29ef089e8",
"sourceCommit": "171a9683ff45d11a4b5d3917dc428ad2722b0d99",
"sdkContractSha256": "71454ab4bb66d844aeedd325d9a62086cd6b6ba39a135197fd4f5ca29ef089e8"
},
{
"family": "platform",
"method": "GET",
"path": "/platform/analytics/metrics",
"operationId": "exportWhatsAppAnalyticsMetrics",
"typescript": {
"status": "covered",
"method": "Client.analytics.metrics"
},
"fingerprint": "520ce37bc6a198e313d9495ddd968ebb54cbbe5cc84f4d6bea636c43a4ea62c5",
"sourceContractSha256": "71454ab4bb66d844aeedd325d9a62086cd6b6ba39a135197fd4f5ca29ef089e8",
"sdkContractSha256": "71454ab4bb66d844aeedd325d9a62086cd6b6ba39a135197fd4f5ca29ef089e8",
"sourceCommit": "171a9683ff45d11a4b5d3917dc428ad2722b0d99"
},
{
"family": "platform",
"method": "GET",
"path": "/platform/projects/{projectId}/analytics/metrics",
"operationId": "exportProjectWhatsAppAnalyticsMetrics",
"typescript": {
"status": "covered",
"method": "Client.analytics.metrics"
},
"fingerprint": "56e2540bc5d78c3f458fbd363d63b101df49fcd273b7cc81e1fa9318d69b30b6",
"sourceContractSha256": "71454ab4bb66d844aeedd325d9a62086cd6b6ba39a135197fd4f5ca29ef089e8",
"sdkContractSha256": "71454ab4bb66d844aeedd325d9a62086cd6b6ba39a135197fd4f5ca29ef089e8",
"sourceCommit": "171a9683ff45d11a4b5d3917dc428ad2722b0d99"
},
{
"family": "platform",
"method": "GET",
"path": "/console/insights/vitals",
"operationId": "getConsoleErrorVitals",
"fingerprint": "4c3c1667cc5f2feb631064100976c3e399cd917cb29e4f336b85baf81335e217",
"typescript": {
"status": "excluded",
"reason": "Dashboard-only operational error vitals require a live Console identity; server API keys do not grant this authority."
}
}
]
}
Loading
Loading