Complete Guide

How MQTTBridge works

From creating your account to streaming live sensor data โ€” and pulling it into your own projects with an API key. Everything is covered here.

OverviewStep-by-stepData formatsPublishing dataAlertsAPI & CodeLimits & tips
Overview

What MQTTBridge actually does

MQTTBridge sits between your device and your browser. It maintains a live MQTT connection to your broker so you don't have to manage one yourself.

๐Ÿญ
Your Device
PLC / Sensor / Pi
โ†’
๐Ÿ“ก
MQTT Broker
EMQX / HiveMQ / any
โ†’
โš™๏ธ
MQTTBridge Backend
Subscribes ยท Translates ยท Stores
โ†’
๐Ÿ—„๏ธ
Database
Supabase Postgres
โ†’
๐Ÿ–ฅ๏ธ
Your Dashboard
Live ยท Alerts ยท Export
1

Your device publishes data

Your PLC, ESP32, Raspberry Pi, or any MQTT-capable device publishes messages to a topic on an MQTT broker โ€” public or private.

2

Backend subscribes and translates

MQTTBridge connects to your broker and subscribes to your topic. Every incoming message is decoded according to your chosen format (JSON, Hex, Binary, or Plain) and stored with a timestamp.

3

Dashboard streams it live

Your dashboard reads from the database via Supabase Realtime โ€” messages appear the moment they arrive. Switch to dashboard view for live value tiles and a time-series chart.

Step-by-step guide

From zero to live data

1

Create a free account

Go to the Sign Up page and register with an email and password. You'll receive a confirmation email โ€” click the link to activate your account, then sign back in.

๐Ÿ“ฌ
Check your spam folder
The confirmation email sometimes lands in spam. If you don't see it within 2 minutes, check your spam/junk folder. The confirmation link expires after 24 hours.
2

Have an MQTT broker your device publishes to

MQTTBridge connects to your broker โ€” it doesn't host one. You need a broker your device already publishes to, or you can point your device at one of these free public brokers:

EMQX PublicRecommended
mqtt://broker.emqx.iomqtts://broker.emqx.ioPort 1883 ยท TLS: 8883
HiveMQ PublicReliable
mqtt://broker.hivemq.commqtts://broker.hivemq.comPort 1883 ยท TLS: 8883
โš ๏ธ
Public brokers are shared spaces โ€” anyone can subscribe to any topic. Never publish personal data to a public broker. Use a unique topic prefix like yourname/project/sensor to avoid accidentally receiving other users' messages.
๐Ÿ’ก
Have a private broker? That works too. Enter your username and password in the credentials section when creating a subscription. They are encrypted with AES-256 before being stored โ€” never in plain text.
3

Create a subscription

Once signed in, open your Dashboard and click + New Subscription. Fill in the form:

Label
optional
A friendly name like "Factory Line 1 Temp" so you can identify it in the sidebar. Optional but recommended.
Broker URL
required
Full URL of your broker. e.g. mqtt://broker.emqx.io or mqtts://broker.emqx.io for TLS.
Topic
required
The exact topic your device publishes to. e.g. factory/line1/temperature. Wildcards like # and + are supported.
Data Format
required
Choose the format your device sends: JSON, Hex, Binary, or Plain. See the Data Formats section below.
Username / Password
optional
Only needed for private brokers that require authentication. Credentials are encrypted before storage.

Click Subscribe โ†’ and the backend connects to your broker immediately. The subscription appears in your dashboard sidebar within seconds.

4

Publish data from your device

Your device (PLC, ESP32, Raspberry Pi, Node-RED, or any MQTT client) publishes to the same broker and topic you registered. Here are working examples for common platforms:

