> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hypermid.io/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK overview

> One package, four entry points, and a hard rule about which run in a browser.

```bash theme={"system"}
npm install @hypermid/sdk
```

The package is deliberately split so the dangerous part cannot be imported by
accident into the wrong runtime.

<CardGroup cols={2}>
  <Card title="Payments" icon="server" href="/sdk/payments">
    Create and read sessions. **Server only** — carries your secret key.
  </Card>

  <Card title="Webhooks" icon="signature" href="/guides/webhooks">
    `verifyWebhook` — constant-time signature check over the raw body, with the
    rotation overlap handled. Node only.
  </Card>

  <Card title="Widget" icon="browser" href="/sdk/widget">
    Embed the hosted payment page, optionally bridging a connected wallet.
  </Card>

  <Card title="Swap" icon="arrows-rotate" href="/sdk/swap">
    Quote a route and get back what the user should execute.
  </Card>

  <Card title="Read client" icon="database" href="/sdk/read-client">
    Chains, tokens, balances, status. Safe anywhere.
  </Card>

  <Card title="Customization" icon="sliders" href="/sdk/customization">
    Every knob — theming, the widget bridge, client options, webhook verification.
  </Card>
</CardGroup>

## Import paths

Import from **`@hypermid/sdk`**. Everything is re-exported there, and it is
what every example in these docs uses.

The subpaths exist for tree-shaking and for making the runtime boundary visible
at the import site — `@hypermid/sdk/payments` is the server-only half — but
they resolve to the same functions:

```typescript theme={"system"}
import { createCheckout } from "@hypermid/sdk";            // canonical
import { createCheckout } from "@hypermid/sdk/payments";   // identical
```

## The one rule

`payments.*` sends your **secret key**. It throws immediately if `window`
exists:

```
@hypermid/sdk: payments.* is server-only — it sends your SECRET key.
Calling it from a browser publishes that key to every visitor.
```

That is a hard throw, not a warning, on purpose. The failure it prevents is
silent by nature: the code works perfectly in a browser, and the only symptom
is that your secret key is now in a bundle every visitor can read. A warning
would be discovered by an attacker, not by you.

Everything else — the widget bridge, `quoteSwap`, the read client — is designed
for the browser and takes a publishable key or none at all.

## Types

The package ships TypeScript types generated from the same OpenAPI document
that produces this documentation, so the types and these pages cannot disagree.

```typescript theme={"system"}
import type { PaymentSession, SwapQuote, ApiQuoteResponse } from "@hypermid/sdk";
```

<Note>
  `QuoteResponse` is exported as **`ApiQuoteResponse`**. The name collided: the
  API's route quote and the SDK's own swap result are different shapes, and the
  established `SwapQuote` kept the plain name.
</Note>
