Skip to content

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…UseWhere OAuth happens
On your own server, at a fixed URL you controlDirect OAuth installYou 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 registerThe 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 TLS

Step 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 /exchange call (step 6).
  • PKCE binds the handoff to the site that started the flow. The plugin keeps a code_verifier and sends only its SHA-256 code_challenge to 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.
  • state is verified on both legs (site↔broker and broker↔OAuth) against CSRF, and the post-connect return URL must share the host of site_url.

© Stayblox — Developer Platform