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

# POS API

> The point-of-sale surface — staff login, device pairing, carts, catalog, order capture and the back-office lookups a till needs, all on the storefront base URL.

The POS API is served under the same base URL as the Storefront API (`/api/v1/{store_id}/storefront`) with every path prefixed `/pos/`. It exists so a till can run on a **POS channel** API key with its own staff identity and device pairing, while reusing the storefront cart, catalog and order machinery.

<CardGroup cols={2}>
  <Card title="Pair a device" icon="scanner-touchscreen" href="/docs/api-reference/pos/pair-pos-device">
    Activate a till with the pairing code sent to the store operator.
  </Card>

  <Card title="Log in staff" icon="lock" href="/docs/api-reference/pos/login-with-email">
    OTP login for POS users; the tokens you get back carry the POS channel scope.
  </Card>

  <Card title="Capture an order" icon="receipt" href="/docs/api-reference/pos/create-pos-order">
    Create the order from a POS cart and record the payment taken at the counter.
  </Card>

  <Card title="TypeScript SDK" icon="code" href="/docs/pos/overview">
    `@commercengine/pos` wraps every operation on this page with typed methods.
  </Card>
</CardGroup>

## Authentication

<Steps>
  <Step title="Generate a POS channel API key">
    In the dashboard, open **Settings → Channels**, pick (or create) a **POS** channel and generate its key. Keys are scoped to a store *and* a channel — a Web channel key is rejected on `/pos/*`.
  </Step>

  <Step title="Pair the device">
    Call `POST /pos/auth/pair-device` with the pairing code sent to the operator by phone or email. A paired device shows up in `GET /pos/devices` as `available`.
  </Step>

  <Step title="Log the operator in">
    Start an OTP login with `POST /pos/auth/login/email`, `/phone` or `/whatsapp`, then `POST /pos/auth/verify-otp`. Use the returned access token as `Authorization: Bearer …` and refresh it with `POST /pos/auth/refresh-token`.
  </Step>

  <Step title="Claim the device for this session">
    `POST /pos/devices/{id}/claim` binds an `available` device to the logged-in operator; the device must belong to the location the operator logged in to. `unclaim` releases it at the end of the shift.
  </Step>
</Steps>

<Info>
  Requests made with a POS channel token are treated as in-store activity: storefront analytics events and the `cart.*` / `wishlist.*` webhooks are not emitted for them. Order, payment and shipment webhooks fire as usual.
</Info>

## Two kinds of operations

| Group                              | What it is                                                                                                                                                                                                                                    | Auth             |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| **Point of Sale**                  | Native POS operations backed by the storefront service — auth, devices, carts, catalog, fulfillment, order capture and payment methods.                                                                                                       | POS access token |
| **Back office (proxied to Admin)** | Read-mostly admin operations the POS backend proxies for the till — order history and receipts, shipments and invoices, customer records and addresses, inventory. Same request and response shapes as the corresponding Admin API endpoints. | POS access token |

Both groups are documented from a single OpenAPI document, `https://openapi.commercengine.io/ce-pos.json`, which you can use directly for code generation.
