# Products and operations

> The product types, how to read a product's state, and which operations each type
> supports.

## Product types

| `product_type_id` | Type | Type block in the response | Device id |
| --- | --- | --- | --- |
| `2` | Barrier | `barrier` | `B` + 6 characters |
| `3` | Gate | `gate` | `G` + 6 characters |
| `4` | Brain | `brain` | `R` + 6 characters |
| `5` | Chain | `chain` | `C` + 6 characters |
| `6` | Bollard | `bollard` | `P` + 6 characters |

The 6 characters are uppercase letters and digits, for example `B1A2B3C`.

[`GET /v2/products`](/api/endpoints/products-find-all) lists your products, except
products that aren't paired (no active pairing with the Connect app).

## Reading a product

Every product has these fields, among others:

| Field | Values |
| --- | --- |
| `status` | `online`: a connected Gateway can see the product, so commands can reach it. `offline`: none can. |
| `power_type` | `battery` or `grid` |
| `battery_status` | Battery level in percent; `null` while offline |
| `rssi` | Bluetooth signal strength to the best Gateway, in dBm; `null` while offline |
| `lot_id`, `zone_id` | Where the product is |
| `product_error` | The device's error flags (below), or `null` |

Plus exactly **one type block**, named after the type:

**`barrier`**

| Field | Values |
| --- | --- |
| `state` | `opened` or `closed` |
| `is_autoclose` | `1` if auto-close is on, else `0` |
| `autoclose_time` | The auto-close delay, in seconds |
| `is_car_on_top` | `1` while a car is over the barrier, else `0` |

**`gate`, `chain`, `bollard`, `brain`**

| Field | Values |
| --- | --- |
| `state` | `opened`, `closed`, `error`, `unknown`, `reserved` or `disabled` |
| `permanent_position` | `disabled` (normal operation), `stay_open` or `stay_close` |

## What open and close mean

| Product | `open` | `close` |
| --- | --- | --- |
| **Barrier** | The arm **lowers**: the spot can be used. | The arm **rises**: the spot is blocked. |
| **Gate, chain, bollard, brain** | The passage opens: vehicles can pass. | The passage closes. |

A barrier protects a single parking space, so "open" means the space is open to park in.

## Operations

Send operations with
[`POST /v2/products/{id}/state`](/api/endpoints/products-change-state):

```json title="Request body"
{ "operation": "open" }
```

| Operation | Barrier | Gate, chain, bollard, brain |
| --- | --- | --- |
| `open` | ✅ arm lowers | ✅ passage opens |
| `close` | ✅ arm rises | ✅ passage closes |
| `force_close` | ✅ | — |
| `stay_open` | — | ✅ holds the passage open |
| `stay_close` | — | ✅ holds the passage closed |
| `clear_stay_open` | — | ✅ ends `stay_open` |
| `clear_stay_close` | — | ✅ ends `stay_close` |

The API doesn't check the combination for you: **check the matrix in your code** before
sending an operation. Combinations marked — aren't supported.

The call returns an `event_id` straight away; the result arrives later over the realtime
connection. See [Asynchronous operations](/concepts/asynchronous-operations).

## Settings (barriers)

[`POST /v2/products/{id}/settings`](/api/endpoints/products-change-settings) changes a
barrier's auto-close. Send **one** setting per call:

```json title="Turn auto-close on or off"
{ "is_autoclose": true }
```

```json title="Set the auto-close delay (5–60 seconds)"
{ "autoclose_time": 30 }
```

- Send `is_autoclose` as a JSON boolean, `true` or `false`, not `1`/`0`.
- If you send both, only `is_autoclose` is applied.
- An empty body fails.

Like a state change, it returns an `event_id`, and the result arrives as a realtime
event.

## Error flags

`product_error` reports problems the device itself detects. Each flag is `0` or `1`:

| Flag | Meaning |
| --- | --- |
| `jammed` | The arm or mechanism is blocked. |
| `sensor_dirty` | The car-detection sensor is dirty. |
| `pin_broken` | Reported by the device; see the product's manual. |
| `rtcc_invalid` | The device's clock isn't set. Time-limited credentials (operation tokens, keys) won't work until it is. |
| `battery_empty` | The battery is empty. |
| `master_key_not_set` | Reported by the device; see the product's manual. |

`error_code` holds the same six flags as a string of `0`s and `1`s, in the order above;
for example `"010010"` means a dirty sensor and an empty battery.

## Next

- [Asynchronous operations](/concepts/asynchronous-operations)
- [Quickstart](/get-started/quickstart)
