Skip to Content
DocumentationGetting StartedOverview

Getting Started

This section takes you from nothing to a phone that sends a message on command from your own server. It is four steps, and the whole path is meant to take under an hour.

In a hurry? The Quickstart is the whole path compressed into one runnable file — install, pair, send, receive — with the reasoning stripped out. The pages below are the same ground, explained.

What you need

  • An Android device, API 26 (Android 8.0) or newer, with an active SIM and a plan that permits person-to-person SMS. A spare or second-hand handset is the normal choice — this device will be plugged in and running permanently.
  • The app, from Google Play . To build it yourself instead you need the Flutter SDK and adb — note that sideloading has real consequences on Android 15+, see Play Protect.
  • A server that speaks the Luno protocol. The fastest route is the @luno-oss/* SDK, which implements the server half for you and runs on Node, Bun, Deno or Cloudflare Workers.
  • HTTPS. The node refuses plaintext transport. For local development a tunnel (cloudflared, ngrok, tailscale funnel) is the usual answer; http:// is permitted only by debug builds on a LAN.

Do not use your personal SIM for testing. Delivery-report and rate-limit behaviour is best explored on a SIM you are willing to have flagged.

The path

Install the app

Install from Google Play, or build a flavored APK and install it over adb. → Installation

Stand up a backend

Create a Luno engine, give it a store, and mount it on the framework you already use. → Backend SDK

Pair the device

Mint a pairing session on the server, then scan the QR code or type the code into the app. The device receives a Keystore-sealed credential and connects. → Pairing

Send your first message

Call luno.sms.send(...) and watch the message move through sms_acceptedsms_sentdelivery_report. → First message

A note on the mental model

It helps to keep one sentence in mind while setting this up:

The node’s entire responsibility is: receive a command, act on the radio, report faithfully what happened.

Everything else — who may send, how many messages per minute, which recipients are permitted, how long a pairing code lives, what happens to a message after delivery — belongs to your backend. The node deliberately holds no policy of its own, so changing policy never requires shipping an app update.