Skip to main content

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

  1. Verify the signature — compute HMAC-SHA256(raw_json_body, your_signing_secret) and compare with the header value using a constant-time comparison.
  2. Store the install_id — you will use it to scope API tokens.
  3. 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>&timestamp=<unix>&hmac=<hmac>
ParamDescription
install_idThe install UUID
stateOpaque value issued by xPage — do not parse or modify it
timestampUnix timestamp of when the redirect was generated
hmacHMAC-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=...&timestamp=...&redirect_uri=...&state=...&hmac=...
ParamRequiredDescription
client_idYesYour app's public client identifier
timestampYesCurrent Unix timestamp — must be within 60 seconds
redirect_uriYesWhere xPage will redirect the user after approval
stateNoOpaque value you generate to track the session (e.g. a random nonce)
hmacYesHMAC-SHA256 signature

Sign all params (excluding hmac, omitting null values) sorted alphabetically:

HMAC-SHA256(ksort(params_except_hmac), signing_secret)
Sign server-side

The HMAC must be computed server-side using your signing_secret. Never expose your signing secret to the browser.

Timestamp validity

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>&timestamp=<unix>&state=<your_state>&hmac=<hmac>
ParamDescription
install_idThe newly created install UUID
timestampUnix timestamp of when the callback was issued
stateThe state value you passed in step 1 (omitted if not provided)
hmacHMAC-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.

Use state to prevent CSRF

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"
}
}
Auth code is single-use

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.