# [SDK presentation updates](https://rebilder.com/docs/sdk-updates)

> Connect an upgraded gateway to receive signed presentation updates in the background, retain a local fallback and verify the profile served.

- **Updated:** 2026-09-13
- **Author:** Rebilder
- **Section:** Getting started
- **Description:** Connect an upgraded gateway to receive signed presentation updates in the background, retain a local fallback and verify the profile served.
- **Publisher:** Rebilder

## Connect your SDK once

- Upgrade to @rebilder/gateway 0.4.0 or later, which exports createCompatibilityUpdater. Older installations require this one-time code update.
- Enable Autopilot and presentation updates for the site. The feed checks your current Pro or Agency subscription and configured authority before sending a candidate.
- In [Settings](/console/settings), generate a separate update key. Store it as REBILDER_STORE_API_KEY in your SDK process. This key has config:read scope; your existing event key keeps its scope.
- Retrieve the setup document over HTTPS using that key. Save its audience, keyId and publicKey in deployment configuration. Pin the public key once; do not download a new verification key on every refresh.

Install the SDK with update support

```
pnpm add @rebilder/gateway@^0.4.0
```

Retrieve your public setup configuration

```
curl -fsSL "https://api.rebilder.com/v1/autopilot/compatibility?setup=1" \
  -H "Authorization: Bearer $REBILDER_STORE_API_KEY"
```

## Refresh outside request handling

Wire the updater into a long-running server or a deployment scheduler. The source resolvers remain your existing gateway configuration. Durable cache storage should use an atomic write and be scoped to this site.

Server initialization

```
import { createCompatibilityUpdater } from '@rebilder/gateway'

const updater = createCompatibilityUpdater({
  url: setup.url,
  audience: setup.audience,
  apiKey: process.env.REBILDER_STORE_API_KEY,
  publicKeys: { [setup.keyId]: setup.publicKey },
  cache: {
    load: () => profileCache.read(setup.audience),
    save: (envelope) => profileCache.writeAtomically(setup.audience, envelope),
  },
})
await updater.restore()
await updater.refresh()
const stopUpdates = updater.start(15 * 60 * 1000)

export const gatewayConfig = {
  storeId,
  sources,
  compatibilityProfile: updater.current,
}
```

The gateway reads the current profile synchronously. A request never starts a configuration fetch or model call. Serverless request scopes do not keep timers running: refresh from scheduled work, persist the signed envelope and restore it during initialization.

## Verify and reverse an update

Fetch a connected page with Accept: text/markdown. Its x-rebilder-profile-id and x-rebilder-profile-version headers identify the presentation actually served. The same fields appear in gateway events. A page whose byte budget cannot fit the candidate uses baseline and reports baseline.

Inspect or roll back locally

```
const status = updater.status()
// Emergency local rollback also stops background polling.
updater.rollback()
// After resolving the issue, an explicit refresh resumes updates.
await updater.refresh()
```

Disabling presentation updates causes the next authorized refresh to receive a signed baseline. Revoking the update key prevents further downloads; the current signed configuration expires within one hour. Network failures retain the last valid profile, then baseline at expiry. Your business source data stays in your application.

## What a presentation release establishes

Candidates are compiled-in presentation rules that preserve your source content. The control plane accepts a release only after controlled model comparisons pass factual, qualification and held-out checks. An offline formatting check alone cannot release a candidate. With no qualifying release, the feed serves baseline.

The signed payload includes the evaluation ID for its candidate. Delivery headers establish what your gateway served. External assistant citations, recommendations and answers require separate observations.