Sorry, ▒▒▒▒▒▒, but {{system.tokens}} don’t work in webhook response mappings

On our last MUG Q&A call, a Marketo vet asked about a webhook setup recommended by a certain vendor (who will remain anonymous to save embarrassment).

The vendor’s setup guide included this striking note:

For items like date, system tokens can be used since the API does not, in most cases, include a timestamp in its response.

And an accompanying screenshot:

This was mind-blowing for everyone on the call. Despite being — I think it’s safe to say! — a Marketo webhooks guru, I’d never seen this attempted before. We extended the Q&A by a half hour just to test it out live.

Problem is it doesn’t actually work. The response mapping does do something to the person record, and if you’re not paying close attention (and/or are not an experienced Marketo user, as was probably the case at the vendor) you might think it works.

Setting up a test

I set up a webhook hitting one of my test servers, which always returns this static JSON:

{
   "car_count" : 123456,
   "item_count" : 117733,
   "item_types" : [
      {
         "item_type" : "Blue Car",
         "item_type_count" : 1115,
         "item_type_ratio" : 12
      },
      {
         "item_type" : "Red Car",
         "item_type_count" : 1225,
         "item_type_ratio" : 14
      },
      {
         "item_type" : "Yellow Car",
         "item_type_count" : 1345,
         "item_type_ratio" : 6
      }
   ],
   "item_types_ratio" : 22
}

And mapped both a real response field car_count and the built-in token {{system.datetime}}:

Then ran a list of about 15,000 people through the ‘hook (wasn’t messing around with a spot check!). And saw a promising number of people with the same value:

But therein lay the first clue. It wasn’t just a bunch of people with the same value. It was all 15,000 with the same value. Which meant it couldn’t possibly be stamped when the webhook returns.

See, Marketo’s webhook capacity is very high — which is awesome — but it’s not so high that 15,000 people can start + finish in the same minute. It takes at least a few minutes even with a lightning-fast service on the other end.

Indeed, you can see that some people fired the webhook at 26 after the hour but their value was set to 25 after:

Then another “Wait, hold on” moment: the webhook fired on September 2nd, but the value was set to September 1st! That ain’t right.

And yet another moment: the webhook fired at 5:26pm US Eastern time but appeared to set the time to 12:25pm US Eastern. That ain’t right, either.

Making matters weirder, per the Activity Log the value being set was 2024-09-01 11:25:04, not 2024-09-01 12:25:04:

This isolated part makes sense, at least. When you set a value to a date-like string in local time, the time zone is assumed to be the server time zone. In this case, that’s US Central time — so 12:25pm displayed in US Eastern. Whew. At least not everything is inexplicable.

But nothing else made sense. We put the setup through a few more tests and saw seemingly random values being written instead of the actual {{system.datetime}}. Sometimes we saw the value of another field from the JSON payload being written.

All in all, we confirmed this setup is not supported and only appeared to work for the vendor because they saw some value being written to the DateTime! Also, because they were using a Date instead of a DateTime, that obscured some of the errors.

Keep using a Smart Campaign

Ignore the vendor’s over-hopeful, under-tested approach.

The correct way to store when a webhook executed is to trigger on Webhook is Called and call Change Data Value to set a DateTime field to {{system.datetime}}.