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:
- Your language doesn't have a Tendrl SDK (C, Rust, Ruby, shell scripts, anything)
- You want a single process managing all Tendrl communication
- You want multiple local applications sharing one authenticated connection
- You need high throughput with minimal application overhead
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
curl -fsSL https://app.tendrl.com/api/public/tools/nano-agent/v1/latest/install.sh | sh
Windows
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:
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
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.
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.
CLI (Recommended)
Install tendrl from the platform's tool downloads (see CLI Client), then:
tendrl ping
tendrl publish -data '{"temperature": 22.5, "humidity": 65}' -tags sensor
Bash (Raw Socket)
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)
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
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
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:
{"msg_type": "state_update", "data": {"firmware": "1.2.0", "status": "active"}}
{"msg_type": "state_read"}
Response: {"statusTable": {"firmware": "1.2.0", "status": "active"}}
Check for Commands
Poll for incoming messages:
{"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:
- Batches messages: groups socket writes into efficient bulk HTTP sends
- Adapts to load: dynamic batch sizing based on CPU and memory
- Retries with backoff: failed sends are retried automatically
- Sends heartbeats: reports system metrics to Contact
- Manages authentication: one API key, shared by all local applications
Your application code stays simple: just open a socket and write JSON.
What's Next
- CLI Client:
tendrlcommand reference for debugging and shell scripts - Configuration: Flags, tuning, running as a systemd/launchd service
- Examples: All message types, full Python helper, shell scripts
- API Reference: Complete socket protocol reference
Tendrl