Skip to content
Open
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
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ packages/*/dist/
coverage/
contracts/openapi.messaging.json
contracts/openapi.platform.json
contracts/drafts/bansafe/openapi.messaging.json
contracts/drafts/bansafe/openapi.platform.json
package-lock.json
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## Unreleased

- Added typed BanSafe Health, telemetry, collection, findings, enforcement,
incidents, claims, and Health action reads to `Client.banSafe`.
Project and session resources now cover Safe Mode, warm-up, Ban Insurance
evidence, and Health policy settings. Dashboard-only finding acknowledgement
and appeals remain outside the server-key client.

- Aligned public requests with the `/messaging` and `/platform` namespaces.
Typed HTTP errors now preserve the canonical nested error code and message.

- Export typed terminal Calls webhooks. `call.ended` preserves a nullable caller
identity for `pod_lost`; `call.telemetry` preserves cumulative traffic values.

Expand Down Expand Up @@ -103,7 +112,7 @@
and localized through new `calls.*` messages; `pmfa-call` follows the same
controller contract.
- Refreshed the Messaging and Platform contracts and the coverage ledger for
the `/api/voip/*` signaling routes and the `call.ended` / `call.telemetry`
the `/messaging/voip/*` signaling routes and the `call.ended` / `call.telemetry`
webhook events.

## 0.1.0-dev.0 - 2026-08-19
Expand Down
18 changes: 12 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,15 @@ The organization view also exposes these management resources:
- `projectTokens`: list token metadata for an explicit project
- `billing`: retrieve balance and currency, inspect usage meters, list
transactions and tier pricing, and update low-balance reminders
- `projects`: list, create, request production enrollment, approve, and cancel
- `banSafe`: inspect Health, telemetry collection, signal definitions, findings,
restrictions, incidents, claims, and Health action history; report and retract
customer incidents
- `projects`: list, create, request production enrollment, approve, and cancel;
retrieve and update Safe Mode, warm-up, Ban Insurance evidence, and Health
policy settings
- `sessions`: list, start, stop, or delete one session; stop or delete a bounded
batch; set tier override; and create a testing session
batch; set tier override; create a testing session; and retrieve or update
the session Safe Mode override
- `campaigns`: list, create, retrieve, update, delete, lifecycle actions,
analytics, events, and recipients
- `customers`: enable Customers for a project; create, list, retrieve, update,
Expand Down Expand Up @@ -323,14 +329,14 @@ Every client exposes `raw.request<T>()` for deliberate API escape hatches:
```ts
const response = await client.raw.request<{ data: unknown }>({
method: "GET",
path: "/v1/operations/operation_123",
path: "/platform/operations/operation_123",
query: { projectId: "project_123" },
});
```

Organization raw paths remain relative API paths. Project raw paths are
relative to the bound project and receive the encoded
`/v1/projects/{projectId}` prefix automatically. Project raw requests reject
`/platform/projects/{projectId}` prefix automatically. Project raw requests reject
absolute URLs, traversal, explicit project prefixes, backslashes, and
`Authorization` overrides before transport. Raw requests retain typed errors,
metadata, cancellation, API versions, retry rules, and idempotency.
Expand Down Expand Up @@ -386,7 +392,7 @@ helpers.
## QuickLink lifecycle and settings

`MessagingClient.quickLinks.create()`, `retrieve()`, and `cancel()` map the
authenticated hosted lifecycle at `/api/quicklinks`. They accept organization
authenticated hosted lifecycle at `/messaging/quicklinks`. They accept organization
API keys or project tokens with `quicklink:manage`; browser client tokens fail
before transport. Organization keys can set `projectId` on creation, while a
project token remains bound by the server.
Expand All @@ -395,7 +401,7 @@ These methods expose the short-lived connection URL and status record. They do
not add list, recovery, or history operations that the API does not provide.

`client.quickLinkSettings.retrieve()` and `update()` map only the management
`GET /v1/quicklink` and `PUT /v1/quicklink` settings contract. The same methods
`GET /platform/quicklink` and `PUT /platform/quicklink` settings contract. The same methods
on `client.project(projectId)` use the immutable project ownership context.

## Browser controllers and UI
Expand Down
9 changes: 9 additions & 0 deletions contracts/drafts/bansafe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# BanSafe draft contracts

These files are byte-identical copies of the BanSafe API pull request specs at
the commit and hashes recorded in `source.json`. These snapshots do not claim a
merged Polymorfa source revision or published SDK parity.

The canonical files under `contracts/` and their coverage ledger stay pinned to
the last merged source revision. Replace that pin only after the API changes
land at one exact commit and the coverage ledger has been reconciled.
199 changes: 199 additions & 0 deletions contracts/drafts/bansafe/coverage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
{
"schemaVersion": 1,
"platformSha256": "a7f9d3b449aa93ebdf1e52c5c04519dd405d963a2da59db85d43748f671c95bf",
Comment thread
purpshell marked this conversation as resolved.
"scope": "OpenAPI operations tagged bansafe",
"covered": 25,
"excluded": 2,
"missing": 0,
"operations": [
{
"operationId": "listBanSafeHealth",
"method": "GET",
"path": "/platform/bansafe/health",
"status": "covered",
"sdkPath": "Client.banSafe.listHealth"
},
{
"operationId": "getBanSafeHealth",
"method": "GET",
"path": "/platform/bansafe/health/{session}",
"status": "covered",
"sdkPath": "Client.banSafe.getHealth"
},
{
"operationId": "listBanSafeHealthHistory",
"method": "GET",
"path": "/platform/bansafe/health/{session}/history",
"status": "covered",
"sdkPath": "Client.banSafe.listHealthHistory"
},
{
"operationId": "listBanSafeSignals",
"method": "GET",
"path": "/platform/bansafe/signals",
"status": "covered",
"sdkPath": "Client.banSafe.listSignals"
},
{
"operationId": "getBanSafeTelemetry",
"method": "GET",
"path": "/platform/bansafe/telemetry/{session}",
"status": "covered",
"sdkPath": "Client.banSafe.getTelemetry"
},
{
"operationId": "listBanSafeTelemetryHistory",
"method": "GET",
"path": "/platform/bansafe/telemetry/{session}/history",
"status": "covered",
"sdkPath": "Client.banSafe.listTelemetryHistory"
},
{
"operationId": "listBanSafeCollection",
"method": "GET",
"path": "/platform/bansafe/collection",
"status": "covered",
"sdkPath": "Client.banSafe.listCollection"
},
{
"operationId": "listBanSafeHealthActions",
"method": "GET",
"path": "/platform/bansafe/health-actions",
"status": "covered",
"sdkPath": "Client.banSafe.listHealthActions"
},
{
"operationId": "listBanSafeFindings",
"method": "GET",
"path": "/platform/bansafe/findings",
"status": "covered",
"sdkPath": "Client.banSafe.listFindings"
},
{
"operationId": "acknowledgeBanSafeFinding",
"method": "POST",
"path": "/platform/bansafe/findings/{findingId}/acknowledge",
"status": "excluded",
"reason": "Requires signed-in dashboard identity; server API keys and project tokens are refused."
},
{
"operationId": "listBanSafeEnforcement",
"method": "GET",
"path": "/platform/bansafe/enforcement",
"status": "covered",
"sdkPath": "Client.banSafe.listEnforcement"
},
{
"operationId": "appealBanSafeEnforcement",
"method": "POST",
"path": "/platform/bansafe/enforcement/{session}/appeal",
"status": "excluded",
"reason": "Requires signed-in dashboard identity; server API keys and project tokens are refused."
},
{
"operationId": "listBanSafeIncidents",
"method": "GET",
"path": "/platform/bansafe/incidents",
"status": "covered",
"sdkPath": "Client.banSafe.listIncidents"
},
{
"operationId": "createBanSafeIncident",
"method": "POST",
"path": "/platform/bansafe/incidents",
"status": "covered",
"sdkPath": "Client.banSafe.createIncident"
},
{
"operationId": "retractBanSafeIncident",
"method": "POST",
"path": "/platform/bansafe/incidents/{incidentId}/retract",
"status": "covered",
"sdkPath": "Client.banSafe.retractIncident"
},
{
"operationId": "listBanSafeClaims",
"method": "GET",
"path": "/platform/bansafe/claims",
"status": "covered",
"sdkPath": "Client.banSafe.listClaims"
},
{
"operationId": "getBanSafeClaim",
"method": "GET",
"path": "/platform/bansafe/claims/{claimId}",
"status": "covered",
"sdkPath": "Client.banSafe.getClaim"
},
{
"operationId": "getProjectSafeModeCeiling",
"method": "GET",
"path": "/platform/projects/{projectId}/safe-mode",
"status": "covered",
"sdkPath": "Client.projects.getSafeMode"
},
{
"operationId": "updateProjectSafeModeCeiling",
"method": "PUT",
"path": "/platform/projects/{projectId}/safe-mode",
"status": "covered",
"sdkPath": "Client.projects.updateSafeMode"
},
{
"operationId": "getNumberSafeMode",
"method": "GET",
"path": "/platform/sessions/{sessionId}/safe-mode",
"status": "covered",
"sdkPath": "Client.sessions.getSafeMode"
},
{
"operationId": "updateNumberSafeMode",
"method": "PUT",
"path": "/platform/sessions/{sessionId}/safe-mode",
"status": "covered",
"sdkPath": "Client.sessions.updateSafeMode"
},
{
"operationId": "getProjectWarmupPlanSettings",
"method": "GET",
"path": "/platform/projects/{projectId}/warmup-plan",
"status": "covered",
"sdkPath": "Client.projects.getWarmupPlan"
},
{
"operationId": "updateProjectWarmupPlanSettings",
"method": "PUT",
"path": "/platform/projects/{projectId}/warmup-plan",
"status": "covered",
"sdkPath": "Client.projects.updateWarmupPlan"
},
{
"operationId": "getProjectHealthPolicySettings",
"method": "GET",
"path": "/platform/projects/{projectId}/health-policy",
"status": "covered",
"sdkPath": "Client.projects.getHealthPolicy"
},
{
"operationId": "updateProjectHealthPolicySettings",
"method": "PUT",
"path": "/platform/projects/{projectId}/health-policy",
"status": "covered",
"sdkPath": "Client.projects.updateHealthPolicy"
},
{
"operationId": "getInsuranceEvidenceSettings",
"method": "GET",
"path": "/platform/projects/{projectId}/insurance-evidence",
"status": "covered",
"sdkPath": "Client.projects.getInsuranceEvidence"
},
{
"operationId": "updateInsuranceEvidenceSettings",
"method": "PUT",
"path": "/platform/projects/{projectId}/insurance-evidence",
"status": "covered",
"sdkPath": "Client.projects.updateInsuranceEvidence"
}
]
}
Loading