# API Reference

WebBLE exposes two distinct API surfaces:

- **`navigator.bluetooth`** — the standard W3C Web Bluetooth API. Pure polyfill; works identically to Chrome/Edge implementations. Portable across browsers.
- **`window.webbleIOS`** — an iOS-only vendor-prefixed surface for capabilities that are deliberately not part of the W3C spec (peripheral / GATT-server mode, background sync, beacon scanning, iOS notifications). Feature-detect with `'webbleIOS' in window`.

Every method documented below is present at runtime; every premium signature is derived from `src/webble/api/` and `src/types/background-sync.ts` in the repo.

---

## Standard surface — `navigator.bluetooth`

### `navigator.bluetooth.requestDevice(options)`

Prompts the user to select a nearby Bluetooth Low Energy peripheral matching the given filters. Must be invoked from a user activation (click/tap).

**Signature**

```ts
navigator.bluetooth.requestDevice(options: RequestDeviceOptions): Promise<BluetoothDevice>
```

**Parameters**

- `options.filters` — array of `BluetoothLEScanFilter`. At least one required unless `acceptAllDevices: true`.
- `options.optionalServices` — additional service UUIDs the page may access after pairing.
- `options.acceptAllDevices` — if `true`, shows every advertising peripheral. Cannot combine with `filters`.

**Returns**

A `BluetoothDevice` handle. The user may cancel the chooser, in which case the promise rejects with `NotFoundError`.

**Example**

```js
const device = await navigator.bluetooth.requestDevice({
  filters: [{ services: ['heart_rate'] }],
  optionalServices: ['battery_service']
});
```

**Spec:** [W3C §requestDevice](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice)

---

### `navigator.bluetooth.getAvailability()`

Reports whether the browser has a usable Bluetooth radio and the WebBLE extension is reachable on this origin.

**Signature**

```ts
navigator.bluetooth.getAvailability(): Promise<boolean>
```

**Returns** — `true` if the polyfill is mounted and the extension is enabled for this site; `false` otherwise.

**Example**

```js
if (!(await navigator.bluetooth.getAvailability())) {
  alert('Enable the WebBLE extension on this site');
}
```

**Spec:** [W3C §getAvailability](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability)

---

### `BluetoothDevice.gatt.connect()`

Opens a GATT connection to the peripheral represented by the `BluetoothDevice`.

**Signature**

```ts
device.gatt.connect(): Promise<BluetoothRemoteGATTServer>
```

**Returns** — a connected `BluetoothRemoteGATTServer`. Rejects with `NetworkError` if the peripheral is out of range or refuses the connection.

**Example**

```js
const server = await device.gatt.connect();
```

**Spec:** [W3C §gatt.connect](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect)

---

### `BluetoothDevice.gatt.disconnect()`

Tears down the GATT connection. Fires a `gattserverdisconnected` event on the device.

**Signature**

```ts
device.gatt.disconnect(): void
```

**Example**

```js
device.addEventListener('gattserverdisconnected', () => console.log('dropped'));
device.gatt.disconnect();
```

**Spec:** [W3C §gatt.disconnect](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-disconnect)

---

### `BluetoothRemoteGATTServer.getPrimaryService(uuid)`

Returns a primary GATT service advertised by the peripheral.

**Signature**

```ts
server.getPrimaryService(service: BluetoothServiceUUID): Promise<BluetoothRemoteGATTService>
```

**Parameters** — `service`: a 16-bit alias (`'heart_rate'`), 128-bit UUID string, or numeric service ID.

**Returns** — a `BluetoothRemoteGATTService`. Rejects with `NotFoundError` if the service is not present on the peripheral or was not listed in `filters`/`optionalServices`.

**Example**

```js
const service = await server.getPrimaryService('heart_rate');
```

**Spec:** [W3C §getPrimaryService](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice)

---

### `BluetoothRemoteGATTService.getCharacteristic(uuid)`

Returns a single GATT characteristic of this service.

**Signature**

```ts
service.getCharacteristic(
  characteristic: BluetoothCharacteristicUUID
): Promise<BluetoothRemoteGATTCharacteristic>
```

**Example**

```js
const char = await service.getCharacteristic('heart_rate_measurement');
```

**Spec:** [W3C §getCharacteristic](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattservice-getcharacteristic)

---

### `BluetoothRemoteGATTCharacteristic.readValue()`

Performs a GATT read of the characteristic.

**Signature**

```ts
char.readValue(): Promise<DataView>
```

