Smart home
Node-RED SMS: send and receive texts with the http request and http in nodes
Published and updated
Node-RED sends SMS through textbee with two core nodes: a function node that sets the headers and the payload, and an http request node that posts to the textbee send endpoint. An http in node receives every incoming text as msg.payload and an http response node acknowledges it. No contrib node is needed, and it runs on a Raspberry Pi next to MQTT, Home Assistant or your sensors.
- Send
- HTTP POST
- to the textbee send endpoint
- Receive
- Webhook
- MESSAGE_RECEIVED, flat JSON
- Pace
- 10 to 15 / min
- per Android phone
- textbee code
- None
- uses what the tool ships today
What you need
- Node-RED 3 or newer. The function node loads the crypto module through its Setup tab.
- A textbee account with the Android app installed on the phone that holds the SIM, and an API key from the dashboard.
- For receiving: the http in endpoint reachable over public HTTPS, through a reverse proxy or a tunnel.
- The textbee app on the phone. Download the app, then create an API key in the dashboard.
Send SMS from Node-RED
The API key comes from an environment variable, so an exported flow never contains it. Set TEXTBEE_API_KEY where Node-RED starts, or in settings.js.
Build the request in a function node
The node expects msg.to and msg.text from whatever feeds it: an inject node, an MQTT message, a sensor flow.
function: build requestmsg.url = 'https://api.textbee.dev/api/v1/gateway/send-sms' msg.headers = { 'x-api-key': env.get('TEXTBEE_API_KEY'), 'Content-Type': 'application/json' } msg.payload = { recipients: [msg.to], message: msg.text } return msgAdd the http request node
Leave the URL field empty so the node uses msg.url, and set the return type so the response is parsed.
Field Value Method POST URL empty, taken from msg.url Return a parsed JSON object Trigger it
Wire an inject node that sets msg.to to +12015550123 and msg.text to a test message, then the function node, the http request node and a debug node. Deploy and click inject. The debug shows data.success true.
Feed it from your flows
Replace the inject node with the flow that should text: an MQTT in node, a Home Assistant event, a schedule. Any message with msg.to and msg.text sends a text.
Receive SMS in Node-RED
The http in node parses JSON into msg.payload and keeps the headers in msg.req.headers, so a function node can verify the signature before anything else runs.
Add the endpoint
An http in node with Method POST and URL /textbee. Wire it to the function below. Output 1 carries verified texts, output 2 goes to an http response node.
Verify the signature
In the function node Setup tab add the module crypto as the variable crypto. Set TEXTBEE_WEBHOOK_SECRET in the environment to the signing secret you use in the textbee dashboard.
function: verify and routeconst secret = env.get('TEXTBEE_WEBHOOK_SECRET') const expected = Buffer.from(crypto.createHmac('sha256', secret).update(JSON.stringify(msg.payload)).digest('hex')) const given = Buffer.from(msg.req.headers['x-signature'] || '') if (given.length !== expected.length || !crypto.timingSafeEqual(given, expected)) { msg.statusCode = 401 return [null, msg] } msg.statusCode = 200 if (msg.payload.webhookEvent !== 'MESSAGE_RECEIVED') return [null, msg] msg.sender = msg.payload.sender msg.text = msg.payload.message return [msg, msg]Expose and register
Put Node-RED behind HTTPS with a reverse proxy or a tunnel, then register https://your-host/textbee in the textbee dashboard with the MESSAGE_RECEIVED event and the same signing secret.
Test it
Text the phone from another number. Output 1 emits a message with msg.sender and msg.text; wire it to a switch node that branches on the text.
Ask your AI agent to set it up
The prompt below carries the endpoints, the payloads and the Node-RED details from this page. Change the line that starts with What I want, paste the prompt into your agent, and it walks you through the setup with your own field names and numbers.
Prompt for your AI agent
Paste it into Claude, ChatGPT, Cursor or any coding agent. It carries the textbee API facts and the Node-RED details the agent needs, so it does not guess.
I want to connect textbee to Node-RED. textbee is an SMS gateway that sends and receives SMS through my own Android phone. Help me set it up step by step.
Facts about the textbee API. Use only these. Do not invent endpoints or fields.
- Send an SMS: POST https://api.textbee.dev/api/v1/gateway/send-sms with the header x-api-key: <TEXTBEE_API_KEY> and a JSON body like {"recipients": ["+12015550123"], "message": "Hello"}. recipients must be a JSON array of E.164 numbers, even for one number. Optional fields: deviceId, simSubscriptionId, scheduledAt (ISO 8601, in the future). The response is {"data": {"success": true, "smsBatchId": "..."}}.
- Check delivery or read replies: GET https://api.textbee.dev/api/v1/gateway/messages with the same header. Filters: direction=received, smsBatchId=<id from the send>, from and to as ISO timestamps. Each row has a status such as sent, delivered, failed or received.
- Receive an SMS: textbee posts JSON to a webhook URL I register in the dashboard. A MESSAGE_RECEIVED delivery has these top-level fields: smsId, message, deviceId, webhookSubscriptionId, webhookEvent, idempotencyKey, sender, receivedAt. The header X-Signature holds an HMAC-SHA256 hex digest of the raw body, keyed with the signing secret I set on the webhook. Retries reuse the same idempotencyKey.
- Limits: One Android phone sends roughly 10 to 15 messages a minute. Text only, no MMS. Messages over 160 characters are split into segments.
What I want: Send SMS from my Node-RED flows, and receive texts into a flow with the signature verified, using core nodes only.
Node-RED specifics you should know:
- Core nodes only: a function or change node sets msg.url, msg.headers and msg.payload, then an http request node with Return set to a parsed JSON object.
- http in with Method POST plus http response; the parsed body is msg.payload and the headers are in msg.req.headers.
- Function nodes load Node modules through the Setup tab, and env.get() reads environment variables.
- textbee signs JSON.stringify of the payload with no extra whitespace, so re-serializing msg.payload reproduces the signed bytes.
Give me:
1. The exact clicks and field values in Node-RED, using its real field labels.
2. The request body or field mapping, with placeholders for my API key and phone numbers. Never ask me to paste the real key into this chat.
3. A test with one number and what a correct result looks like.
4. The three most likely failure causes and how to check each one.Automations that work well
- Sensor alert
- MQTT in node on a temperature topic, a switch node on the threshold, then the send flow. A text reaches you when the freezer warms up.
- Daily summary
- An inject node at 8 am, a function that reads global context or a database, then one text with the numbers.
- Command by text
- The receive flow, a switch node on msg.text, then GPIO, MQTT or a Home Assistant call. Restrict it to your own number in the switch.
- Two phones, two SIMs
- Register both phones in textbee and set deviceId in msg.payload to pick which SIM sends. Useful when one number is for the family and one for the business.
Why teams move Node-RED SMS to their own phone
- No provider account
- The usual Node-RED SMS path is a contrib node wrapped around a cloud provider, with a number to rent and a per-message fee. Core nodes and a phone replace it.
- Alerts that get through
- A text from a number people have saved wakes a phone on do not disturb and needs no app on the receiving side.
- Runs where your flows run
- On the same Raspberry Pi or server as the rest of the flows, with the key in an environment variable and nothing new to install.
A cloud SMS provider in Node-RED vs textbee in Node-RED
| What you care about | Cloud SMS provider | textbee |
|---|---|---|
| Setup | Create the provider account, buy a number, register the sender where required, install a contrib node and add its credentials | Set one environment variable, add a function node and an http request node: about five minutes |
| Sender the contact sees | A rented virtual number, or an alphanumeric sender where the country allows it | Your own mobile number, which your contacts already have saved |
| Monthly cost | Per message, plus number rental and carrier surcharges in some countries | A flat plan with messages included: Pro is $14.99 a month for 5,000 messages. No per-message fee, no number rental, no carrier surcharge. |
| Throughput | Set by the provider tier and by sender registration | One phone sends roughly 10 to 15 messages a minute. Add phones to scale. |
| Replies | Inbound webhook from the provider, or the provider app in the tool | textbee webhook: flat JSON, signed with HMAC-SHA256 |
| Where the message leaves from | The provider data center | An Android phone you own, plugged in, on Wi-Fi or mobile data |
| Node-RED cost | None beyond the provider fees | None. Receiving needs the http in node behind public HTTPS |
Per-message prices by provider and country, with sources and dates, are on the provider comparison pages.
What works and what does not
Works today
- Sending from any flow with core nodes and an environment variable for the key
- Receiving with the signature verified in a function node
- Picking the sending phone with deviceId
- Delivery checks with an http request that GETs the messages endpoint by smsBatchId
Not with this route
- Receiving without a public HTTPS address for the http in node
- MMS
What Node-RED charges
Node-RED is free and open source. Receiving needs the http in endpoint reachable over public HTTPS. nodered.org, checked on September 25, 2026. textbee itself charges a flat monthly plan with messages included; see pricing.
Frequently asked questions
Is there a textbee contrib node?
No, and none is needed. The http request and http in nodes are core nodes, and the function node handles headers and the signature.
Where do I put the API key?
In an environment variable named TEXTBEE_API_KEY, set where Node-RED starts or in settings.js, and read with env.get() in the function node. Never paste it into the flow: exported flows are often shared.
Does the http in node need HTTPS?
Yes. textbee posts to a public URL and rejects private and loopback addresses. Put Node-RED behind a reverse proxy with a certificate, or use a tunnel service, and register the public URL.
How do I send to a list?
Put every number in the recipients array of one request, or use a split node and a delay node set to 4 seconds between messages. The phone sends roughly 10 to 15 messages a minute.
How do I know a text was delivered?
Keep data.smsBatchId from the send response, wait a minute, then GET the messages endpoint with smsBatchId set and the same x-api-key header. Each row has a status; delivered, failed and unknown are final.
Can I schedule a text for later?
Yes. Add scheduledAt with an ISO 8601 time to msg.payload and textbee sends it at that time. This is simpler than a delay node for anything more than a few minutes away.
Can I use a change node instead of the function node?
Yes. Set msg.url to the send URL, msg.headers to a JSON object with x-api-key and Content-Type, and msg.payload to a JSON object with recipients and message. The function node is shorter when the values come from msg.
Why does the http in node answer 401 to textbee?
The signature check failed. Check that TEXTBEE_WEBHOOK_SECRET matches the signing secret on the webhook in the dashboard, that the crypto module is added in the Setup tab, and that nothing between the proxy and Node-RED rewrites the body.
How long does the setup take?
About five minutes with a phone at hand: install the textbee app, register the phone, create an API key, and add the two nodes to a flow. Receiving adds a webhook in the textbee dashboard and an http in node behind public HTTPS.
Sources
- nodered.org, checked on September 25, 2026
- cookbook.nodered.org: Create an HTTP endpoint, checked on September 25, 2026
Read next
- Server and uptime alerts with SMS from your own Android number
- Receiving SMS into your app with a webhook from your own Android number
- Run an SMS gateway on a Raspberry Pi
- Slack SMS integration: get every text your phone receives in a channel, no code
- Shopify SMS integration: order and shipping texts from your own phone with Shopify Flow
- All integrations
Your phone is already an SMS gateway. Switch it on.
Set up in minutes and send your first message for free. No credit card, no per-message fees, no carrier contracts.
Need self-hosting help or a custom integration? See services