Appearance
Connecting self-hosted plugins
There are two ways an app obtains a host's per-install API token, and which one you use depends on where your app runs.
| Your app runs… | Use | Where OAuth happens |
|---|---|---|
| On your own server, at a fixed URL you control | Direct OAuth install | You redirect the host to /oauth/authorize and exchange the code yourself. |
| As a self-hosted plugin installed on each host's own server (WordPress, …), with no single callback URL to register | The connect broker (this page) | Stayblox runs the broker; it relays OAuth for every site. |
The official WordPress plugin is the first of these self-hosted integrations; Framer, Webflow, and others follow the same path.
Why a broker
Direct OAuth needs a redirect_uri that exactly matches one registered in your app manifest. That works when your app is a single hosted service at a stable URL. A self-hosted plugin is the opposite: it runs on each host's own domain (https://anyhotel.example/wp-admin/…), so there is no single callback to register.
The broker solves this with one fixed, registered callback, https://connect.stayblox.com/callback, that serves every site. Stayblox operates it; you deploy nothing. It is a relay in front of the existing OAuth server, not a replacement for it.
One app per platform
Each self-hosted platform is one first-party app (wordpress, framer, …) declaring only the scopes it needs. The broker resolves the right app from a platform slug on each request and uses that app's own credentials, so the WordPress plugin's scopes are independent of Framer's, and adding a platform is just registering another app whose redirect_uri is the broker callback.
The flow
The host clicks "Connect" inside the plugin (on their own site)
│
1. Plugin → GET https://connect.stayblox.com/auth
?platform=wordpress&site_url=…&code_challenge=…&state=…&return=…
│
2. Broker → the real consent screen:
https://admin.stayblox.com/oauth/authorize
(the wordpress app's client_id + scopes; redirect_uri = the broker)
│
3. Host approves → OAuth redirects back to the broker /callback with a code
│
4. Broker exchanges the code at /oauth/token (server-to-server, app secret)
→ receives the install token + webhook secret
│
5. Broker → redirects the browser back to the site's `return` URL with a
single-use handoff code (NOT the token)
│
6. The site's server → POST https://connect.stayblox.com/exchange
{ handoff_code, code_verifier } → receives the token over TLSStep 2 is the same /oauth/authorize an app on its own server would call directly; the broker just stands in the middle so the site doesn't need its own registered redirect_uri.
Security
- The token never rides in a redirect URL. The browser only ever carries a single-use
handoff_code; the token is delivered to the site's server over the back-channel/exchangecall (step 6). - PKCE binds the handoff to the site that started the flow. The plugin keeps a
code_verifierand sends only its SHA-256code_challengeto the broker; the handoff can only be redeemed by presenting the matching verifier, so an intercepted code is useless. - The broker is near-stateless. It keeps nothing permanently: only a short-TTL record of each in-flight flow and handoff. A host's token lives only on that host's own site.
stateis verified on both legs (site↔broker and broker↔OAuth) against CSRF, and the post-connectreturnURL must share the host ofsite_url.