OAuth2 for third-party apps
Only for apps that other WASync customers install. Authorization Code with PKCE, rotating refresh tokens, and one structural limit.
Skip this if you are automating your own account
An API key does everything in these docs with none of the machinery. OAuth is the right tool for exactly one job: your app is installed by other WASync customers, and those customers have to consent to connections they own.
Register the app
Register at https://developers.wasync.app/apps. You get a client_id and a
client_secret (shown once), and you set one or more redirect_uri (matched
exactly at token exchange), an optional webhook_url, and the scopes you need.
The flow
Authorization Code with PKCE — S256 is required. Send the user to
/oauth/authorize with response_type=code, your client_id, redirect_uri,
scope, a state and a code_challenge.
| Endpoint | URL |
|---|---|
| Authorize | https://cloudapi.wasync.app/oauth/authorize |
Token (client_secret_post) | https://cloudapi.wasync.app/oauth/token |
| Discovery | https://cloudapi.wasync.app/.well-known/oauth-authorization-server |
These URLs — and the MCP server URL — read
cloudapi.wasync.app on purpose. They are protocol identifiers your client
library and our discovery documents have already registered, so they must match
byte-for-byte. Only the REST base URL and the human-facing pages use the
canonical developers.wasync.app.
Consent depends on who owns the connections
Bitrix24. WASync shows a short user code, and the portal admin enters it under Settings → API & Agents, picking connections and scopes.
Standalone. The developer approves at https://developers.wasync.app/authorize — auto-approved when they own exactly one workspace with at least one connection.
Exchange the code
curl -X POST https://cloudapi.wasync.app/oauth/token \
-d grant_type=authorization_code \
-d code=$AUTH_CODE \
-d redirect_uri=https://your.app/callback \
-d client_id=$CLIENT_ID \
-d client_secret=$CLIENT_SECRET \
-d code_verifier=$CODE_VERIFIERaccess_token lives 15 minutes. refresh_token lives 30 days and rotates
on use — persist the new one atomically and serialise refreshes across
workers, or two workers racing will invalidate each other's token.
The access token goes in the same header as an API key:
Authorization: Bearer …. Both credential types reach every endpoint.
One structural limit
A grant is only ever issued over connections that already exist, so an OAuth-only integration cannot create a workspace's first connection. An API key can — which is why the quickstart starts with one.
Webhooks for OAuth apps
An OAuth app sets webhook_url on the app itself rather than calling
PUT /webhook, and the grant must have been approved with whatsapp.events
or nothing is delivered. Everything else — the signature scheme, the retry
policy, the payloads — is identical to the Webhooks
guide.
Subscriptions created before 24 July 2026 receive only message.received;
those created before 10 August 2026 do not receive the connection events.
Re-authorize to pick up the newer event types, or write to support and ask for
them to be added to your existing subscription.