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

# Browser SDK

> Show a Device Billing menu and start checkouts from your own website

The Browser SDK endpoints let your own website show a merchant's menu and start a paid session on a device. They are made for browser code and use the publishable SDK key, never a workspace API token.

## Setup

1. Open **Dashboard → Integrations → Browser SDK access** for your Device Billing merchant.
2. Generate the **Publishable SDK key** and copy the **SDK merchantId**.
3. Add your website to **Allowed origins**, for example `https://shop.example.com`.

Send both values on every request:

```
X-API-Key: <PUBLISHABLE_SDK_KEY>
X-Merchant-ID: <SDK_MERCHANT_ID>
```

Requests from origins that are not in the list are rejected with `403`. Requests are rate limited per visitor.

## List menu items

```
GET /api/v1/sdk/menu
```

| Parameter | Description |
| - | - |
| `category_id` | Only items in this category. |
| `search` | Match title or description. |
| `filter` | `available` or `recommended`. |

```json theme={null}
{
  "menu_items": [
    {
      "id": "6a3c...",
      "title": "Wash 30 minutes",
      "price": "15000",
      "is_active": true,
      "payment_type": "prepaid",
      "category": { "id": "1d2e...", "name": "Laundry" }
    }
  ]
}
```

## Create a transaction

```
POST /api/v1/sdk/transactions
Content-Type: application/json

{
  "device_id": "{device_id}",
  "menu_item_id": "6a3c...",
  "quantity": 1,
  "customer": { "email": "customer@example.com", "name": "Sari" }
}
```

| Field | Required | Description |
| - | - | - |
| `device_id` | If the merchant has more than one device | The device that will serve the order. |
| `menu_item_id` | Yes | Item to buy. Use `items` (a list of `menu_item_id` and `quantity`) for several items. |
| `customer.email` | Yes | Receipt address. |
| `customer.name`, `customer.phone` | No | Shown on the order. |

The response contains the order and how to pay it:

```json theme={null}
{
  "order_id": "0b9f...",
  "order_code": "ORD-8K2M",
  "guest_token": "gt_...",
  "status": "pending",
  "payment_url": "https://...",
  "expires_at": "2026-10-28T03:30:00Z"
}
```

Open `payment_url` (or show `qr_code` when present) so the customer can pay. Order `status` is one of `pending`, `processing`, `paid`, `expired`, or `cancelled`.

Keep the `guest_token` in the visitor's browser. It identifies their orders.

> [!NOTE]
>
> Checkout requests are protected by a human verification check and pass its result as `turnstile_token`. Contact firmngin support to enable verification for your website domain before going live.

## List a visitor's transactions

```
GET /api/v1/sdk/transactions?guest_token={guest_token}
```

Supports `status`, `page`, and `limit` (max `100`).

```json theme={null}
{
  "data": [
    {
      "id": "0b9f...",
      "order_code": "ORD-8K2M",
      "status": "paid",
      "device_id": "8f0c...",
      "menu_item": "Wash 30 minutes",
      "amount": "15000",
      "created_at": "2026-10-28T03:15:00Z",
      "ended_at": "2026-10-28T03:45:00Z"
    }
  ],
  "meta": { "total": 1, "page": 1, "limit": 10 }
}
```

## Live device events

```
GET /api/v1/sdk/stream
Accept: text/event-stream
```

A Server-Sent Events stream for all of the merchant's devices. Use it to update availability on your page without polling. Every event includes `device_id`.

| Event | Sent when |
| - | - |
| `status` | A device becomes busy or available. |
| `lwt` | A device goes online or offline. |
| `maintenance` | A device enters or leaves maintenance. |
| `menu` | The menu changes. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.