Help constructing JSON body for HTTP Request Node (Garmin API)

Describe the issue/error/question

Hello again n8n community!
I need to send a HTTP request to a Garmin API to send a message but struggling to work out how to pass the body data properly. Here is their model schema from their API:

{
  "Messages": [
    {
      "Recipients": [
        "integer(64)"
      ],
      "Sender": "",
      "Timestamp": "Date",
      "Message": "",
      "ReferencePoint": {
        "LocationType": "",
        "Altitude": "integer(64)",
        "Speed": "integer(64)",
        "Course": "integer(64)",
        "Coordinate": {
          "Latitude": 0,
          "Longitude": 0
        },
        "Label": ""
      }
    }
  ]
}

From what I can gather from their documentation here is that I need to pass the above JSON with the Key messages.

What is the error message (if any)?

I keep getting an ‘invalid payload’ error, I’ve read several posts on this forum of other asking for similar help, and tried different permeations of adding or removing quote marks and parentheses, but still no joy. I also tried sending RAW data and then got another message saying not valid JSON. No doubt the answer is in front of me but I cannot see it.

Please share the workflow

{
  "nodes": [
    {
      "parameters": {
        "authentication": "basicAuth",
        "requestMethod": "POST",
        "url": "https://us0-origin.explore.garmin.com:443/ipcinbound/V1/Messaging.svc/Message",
        "options": {},
        "bodyParametersUi": {
          "parameter": [
            {
              "name": "messages",
              "value": "={\n  Messages: [\n    {\n      Recipients: [\n        {{$json[\"fields\"][\"Recipient IMEI\"]}}\n      ],\n      Sender: {{$json[\"fields\"][\"Timestamp\"]}},\n      Timestamp: {{$json[\"fields\"][\"Timestamp\"]}},\n      Message: {{$json[\"fields\"][\"Message Body\"]}},\n    }\n  ]\n}"
            }
          ]
        }
      },
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        3140,
        540
      ],
      "credentials": {
        "httpBasicAuth": {
          "id": "8",
          "name": "Garmin IPC Inbound"
        }
      }
    }
  ],
  "connections": {}
}

Share the output returned by the last node

Information on your n8n setup

  • n8n version:
  • Database you’re using (default: SQLite):
  • Running n8n with the execution process [own(default), main]:
  • Running n8n via [Docker, npm, n8n.cloud, desktop app]:

I’ve also had a lot of trouble sending payloads of nested JSON. The consistent fix I’ve found is to just turn off the n8n body parameters by flipping the JSON/RAW Parameters switch on the http request node and putting it as valid json. The issue then becomes adding the header and query parameters after, but if you use a website like http://www.objgen.com/ you can quickly build your valid JSON there without having to completely understand the JSON language. Then use https://jsonlint.com/ to check your values before sending them off (make sure to remove any javascript from the json before you check it as the javascript will mess up the linter). See code snippet below:

{
  "nodes": [
    {
      "parameters": {
        "authentication": "basicAuth",
        "requestMethod": "POST",
        "url": "https://us0-origin.explore.garmin.com:443/ipcinbound/V1/Messaging.svc/Message",
        "jsonParameters": true,
        "options": {},
        "bodyParametersJson": "={\n  Messages: [\n    {\n      Recipients: [\n        {{$json[\"fields\"][\"Recipient IMEI\"]}}\n      ],\n      Sender: {{$json[\"fields\"][\"Timestamp\"]}},\n      Timestamp: {{$json[\"fields\"][\"Timestamp\"]}},\n      Message: {{$json[\"fields\"][\"Message Body\"]}},\n    }\n  ]\n}"
      },
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        900,
        700
      ],
      "credentials": {
        "httpBasicAuth": {
          "id": "8",
          "name": "T-mobile"
        }
      }
    }
  ],
  "connections": {}
}

Hi @djangelic! Thanks for the reply and the resources, I’m still a little unsure as to how to make it work :joy:

If I input the body in RAW mode, do I need to declare something in the header or query params?
This is what I now have for the body params but just getting unexpected error.

