Unverified REST hook


I’ve used the REST api to create a rest hook, but getting “Unverified” as it’s status. I’ve also tried to verify it multiple times but no luck. Is there an extra step I need to take?


When you get the initial response after setting the Hook, a Hook Secret value “HTTP_X_HOOK_SECRET” is set in the Header.

To auto-verify it you need to pass it back via the header, eg:

header('X-Hook-Secret: ’ . $_SERVER[‘HTTP_X_HOOK_SECRET’]);

You will need to put a check in your code to see when the Hook Secret is set.

1 Like


Thank you for your response.
I’ve checked the header that I get back from the call (doing a curl call via php), and there isn’t any ‘X-Hook-Secret’ key-pair in it. Should I do it in another way?


How I did it in the past was doing everything in one script.

The PHP script runs this statement:
$contents = file_get_contents(‘php://input’);

If the contents are empty, then it checks and creates the required hook.

If the contents were not empty, then it checks if the Hook Secret is present by doing the following:

If the Hook Secret is present, then it auto-verifies by doing the following:
header('X-Hook-Secret: ’ . $_SERVER[‘HTTP_X_HOOK_SECRET’]);

If there is Contents, but no Hook Secret, then the Rest Hook has posted data in which you can process it accordingly.

Hope that helps.


We pretty much do the same thing only getting/setting the header happens on an isset() instead but same idea.

This works. Thanks a million!!
This type of info should be specified in the documentation, here: Keap REST API
Where did you get this extra step from? Was I looking in the wrong place?

You had to ask for the documentation when Rest Hooks became available last year.

If you want to know more information, drop Michael Fairchild a message at: @MichaelFairchild

I noticed that the Developer Documentation has been undergoing recent updates, maybe more information will be added soon.

1 Like

Rest Hook documentation has been added as well as making the hooks officially live as of ICON. This also includes the addition of hooks for applying and removing tags. We are continuing to add more clarity to the documentation both in general and specific to rest hooks (more info and communication on that coming in the next few weeks).

1 Like

Hey all!

So I am also running into this issue, but I am not developing in PHP. Basically right now I am not able to create a webhook either through the interactive rest docs, or through postman. After posting to create the hook, these are the only headers I receive(Status 200):

Cache-Control →no-cache, no-store
Connection →keep-alive
Content-Type →application/json;charset=UTF-8
Date →Fri, 12 May 2017 19:51:12 GMT
Expires →Fri, 12 May 2017 19:51:11 GMT
Pragma →no-cache
Server →Apache-Coyote/1.1
Vary →Accept-Encoding
X-Mashery-Message-ID →4deece63-67bf-4646-9369-d4d851dfea92
X-Mashery-Responder →prod-j-worker-us-west-1b-60.mashery.com
X-Plan-QPS-Allotted →25
X-Plan-QPS-Current →1
X-Plan-Quota-Allotted →125000
X-Plan-Quota-Current →37
X-Plan-Quota-Reset →Saturday, May 13, 2017 12:00:00 AM GMT
transfer-encoding →chunked

As you can tell, there is no X-Hook-Secret… Is there a specific header I am supposed to send besides content-type? Also when trying to verify just straight from the interactive docs it does not verify, it just returns a 200 with status unverified in the body

the x-hook-secret is not passed back to the caller. it is sent to the specified end point where you would need to have code to send the header entry/value back to them to confirm the endpoint is valid. THEN they send back to the caller a response that include the status of that action

Hmmm… okay. I will see if I can figure this out. I am working with workato(similar to zapier) and I don’t have access to the headers, only the payload when it sends the verification call… I assume I could have it send the initial call to something that I can see, verify it, and then update the url? Or does it have to be verified again after the URL is updated?

Or is there a header I can send to have it autoverify?

You’re not going to be able to use that approach. I would use a relay on a server you have access to. Verify/register that as the endpoint. If you want information from that point forward to go anywhere then you have code level access to respond to the data sent from the REST hook.

This worked for me. Please place this into the API docs.

To elaborate, here’s how I solved it using Rails (on the webhook hook_url endpoint):

# Verify hook request if needed
response.set_header("X-Hook-Secret", request.env["HTTP_X_HOOK_SECRET"]) if request.env["HTTP_X_HOOK_SECRET"].present?

Hey Eric I agree with you. Worked for me! Thanks for sharing!

Okay so I did this and am having still having issues… it never sends the inital verification request to my hookurl…
Basically looks like this:
Client sends request-> Server(route1 - create) → Infusionsoft(create hook ,sends verification request to hookURL) → Server(route2(hookurl) - verify) → client with response from route 1
I get the response from route 1, which means that Infusionsoft is able to talk to my server, but the verification step is never happening… If I am understanding the process right, after the create request is sent, Infusionsoft should immedietely send a POST request to the HookURL, correct?

Basically I am doing the relay server, like you suggested. I could manually create the hook through the interactive docs and set the hook url to the verification, but when Infusionsoft sends the verification header(xhttp thing), my server never receives it. But, when Infusionsoft replies saying the hook was created(albeit with unverified status) my server receives it.

I am working on Laravel 5.2 (PHP Framework) and I have shared my code below. Here I have tried to write the information which is sent over the hook to my website.

I have set the route for the hook url as Route::any so that it can process any kind of request.

public function writeContactToFile()
    $data = Input::all();
    // Create a file to write the input data
    $file_name = date('Y-m-d-H-i-s') . '.txt';
    Storage::put($file_name, json_encode($data));
    $content = Storage::get($file_name);

    // Check for hook secret
    $hook_secret = request()->server('HTTP_X_HOOK_SECRET');

    if (empty($hook_secret))
        $hook_secret = 'YOUR-HOOK-SECRET';

    $headers = ['X-Hook-Secret' => $hook_secret];

    return response()->json(['content' => $content], 200, $headers);

Any Suggestions if you don’t have access to a [relay] server ?

We are using IronIO. All of our code lives in IronIO Workers and are initiated by WebHook or Scheduler. And would love to change our polling to Event driven processing leveraging REST Hooks.

My Plan was to wire a REST Hook from IS to one of our WebHook’s, but since IronIO processes the HTTP traffic my application code cannot insert Header info. Then after verified, to update hte URL from PostBin to our real WebHook. So using Command Line Python or CURL to setup REST Hook.

If you can’t update the URL after its been verified, could code this 100% in the WebHook python code that receives the payload from IronIO, so the URL would be static, just would need to deploy code to production that basically prints out the header, but I am still stuck in not being able to implement the “Immediate Confirmation” flow, as IronIO has already responded to the HTTP POST Request on the WebHook URL.

The Supporting documentation references RESTHooks.org, which outlines a “Delayed Confirmation” flow

but it seems the /hooks/{id}/activate endpoint is not implemented.

This /activate action generates a 404.

The resthooks.org, specifies support for delayed confirmation,

Any suggestion for a truly server-less ecosystem, that wants to take advantage of the event based processing of a REST Hook ?

See REST Hook Delayed Confirmation Flow: Does it work? - #6 by mike.christianson.

Rest Hook documentation has been added as well as making the hooks officially live as of ICON. This also includes the addition of hooks for applying and removing tags.

What is the event type for listening to new and deleted tags? in the webhook