python โ€” paho-mqtt
# Python โ€” paho-mqtt (pip install paho-mqtt)
import paho.mqtt.client as mqtt, json
client = mqtt.Client()
client.connect('broker.emqx.io', 1883)
payload = json.dumps({'temperature': 23.4, 'humidity': 61})
client.publish('yourname/sensors/env', payload)
arduino / esp32 โ€” PubSubClient
// Arduino / ESP32 โ€” PubSubClient library
#include <PubSubClient.h>
client.connect("esp32-device");
// Plain text value
client.publish("yourname/sensors/temp", "23.4");
// Or a JSON string
client.publish("yourname/sensors/env", "{\"temp\":23.4,\"rh\":61}");
node.js โ€” mqtt package
// Node.js โ€” npm install mqtt
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://broker.emqx.io');
client.on('connect', () => {
client.publish('yourname/sensors/temp',
JSON.stringify({ temperature: 23.4 }));
});
โฑ๏ธ
Rate limiting โ€” one message stored every 10 seconds
MQTTBridge stores one message per subscription every 10 seconds. Messages arriving faster are acknowledged by the backend but not saved to the database. This prevents database flooding. If your device publishes every second, approximately 6 messages per minute are saved โ€” which is enough for most monitoring use cases.
5

Watch your data stream live

Select your subscription in the sidebar. Messages appear in real time as they arrive, translated into readable values. The topbar shows connection status, message count, and controls.

โ‰ก
List view
Scrollable feed of every message with timestamp and translated value. Click a JSON message to expand the full pretty-printed payload.
โŠž
Dashboard view
Live value tiles for each field in your data, plus a time-series chart. Toggle between 5 min, 30 min, 1 hour, or all data.
โธ
Pause / Resume
Pause a subscription to stop receiving messages without deleting it. The broker connection closes cleanly and reopens on resume.
โ†“
Export
Download the last 50 messages as JSON or CSV from the topbar at any time.
Data formats

How your data gets translated

Choose the format that matches what your device sends when creating a subscription. Every message is decoded automatically โ€” no code needed on your end.

JSON
Input payload
{"temperature":23.4,"humidity":61,"unit":"C"}
Translated to
temperature: 23.4 humidity: 61 unit: C
JSON objects are flattened into key: value pairs, one per line. Nested objects are flattened with a pipe separator. Arrays of primitives are listed inline.
HEX
Input payload
0x0041
Translated to
65 (0x0041)
Strips the 0x prefix and whitespace, validates hex characters, attempts UTF-8 decode. If the result is printable text it returns text (0xHEX) โ€” otherwise converts to decimal using BigInt and returns decimal (0xHEX).
BINARY
Input payload
01000001
Translated to
65 [0x41]
Interprets by byte length: 1 byte โ†’ uint8, 2 bytes โ†’ uint16 + int16, 4 bytes โ†’ float32 or uint32, 8 bytes โ†’ float64. Output shows the interpreted value alongside a hex dump.
PLAIN
Input payload
23.4
Translated to
23.4
The raw payload string is passed through exactly as received. Use this for sensors that publish a single number, a status string, or any value that needs no decoding.
โš ๏ธ
Format mismatch: If your device sends a format that doesn't match your selection (e.g. you chose JSON but your device sends plain text), the raw payload is displayed as-is without crashing. You can delete and re-add the subscription with the correct format at any time.
Publishing data

Send commands back to your device

MQTTBridge is two-way. You can publish a message to your broker from the dashboard or via the API โ€” useful for sending commands, resetting values, or triggering actions on your device.

From the dashboard

1
Select a subscription in the sidebar
2
Click the โ†‘ Publish button in the topbar
3
Choose the payload format (Plain, JSON, Hex, or Binary)
4
Optionally change the topic โ€” by default it publishes to the same topic the subscription listens on
5
Type your payload and click Publish โ†‘ (or press โŒ˜ Enter)
๐Ÿ’ก
You can publish to a different topic than the one your subscription listens on. For example, your subscription might listen on factory/sensor/temp but you publish a command to factory/device/control โ€” as long as both are on the same broker.

Payload validation by format

Plain
Any string up to 64 KB. Sent as-is.
JSON
Must be valid JSON. Rejected if malformed โ€” you'll see the error inline.
Hex
Must contain only hex characters (0โ€“9, aโ€“f). Spaces are stripped before sending.
Binary
Must contain only 0s and 1s. Spaces are stripped before sending.
Alert Rules

Get notified when a value goes out of range

Set threshold rules per subscription. When a message triggers a rule, you're notified on your dashboard and optionally via Telegram.

