Docs / Contact / sdks/nano-agent/getting-started

Nano Agent: Getting Started

Send data to Contact from any language in 3 lines. The Nano Agent is a lightweight binary that runs on your device, exposes a Unix socket, and handles all the heavy lifting: batching, retry, heartbeats, and HTTP communication. Your application just writes JSON to a socket.

Use the Nano Agent when:

Requirements: Linux, macOS, or Windows 10 1803+

Install

One command on any platform. The installer detects your OS and architecture, verifies checksums, and puts tendrl-agent (plus the tendrl CLI, when the release includes it) on your PATH. It downloads with curl, so macOS Gatekeeper and Windows SmartScreen never flag the binaries.

macOS / Linux

bash

curl -fsSL https://app.tendrl.com/api/public/tools/nano-agent/v1/latest/install.sh | sh

Windows

powershell

powershell -c "irm https://app.tendrl.com/api/public/tools/nano-agent/v1/latest/install.ps1 | iex"

Set TENDRL_BIN_DIR to override the install directory. To pin a build, swap latest for a version tag; direct per-platform downloads and checksums are listed at /api/public/tools/nano-agent/v1/meta.

Linux: socket directory

The agent serves its socket from /var/lib/tendrl by default, so create that directory (and a group for the local users allowed to talk to it) once:

bash

sudo mkdir -p /var/lib/tendrl
sudo groupadd tendrl
sudo chown :tendrl /var/lib/tendrl
sudo chmod 770 /var/lib/tendrl
sudo usermod -aG tendrl $(whoami)

On macOS, or to run without root on Linux, point the agent (and its clients) at a user-writable path instead with TENDRL_SOCKET=/tmp/tendrl_agent.sock or the -socket flag.

Start the Agent

Need an API key?

The agent authenticates with an entity API key. If you haven't created one yet, create your first entity and copy its API key from the Connection Instructions dialog.

bash

export TENDRL_KEY=your_api_key
tendrl-agent

The agent creates a socket and starts listening. That's the entire setup.

Platform Socket Path
Linux/macOS /var/lib/tendrl/tendrl_agent.sock
Windows C:\ProgramData\tendrl\tendrl_agent.sock

Send Your First Message

The fastest way to send a message is the tendrl CLI client. For production code, write JSON directly to the socket in any language.

Install tendrl from the platform's tool downloads (see CLI Client), then:

bash

tendrl ping
tendrl publish -data '{"temperature": 22.5, "humidity": 65}' -tags sensor

Bash (Raw Socket)

bash

echo '{"msg_type":"publish","data":{"temperature":22.5},"context":{"tags":["sensor"]}}' | \
  nc -U /var/lib/tendrl/tendrl_agent.sock

On Windows, prefer the tendrl CLI, because nc -U is not always available.

Python (No SDK Needed)

python


sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect("/var/lib/tendrl/tendrl_agent.sock")
sock.sendall(json.dumps({
    "msg_type": "publish",
    "data": {"temperature": 22.5, "humidity": 65},
    "context": {"tags": ["sensor"]}
}).encode())
sock.close()

C

c

int fd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr = { .sun_family = AF_UNIX };
strncpy(addr.sun_path, "/var/lib/tendrl/tendrl_agent.sock", sizeof(addr.sun_path) - 1);
connect(fd, (struct sockaddr *)&addr, sizeof(addr));
write(fd, "{\"msg_type\":\"publish\",\"data\":{\"temp\":22.5}}", 43);
close(fd);

Rust

rust

let mut stream = UnixStream::connect("/var/lib/tendrl/tendrl_agent.sock")?;
stream.write_all(br#"{"msg_type":"publish","data":{"temp":22.5},"context":{"tags":["sensor"]}}"#)?;

That's it. The agent queues your message, batches it with others, and delivers it to Contact. You get dynamic batching, retry with backoff, and heartbeats without writing a single line of infrastructure code.

Track Device State

Store and retrieve persistent state through the socket:

json

{"msg_type": "state_update", "data": {"firmware": "1.2.0", "status": "active"}}
json

{"msg_type": "state_read"}

Response: {"statusTable": {"firmware": "1.2.0", "status": "active"}}

Check for Commands

Poll for incoming messages:

json

{"msg_type": "msg_check", "context": {"limit": 5}}

The agent returns an array of pending messages, or 204 if none are waiting.

What the Agent Handles for You

The agent runs as a single process and automatically:

Your application code stays simple: just open a socket and write JSON.

What's Next