{
  "Messages": [
    {
      "Recipients": [
        "{{$json["fields"]["Recipient IMEI"]}}"
      ],
      "Sender": "{{$json["fields"]["Sender"]}}",
      "Timestamp": "{{$json["fields"]["Timestamp"]}}",
      "Message": "{{$json["fields"]["Message Body"]}}",
      "ReferencePoint": {
        "LocationType": "",
        "Altitude": "",
        "Speed": "",
        "Course": "",
        "Coordinate": {
          "Latitude": 0,
          "Longitude": 0
        },
        "Label": ""
      }
    }
  ]
}

Okay, several more hours spent here to no avail. I’m getting ready to throw my laptop out of the window. Does anyone have any further insight or guidance that might help me?

Usually you need to include a header item:
Content-type: Application/json
Which in the raw needs to be encased in json brackets. I’m away from my computer right now but the best thing to do is check garmins api documentation to see what they require since each server is slightly different in its requirements. When I get into the office today I’ll try to check and see what I find.

So I took a gander at their documentation and it looks like it’s missing that content-type header. Put this in the header field and let me know if it works:

{
  "content-type": "application/json"
}

Thanks for the support @djangelic! I added the above JSON to the header but still getting an error.

Here is the computed JSON body:

{
  "Messages": [
    {
      "Recipients": [
        "300434036242990"
      ],
      "Sender": "Felix",
      "Timestamp": "1642112675000",
      "Message": "Test",
      "ReferencePoint": {
        "LocationType": "",
        "Altitude": "",
        "Speed": "",
        "Course": "",
        "Coordinate": {
          "Latitude": 0,
          "Longitude": 0
        },
        "Label": ""
      }
    }
  ]
}




I think the issue is due to weird spacing in the post body. Let me play around with the JSON a little bit to try again.

2 Likes

Ok lets try this again. I’ve hardcoded the calls into it, just to make sure the issue is not a variable sending in a null value, if this works replace the hardcoded values with your javascript expressions and then test that:

{
  "nodes": [
    {
      "parameters": {
        "authentication": "basicAuth",
        "requestMethod": "POST",
        "url": "https://us0-origin.explore.garmin.com:443/ipcinbound/V1/Messaging.svc/Message",
        "jsonParameters": true,
        "options": {},
        "bodyParametersJson": "={\n\t\"Messages\": [{\n\t\t\"Recipients\": [\n\t\t\t\"300434036242990\"\n\t\t],\n\t\t\"Sender\": \"Felix\",\n\t\t\"Timestamp\": \"1642112675000\",\n\t\t\"Message\": \"Test\",\n\t\t\"ReferencePoint\": {\n\t\t\t\"LocationType\": \"\",\n\t\t\t\"Altitude\": \"\",\n\t\t\t\"Speed\": \"\",\n\t\t\t\"Course\": \"\",\n\t\t\t\"Coordinate\": {\n\t\t\t\t\"Latitude\": 0,\n\t\t\t\t\"Longitude\": 0\n\t\t\t},\n\t\t\t\"Label\": \"\"\n\t\t}\n\t}]\n}",
        "headerParametersJson": "{\n  \"content-type\": \"application/json\"\n}"
      },
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        500,
        300
      ],
      "credentials": {
        "httpBasicAuth": {
          "id": "8",
          "name": "T-mobile"
        }
      }
    }
  ],
  "connections": {}
}

Thanks so much for you continued support @djangelic. It’s still throwing the same error unfortunately. I will reach out to Garmin today and see if they can offer any insight as to why it is failing.

Okay - Garmin hid this pretty well - but I managed to find the following example:

{
	"Messages":[{
		"Message":"String content",
		"Recipients":[9223372036854775807],
		"ReferencePoint":{
			"Altitude":9223372036854775807,
			"Coordinate":{
				"Latitude":1.26743233E+15,
				"Longitude":1.26743233E+15
			},
			"Course":9223372036854775807,
			"Label":"String content",
			"LocationType":0,
			"Speed":9223372036854775807
		},
		"Sender":"String content",
		"Timestamp":"\/Date(928149600000+0000)\/"
	}]
}

I needed to pass the recipient IMEI in an array, and the timestamp as above - at last! Success! It worked :slight_smile:

Thanks @djangelic and @MutedJam for the support!!

1 Like

That’s awesome news, thanks a lot for sharing!

Awesome!! Glad you got it figured out!! :muscle: