Skip to main content
SandyWP supports public OAuth clients for connector integrations. The generated reference covers the two machine-to-machine contracts: RFC 7591 registration and the RFC 6749 authorization-code exchange with S256 PKCE.

Register a public client

Send JSON to POST /api/connect/register with at least one HTTPS redirect URI. Localhost-like development hosts may use HTTP; fragment URLs are rejected. The response returns a public client_id and no client_secret. Set token_endpoint_auth_method to none (or omit it), then retain the returned client ID for consent and token-exchange requests. Direct the signed-in account holder through SandyWP’s OAuth consent experience with the registered client ID, an exact registered redirect URI, an S256 PKCE challenge, and requested scopes. The browser redirect returns a short-lived, single-use authorization code to your redirect URI. The consent screen also asks which workspace the connection belongs to. It defaults to the workspace that is active in the dashboard. The issued token only acts in that workspace: an X-SandyWP-Workspace header naming any other workspace returns 403, and so does every call after the account leaves the workspace. To work in another workspace, connect again and pick it. Consent is intentionally a browser interaction, not a generated REST endpoint. Never collect a SandyWP password or substitute a client secret for the PKCE verifier.

Exchange the code

POST the code, client_id, redirect_uri, and matching code_verifier to POST /api/connect/token. The endpoint accepts either application/json or application/x-www-form-urlencoded; set grant_type to authorization_code. The response is a bearer access_token and the granted space-separated scope. SandyWP Cloner exchanges also include account_email and site_url; connector responses do not include refresh tokens.

Use scopes deliberately

Scoped OAuth access is narrower than a personal API token. In this generated REST reference, scoped tokens can call GET /api/account/me and the Imports endpoints only, and Import reads/writes require the matching import:read or import:write scope. Treat every access token and authorization code as a credential: keep them out of logs, use TLS, and revoke a connection from the account token endpoint when it is no longer needed.