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

# SDKs

> Official TypeScript and Python clients for the Headless Commerce API

# SDKs

Type-safe, production-ready clients for the Headless Commerce API.

## Installation

<Tabs>
  <Tab title="TypeScript / Node.js">
    <CodeGroup>
      ```bash npm theme={null}
      npm install @headless-commerce/sdk
      ```

      ```bash pnpm theme={null}
      pnpm add @headless-commerce/sdk
      ```

      ```bash yarn theme={null}
      yarn add @headless-commerce/sdk
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```bash pip theme={null}
      pip install headless-commerce
      ```

      ```bash poetry theme={null}
      poetry add headless-commerce
      ```

      ```bash uv theme={null}
      uv add headless-commerce
      ```
    </CodeGroup>

    **Requirements:** Python 3.10+. The only runtime dependency is [httpx](https://www.python-httpx.org/).
  </Tab>
</Tabs>

## Quick Start

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { HeadlessCommerce } from '@headless-commerce/sdk';

    // Admin client (server-side)
    const admin = new HeadlessCommerce({
      secretKey: 'sk_test_your_key',
    });

    // Storefront client (client-side safe)
    const storefront = new HeadlessCommerce({
      publishableKey: 'pk_test_your_key',
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from headless_commerce import HeadlessCommerce

    # Context manager ensures proper cleanup
    with HeadlessCommerce(api_key="sk_test_your_key") as client:
        products = client.products.list({"limit": 10})
        print(products["data"])
    ```

    For async applications (FastAPI, Django async, etc.):

    ```python theme={null}
    from headless_commerce import AsyncHeadlessCommerce

    async with AsyncHeadlessCommerce(api_key="sk_test_your_key") as client:
        products = await client.products.list({"limit": 10})
    ```
  </Tab>
</Tabs>

## Usage Examples

### List Products

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const { data, has_more } = await storefront.products.list({
      status: 'active',
      limit: 20,
    });
    // data: Product[] — fully typed with autocompletion
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    result = client.products.list({
        "q": "shirt",
        "limit": 20,
    })
    # result["data"] — list of products
    # result["has_more"] — whether more pages exist
    ```
  </Tab>
</Tabs>

### Cart Flow

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // Create a cart
    const cart = await storefront.carts.create({
      session_id: 'guest-session-123',
    });

    // Add an item
    await storefront.carts.addItem(cart.id, {
      variant_id: 'var_001',
      quantity: 2,
    });

    // Get cart with calculated totals
    const updated = await storefront.carts.get(cart.id);
    console.log(updated.summary.total);
    // { amount: 78000, currency: "KRW" }

    // Checkout
    const order = await storefront.carts.checkout(cart.id, {
      email: 'customer@example.com',
      payment_provider: 'stripe',
      payment_method_id: 'pm_xxx',
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # Create a cart
    cart = client.carts.create()

    # Add an item
    cart = client.carts.add_item(cart["id"], {
        "variant_id": "var_001",
        "quantity": 2,
    })

    # View totals
    print(cart["summary"]["total"])
    # {"amount": 78000, "currency": "KRW"}

    # Checkout
    order = client.checkout.create(cart["id"], {
        "email": "customer@example.com",
        "payment_provider": "stripe",
        "payment_method_id": "pm_xxx",
    })
    ```
  </Tab>
</Tabs>

