Klaviyo Webhook Payload Issue

Author
Charlotte Brown Author
|
3 weeks ago Asked
|
46 Views
|
2 Replies
0

I'm trying to fire a custom event using Klaviyo's webhook action in a flow, specifically targeting the /api/track endpoint. I'm hitting a consistent 400 Bad Request, even after reviewing the API documentation for event tracking.

It seems to struggle with the specific payload structure when including certain nested properties. Here's a simplified version of the payload and the error I'm seeing:

POST /api/track
Host: track.klaviyo.com
Content-Type: application/json

{
  "token": "YOUR_PUBLIC_API_KEY",
  "event": "Custom Event Name",
  "customer_properties": {
    "$email": "[email protected]"
  },
  "properties": {
    "product_id": "PROD123",
    "metadata": {
      "source": "internal_app",
      "status": "processed"
    }
  }
}

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "message": "Invalid JSON or malformed request."
}

Is there a specific way to structure nested JSON objects within the properties field for Klaviyo's track API via webhooks, or am I missing a critical header for this type of data?

Any expert insights would be greatly appreciated.

2 Answers

0
Zahra Khan
Answered 2 weeks ago

It sounds like your Klaviyo webhook is having a bit of a 'struggle' โ€“ a very human way to describe a system mismatch! The issue you're encountering with the /api/track endpoint and the 400 Bad Request is a common pitfall when dealing with Klaviyo's older, but still widely used, event tracking API.

The core problem isn't necessarily the nested structure within your properties, but rather how the entire payload is transmitted to the /api/track endpoint. Unlike many modern REST APIs that expect a raw JSON body with Content-Type: application/json, Klaviyo's legacy /api/track endpoint expects a single data parameter in the request body, which contains a Base64 encoded JSON string.

Hereโ€™s how to correctly structure your Klaviyo webhook configuration for this endpoint:

  • Payload Structure (Pre-Encoding): Your JSON structure itself is largely correct for what Klaviyo expects internally. The nested metadata object within properties is perfectly fine. The JSON you've provided is what needs to be base64 encoded.
  • Base64 Encoding: The entire JSON object ({"token": "YOUR_PUBLIC_API_KEY", "event": "Custom Event Name", ...}) must be converted into a Base64 string. Most webhook platforms or custom code will have a function for this (e.g., btoa() in JavaScript, base64_encode() in PHP, or a dedicated library in Python/Ruby).
  • Webhook Request Body: The actual body of your POST request to track.klaviyo.com/api/track should then be in application/x-www-form-urlencoded format, containing only one parameter: data=YOUR_BASE64_ENCODED_STRING.
  • Example Request Body: If your encoded JSON string was eyJ0b2tlbiI6ICJZ..., your webhook's request body would simply be:
    data=eyJ0b2tlbiI6ICJZ...
  • Webhook Headers: Ensure your webhook is sending a Content-Type: application/x-www-form-urlencoded header. If your platform only allows raw JSON, you might need to use a different Klaviyo API endpoint (like the newer V2/V3 event tracking APIs, which do accept raw JSON but have different endpoint paths and authentication). For /api/track, stick to the Base64 encoding.

By adjusting your webhook to send the Base64 encoded JSON as the value of a data parameter with the correct Content-Type, you should resolve the 400 Bad Request. This is crucial for successful Klaviyo API event tracking with the legacy endpoint.

Hope this helps your conversions!

0
Charlotte Brown
Answered 2 weeks ago

That Base64 encoding tip for the data parameter totally fixed the 400 error, thanks! But it also made me wonder if I should just transition to those newer V2/V3 APIs Zahra mentioned instead of relying on the legacy endpoint.

Your Answer

You must Log In to post an answer and earn reputation.