---
title: Essential Requests
description: When building an embedded IoT application with Blues Notecard, there are a number of essential API requests to know.
source_url: https://dev.blues.io/notecard/notecard-walkthrough/essential-requests/
canonical_url: https://dev.blues.io/notecard/notecard-walkthrough/essential-requests/
markdown_url: https://dev.blues.io/notecard/notecard-walkthrough/essential-requests.md
---

# Essential Requests

When building an embedded application with the Notecard, there are a number of essential API requests to know.

## Notehub Configuration `hub.set`

Every Notecard must be configured to connect to a cloud project on [Notehub](https://dev.blues.io/notehub.md) before it can attempt to sync data. The `hub.set` request is used to:

- Assign a Notehub [ProductUID](https://dev.blues.io/api-reference/glossary.md#productuid) to the Notecard.
- Optionally set a [Serial Number](https://dev.blues.io/api-reference/glossary.md#product-sn) for the Notecard.
- Configure the synchronization mode between the Notecard and Notehub.

### Setting a ProductUID & Serial Number

Most of the time, your first request to the Notecard in a new application will be to set the ProductUID. This is done with the `hub.set` request and `product` argument, which will correspond to a [ProductUID pre-configured in Notehub](https://dev.blues.io/notehub/notehub-walkthrough.md#finding-a-productuid). If the Notecard attempts to sync with a missing ProductUID, the device will be rejected by Notehub.

**JSON**

```json
{
  "req": "hub.set",
  "product": "your-productuid"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "product", "your-productuid");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["product"] = "your-productuid"
card.Transaction(req)
```

Optionally, you can associate your product's serial number (as an arbitrary string) with the Notecard by using hub.set with the `sn` argument. This arbitrary field can be used to more easily identify devices in Notehub or your own cloud applications.

**JSON**

```json
{
  "req": "hub.set",
  "product": "your-productuid",
  "sn": "your-serial-number"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "product", "your-productuid");
JAddStringToObject(req, "sn", "your-serial-number");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["product"] = "your-productuid"
req["sn"] = "your-serial-number"
card.Transaction(req)
```

> **Note:**
>
> **Configuration Does Not Require Connectivity**
>
> `hub.set` (like all Notecard requests) is processed locally by the Notecard — it does not require cellular, satellite, LoRa, or WiFi connectivity. The values you set, including the ProductUID and serial number, are written to the Notecard's non-volatile memory immediately and persist across power cycles. This means you can fully pre-configure a Notecard on the bench with no network coverage; the Notecard only needs connectivity later, when it actually syncs the stored settings and your data with Notehub.

### Configuring Synchronization Modes

The Notecard's connection to Notehub is configurable, and can be adjusted based on the battery and data needs of your application. The `mode` field of `hub.set` accepts several values, but most applications use one of two:

- `periodic` - (Default) "On demand" mode. The Notecard will periodically power-on the modem and connect to Notehub whenever it needs to synchronize with the service, and will then power-off the modem when not in use. This is the right choice for most battery-powered devices.
- `continuous` - Maintains an active network and Notehub connection. For Cellular Notecards this includes keeping the cellular modem powered on. For Notecard WiFis this includes keeping an active connection to a WiFi access point. Use this when your application needs low-latency, always-on communication and has the power budget to support it.

For example, to place the Notecard in `periodic` mode:

**JSON**

```json
{
  "req": "hub.set",
  "mode": "periodic"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "mode", "periodic");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["mode"] = "periodic"
card.Transaction(req)
```

> **Note:**
>
> **Less Common Sync Modes**
>
> The `mode` field accepts three additional values that disable normal synchronization. They're reserved for specialized situations, such as conserving power during long periods of inactivity or performing firmware updates.
>
> - `minimum` - Disables automatic connection to Notehub. In this mode, you will need to manually send a `hub.sync` request to trigger a sync. OTA DFU (for both [host MCU](https://dev.blues.io/notehub/host-firmware-updates/host-dfu-overview.md) and [Notecard](https://dev.blues.io/notecard/notecard-walkthrough/updating-notecard-firmware.md#ota-dfu-with-notehub) updates) is not available on Notecard when using this mode.
> - `off` - Disables both automatic and manual connection to Notehub. This is, in essence, the Notecard's "airplane mode" which ensures that the modem will not power-on under any circumstances. OTA DFU (for both [host MCU](https://dev.blues.io/notehub/host-firmware-updates/host-dfu-overview.md) and [Notecard](https://dev.blues.io/notecard/notecard-walkthrough/updating-notecard-firmware.md#ota-dfu-with-notehub) updates) is not available on Notecard when using this mode.
> - `dfu` - Puts the Notecard into DFU mode for [IAP host MCU firmware updates](https://dev.blues.io/notehub/host-firmware-updates/iap-firmware-update.md). In terms of the Notecard's network and Notehub connections, this mode behaves the same as `off`.

In the case of both `periodic` and `continuous` sync modes, the Notecard will periodically synchronize both outbound and inbound data with Notehub using a timing algorithm set by the configured `outbound` and `inbound` "sync times" ([see below](#setting-sync-times-for-outbound-and-inbound-data)).

### Setting Sync Times for Outbound and Inbound Data

After setting the synchronization mode, you can set the frequency of outbound and inbound sync requests using the `outbound` and `inbound` arguments. **These arguments are required** if operating in `periodic` or `continuous` mode.

The `outbound` argument configures the max wait time (in minutes) to sync **outbound** data, such as new Notes added by the host application. Data may sync more frequently, but the Notecard will never wait longer than this amount of time to initiate a sync if data is awaiting upload. The value passed into this field must be an integer.

**JSON**

```json
{
  "req": "hub.set",
  "outbound": 60
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddNumberToObject(req, "outbound", 60);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["outbound"] = 60
card.Transaction(req)
```

The `inbound` field configures the max wait time (in minutes) to sync **inbound** data, such as environment variables or inbound Notes from Notehub. Data may sync more frequently, but the Notecard will never wait longer than this amount of time to initiate a sync. The value passed into this field must be an integer.

**JSON**

```json
{
  "req": "hub.set",
  "inbound": 120
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddNumberToObject(req, "inbound", 120);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["inbound"] = 120
card.Transaction(req)
```

> **Note:**
>
> The cadence of outbound and inbound syncs are based off of the boot time of the Notecard. Explicit syncs (e.g. using a `hub.sync` request) do not affect this cadence.

> **Tip:**
>
> On battery-powered devices you can vary these sync intervals by available energy instead of using fixed values. The `voutbound` and `vinbound` arguments accept voltage-variable strings that override `outbound` and `inbound` as the battery drains. See [Customizing Voltage-Variable Behaviors](https://dev.blues.io/notecard/notecard-walkthrough/low-power-firmware-design.md#customizing-voltage-variable-behaviors) for the string format.

### Syncing Inbound Data Immediately

If your application is using `continuous` mode and is expecting inbound data from the service where responsiveness is key, adding the `sync` flag to a `hub.set` request will cause inbound data from Notehub to be synchronized to the Notecard as soon as it is detected.

**JSON**

```json
{
  "req": "hub.set",
  "mode": "continuous",
  "sync": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "mode", "continuous");
JAddBoolToObject(req, "sync", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["mode"] = "continuous"
req["sync"] = True
card.Transaction(req)
```

### Configuring Session Duration in Continuous Mode

When the Notecard establishes a new session with Notehub, it syncs [session-specific information](https://dev.blues.io/api-reference/system-notefiles.md#session-qo) — such as signal strength and voltage — that isn't included in every individual Note.

In `continuous` mode, the Notecard keeps an always-on network connection and holds a single Notehub session open across many sync cycles. Outbound and inbound syncs still happen on the cadence set by your `outbound` and `inbound` values, but they all run inside the same session, so session-specific fields aren't refreshed until that session ends.

If you need session-specific data refreshed on a fixed schedule, use the `duration` argument with an integer number of minutes (minimum `15`). When `duration` elapses, the Notecard ends the current session and starts a new one — refreshing the session-level fields in the process.

> **Note:**
>
> Notecard for LoRa does not support explicit Notehub sessions like other Notecards, so the `duration` argument has no effect.

**JSON**

```json
{
  "req": "hub.set",
  "mode": "continuous",
  "duration": 240
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "mode", "continuous");
JAddNumberToObject(req, "duration", 240);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["mode"] = "continuous"
req["duration"] = 240
card.Transaction(req)
```

Once set, after the `duration` period elapses, the Notecard will gracefully drop the current session and immediately establish a new one to sync session information.

> **Note:**
>
> **Combining Requests**
>
> The prior requests, and the majority of requests in this guide, do not need to be performed separately. For instance, it's common for a host application to set all of these parameters on boot. This can be performed with the following request:
>
> **JSON**
>
> ```json
> {
>   "req": "hub.set",
>   "product": "your-productuid",
>   "sn": "your-serial-number",
>   "mode": "continuous",
>   "outbound": 60,
>   "inbound": 120,
>   "duration": 240,
>   "sync": true
> }
> ```
>
> **C/C++**
>
> ```cpp
> J *req = NoteNewRequest("hub.set");
> JAddStringToObject(req, "product", "your-productuid");
> JAddStringToObject(req, "sn", "your-serial-number");
> JAddStringToObject(req, "mode", "continuous");
> JAddNumberToObject(req, "outbound", 60);
> JAddNumberToObject(req, "inbound", 120);
> JAddNumberToObject(req, "duration", 240);
> JAddBoolToObject(req, "sync", true);
>
> NoteRequest(req);
> ```
>
> **Python**
>
> ```python
> req = {"req": "hub.set"}
> req["product"] = "your-productuid"
> req["sn"] = "your-serial-number"
> req["mode"] = "continuous"
> req["outbound"] = 60
> req["inbound"] = 120
> req["duration"] = 240
> req["sync"] = True
> card.Transaction(req)
> ```

The result of all `hub.set` requests, if successful, is an empty JSON object (`{}`).

> **Tip:**
>
> Watch [An In-Depth Guide to Notecard’s hub.set Request](https://www.youtube.com/watch?v=3D2p1t8UMHQ) for a complete walkthrough of these configuration options. The video steps through real-world scenarios that show how your choice of `mode`, `outbound`, `inbound`, and `sync` values determines exactly when your Notecard connects and syncs with Notehub.

## Adding Notes to Notefiles `note.add`

When you're ready to add data to your Notecard for synchronization with Notehub, you'll use a `note.add` request. This request adds a single [Note](https://dev.blues.io/api-reference/glossary.md#note) (or event) with an arbitrary JSON-formatted `body` to a [Notefile](https://dev.blues.io/api-reference/glossary.md#notefile), which is an outbound queue of data to synchronize with Notehub.

By default, all Notes are added to the `data.qo` Notefile. The `.qo` extension signifies that this is an **outbound queue** Notefile.

**JSON**

```json
{
  "req": "note.add",
  "body": { "foo": "bar" }
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("note.add");
J *body = JCreateObject();
JAddStringToObject(body, "foo", "bar");
JAddItemToObject(req, "body", body);

NoteRequest(req);
```

**Python**

```python
req = {"req": "note.add"}
req["body"] = {"foo": "bar"}
rsp = card.Transaction(req)
```

The `body` field of a `note.add` request must be a valid JSON object. The contents of that object are up to you and can be fully customized for your application.

**JSON**

```json
{
  "req": "note.add",
  "body": {
    "foo": "bar",
    "temp": 23.134,
    "active": true
  }
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("note.add");
J *body = JCreateObject();
JAddStringToObject(body, "foo", "bar");
JAddNumberToObject(body, "temp", 23.134);
JAddBoolToObject(body, "active", true);
JAddItemToObject(req, "body", body);

NoteRequest(req);
```

**Python**

```python
req = {"req": "note.add"}
req["body"] = {"foo": "bar", "temp": 23.134, "active": True}
rsp = card.Transaction(req)
```

> **Note:**
>
> If using a Notecard LoRa, Notes must use a [Note Template](https://dev.blues.io/notecard/notecard-walkthrough/low-bandwidth-design.md#working-with-note-templates).

### Adding Notes to a Custom Notefile

If you wish to organize your Notes by function or type of data being captured, you can use the `file` field to specify a Notefile ID of your choosing, ending in a `.qo` extension.

**JSON**

```json
{
  "req": "note.add",
  "body": { "foo": "bar" },
  "file": "sensors.qo"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("note.add");
JAddStringToObject(req, "file", "sensors.qo");

J *body = JCreateObject();
JAddStringToObject(body, "foo", "bar");
JAddItemToObject(req, "body", body);

NoteRequest(req);
```

**Python**

```python
req = {"req": "note.add"}
req["file"] = "sensors.qo"
req["body"] = {"foo": "bar"}
rsp = card.Transaction(req)
```

> **Warning:**
>
> Notefiles are limited to 100 unsynced Notes (unless you use a [Note Template](https://dev.blues.io/notecard/notecard-walkthrough/low-bandwidth-design.md#working-with-note-templates)). Attempting to add new Notes beyond this limit will result in this error:
>
> ```json
> {
>  "err": "error adding note: can't exceed 100 notes per file (currently 100; see note.template)"
> }
> ```
>
> This limit does not apply to Notefiles that have a template, since the Notecard uses much less memory to store and sync templated Notes.

### Adding Notes for Secure Transport

If you want to ensure that Notes are sent over encrypted TLS to Notehub, use the `.qos` extension instead of `.qo`. `qos` signifies that the Notefile is a **secure outbound queue**.

**JSON**

```json
{
  "req": "note.add",
  "body": { "foo": "bar" },
  "file": "sensors.qos"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("note.add");
JAddStringToObject(req, "file", "sensors.qos");

J *body = JCreateObject();
JAddStringToObject(body, "foo", "bar");
JAddItemToObject(req, "body", body);

NoteRequest(req);
```

**Python**

```python
req = {"req": "note.add"}
req["file"] = "sensors.qos"
req["body"] = {"foo": "bar"}
rsp = card.Transaction(req)
```

### Adding Payloads to Notes

The Notecard can be used to upload data generated by host firmware that encodes data in a binary format. These applications can easily attach the Base64-encoded binary data to a Note by using the `payload` field. Payloads are limited to 256 bytes.

> If you need to send binary data larger than 256 bytes, please consult our guide on [Sending and Receiving Large Binary Objects](https://dev.blues.io/guides-and-tutorials/notecard-guides/sending-and-receiving-large-binary-objects.md)

**JSON**

```json
{
  "req": "note.add",
  "payload": "ewogICAgInRlbXAiOiAyMy4xMzQKfQ=="
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("note.add");
JAddStringToObject(req, "payload", "ewogICAgInRlbXAiOiAyMy4xMzQKfQ==");

NoteRequest(req);
```

**Python**

```python
req = {"req": "note.add"}
req["payload"] = "ewogICAgInRlbXAiOiAyMy4xMzQKfQ=="
rsp = card.Transaction(req)
```

It's also possible to send both a `body` and a `payload` in a single Note.

**JSON**

```json
{
  "req": "note.add",
  "body": { "foo": "bar" },
  "payload": "ewogICAgInRlbXAiOiAyMy4xMzQKfQ=="
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("note.add");
J *body = JCreateObject();
JAddStringToObject(body, "foo", "bar");
JAddItemToObject(req, "body", body);
JAddStringToObject(req, "payload", "ewogICAgInRlbXAiOiAyMy4xMzQKfQ==");

NoteRequest(req);
```

**Python**

```python
req = {"req": "note.add"}
req["body"] = {"foo": "bar"}
req["payload"] = "ewogICAgInRlbXAiOiAyMy4xMzQKfQ=="
rsp = card.Transaction(req)
```

### Initiating an Immediate Sync

If you want to initiate a sync immediately after adding a Note, set the `sync` field to `true`.

**JSON**

```json
{
  "req": "note.add",
  "body": { "foo": "bar" },
  "sync": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("note.add");
JAddBoolToObject(req, "sync", true);
J *body = JCreateObject();
JAddStringToObject(body, "foo", "bar");
JAddItemToObject(req, "body", body);

NoteRequest(req);
```

**Python**

```python
req = {"req": "note.add"}
req["body"] = {"foo": "bar"}
req["sync"] = True
rsp = card.Transaction(req)
```

The JSON response of all `note.add` requests, if successful, is the total number of Notes pending sync in the specified or default Notefile.

```json
{ "total": 3 }
```

> **Note:**
>
> **Use Templated Notefiles for your production apps!**
>
> Working with ad-hoc Notes is a great way to get started with and build your Notecard-based prototypes. However, as your project gets closer to deployment and as you're working with more data, you'll want to use [Templates for Notes and Notefiles](https://dev.blues.io/notecard/notecard-walkthrough/low-bandwidth-design.md#working-with-note-templates). Templates allow you to define a schema for Notes, which the Notecard then uses to store data in smaller chunks for storage and transfer.

## Working with Environment Variables

In IoT applications, many products require configuration variables or settings that are used on an end device, but managed and updated after the product is deployed in the field. In addition, these products often need the ability to manage these values at multiple levels, from the device to a fleet or even within an entire product and all of its deployed devices.

Environment variables are a Notecard and Notehub feature that enable settings synchronization that "just work," with no special setup or configuration needed. These variables are key-value pairs, can be set in Notehub and propagate to devices in a project or fleet, or set on a Notecard directly using the same synchronization mechanism used for Notes and Notefiles.

On the Notecard, `env.get` is used to obtain one or more environment variables. `env.default` is used to set default values on that Notecard, that are overwritten if that variable is also set at Notehub. Finally, `env.modified` is used to determine if any environment variables have changed.

> See our guide on [Understanding Environment Variables](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables.md) for more detailed information on using environment variables.

> **Note:**
>
> You can use the [`env.template` request](https://dev.blues.io/api-reference/notecard-api/env-requests/latest.md#env-template) to provide Notecard with a [template](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables.md#setting-environment-variable-templates) of the environment variables your application intends to use. Templates allow Notecard to store environment variables more efficiently, and are **required** when running in one of the following low-bandwidth environments:
>
> - Notecard for LoRa
> - Any Notecard using NTN mode with a connected Starnote
> - Notecard for Skylo in NTN mode

### Getting Environment Variables

Use the `env.get` request to retrieve all variables, a subset of variables or a single variable, by name. To get all variables, simply send an `env.get` request with no arguments.

**JSON**

```json
{
  "req": "env.get"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.get");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.get"}

rsp = card.Transaction(req)
```

When requesting all variables, the Notecard returns each key-value pair in the `body` of the response object.

```json
{
 "body": {
  "monitor-pump": "true",
  "_tags": "office"
 },
 "time": 1656315835
}
```

To retrieve a group of named environment variables, use the `names` field, and provide an array of variable names.

**JSON**

```json
{
  "req": "env.get",
  "names": ["monitor-pump", "_tags"]
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.get");

J *names = JAddArrayToObject(req, "names");
JAddItemToArray(names, JCreateString("monitor-pump"));
JAddItemToArray(names, JCreateString("_tags"));

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.get"}
req["names"] = ["monitor-pump","_tags"]

rsp = card.Transaction(req)
```

As when requesting all variables, the matched key-value pairs are returned in the `body` of the response object.

```json
{
 "body": {
  "monitor-pump": "true",
  "_tags": "office"
 },
 "time": 1656315835
}
```

To retrieve a single environment variable, use the `name` field to specify the variable you want.

**JSON**

```json
{
  "req": "env.get",
  "name": "monitor-pump"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.get");
JAddStringToObject(req, "name", "monitor-pump");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.get"}
req["name"] = "monitor-pump"

rsp = card.Transaction(req)
```

When requesting a single variable, the Notecard returns an object with a key of `text` and value corresponding to the variable name provided.

```json
{
 "text": "true",
 "time": 1656315835
}
```

If the `name` provided does not match a known variable, or if no variables exist on the Notecard or Notehub, an empty JSON object (`{}`) is returned.

To retrieve a single, all, or a group of environment variables after a modified time, pass a UNIX Epoch time in the `time` field of a `env.get` request.

**JSON**

```json
{
  "req": "env.get",
  "name": "monitor-pump",
  "time": 1656315835
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.get");
JAddStringToObject(req, "name", "monitor-pump");
JAddNumberToObject(req, "time", 1656315835);

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.get"}
req["name"] = "monitor-pump"
req["time"] = 1656315835

rsp = card.Transaction(req)
```

If a variable or variables have changed, the Notecard will return them in the response. Otherwise, the Notecard will return an `{env-not-modified}` error.

```json
{
  "err": "environment hasn't been modified {env-not-modified}"
}
```

> **Note:**
>
> **The Hierarchy of Environment Variables**
>
> Environment variables can be defined in a number of locations, from the Notecard, to Notehub device settings, the device's [Fleet](https://dev.blues.io/api-reference/glossary.md#fleet), and the Notehub project. Variables set at different levels of this hierarchy can override one another. When obtaining an environment variable, the Notecard uses the following priority order, where the first matched result is returned:
>
> 1. The value set on that Notecard with the (deprecated) `env.set` request.
> 2. The value set in Notehub directly on Notehub's record for the Device.
> 3. The value set in Notehub on a Fleet to which the Device belongs.
> 4. The value set in Notehub on the [Project](https://dev.blues.io/api-reference/glossary.md#project) to which the Device belongs.
> 5. The value set on that Notecard with the `env.default` request.

### Setting Environment Variable Defaults

Use the `env.default` request to set a default value for the host. Once this value is set, it will be returned as defined by `env.get` unless the variable has been overridden on Notehub.

For instance, assume that you need to create a variable to determine whether your [Host MCU](https://dev.blues.io/api-reference/glossary.md#host-mcu) should monitor a connected pump, and that you want to be able to override this value from your Notehub project. To set a default, you'd send the following request:

**JSON**

```json
{
  "req": "env.default",
  "name": "monitor-pump",
  "text": "true"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.default");
JAddStringToObject(req, "name", "monitor-pump");
JAddStringToObject(req, "text", "true");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.default"}
req["name"] = "monitor-pump"
req["text"] = "true"

card.Transaction(req)
```

Then, your host can obtain this value using `env.get`:

**JSON**

```json
{
  "req": "env.get",
  "name": "monitor-pump"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.get");
JAddStringToObject(req, "name", "monitor-pump");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.get"}
req["name"] = "monitor-pump"

rsp = card.Transaction(req)
```

Which returns the following:

```json
{"text": "true"}
```

If, in the future, a Notehub administrator wishes to disable monitoring without having to directly update the Notecard, they can do so by setting the `monitor-pump` variable directly in the Notehub UI. After the next sync, an `env.get` request will return this overridden value, and your host MCU can respond accordingly.

**JSON**

```json
{
  "req": "env.get",
  "name": "monitor-pump"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.get");
JAddStringToObject(req, "name", "monitor-pump");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.get"}
req["name"] = "monitor-pump"

rsp = card.Transaction(req)
```

Which returns the following:

```json
{"text": "false"}
```

`env.default` can also be used to remove environment variables. Simply provide the variable `name`, but omit the `text` field, and the variable will be removed from the Notecard's internal storage.

**JSON**

```json
{
  "req": "env.default",
  "name": "monitor-pump"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.default");
JAddStringToObject(req, "name", "monitor-pump");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.default"}
req["name"] = "monitor-pump"

card.Transaction(req)
```

The result of all `env.default` requests, if successful, is an empty JSON object (`{}`).

### Setting Environment Variables on the Notecard

> **Warning:**
>
> The `env.set` API is deprecated as of v7.2.2. We recommend setting environment variables in Notehub using either the Notehub user interface or [Notehub API](https://dev.blues.io/api-reference/notehub-api.md). You may also use the `env.default` API to provide a default value for an environment variable, until that variable is overridden by a value from Notehub.

Use the `env.set` request to set an environment variable only on the Notecard. This variable will be returned in `env.get` requests, and sent to Notehub in the next sync, but cannot be overridden by Notehub.

To set a variable, the `name` and `text` fields are used to set the variable name and value, respectively.

**JSON**

```json
{
  "req": "env.set",
  "name": "monitor-pump",
  "text": "false"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.set");
JAddStringToObject(req, "name", "monitor-pump");
JAddStringToObject(req, "text", "false");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.set"}
req["name"] = "monitor-pump"
req["text"] = "false"

card.Transaction(req)
```

`env.set` can also be used to remove environment variables. Simply provide the variable `name`, but omit the `text` field, and a locally-defined variable will be removed from the Notecard's internal storage.

**JSON**

```json
{
  "req": "env.set",
  "name": "monitor-pump"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.set");
JAddStringToObject(req, "name", "monitor-pump");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.set"}
req["name"] = "monitor-pump"

card.Transaction(req)
```

The result of all `env.set` requests, if successful, is an empty JSON object, (`{}`).

### Checking for Environment Variable Changes

When working with multiple environment variables on a device, it can become cumbersome for the host to continually check each variable to determine which values have changed. In these cases, use `env.modified` to obtain the time of the last update to any environment variable managed by the Notecard.

**JSON**

```json
{
  "req": "env.modified"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.modified");

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.modified"}

card.Transaction(req)
```

The result, if successful, is an empty JSON object (`{}`) if the Notecard is not tracking any environment variables, or a UNIX epoch timestamp indicating the last time any environment variable was changed on the device.

```json
{
  "time": 1605814493
}
```

When performing this request periodically, if the `time` value is unchanged between requests, it indicates that no environment variables have changed since the last request.

Alternatively, you can supply a `time` field in an `env.modified` request to determine whether the Notecard has detected an environment variable change since a known epoch time.

**JSON**

```json
{
  "req": "env.modified",
  "time": 1605814493
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("env.modified");
JAddNumberToObject(req, "time", 1605814493);

NoteRequest(req);
```

**Python**

```python
req = {"req": "env.modified"}
req["time"] = 1605814493

rsp = card.Transaction(req)
```

In response, the Notecard will return either a response with the `time` of a change or an `{env-not-modified}` error.

```json
{
  "err": "environment hasn't been modified {env-not-modified}"
}
```

> **Note:**
>
> `env.modified` does not indicate which environment variable on the Notecard has changed, only that a local variable has been modified. Use `env.get` to retrieve the latest variable values after issuing this request, if needed.

## Interacting with Notehub

In addition to providing interfaces for setting synchronization settings on the Notecard, the `hub` API provides a number of requests for getting settings, initiating syncs, and sending device logs to Notehub.

### Getting Service Configuration Parameters

To check all of the current configuration parameters on the Notecard, use the `hub.get` request:

**JSON**

```json
{
  "req": "hub.get"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.get");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.get"}

rsp = card.Transaction(req)
```

The Notecard will return an object with the [DeviceUID](https://dev.blues.io/api-reference/glossary.md#deviceuid), ProductUID, and serial number of your Notecard, as well as the Notehub host, `mode`, `outbound`, and `inbound` max sync time values.

```json
{
 "device": "dev:0000000000000000",
 "product": "com.your-company.your-name:your_product",
 "mode": "continuous",
 "outbound": 60,
 "inbound": 120,
 "host": "a.notefile.net",
 "sn": "your-serial-number",
 "sync": true
}
```

### Getting Service Connection Status

If you want to check on the status of your Notecard's connection to the network and Notehub, use the `hub.status` request:

**JSON**

```json
{
  "req": "hub.status"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.status");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.status"}

rsp = card.Transaction(req)
```

This request will return an object with:

- `status` - The current status of the Notecard's network connection.
- `connected` - A boolean indicating whether the Notecard is connected to Notehub.

```json
{
 "status": "connected (session open) {connected}",
 "connected": true
}
```

### Initiating a Notehub Sync

If you need to manually initiate a sync between your Notecard and Notehub, you can do so with the `hub.sync` request. If your Notecard is set to `minimum` mode, this request must be issued to trigger a sync. If your Notecard is set to `off` mode, this request will be ignored.

**JSON**

```json
{
  "req": "hub.sync"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.sync");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.sync"}

card.Transaction(req)
```

The result of a `hub.sync` request, if successful, is an empty JSON object (`{}`).

If you wish to check on the status of a recently triggered or previous sync, you can do so with the `hub.sync.status` request.

**JSON**

```json
{
  "req": "hub.sync.status"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.sync.status");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.sync.status"}

rsp = card.Transaction(req)
```

In response, the Notecard will return an object that varies based on the conditions of the request.

A sync in-progress will return the `status` of the sync, and the `requested` field, which represents the number of seconds since the sync was initiated.

```json
{
 "status": "starting communications {wait-module} {connecting}",
 "requested": 8
}
```

A successful sync will return the `status`, along with the Unix epoch `time` when the sync was completed, and the `completed` field to represent the number of seconds since the sync completed:

```json
{
 "status": "completed {sync-end}",
 "time": 1598367163,
 "completed": 1648
}
```

If the sync was triggered manually, the `sync` field will be returned and set to `true`:

```json
{
 "status": "completed {sync-end}",
 "time": 1598367163,
 "sync": true,
 "completed": 1648
}
```

If an error occurs during a sync, the `alert` field is returned and set to true.

```json
{
 "status": "merge notefile: sensors.qo",
 "time": 1598371227,
 "alert": true,
 "completed": 37
}
```

You can also trigger a sync through a call to `hub.sync.status` by setting the `sync` field to `true`. This auto-initiates the sync if the Notecard has pending outbound data.

**JSON**

```json
{
  "req": "hub.sync.status",
  "sync": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.sync.status");
JAddBoolToObject(req, "sync", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.sync.status"}
req["sync"] = True

rsp = card.Transaction(req)
```

### Sending Log Messages to Notehub

If you need to send log messages from the Notecard to Notehub, you can do so with the `hub.log` request. These messages are added as Notes in a special [`_health_host.qo` Notefile](https://dev.blues.io/api-reference/system-notefiles.md#healthhost-qo) and sent to Notehub on the next sync.

**JSON**

```json
{
  "req": "hub.log",
  "text": "Hello World!"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.log");
JAddStringToObject(req, "text", "Hello World!");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.log"}
req["text"] = "Hello World!"

card.Transaction(req)
```

To mark the message as urgent, use the `alert` field:

**JSON**

```json
{
  "req": "hub.log",
  "text": "something is wrong!",
  "alert": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.log");
JAddStringToObject(req, "text", "something is wrong!");
JAddBoolToObject(req, "alert", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.log"}
req["text"] = "something is wrong!"
req["alert"] = True

card.Transaction(req)
```

If you need to trigger a sync immediately after queueing the message, set the `sync` field to `true`:

**JSON**

```json
{
  "req": "hub.log",
  "text": "something is wrong!",
  "alert": true,
  "sync": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.log");
JAddStringToObject(req, "text", "something is wrong!");
JAddBoolToObject(req, "alert", true);
JAddBoolToObject(req, "sync", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.log"}
req["text"] = "something is wrong!"
req["alert"] = True
req["sync"] = True

card.Transaction(req)
```

The result of a `hub.log` request, if successful, is an empty JSON object (`{}`).

## Resetting Request Argument Values

After submitting an API request to the Notecard, you may want to reset one or more of the arguments to their default values. This is most easily accomplished by sending a new request with reserved "reset" values, depending on the data type of the argument.

### Resetting String Arguments

String-based arguments in Notecard API requests are reset by re-sending requests with the argument value of `"-"`.

For example, to reset the `mode` of a call to `card.triangulate`, simply send a request like so:

```json
{
  "req": "card.triangulate",
  "mode": "-"
}
```

### Resetting Numeric Arguments

Numeric arguments in Notecard API requests are reset by re-sending requests with the argument value of `-1`.

For example, to reset the `seconds` argument of a call to `card.location.mode`, send a request like so:

```json
{
  "req": "card.location.mode",
  "seconds": -1
}
```

### Resetting Boolean Arguments

Depending on the type of argument being reset, boolean arguments in Notecard API requests may be reset a few different ways:

1. If the argument is a **required** parameter, re-send the request to reflect the state of the argument you want to achieve. For example, `{"req": "hub.set", "mode": "continuous", "sync": true}`\
   versus\
   `{"req": "hub.set", "mode": "continuous", "sync": false}`.
2. If the argument is an **optional** parameter, simply omit that argument on subsequent API calls. The Notecard will interpret the omission as a `false`.
3. Likewise, some **optional** parameters have complementary arguments that can override each other, such as `"on": true` and `"off": true` in a [card.dfu](https://dev.blues.io/api-reference/notecard-api/card-requests.md#card-dfu) request.

## Understanding Persistent Notecard Configurations

Some Notecard API arguments modify the Notecard's configuration, and those settings persist across device restarts and repeated API calls, unless explicitly overridden or reset.

> **Note:**
>
> As a rule of thumb, any API argument that sets a configuration or behavior, rather than reading a status or value, is persistent across restarts and additional API calls.

For example, let's start with the following `hub.set` request:

**JSON**

```json
{
  "req": "hub.set",
  "mode": "continuous",
  "outbound": 90,
  "inbound": 240
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "mode", "continuous");
JAddNumberToObject(req, "outbound", 90);
JAddNumberToObject(req, "inbound", 240);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["mode"] = "continuous"
req["outbound"] = 90
req["inbound"] = 240

card.Transaction(req)
```

Note that the `mode`, `outbound`, and `inbound` arguments are all persistent. If you were to issue another `hub.set` request *without* changing or resetting those values, they would be retained on the device:

**JSON**

```json
{
  "req": "hub.set",
  "product": "com.your-company.your-name:your_product"
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "product", "com.your-company.your-name:your_product");

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["product"] = "com.your-company.your-name:your_product"

card.Transaction(req)
```

This can be confirmed with a `hub.get` request:

```json
{"req":"hub.get"}
```

```json
{
 "mode": "continuous",
 "host": "a.notefile.net",
 "product": "com.your-company.your-name:your_product",
 "device": "dev:860322068012345",
 "inbound": 240,
 "outbound": 90
}
```

Depending on the API, there are potentially three different ways to update a Notecard's configuration when working with persistent arguments.

### Re-Invoke the API with a New Value

You can always issue a new API request with updated values or reset the values to their defaults. See the previous section for more information on [resetting argument values](#resetting-request-argument-values) based on their data type.

Expanding upon the `hub.set` API requests from above, if you wanted to *update* the `outbound` value to a new value and *reset* the `mode` to its default, you could re-invoke the same `hub.set` request with an updated value and a reset character (ignoring all of the other values that you do not want to update or otherwise reset):

**JSON**

```json
{
  "req": "hub.set",
  "mode": "-",
  "outbound": 600
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "mode", "-");
JAddNumberToObject(req, "outbound", 600);

NoteRequest(req);
```

**Python**

```python
req = {"req": "hub.set"}
req["mode"] = "-"
req["outbound"] = 600

card.Transaction(req)
```

This can be confirmed with another `hub.get` request:

```json
{"req":"hub.get"}
```

```json
{
 "mode": "periodic",
 "host": "a.notefile.net",
 "product": "com.your-company.your-name:your_product",
 "device": "dev:860322068012345",
 "inbound": 240,
 "outbound": 600
}
```

### Use Companion Arguments When Available

Certain APIs, such as [card.location.track](https://dev.blues.io/api-reference/notecard-api/card-requests/latest.md#card-location-track), contain related argument values like `"start":true` and `"stop":true` or `"on":true` and `"off":true` that enable or disable particular features.

For example, to start tracking mode on a Notecard, you would issue the following request:

**JSON**

```json
{
  "req": "card.location.track",
  "start": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("card.location.track");
JAddBoolToObject(req, "start", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "card.location.track"}
req["start"] = True
rsp = card.Transaction(req)
```

However, to reset or disable it, you would NOT send a request like `{"req":"card.location.track", "start":false}`. Rather, you would use the companion argument of `"stop":true`:

**JSON**

```json
{
  "req": "card.location.track",
  "stop": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("card.location.track");
JAddBoolToObject(req, "stop", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "card.location.track"}
req["stop"] = True

rsp = card.Transaction(req)
```

### Factory Reset Notecard

Using the [card.restore API](https://dev.blues.io/api-reference/notecard-api/card-requests/latest.md#card-restore) along with the `"delete":true` argument will perform a "factory reset" of your Notecard and reset almost all Notecard configurations.

> You can learn more about this feature in our guide on [Factory Resetting the Notecard](https://dev.blues.io/notecard/notecard-walkthrough/advanced-notecard-configuration.md#factory-resetting-the-notecard).

**JSON**

```json
{
  "req": "card.restore",
  "delete": true
}
```

**C/C++**

```cpp
J *req = NoteNewRequest("card.restore");
JAddBoolToObject(req, "delete", true);

NoteRequest(req);
```

**Python**

```python
req = {"req": "card.restore"}
req["delete"] = True

card.Transaction(req)
```

[Notecard Interfaces](https://dev.blues.io/notecard/notecard-walkthrough/notecard-interfaces.md "Notecard Interfaces") [Time & Location Requests](https://dev.blues.io/notecard/notecard-walkthrough/time-and-location-requests.md "Time & Location Requests")