### Admin Operations

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // Create a product with variants
    const product = await admin.products.create({
      name: 'Classic T-Shirt',
      type: 'physical',
      status: 'draft',
      options: [
        { name: 'Size', values: ['S', 'M', 'L'] },
        { name: 'Color', values: ['Black', 'White'] },
      ],
    });

    // Auto-pagination
    for await (const order of admin.orders.listAll({ status: 'confirmed' })) {
      console.log(order.number);
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # Create a product
    product = client.products.admin_create({
        "name": "Classic T-Shirt",
        "type": "physical",
        "status": "draft",
        "options": [
            {"name": "Size", "values": ["S", "M", "L"]},
            {"name": "Color", "values": ["Black", "White"]},
        ],
    })

    # Auto-pagination (yields every item across all pages)
    for product in client.products.admin_list_auto_paginate():
        print(product["name"])
    ```
  </Tab>
</Tabs>

## Error Handling

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import { HeadlessCommerceError } from '@headless-commerce/sdk';

    try {
      const product = await storefront.products.get('nonexistent');
    } catch (error) {
      if (error instanceof HeadlessCommerceError) {
        console.log(`API error ${error.status}: ${error.code} — ${error.message}`);
      }
    }
    ```
  </Tab>

  <Tab title="Python">
    The SDK raises typed exceptions that map to HTTP status codes:

    ```python theme={null}
    from headless_commerce import (
        HeadlessCommerceError,  # Base class — catches all errors
        NotFoundError,          # 404
        ValidationError,        # 400 / 422
        AuthenticationError,    # 401
        RateLimitError,         # 429
        InternalServerError,    # 500+
    )

    try:
        product = client.products.get("nonexistent")
    except NotFoundError as e:
        print(f"Not found: {e}")
    except HeadlessCommerceError as e:
        print(f"API error {e.status}: {e.code} — {e}")
        print(f"Request ID: {e.request_id}")
    ```

    All subclasses inherit from `HeadlessCommerceError`, so you can catch specific errors or handle them all at once.
  </Tab>
</Tabs>

## Webhook Verification

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    import crypto from 'node:crypto';

    function verifyWebhook(payload: string, signature: string, secret: string): boolean {
      const expected = crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');
      return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
    }
    ```

    See the [Webhooks guide](/webhooks) for complete integration patterns.
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from headless_commerce import verify_webhook_signature

    is_valid = verify_webhook_signature(
        payload=request.body,
        signature=request.headers["x-webhook-signature"],
        secret="whsec_your_secret",
    )
    ```

    With timestamp replay protection:

    ```python theme={null}
    verify_webhook_signature(
        payload=request.body,
        signature=request.headers["x-webhook-signature"],
        secret="whsec_your_secret",
        timestamp=request.headers["x-webhook-timestamp"],
        tolerance=300,  # reject if older than 5 minutes
    )
    ```
  </Tab>
</Tabs>

## Configuration

<Tabs>
  <Tab title="TypeScript">
    | Option           | Type   | Required | Description                                                         |
    | ---------------- | ------ | -------- | ------------------------------------------------------------------- |
    | `secretKey`      | string | \*       | Secret API key for server-side usage                                |
    | `publishableKey` | string | \*       | Publishable key for client-side usage                               |
    | `baseUrl`        | string | No       | Custom API base URL (default: `https://api.headlesscommerce.io/v1`) |

    <Info>
      One of `secretKey` or `publishableKey` is required.
    </Info>
  </Tab>

  <Tab title="Python">
    | Option        | Type         | Required | Description                                                         |
    | ------------- | ------------ | -------- | ------------------------------------------------------------------- |
    | `api_key`     | str          | Yes      | API key (`sk_*` for admin, `pk_*` for storefront)                   |
    | `base_url`    | str          | No       | Custom API base URL (default: `https://api.headlesscommerce.io/v1`) |
    | `max_retries` | int          | No       | Max retries on 429/5xx errors (default: `2`)                        |
    | `timeout`     | float        | No       | Request timeout in seconds (default: `30`)                          |
    | `http_client` | httpx.Client | No       | Custom httpx client for proxy/mTLS/transport                        |

    ### Retry Behavior

    The SDK automatically retries on:

    * **429** Too Many Requests (respects `Retry-After` header)
    * **5xx** Server errors
    * Network errors and timeouts

    Retries use exponential backoff with jitter. Non-retryable errors (400, 401, 404, 422) fail immediately.
  </Tab>
</Tabs>

## Resources

All 23 API resources are available:

| Resource           | Storefront                    | Admin                                           |
| ------------------ | ----------------------------- | ----------------------------------------------- |
| `products`         | list, get, get\_by\_slug      | CRUD, images, bundles                           |
| `categories`       | list, tree                    | CRUD                                            |
| `collections`      | list, get                     | CRUD                                            |
| `carts`            | create, get, items, discounts | —                                               |
| `checkout`         | create                        | —                                               |
| `orders`           | list, get, lookup             | CRUD, confirm, cancel, complete                 |
| `customers`        | me, addresses                 | CRUD, tokens                                    |
| `variants`         | —                             | CRUD                                            |
| `inventory`        | —                             | get, adjust, set                                |
| `fulfillments`     | —                             | create, ship, deliver                           |
| `discounts`        | validate                      | CRUD                                            |
| `shipping_methods` | list                          | CRUD                                            |
| `payments`         | —                             | record, complete                                |
| `returns`          | request, list, get            | CRUD, approve, reject, receive                  |
| `refunds`          | —                             | create                                          |
| `regions`          | —                             | CRUD, prices, currencies, locales, translations |
| `webhooks`         | —                             | CRUD, test                                      |
| `api_keys`         | —                             | CRUD, rotate                                    |
| `organization`     | —                             | get, update, members                            |
| `store`            | —                             | get, update                                     |
| `logs`             | —                             | list, get, stats                                |
| `dashboard`        | —                             | stats                                           |