How to create an alert rule

1
Select a subscription in the sidebar
2
Click the ๐Ÿ”” Rules button in the topbar
3
Give the rule a name (optional), set the condition and threshold value
4
For JSON subscriptions, enter the field name to watch (e.g. "temperature"). Leave blank to match on the whole translated payload.
5
Set a cooldown โ€” the minimum time between alerts from this rule (1โ€“1440 minutes, default 10 min)
6
Toggle "Notify via Telegram" if you want a Telegram message when it fires
7
Click + Add Rule
> Greater than
Temp above 80ยฐC
< Less than
Pressure below 10 bar
= Equals
Status is "FAULT"
โ‰  Not equals
Mode changed from normal
โˆ‹ Contains
Message includes "error"

Setting up Telegram notifications

To receive alert messages on Telegram you need to provide your Telegram Chat ID. This is a one-time setup in Settings:

1
Open Telegram and search for @BotFather
2
Send /newbot and follow the prompts to create a bot โ€” Save the bot token BotFather gives you.
3
Start a conversation with your new bot โ€” Send it any message (e.g. "hello").
4
Get your Chat ID โ€” Visit api.telegram.org/bot<YOUR_TOKEN>/getUpdates in a browser โ€” find "chat":{"id": 123456789} in the response.
5
Go to Settings โ†’ Telegram Alerts in your dashboard โ€” Click your avatar in the bottom-left of the sidebar.
6
Paste your Chat ID and click Save โ€” MQTTBridge will now send Telegram messages when a rule fires.
๐Ÿ“ฑ
What the Telegram message looks like
๐Ÿšจ MQTTBridge Alert
Rule: Temp too high
Value: 85.3
Time: 27/05/2026, 14:32:00
API Keys & Code Integration

Use your data in your own projects

Generate a personal API key and pull live or historical sensor data into any frontend, script, or automation tool โ€” no backend or session needed.

How to generate an API key

1
Open your Dashboard โ€” Click your email / avatar in the bottom-left of the sidebar to open Settings.
2
Click the "API Keys" tab
3
Enter a label for the key โ€” e.g. "My Grafana Dashboard", "Raspberry Pi script". This helps you remember which key belongs to which project.
4
Click Generate Key โ€” Copy it immediately and store it safely โ€” you can see the key again from the keys list at any time.
5
Use it in your code via the x-api-key header โ€” See the examples below.
๐Ÿ“‹ Finding your Subscription ID

Every API request for messages or publishing requires your subscription ID โ€” a UUID that identifies which subscription you're referencing. There are two ways to get it:

1. Via the API: Call GET /api/subscriptions with your API key โ€” it returns all your subscriptions including their IDs.
2. From the dashboard URL: Open your dashboard, select a subscription โ€” the URL will contain the subscription ID in some implementations. Or check your browser dev tools for the ID in network requests.

Available API endpoints

All endpoints use the header x-api-key: mqttb_your_key_here. Click any endpoint to expand the full details.

Code examples

Replace the highlighted variables with your own values. Your API key starts with mqttb_ and is found in Settings โ†’ API Keys.

