Downlink formatter

Im trying to get an encoded downlink to a device. To do so I did the following:

  • The device sends a downlink request.
  • I respond to this using the x-downlink-replace url and x-downlink-apikey from the headers to reply
  • I created a encodeDownlink(input) function in the downlink javascript formatter. And to see it working I return the object as descibed in the docs
function encodeDownlink(input) {
    return {
    bytes: [1, 2, 3],
    fPort: 1

I would expect the bytes to be passed to FRMPayload. But cant find it back.

Any clues what I might do wrong?

Did the online JavaScript checker not report an error - like a missing bracket?

I missed the bracket in the copy-paste…

No apology necessary. Can you give me the 30 seconds of my life back it took to type an answer?

Does the console for the device and the gateway show the downlink being sent?

Just to be clear, downlinks only happen when the device uplinks.

My apologies!
I will promise you, ones I master the continuum of time, I will give you 30 seconds back.

The console is showing the Receive downlink data message and Forward downlink data message.

Am I correct to assert Forward downlink data message should contain the FRMPayload?

At this moment I cannot look in the gateway logs. I have not yet given the authorizations to see it. Will ask for it next week when my colleague is back.

What is the device?

Are you connecting via ABP or OTAA?

Is the device setup for the new Rx1 delay of 5 seconds?

How often does the device uplink?

Do you have a spare device you can see the serial console of to see what’s happening?

I think the problem is not in relaying the message to the device, but in the format of the message.

In the Live data we see a message being sent to the device. But the frm_payload is missing there. (there is one part of the mac_payload, but that is something different).

The device uplinks every 3 minutes. The gateway is running on v2. Which seems not to display the v3 downlink messages (written in this thread: New Application V3 OTAA not working)

I find that too - but downlinks do work when done via the console. I haven’t got as far as downlinks on v3 via MQTT or Web API yet. I’ll have another look at the docs sooner rather than later.

After some more work we got it to work.

The frm_payload in the mac object is what we needed after all.
Thanks for thinking along!

This sounds promising - can you say what exactly you had to do to get this working?
It seems like im stuck with the same problem.

Im trying to send a downlink message to a v3 device, and i just cant manage to get this properly scheduled via MQTT.

This is my first attempt with ttn & I dont know if i entirely did something wrong, or if something doesnt work:

  • scheduling a downlink from the v3 console works fine & is processed by my device
  • an attempt via MQTT does somehow show up in two messages in the console, but just as
    “Schedule data downlink for transmission on Gatway Server”
    “Successfully scheduled data downlink for transmission on Gateway Server”
    …for the correct application + device, but without the payload i wanted to send; and the message in the end never arrives at the device

I aligned my tests to the instructions posted on the v3 Documentation / link below, and tried to send a message using mosquitto_pub & python / paho.mqtt - it ends up in the same result; tried to post to both topics which i understood i should use for it:

"v3/appname/devices/devicename/down/push" or

The message is just a byte message:

 payload="{'downlinks': [{'f_port': 1, 'frm_payload': 'PA==', 'priority': 'NORMAL'}]}"

For Uplinks: im connected to the same v3 MQTT server, subscribed to the messages posted for my application & this is perfectly working. Subscribed to “#” i also see the downlinks im scheduling in the v3 console; my own attempts dont show up there.

Sending something to to a v2 device is working fine (obviously on a different topic & server, but with both mosquitto_pub & paho.mqtt)

If anyone steps across this post, its at least working for me using mosquitto_pub with the tenant ID added to the topic. The docs currently have:

“## Multi-Tenancy
Note that on multi-tenant environments such as Cloud, application IDs and other endpoints include the tenant ID, e.g app1@tenant1. On single tenant environments such as Open Source, the tenant ID can be removed, i.e app1.”

I can subscribe to uplinks using it as a username without adding the tenant id, but cant schedule any downlink, so just add it:


works, while


does not.

Edit: just to clarify; “appname” works as login user, im subscribed to “#”; and the uplink messages go to “…/appname@ttn/…”. In any case: its required to add it.

1 Like

Can you open a GitHub issue on this for the docs?

They are clearly discussing a standalone install.

Whereas the TTN we use is multi-tenanted - all the MQTT users end in @ttn.

It’s almost like we need a sub-set of the docs that don’t have any of the enterprise or self-hosted cruft in it.

Sure, done: Clarify MQTT tenant-id usage for TTN V3 · Issue #280 · TheThingsIndustries/lorawan-stack-docs · GitHub

1 Like

I am experiencing also issue in sending downlink msg via node-red.

I have tried both Public and Public TSL.

My flow

` [{"id":"dc624c04.8b9a","type":"mqtt out","z":"1c27c045.696c9","name":"","topic":"","qos":"2","retain":"","broker":"a2b276d9.819678","x":690,"y":800,"wires":[]},{"id":"dade35a3.2ad6b8","type":"inject","z":"1c27c045.696c9","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"020000","payloadType":"str","x":330,"y":800,"wires":[["b6ddfc4c.3963a"]]},{"id":"71edf668.1cc998","type":"debug","z":"1c27c045.696c9","name":"send","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":710,"y":860,"wires":[]},{"id":"b6ddfc4c.3963a","type":"function","z":"1c27c045.696c9","name":"send","func":"msg.topic = \"v3/appnameb@ttn/devices/devicenamepb-1/down/push\";\n\nmsg.payload = {\n        \"downlinks\": [{\n      \"f_port\": 2,\n      \"frm_payload\": msg.payload.toString(\"base64\"),\n      \"priority\": \"NORMAL\"\n    }]\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":510,"y":800,"wires":[["dc624c04.8b9a","71edf668.1cc998"]]},{"id":"a2b276d9.819678","type":"mqtt-broker","name":"abeeway-tracker","broker":"","port":"1883","tls":"c367e243.42a69","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"c367e243.42a69","type":"tls-config","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":true}]`

My input to MQTT


In my application console log (live data) I can see the mqtt connecting but not the uplink

In my msg.topic = “v3/appnameb@ttn/devices/devicenamepb-1/down/push”

appnameb is

And devicenamepb-1 is

For this case downlink not show in Live Data TTN. Can you solve? I have a same issue.

You need to fix your topic, appnameb@ttn=“Application ID” and devicenamepb-1 = "End device ID"