# SDK Quickstart

Install the SDK in the issuer host application and mount it into a stable container.

```ts
import { Percents } from '@percents/web-sdk';

const widget = Percents.init({
  container: '#percents-widget',
  sessionEndpoint: '/api/percents/session',
  view: 'offers',
  appearance: {
    displayName: 'Branded Rewards',
    primaryColor: '#0079d2',
    accentColor: '#028a00',
    fontFamily: "Gilroy, 'Gilroy Regular', ui-sans-serif, system-ui",
  },
});

widget.on('merchant_activation_completed', (payload) => {
  console.log('Merchant activated', payload);
});
```

## Session Endpoint

`sessionEndpoint` is owned by the issuer. It authenticates the current user, resolves the cardholder group, mints or retrieves a proxy session, and returns:

```json
{
  "widgetUrl": "https://widgets.percents.com/embed/index.html",
  "proxyApiBaseUrl": "https://issuer.example.com/api/percents/proxy",
  "proxySessionToken": "opaque-session-token",
  "expiresAt": "<RFC3339 expiration timestamp>"
}
```

Store the proxy session and its upstream widget token only on the issuer server. Use a shared, durable session store when the proxy runs on more than one instance.

## Proxy API

The iframe calls the issuer proxy with `Authorization: Bearer <proxySessionToken>`. The proxy validates the session, enforces the CHG scope, forwards the request to Percents, and strips any server-only credentials from browser-visible responses.

When creating the upstream widget session, the proxy authenticates to Percents with a signed mint assertion verified through the issuer's JWKS. See [SDK Authentication](/percents-api/auth-security/sdk-auth#production-mint-authentication) for the required request, claims, and registration details.

## Sandbox Testing

To test the SDK before production, deploy an issuer sandbox proxy that forwards to `https://sandbox.percents.com`. Do not point the browser directly at Percents or embed a long-lived API token in the page.