> ## Documentation Index
> Fetch the complete documentation index at: https://orwel-22af1265.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# CDN & Infrastructure

> How the SDK is distributed and how events reach the server — batched, unload-safe, and idempotent.

The SDK ships as the `orwel` npm package with a self-contained UMD build (\~60 KB, dependencies bundled). Use it from a CDN with zero build step, or install it into any bundler-based app.

## Distribution

<CodeGroup>
  ```html CDN theme={null}
  <script src="https://cdn.jsdelivr.net/npm/orwel@1/dist/orwel.umd.js"></script>
  ```

  ```bash npm theme={null}
  npm install orwel
  ```
</CodeGroup>

The UMD bundle attaches the SDK to `window.orwel`; the ESM build is used by bundlers automatically. Both are served by any npm CDN (jsDelivr, unpkg).

## The pipeline

```mermaid theme={null}
flowchart LR
  A[Orwel SDK<br/>browser] -->|batched events| B[Ingest API<br/>api.orwel.io]
  B --> C[(Supabase<br/>per-workspace)]
  C --> D[Personality Engine<br/>Bayesian traits]
  C --> E[Dashboard<br/>features · journeys]
```

## How events reach the server

The SDK never blocks your app. Events are queued in memory and flushed in batches to keep requests few and small.

<AccordionGroup>
  <Accordion title="Batched + keepalive" icon="layer-group">
    Events post to `/ingest/batch` with `keepalive: true` so in-flight requests survive navigation.
  </Accordion>

  <Accordion title="Unload-safe" icon="shield-halved">
    On `beforeunload` / tab hide, the queue is flushed via `navigator.sendBeacon` (falling back to a sync request) so the last events aren't lost.
  </Accordion>

  <Accordion title="Safe to retry" icon="fingerprint">
    Each event carries a unique id, and the batch endpoint is built to absorb retries without doubling records — so transient network failures and the unload-time `sendBeacon` flush never produce duplicate visitor activity.
  </Accordion>

  <Accordion title="Timestamped" icon="clock">
    Every event is stamped with an ISO `timestamp` at the moment it's queued; sessions track their own `startedAt`, `updatedAt`, and `finishedAt`. Useful for ordering, latency analysis, and reconstructing real-time journeys.
  </Accordion>
</AccordionGroup>

## Ingest endpoints

| Endpoint                | Purpose                                         |
| ----------------------- | ----------------------------------------------- |
| `POST /ingest`          | Single event / session / conversion.            |
| `POST /ingest/batch`    | A batch of events (the common path).            |
| `POST /visitor-resolve` | Resolve a stable visitor id from a fingerprint. |

<Note>
  Every request is authenticated with the `X-Orwel-Key` header, which maps to a workspace. Events are always scoped to that workspace — your data never mixes with another's.
</Note>
