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

# Install and configure the Quickshops TypeScript SDK

> Install @quickshops/sdk, create a server-only client, and explore the complete method reference for building headless storefronts.

<Note>
  **Developers only.** Selling through the built-in Quickshops storefront does not require the SDK. Start with the [Quickstart](/quickstart) if you're setting up a store as a seller.

  The SDK requires a **Pro** plan API key from **Settings → API keys**. See [Authentication](/api/authentication) for setup.
</Note>

The Quickshops TypeScript SDK gives you a typed, server-side client for every API operation your storefront needs — from fetching products to managing carts and initiating checkout. Install it once, wire up your API key in a server-only module, and call methods from your server boundary.

## Install the package

```bash theme={null}
npm install @quickshops/sdk
```

## Package structure

`@quickshops/sdk` is the official TypeScript client for the Quickshops Headless API. Instantiate it only in server-only modules (loaders, actions, API routes) and pass response data to your UI.

<Warning>
  Never construct `Quickshops` in client components, hooks, or any file marked `"use client"`. The API key must stay on the server.
</Warning>

## Create a server-only client

Instantiate the SDK once in a dedicated server-only file. In Next.js, add `import "server-only"` so the module cannot be pulled into client bundles.

```ts lib/quickshops.ts theme={null}
import "server-only";

import { Quickshops } from "@quickshops/sdk";

export const qs = new Quickshops({
  bearerAuth: process.env.HEADLESS_API_KEY!,
});
```

Your API key must start with `qk_` and is sent as `Authorization: Bearer qk_...` on every request.

### Constructor options

```ts theme={null}
import { Quickshops } from "@quickshops/sdk";

const qs = new Quickshops({
  bearerAuth: process.env.HEADLESS_API_KEY!,
  serverURL: "https://api.quickshops.app",
});
```

The REST API base URL is `https://api.quickshops.app/v1`. The SDK `serverURL` defaults to `https://api.quickshops.app` and adds `/v1` to each request path automatically.

For local development against a running API instance:

```ts theme={null}
const qs = new Quickshops({
  bearerAuth: process.env.HEADLESS_API_KEY!,
  serverURL: "http://localhost:3006",
});
```

### Passing data to the browser safely

Fetch with the SDK on the server, then pass only the response data to client components as props or through your own API routes. Never pass the `Quickshops` instance, the raw API key, or `process.env.HEADLESS_API_KEY` to the client.

```tsx theme={null}
// app/page.tsx — Server Component
import { qs } from "@/lib/quickshops";
import { ProductList } from "./product-list";

export default async function Page() {
  const { data: products } = await qs.products.productsGetAll();
  return <ProductList products={products} />;
}
```

```tsx theme={null}
// product-list.tsx — Client Component
"use client";

type Product = { id: string; name: string };

export function ProductList({ products }: { products: Product[] }) {
  return (
    <ul>
      {products.map((p) => (
        <li key={p.id}>{p.name}</li>
      ))}
    </ul>
  );
}
```

## Method reference

All SDK methods are `async` and map to REST endpoints on the [API base URL](/api/overview#base-url). Responses are wrapped in `{ data: ... }` unless noted otherwise.

| Method                                                                 | Request                                     | API endpoint                            |
| ---------------------------------------------------------------------- | ------------------------------------------- | --------------------------------------- |
| `qs.store.storeGet()`                                                  | —                                           | `GET /products/store`                   |
| `qs.products.productsGetAll()`                                         | —                                           | `GET /products`                         |
| `qs.products.productsGetById({ productId })`                           | `{ productId }`                             | `GET /products/:productId`              |
| `qs.cart.cartCreate()`                                                 | —                                           | `POST /cart`                            |
| `qs.cart.cartGet({ cartId })`                                          | `{ cartId }`                                | `GET /cart/:cartId`                     |
| `qs.cart.cartAddLine({ cartId, body })`                                | `{ cartId, body: { productId, quantity } }` | `POST /cart/:cartId/lines`              |
| `qs.cart.cartUpdateLine({ cartId, productId, body })`                  | `{ cartId, productId, body: { quantity } }` | `PATCH /cart/:cartId/lines/:productId`  |
| `qs.cart.cartRemoveLine({ cartId, productId })`                        | `{ cartId, productId }`                     | `DELETE /cart/:cartId/lines/:productId` |
| `qs.cart.cartClear({ cartId })`                                        | `{ cartId }`                                | `DELETE /cart/:cartId`                  |
| `qs.checkout.checkoutCreateSession({ cartId })`                        | `{ cartId }`                                | `POST /checkout/session`                |
| `qs.subscription.subscriptionCreatePortalSession({ memberSessionId })` | `{ memberSessionId }`                       | `POST /subscription/portal`             |

### SDK response shapes

Every method returns a response object. Unwrap the payload with `.data`:

```ts theme={null}
const { data: store } = await qs.store.storeGet();
const { data: products } = await qs.products.productsGetAll();
const { data: cart } = await qs.cart.cartCreate();
```

Cart `data` includes `id`, `storeId`, `lines` (`productId` + `quantity`), and `totals` (`subtotal`, `total`, `currency`).

Product `data` items use `id` (not `_id`), plus `storeId`, `name`, `description`, `priceInCents`, `currency`, `type` (`"digital"` or `"subscription"`), `billingInterval`, `imageUrl`, `isActive`, `category`, and `details`.

Store `data` includes `id`, `slug`, `name`, `description`, `logoUrl`, `isPublished`, `paymentsConfigured`, optional `templateKey`, and `templateTexts`.

Checkout session `data` is `{ url: string }`.

## Next steps

<CardGroup cols={2}>
  <Card title="Framework guides" icon="layers" href="/sdk/framework-guides">
    Setup examples for Next.js, Remix, and other frameworks.
  </Card>

  <Card title="Error handling" icon="alert-triangle" href="/sdk/error-handling">
    Handle API errors and retries in your app.
  </Card>

  <Card title="API reference" icon="book" href="/api/overview">
    Full REST API documentation.
  </Card>
</CardGroup>
