Webhooks - JSON Payload Header: content-type

Server Version#: 1.28.0.5999

I have been attempting to send a webhook to IFTTT. Sending it works well enough, but when it gets there it appears that there is no JSON payload. I used https://webhook.site to inspect the payload that Plex was sending and found that the header identifies the payload content-type as multipart/form-data instead of application/json, which inhibits the ability of IFTTT and other platforms to make assumptions about the data that is to follow, and thereby diminishes the richness of the payload. That is, I can’t parse the JSON.

Is there a reason that the JSON payload is not identified as application/json? Could it be?

1 Like

I’ve run into this too. The plex webhook documentation is entirely inadequate. Maybe it just hasn’t been updated in two years, I don’t know. I’ve found posts all over the place about people trying to figure out why plex webhooks don’t work and it’s always because the requests are not actually json, they’re form-data. No standard webhook receiver in existence expects a multipart/form-data request. There’s no mention of this on the docs and I’ve been unable to figure out a way to disable this.

1 Like

The thing is, it truly is sending multipart form data, not just a JSON payload.

The first part is the JSON payload and it is identified as such. The second part is an image, which is also identified as such.

I agree that the documentation could be better here, but the payloads are what they are. It’s completely legitimate to encapsulate multiple parts in a payload.

It’s not even difficult to find reports right here on the plex forums. Plex employees never seem to respond to these though, which I can only assume means they know there’s a problem and they aren’t going to address it.

Specifically mentioning content type:

Just confused because webhooks don’t work:

1 Like

I didn’t say it wasn’t actually form-data. There’s not technically anything wrong with the webhook request. The problem is that a multipart/form-data request doesn’t work with IFTTT, trakt, or basically any other standard webhook receiver because they all expect application/json. They made this change, didn’t document it, didn’t announce it (not that I could find), didn’t add a switch to only send application/json, and thus broke webhooks all over the place and left it to users to individually spend hours debugging what happened and then basically ignore all requests for help/explanation.

1 Like

As I said, I agree that the documentation could be better. However, the examples they provide here use multer specifically to handle multi-part form data. This article hasn’t changed in over three years; the most recent change to the Github repos referenced were over three years ago (with two of the projects not being changed in 5 and 6 years.

It’s been known for years that multi-part form data needed to be considered when handling Plex’s web hook events, or at least it should have been. A naive implementation on a third-party’s part doesn’t necessarily imply a failure on Plex’s.

examples they provide here use multer specifically to handle multi-part form data

Granted, as long as you’re familiar enough with JS to just know what multer is (I didn’t until you mentioned it) and notice the two lines of code referencing it, then yes, it’s completely obvious that they’re sending multipart/form-data.

It’s been known for years 
 or at least it should have been.

How? This is the actual problem. You can call code that expects a webhook request to be JSON naive (and you’re not wrong), basically call people ignorant (paraphrasing - “the docs could be better, but people should just know this”), but that doesn’t fix the documentation that’s been lying to people for “over three years”.

1 Like

The documentation does say it will be multipart.

As stated above, the payload is sent in JSON format inside a multipart HTTP POST request. For the media.play and media.rate events, a second part of the POST request contains a JPEG thumbnail for the media.

You can’t use application/json when the body also contains an image. It has to be multipart/form-data.

Side note: The support article from 2018 also said it is multipart data.

https://web.archive.org/web/20180705054544/https://support.plex.tv/articles/115002267687-webhooks/

1 Like

Good grief. I’ve read that page a number of times now and missed that every time. That’s totally on me - @pshanew (and everyone, really) I apologize for my attitude.

So, trying to read more carefully now, is it true that, at least right now, media.play and media.rate are the only events that are multipart? I suppose the wise course of action is to assume any event could be either json or form-data and handle accordingly.

As background, I was trying to hook plex into argo events. Their webhook event source apparently only supports application/json and I was unfortunately testing by just playing media - no other events happened to fire while I had the receiver running. So it looked like nothing was working. Switching on debug logs on the receiver led me to the json parse failure and then my annoyance with plex.

You’re right - there’s nothing technically wrong about what they’re doing. However, that doesn’t mean it’s the best way, or the way that’s right for the customer. Once I figured out what was going on, I spent hours looking for a platform that would accept form-data in the webhook request - I’ve found none. My solution is going to be to implement tautulli, which is fine. It also comes with some other features that would be nice to have that won’t require me to parse the JSON on the receiving end.

All I’m saying is that a toggle would let Plex play nice with all of the great services available to us, and an update to the documentation to call this out in a more obvious way would be welcome.

I would assume all payloads are multipart/form-data to be consistent, regardless of if there is an image or not.

I also recommended doing webhooks through Tautulli instead. :slight_smile:

Pros:

  • Doesn’t require Plex Pass.
  • Can customize the json payload (and ability to change the Content-Type header to something else).
  • Can filter events using conditions before sending instead of parsing on the receiving end.

Cons:

  • Might not be as quick as Plex’s webhooks because of the intermediary processing.
  • Takes a bit more effort to set up.
1 Like

Yes, indeed. The webhooks functionality pushed me over the edge to deciding to adopt it. It would be nice if Plex put just a bit of effort into making this more adaptable, but c’est la vie.

Ok. I didn’t want to set up Tautulli (I might someday, but not right now) and I couldn’t find anything simple that already did this so I fixed my own problem. This is a dead-simple proxy that accepts either multipart/form-data or application/json requests from Plex. For the multipart requests, it throws the thumb on the floor and forwards the payload. For JSON requests, it just forwards them. Working like a charm so far.

1 Like

Nice! I set up tautulli and it was a piece of cake. Especially if using IFTTT, it allows me to use the free tier instead of the paid tiers (needed to parse JSON). Kudos to you though for fixing this problem. This would definitely work for the original and intended use case, so you get the Solution award. Cheers m8!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.