**Returns** — a `DataView` over the raw characteristic bytes. Also updates `char.value`.

**Example**

```js
const level = (await batteryChar.readValue()).getUint8(0); // 0–100
```

**Spec:** [W3C §readValue](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue)

---

### `BluetoothRemoteGATTCharacteristic.writeValue(value)`

Writes the given bytes to the characteristic. Prefer `writeValueWithResponse` / `writeValueWithoutResponse` when the peripheral supports both and you need to pick explicitly.

**Signature**

```ts
char.writeValue(value: BufferSource): Promise<void>
```

**Example**

```js
await char.writeValue(new Uint8Array([0x01, 0x02]));
```

**Spec:** [W3C §writeValue](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue)

---

### `BluetoothRemoteGATTCharacteristic.startNotifications()`

Subscribes to value-change notifications from the characteristic. Each notification fires a `characteristicvaluechanged` event with the new bytes in `event.target.value`.

**Signature**

```ts
char.startNotifications(): Promise<BluetoothRemoteGATTCharacteristic>
```

**Example**

```js
await char.startNotifications();
char.addEventListener('characteristicvaluechanged', (ev) => {
  const v = ev.target.value; // DataView
  console.log('new value', new Uint8Array(v.buffer));
});
```

Use `stopNotifications()` to unsubscribe.

**Spec:** [W3C §startNotifications](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications)

---

## Premium surface — `window.webbleIOS`

Present only when the WebBLE Safari Web Extension is installed. The surface is frozen; managers are instantiated lazily on first access. Feature-detect with `'webbleIOS' in window`.

```ts
interface WebBLEIOS {
  readonly peripheral: WebBLEPeripheralManager;
  readonly backgroundSync: WebBLEBackgroundSync;
  getCapabilities(): Promise<WebBLECapabilities>;
}
```

### `window.webbleIOS.getCapabilities()`

Returns a bag of capability flags negotiated with the companion app. Useful for runtime dispatch between standalone and IPC-relay modes.

```ts
window.webbleIOS.getCapabilities(): Promise<WebBLECapabilities>
```

---

### `window.webbleIOS.peripheral` — GATT-server mode

Advertise a custom GATT server from the web page. Not present on any other browser. See [recipes: peripheral chat](recipes.md#peripheral-chat) for a full example.

Core methods:

- `peripheral.addService(definition)` — register a GATT service + its characteristics.
- `peripheral.startAdvertising(options?)` — begin advertising to nearby centrals.
- `peripheral.stopAdvertising()` — stop.
- Events: `onwriterequest`, `onsubscriptionchange`, `onconnectionstatechange`, `onadvertisingstatechange`, `onnotificationready`.

Service and characteristic definitions follow the types in [`src/webble/api/webble-peripheral.ts`](https://github.com/wklm/ioswebble-sdk/blob/main/src/webble/api/webble-peripheral.ts).

---

### `window.webbleIOS.backgroundSync` — background operations

Keep connections alive, fire OS notifications on characteristic value changes, and scan for beacons while Safari is backgrounded. Requires the companion app to be running.

```ts
interface WebBLEBackgroundSync {
  requestPermission(): Promise<'granted' | 'denied' | 'prompt'>;
  requestBackgroundConnection(options): Promise<BackgroundRegistration>;
  registerCharacteristicNotifications(options): Promise<BackgroundRegistration>;  // "notifications"
  registerBeaconScanning(options): Promise<BackgroundRegistration>;                // "beacons"
  getRegistrations(): Promise<BackgroundRegistration[]>;
  unregister(id: string): Promise<void>;
  update(id: string, template: Partial<NotificationTemplate>): Promise<void>;
  destroy(): void;
}
```

The conceptual premium categories map to this surface as follows:

| Category | Actual API |
|----------|-----------|
| `backgroundSync` | `window.webbleIOS.backgroundSync.requestBackgroundConnection` |
| `notifications`  | `window.webbleIOS.backgroundSync.registerCharacteristicNotifications` |
| `beacons`        | `window.webbleIOS.backgroundSync.registerBeaconScanning` |
| `peripheral`     | `window.webbleIOS.peripheral` |
| `liveActivity`   | Implicit — the companion app manages ActivityKit Live Activities automatically for active background-sync registrations when running in IPC-relay mode. No direct JS API today. |

Full type surface: [`src/types/background-sync.ts`](https://github.com/wklm/ioswebble-sdk/blob/main/src/types/background-sync.ts). See the [Premium APIs](premium.md) page for narrative usage.
