Install
Installation is the process of linking your app to a user's xPage hosting. There are three flows — the right one depends on whether your app needs to interact with the user during installation, and who initiates it.
A. Direct flow
The simplest flow. xPage sends a signed POST request directly to your install_url. If you return HTTP 200, the install is activated immediately.
What xPage sends
POST {your install_url}
Content-Type: application/json
X-XPage-Signature: sha256=<hmac>
{
"event": "app.installed",
"install_id": "uuid",
"timestamp": 1700000000
}
The X-XPage-Signature header is computed as:
sha256=HMAC-SHA256(raw_json_body, signing_secret)
What you must do
- Verify the signature — compute
HMAC-SHA256(raw_json_body, your_signing_secret)and compare with the header value using a constant-time comparison. - Store the
install_id— you will use it to scope API tokens. - Return HTTP 200 (no body required).
Any non-200 response causes xPage to mark the install as inactive.
Sequence
B. Redirect flow
Use this when your app needs to show a UI during installation (e.g. an onboarding form or OAuth prompt). xPage redirects the user to your install_url with a signed payload; you verify it, handle your setup, then call back to xPage to confirm.
Step 1 — Receive the redirect
xPage redirects the user's browser to:
GET {your install_url}?install_id=<uuid>&state=<encrypted>×tamp=<unix>&hmac=<hmac>
| Param | Description |
|---|---|
install_id | The install UUID |
state | Opaque value issued by xPage — do not parse or modify it |
timestamp | Unix timestamp of when the redirect was generated |
hmac | HMAC-SHA256 signature to verify the request |
Verify the HMAC before processing anything:
HMAC-SHA256(ksort(params_except_hmac), signing_secret)
Reconstruct the query string from the parameters sorted alphabetically by key (excluding hmac), then compute the HMAC using your signing_secret. Compare with the received hmac using a constant-time comparison.
Step 2 — Confirm the install
Once you've completed your setup, call the xPage callback endpoint from your backend, passing back the original state and a new HMAC signed with your signing_secret:
POST /api/apps/v1/auth/confirm-install
Authorization: Bearer <token>
{
"state": "<original_state>",
"hmac": "<hmac>"
}
The HMAC for the callback is computed the same way — sort params alphabetically, build the query string, then sign:
HMAC-SHA256("state=<original_state>", signing_secret)
xPage will verify the request and, if valid, activate the install and return:
{
"data": {
"install": { ... },
"boot_url": "https://..."
}
}
Redirect the user to boot_url. From here, xPage takes over and boots your app — see App Boot for what happens next.
Sequence
C. External install (app-initiated)
Use this when your app wants to initiate the xPage installation from within your own UI — for example, a "Connect to xPage" button on your website. Unlike flows A and B which start from the xPage marketplace, this flow is initiated by your app.
Step 1 — Redirect the user to xPage
From your server, construct and sign the install request, then redirect the user's browser to:
GET /api/apps/v1/auth/install?client_id=...×tamp=...&redirect_uri=...&state=...&hmac=...
| Param | Required | Description |
|---|---|---|
client_id | Yes | Your app's public client identifier |
timestamp | Yes | Current Unix timestamp — must be within 60 seconds |
redirect_uri | Yes | Where xPage will redirect the user after approval |
state | No | Opaque value you generate to track the session (e.g. a random nonce) |
hmac | Yes | HMAC-SHA256 signature |
Sign all params (excluding hmac, omitting null values) sorted alphabetically:
HMAC-SHA256(ksort(params_except_hmac), signing_secret)
The HMAC must be computed server-side using your signing_secret. Never expose your signing secret to the browser.
The request is only accepted for 60 seconds. Generate the signed URL immediately before redirecting — do not cache it.
Step 2 — User approves on xPage
xPage verifies your signature and presents the user with a consent screen showing your app's required permissions. The user logs in (if not already), selects a hosting, and approves.
No action is required from you during this step. The consent token is valid for 15 minutes — if the user takes longer, they will need to restart the flow.
Step 3 — Receive the signed callback
Once the user approves, xPage redirects to your redirect_uri:
GET {redirect_uri}?install_id=<uuid>×tamp=<unix>&state=<your_state>&hmac=<hmac>
| Param | Description |
|---|---|
install_id | The newly created install UUID |
timestamp | Unix timestamp of when the callback was issued |
state | The state value you passed in step 1 (omitted if not provided) |
hmac | HMAC-SHA256 signature to verify the callback |
Verify the HMAC before trusting any values:
HMAC-SHA256(ksort(params_except_hmac), signing_secret)
Then store the install_id — use it to generate restricted tokens for all subsequent API calls.
Generate a cryptographically random state value before redirecting and store it in your session. When the callback arrives, verify the returned state matches before processing the install_id.
Sequence
App Boot
Every time xPage loads your app's iframe, it appends a short-lived ?code=<auth_code> to the URL. This happens both on the first load after installation and on every subsequent load.
Your frontend receives this code and must forward it to your backend immediately. Your backend exchanges it for the install_id of the current session.
POST /api/apps/v1/auth/exchange
Authorization: Bearer <token>
{
"auth_code": "<code from iframe URL>"
}
{
"data": {
"install_id": "uuid"
}
}
The code expires after 60 seconds and is consumed on first use. Forward it to your backend immediately on page load — never cache or reuse it.
Use the returned install_id to generate a restricted token (see Auth) and scope all subsequent API calls to that installation.