Read the latest sensor value
YOUR_API_KEYYOUR_BACKEND_URLSUBSCRIPTION_ID
fetch-latest.js
// Replace these three variables with your own values
const API_KEY = 'mqttb_your_key_here';
const BASE_URL = 'https://your-backend.railway.app';
const SUBSCRIPTION_ID = 'your-subscription-uuid';
const res = await fetch(
`${BASE_URL}/api/messages/${SUBSCRIPTION_ID}/latest`,
{ headers: { 'x-api-key': API_KEY } }
);
if (!res.ok) throw new Error(`API error: ${res.status}`);
const message = await res.json();
console.log(message.translated_payload); // 'temp: 23.4'
console.log(message.received_at); // '2026-05-27T14:32:00Z'
Read message history (last 100)
fetch-history.js
const API_KEY = 'mqttb_your_key_here';
const BASE_URL = 'https://your-backend.railway.app';
const SUBSCRIPTION_ID = 'your-subscription-uuid';
const res = await fetch(
`${BASE_URL}/api/messages/${SUBSCRIPTION_ID}?limit=100`,
{ headers: { 'x-api-key': API_KEY } }
);
const messages = await res.json();
// Array of messages, newest first
messages.forEach(msg => {
console.log(msg.translated_payload, msg.received_at);
});
Publish a command to your device
publish.js
const API_KEY = 'mqttb_your_key_here';
const BASE_URL = 'https://your-backend.railway.app';
const SUBSCRIPTION_ID = 'your-subscription-uuid';
const res = await fetch(`${BASE_URL}/api/publish`, {
method: 'POST',
headers: {
'x-api-key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
subscription_id: SUBSCRIPTION_ID,
payload: 'SET_TEMP:22',
// topic: 'factory/device/control', // optional override
}),
});
const result = await res.json();
// { ok: true, topic: '...', message: 'Published successfully' }
Get your subscription IDs
get-subscriptions.js
const API_KEY = 'mqttb_your_key_here';
const BASE_URL = 'https://your-backend.railway.app';
const res = await fetch(`${BASE_URL}/api/subscriptions`, {
headers: { 'x-api-key': API_KEY }
});
const subscriptions = await res.json();
subscriptions.forEach(sub => {
console.log(sub.id, sub.label, sub.topic);
// Copy the id โ€” that's your SUBSCRIPTION_ID
});
๐Ÿ”’
Security โ€” what your API key can and cannot access
Your API key is scoped strictly to your own account. It can only read your subscriptions and messages, and publish via your connections. It cannot access any other user's data. You can revoke any key at any time from Settings โ†’ API Keys. Keys are stored as SHA-256 hashes โ€” the raw key is never stored, so keep a copy somewhere safe.
Limits & tips

What to know before you build

โฑ๏ธ5 rate limit

One message is stored per subscription every 5 seconds. Messages arriving faster are received but not saved. This prevents database flooding โ€” at 10s intervals your data is still rich enough for monitoring and charting.

๐Ÿ“ฆ50 messages in dashboard

The dashboard shows the last 50 messages. The API can return up to 200 with ?limit=200. Older messages remain in the database โ€” they're not deleted, just not shown in the default view.

๐Ÿ”„Auto-reconnect with backoff

If a broker connection drops, the backend reconnects automatically using exponential backoff โ€” 5s, 10s, 30s, 60s. After 10 failed attempts the subscription is marked inactive and you're notified via Telegram if configured.

โธPaused = broker disconnected

When you pause a subscription the backend cleanly disconnects from that broker+topic. No messages are received or stored until you resume.

๐Ÿ”Heartbeat sync every 30s

A background process checks every 30 seconds that in-memory connection state matches the database. This self-heals any drift after server restarts.

๐Ÿ›ก๏ธRequest body limit: 10 KB

API request bodies are capped at 10 KB. Published payloads are capped at 64 KB separately. This prevents abuse and protects the backend from oversized payloads.

๐Ÿ’ก Tips for best results

โ†’
Use EMQX as your public broker: broker.emqx.io is the most reliable of the free public options โ€” fewest disconnects, lowest latency.
โ†’
Make your topic unique: Public brokers are shared. Use a prefix like your username: johnsmith/factory/line1/temp โ€” this prevents accidentally receiving strangers' messages.
โ†’
Match your data format exactly: If your device sends JSON, pick JSON. If it sends a raw number, pick Plain. A mismatch shows the raw value but makes dashboard view less useful.
โ†’
Use /latest for live dashboards: If you're building a frontend showing current sensor state, /api/messages/{id}/latest is more efficient than fetching all 50 and taking the first element.
โ†’
Export before clearing: The Clear button permanently deletes all stored messages for a subscription. Use the JSON or CSV export in the topbar first if you want the history.
โ†’
Alerts have a cooldown: Each rule has a configurable cooldown (default 10 min). If your value crosses the threshold repeatedly, you won't get flooded โ€” only one alert fires per cooldown window.

Ready to connect your first device?

Create your free account and have live data on your dashboard in under 5 minutes.

Create free account โ†’Back to home