Skip to main content
The Platform API provides team, project, billing, Customer, campaign, template, session, and embedded-signup endpoints under /platform/*.

Authentication

Each generated endpoint page lists its supported credential. Server automation endpoints accept a pmfa_… team key, a pmfa_pt_… project token when the endpoint has a project or session boundary, or a verified dashboard bearer. Endpoints that authorize an action by a specific member accept only a verified dashboard bearer. This dashboard-only group includes team and member changes. Team and member changes require an team owner or admin. Template and flow operations accept machine credentials when their project boundary and required action scope both match. Template responses identify drafts with id and createdAt. Template list responses contain at most 500 drafts. Each generated operation publishes its required action in x-required-scope and its authority in x-polymorfa-resource-boundary. Project tokens are accepted for project and session operations inside their authenticated project. team operations such as billing, membership, team settings, project creation, and team API-key administration return 403. human_only operations require a dashboard bearer. A foreign or conflicting project selector returns 404 resource not found.

Public domains

The Platform API supports session management and testing numbers, number safety, campaign listing, message-template management, billing and usage reads, team settings, projects, members, and QuickLink settings. Use only the endpoints documented in the generated reference. Team-key callers use quicklink:manage (the historical name widget:create is still accepted); project-token callers use the same permission inside their authenticated project; dashboard callers use their active team membership. Client tokens are rejected. Team-key and dashboard callers pass projectId to read or update project-specific settings. A project-token caller may omit it or pass the exact authenticated project id. See Saved settings for the supported fields.

Session-management endpoints

Team-key and project-token callers need sessions:manage. A project token can affect only sessions in its authenticated project. Dashboard callers need current membership and authorization in the active team. Create real and simulated sessions through QuickLink. For a simulated account, send configuration.testing. When Customers is enabled, customerId selects a Customer in the same project; omitting it assigns the protected Default customer. sessionId accepts a session UUID or a stable session slug up to 64 characters. Batch requests accept 1–100 unique identifiers in sessionIds. The two deletion endpoints remove testing numbers immediately. A production number, or a batch containing one, returns 409 without removing any number. Contact support through the Help Center to delete a production number. tierOverride is free, standard, pro, or null to inherit the project plan. Testing-number country accepts one of the 243 WhatsApp-supported ISO alpha-2 country codes in the generated schema and defaults to US. name is an optional 1–100 character display name. Start requests connect a stopped testing number immediately or request a real session start. Stop requests acknowledge an asynchronous stop request. Delete requests permanently remove the session and end its active connection when needed. The generated endpoint pages document the exact validation, not-found, and temporary service-error responses for each endpoint. Open the method reference inside the matching task guide for every path, parameter, body, response, and shared schema. If you generated a private client from an older Platform contract, follow Regenerate Platform API clients.

Customers

Customer reads require customers:read. Enabling Customers, changing records, and creating or revoking pairing links require customers:manage. Team credentials supply projectId for collection requests. A project token is already bound to one project and cannot select another. Dashboard mutations also require a live owner or admin membership. Pairing-link creation accepts optional expectedPhone, methods, and expiresInSeconds. methods contains qr, phone, or both. Expiry accepts 900 through 604800 seconds and defaults to 86400 seconds. The raw URL appears only in the create response. See Customers and Customer pairing links for Console and recipient workflows.

BanSafe

BanSafe reads use sessions:read. Reporting a ban and withdrawing a report use sessions:manage. Project tokens can read and report on their own numbers; a number in another project returns 404. Withdrawing a report requires a team key. GET /platform/bansafe/health requires projectId. The {session} segment accepts a session UUID or a stable session slug. List responses are cursor-paginated with a maximum page size of 100; the health history accepts since and a limit up to 720. It returns the newest matching points, ordered oldest to newest. Telemetry history accepts since, until, an opaque cursor, and a limit from 1 to 50. It defaults to 10 and returns snapshots newest first. Health actions accept projectId, session, public status, cursor, and a limit up to 100. Team credentials supply projectId; a project token is bound to its own project. health is null without a supported estimate or enough fresh evidence. Read healthSource, healthEstimatorVersion, healthUnavailableReason, healthEvaluatedAt, healthFeatureCoverage, healthReliability, and healthExplanation with it. The rules-v1 source has rules_based reliability and null model probabilities. Provider-observed account state and retained findings are separate from the estimate. Telemetry responses expose only catalogue-backed aggregate signals. They do not return raw stored records, message or recipient identifiers, runtime identifiers, device fingerprints, or free-form error text. An unmeasured signal has null value, sampleSize, and codes; zero remains a measured value. See Telemetry and collection. Every recorded finding carries the text to display: title names the retained check, summary is its evidence sentence, fix is its recorded guidance, and its timestamps show when the condition was observed. These rows are historical and do not explain or change current Health. Display them as returned rather than keeping another copy of their wording. POST /platform/bansafe/incidents requires an Idempotency-Key header. Reuse it only to retry the same number’s report. Reusing it for another number returns 409 bansafe_incident_idempotency_scope_conflict. Retracting withdraws a ban you reported. It applies only to your own reports: a restriction Polymorfa observed from WhatsApp answers 409 bansafe_incident_not_a_report and stays on the record. Send no request body. The response includes nullable closedAt, closedBy, and claimId, alongside the incident’s other fields. An unknown incident returns 404, and an invalid incident identifier returns 400. Ban Insurance claims are read-only. A claim is filed for you when a ban is recorded for a number covered by Pro at the incident time, and a person reviews it before credits are returned; there is no request that files, approves, or appeals one. Filter the list by projectId, session, and status. See BanSafe, Findings, Restrictions, and Ban Insurance.

Safe Mode

Safe Mode governs how a number sends: whether it goes online, whether it shows a typing indicator, whether it marks incoming messages read, and how it paces. Set the project ceiling, then tighten any single number against it. Reading needs sessions:read and changing needs sessions:manage. {sessionId} accepts a session UUID or a stable session slug. A signed-in Console caller must be an team owner, admin, or developer to change Safe Mode; reading needs team membership. A PUT body is a partial update: send only the settings you want to change. Every setting is off by default. Each setting on a number also accepts inherit to follow the project ceiling, and an override may only be equally or more conservative than the ceiling. Both GET responses answer the plan question before you send a change. entitled is true when a raise is allowed, and entitlementReason carries the sentence a refused raise would return, or null when the plan includes Safe Mode. On a project, entitled is true when at least one number in the project is on a plan that includes BanSafe Lite; on a number, it is that number’s own plan. The same four operations are on the Messaging API for server-to-server callers, with the same settings, codes, and behaviour:
See Safe Mode.

Warm-up plan

A warm-up plan gives every number in a project a daily message allowance that ramps over the number’s first weeks and moves with its health band. Reading needs sessions:read and changing needs sessions:manage. A signed-in Console caller must be an team owner, admin, or developer to change the plan; reading needs team membership. A PUT body is a partial update over enabled, warmupDays (1 to 90), and dailyStart (1 to 2000). The plan is off until a request turns it on, and turning it off is always allowed. While the plan is on, a send past a number’s allowance is refused with 429 bansafe_daily_allowance_reached; a campaign recipient is deferred to the next reset. If durable accounting is unavailable, the send stops before transport with 503 bansafe_accounting_unavailable and retryAfter: 5. A conflicting attempt returns 409 bansafe_send_outcome_unknown and must not be retried automatically. The same two operations are on the Messaging API for server-to-server callers, with the same settings, codes, and behaviour:
GET /platform/bansafe/health/{session} includes a warmup block with enabled, tenureDay, allowance, sentToday, resetsAt, and curve. A disabled plan has a null allowance and reset, and an empty curve. sentToday comes from the durable active allowance window and is 0 before its first reservation. Health history contains accepted Health evaluations only and does not carry allowance fields. See Warm-up plan.

Ban insurance evidence

Ban insurance evidence lets Polymorfa measure what the other devices linked to a number do with it. The counts help a reviewer assess a Ban Insurance claim. Collection is off until a request turns it on. Reading needs sessions:read and changing needs sessions:manage. A signed-in Console caller must be an team owner, admin, or developer to change the setting; reading needs team membership. A PUT body carries one field, enabled, and it is required. The response carries projectId, enabled, and banInsuranceIncluded. banInsuranceIncluded is true when at least one number in the project has insurance included in its plan. The plan does not gate the setting: you can turn evidence on before a number is on Pro, and the evidence is already there for a ban after the upgrade. The same two operations are on the Messaging API for server-to-server callers, with the same settings, codes, and behaviour:
See Ban Insurance.