Fun with the “Webhook is Called” trigger

Most users think webhooks can only perform inbound updates (that is, updates to the Marketo database) if they include field values in the response.

If we chose a webhook explicitly to update custom fields — like pulling in lead data from an ABM enrichment service — there's no worry about that would-be limitation. If we want to update our SFDC-synced field Annual_Revenue__c and the webhook sends back

{
  "AnnualRevenue" : 10000000
}

we can easily map AnnualRevenue to Annual_Revenue__c in Webhook » Response Mappings.

Or we call an email validation service like Etumos Verify and get

{
  "EmailIsMailable" : true,
  "EmailIsFreemail" : false,
  "LastChecked" : "2016-08-28T02:21:00"
}

and update Boolean and DateTime fields accordingly.

Fieldless actions

But what about cases where we don't want to update any lead fields? Maybe we want to add a lead to a list, give them an Interesting Moment, sync them to CRM, send an alert, etc.?

I've seen clients use a common workaround: create a dummy field, have the response update that field's value, then trigger on the subsequent Data Value Changes activity to do other stuff.

(If you don't know this already, webhook responses do not immediately update the Marketo database. Updates are done asynchronously and new data is not available in the next flow step. And no, don't guess with a Wait step. Do it the right way with a trigger on DVC.)

While the workaround with intermediate fields works, it means creating fields (maybe lots of them) that have no actual significance within the database.

And it also means the webhook author needs to always return well-formed JSON or XML, even if they're referencing a dummy Boolean field.

But some webhook queries are more appropriately answered at the basic HTTP level. For example, what if I want to check for the existence of a particular record in a remote database (not the record data, just whether it exists)? A simple query like

https://remotedatabase.example.com/?search={{Lead.Email Address}}

or in a more RESTful API, just

https://remotedatabase.example.com/{{Lead.Email Address}}

should respond with HTTP 200 if found, HTTP 404 if not. Whether or not the response (which could be free-form HTML) has a machine-parseable payload, the 200 vs. 404 gives us everything we need.

Enter the Marketo Webhook is Called trigger and its Error Type constraint!

Here are triggers for the 200 OK or 404 Not Found response, without using an intermediate field:

ss
ss

Remember, even though in your browser you associate 404 with a “bad” or “error” response (a user or server configuration error) there's actually nothing inherently bad about it. It's simply a negative response to a query for a web-based resource. Sometimes (like looking someone up in a blacklist) negative is good!

Make your own APIs, but look out for rate limits

If you've let your mind wander, you might think that any remote service that uses HTTP status/error codes is a potential webhook.

In theory, yes: Twitter's website will respond with 404 for http://twitter.com/{non-existent-handle} and 200 (obviously) if found. But end-user services like that will quickly become aware that you're trying to use their visual interface as an API and will blacklist you (or rather, your shared Marketo IP, which is very bad). Don't do it.

On the other hand, an HTTP-accessible database that your IT team controls, or one you subscribe to whose known rate limits are very high, can definitely be used as a webhook without the maintainer specifically publishing it as such. Look around for educational and government services with REST APIs whose positive/negative responses are meaningful, even if the word “webhook” doesn't appear in their description.

The Response constraint: meh.

The Response constraint on Webhook is Called is also useful in cases where parsing the response for a particular string value is all you need (without updating a lead field to that value). I'm not in favor of it, though, unless the response is specifically crafted for dumb-as-dirt string parsing. Don't try to use it on JSON or XML. A structured and well-delimited text/plain response like

|prop1|apple|
|prop2|orange|

would be okay.