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.
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.
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
- GoHighLevel SMS integration: send and receive texts through your own phone
- All integrations