Realtime MQTT Public Stream
Category: Backend & APIs
This page is generated from the Air Pipe marketplace. Browse it live to install into your organization.
Open MQTT: clients connect with no username or password and subscribe to a public topic for live data — public sensor networks, transit feeds, prices, status boards, community IoT. It's the EMQX/HiveMQ allow_anonymous model, but multi-tenant-safe and with your pipeline able to run on the stream.
Public streams are for non-sensitive data — anyone can subscribe. For device auth, retained commands, and per-topic ACLs, use the Realtime MQTT Broker pack.
Why open MQTT is safe here
An anonymous connection is admitted, and where tenant isolation is active the proxy restricts it to interfaces marked public: true at every SUBSCRIBE and PUBLISH (fail-closed) — it cannot reach a private topic. On a managed host that isolation is always on, the connection is scoped to your org (the org id rides the username, which isn't a secret), and the per-org abuse floors (publish rate, subscriptions, topics) apply. Open access, bounded blast radius.
Read this before running it self-hosted. That restriction is gated on tenant isolation — managed, or AP_MQTT_ORG_NAMESPACING enabled. On a plain self-hosted broker (single tenant, namespacing off) anonymous is deliberately unrestricted, exactly as EMQX/HiveMQ allow_anonymous behaves: an anonymous client can subscribe to production/# and receive every topic in that deployment. Verified against 3.10.0. If you want a public feed next to private topics self-hosted, put a subscribe_authorizer on the private interfaces — that boundary does hold, a subscribe outside its allow-list is dropped — or enable namespacing, or separate the deployments.
How Air Pipe compares
| EMQX / HiveMQ | AWS IoT Core | Air Pipe | |
|---|---|---|---|
| Anonymous MQTT | ✅ (allow_anonymous) | ❌ | ✅ (public: true interface; scoped to public topics where tenant isolation is on) |
| Safe on multi-tenant / shared infra | ❌ (single-tenant) | ✅ | 🏆 (public-only gate + per-org floors) |
| Run your logic on the public message | ❌ | ❌ | 🏆 built-in |
What's included
| File | Purpose |
|---|---|
public.yml | One public: true MQTT interface (publicdata) that stamps and fans out each message. |
Endpoint
| Transport | Connect URL | Auth |
|---|---|---|
| MQTT over WebSocket | wss://your-airpipe-host/mqtt (sub-protocol mqtt) | none (anonymous) — or username=<ORG_UUID>, no password, on managed |
Public topic: production/publicdata/stream.
Quick start
Node (MQTT.js) — anonymous subscribe:
const mqtt = require("mqtt");
const c = mqtt.connect("wss://your-airpipe-host/mqtt"); // no username/password
c.on("connect", () => c.subscribe("production/publicdata/stream"));
c.on("message", (t, m) => console.log(t, JSON.parse(m.toString())));
Your backend — publish to the public stream:
const pub = require("mqtt").connect("wss://your-airpipe-host/mqtt",
{ username: "<ORG_UUID>", password: "<API_KEY>" }); // authenticated publisher
pub.on("connect", () =>
pub.publish("production/publicdata/stream",
JSON.stringify({ station: "SYD-01", temp_c: 22.1 }), { qos: 1 }));
// → every anonymous subscriber receives it, stamped with received_at by the pipeline
Python (paho-mqtt) — anonymous subscribe:
import paho.mqtt.client as mqtt
c = mqtt.Client(transport="websockets"); c.ws_set_options(path="/mqtt"); c.tls_set()
c.connect("your-airpipe-host", 443) # no username/password
c.subscribe("production/publicdata/stream"); c.loop_forever()
Customisation
- Open publish too: anonymous clients may also publish to the public topic — leave as-is for a fully open feed, or add a
subscribe_authorizer/ publish gate to make it read-only-public. - Process the stream: the
Stampaction runs on every message — swap it for validation, enrichment, a DB insert, or a webhook. - Multiple public streams: add more
public: trueinterfaces, each its ownproduction/<name>/<trigger>topic.
Notes
- Anonymous connections can only reach
public: trueinterfaces — private topics are never exposed. - Targets MQTT-over-WebSocket clients (MQTT.js, paho
transport="websockets", HiveMQ web client). - Each message that triggers the pipeline counts as one request against your plan.
- Only
productionandstagingenvironments are accepted in the topic.
Configuration
public.yml
name: RealtimeMqttPublic
description: >
Public MQTT — clients connect with NO username or password and subscribe to a public topic for
live data (sensor readings, transit, prices, status). The EMQX/HiveMQ `allow_anonymous` model, but
multi-tenant-safe where tenant isolation is active (managed, or AP_MQTT_ORG_NAMESPACING): an
anonymous connection then reaches only interfaces marked `public: true`, never a private topic,
and per-org limits still bound it. On a plain self-hosted broker anonymous is unrestricted, as
with EMQX/HiveMQ allow_anonymous -- gate private topics with a subscribe_authorizer there. Interface-shaped public topics also run your
pipeline — validate/enrich the public stream, which a raw broker can't.
docs: true
# ── How it works ─────────────────────────────────────────────────────────────────
# Connect an MQTT-over-WebSocket client to wss://your-airpipe-host/mqtt with NO credentials:
# (no username, no password) — anonymous / public
# or, on a managed host, username = <ORG_UUID> and NO password (the org id is not a secret; it
# scopes the connection to your org's public topics).
#
# Then subscribe to the public interface topic:
# production/publicdata/stream
# An anonymous connection is restricted to `public: true` interfaces — any other topic is denied
# (fail-closed) — WHERE TENANT ISOLATION IS ACTIVE: managed, or self-hosted with
# AP_MQTT_ORG_NAMESPACING on. That is the condition, and it matters.
#
# ON A PLAIN SELF-HOSTED BROKER (single tenant, namespacing off) ANONYMOUS IS UNRESTRICTED, by
# design — it matches EMQX/HiveMQ `allow_anonymous`. An anonymous client can subscribe to
# `production/#` and receive every topic in the deployment. Verified on 3.10.0.
#
# So if you run this feed self-hosted alongside private topics, gate the private ones with a
# `subscribe_authorizer` (that DOES hold — a subscribe outside its allow-list is dropped), or
# turn namespacing on, or keep public and private on separate deployments.
#
# Publishing: your backend (authenticated) publishes to production/publicdata/stream and every
# anonymous subscriber receives it. Anonymous clients may also publish to the public topic if you
# want a fully open feed — remove that ability by adding a `subscribe_authorizer` / publish gate.
interfaces:
# Public MQTT interface — anonymous clients may pub/sub here (and only here).
publicdata:
mqtt: "stream" # realtime — no `output` needed
# output: http # optional: also accept over HTTP (dual interface)
public: true
summary: Public MQTT stream (no auth)
description: Anonymous clients subscribe to production/publicdata/stream for live public data.
tags: [mqtt, iot, public, pubsub, telemetry]
actions:
# Runs on each publish to the public topic — validate/stamp before it fans out.
- name: Stamp
input: a|body|
post_transforms:
- add_attribute:
received_at: a|timestamp:datetimeutctz|