textbee Logotextbee.dev
Save 44% with yearly billing.View Plans

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.

  1. 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 request
    msg.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 msg
  2. Add 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.

    FieldValue
    MethodPOST
    URLempty, taken from msg.url
    Returna parsed JSON object
  3. 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.

  4. 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.

  1. 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.

  2. 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 route
    const 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]
  3. 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.

  4. 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

  1. nodered.org, checked on September 25, 2026
  2. cookbook.nodered.org: Create an HTTP endpoint, checked on September 25, 2026

Read next