# Unverified REST hook

**URL:** <https://integration.keap.com/t/unverified-rest-hook/375>\
**Category:** API Q&A\
**Created:** [April 25, 2017, 11:45am UTC](https://integration.keap.com/t/unverified-rest-hook/375 "2017-04-25T11:45:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andrei\_Sirbu](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/andrei_sirbu/32/186_2.png) [@Andrei\_Sirbu](https://integration.keap.com/u/Andrei_Sirbu)\
**Post date:** [April 25, 2017, 11:45am UTC](https://integration.keap.com/t/unverified-rest-hook/375/1 "2017-04-25T11:45:07Z")

</div>

Hello,

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?

Thanks

---

<div class="post-metadata">

**Author:** ![Pav](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/pav/32/124_2.png) [@Pav](https://integration.keap.com/u/Pav)\
**Post date:** [April 25, 2017, 2:05pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/2 "2017-04-25T14:05:55Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Andrei\_Sirbu](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/andrei_sirbu/32/186_2.png) [@Andrei\_Sirbu](https://integration.keap.com/u/Andrei_Sirbu)\
**Post date:** [April 27, 2017, 9:25am UTC](https://integration.keap.com/t/unverified-rest-hook/375/3 "2017-04-27T09:25:19Z")

</div>

Hello,

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?

Thanks

---

<div class="post-metadata">

**Author:** ![Pav](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/pav/32/124_2.png) [@Pav](https://integration.keap.com/u/Pav)\
**Post date:** [April 27, 2017, 1:07pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/4 "2017-04-27T13:07:43Z")

</div>

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:  
isset($\_SERVER[‘HTTP\_X\_HOOK\_SECRET’])

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.

---

<div class="post-metadata">

**Author:** ![John\_Borelli](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/john_borelli/32/11880_2.png) [@John\_Borelli](https://integration.keap.com/u/John_Borelli)\
**Post date:** [April 27, 2017, 1:26pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/5 "2017-04-27T13:26:14Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Andrei\_Sirbu](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/andrei_sirbu/32/186_2.png) [@Andrei\_Sirbu](https://integration.keap.com/u/Andrei_Sirbu)\
**Post date:** [April 27, 2017, 3:29pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/6 "2017-04-27T15:29:46Z")

</div>

This works. Thanks a million!!  
This type of info should be specified in the documentation, here: [Keap REST API](https://developer.infusionsoft.com/docs/rest/)  
Where did you get this extra step from? Was I looking in the wrong place?

---

<div class="post-metadata">

**Author:** ![Pav](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/pav/32/124_2.png) [@Pav](https://integration.keap.com/u/Pav)\
**Post date:** [April 27, 2017, 4:16pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/7 "2017-04-27T16:16:50Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![brettpartridge](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/brettpartridge/32/76_2.png) [@brettpartridge](https://integration.keap.com/u/brettpartridge)\
**Post date:** [May 2, 2017, 11:37pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/8 "2017-05-02T23:37:48Z")

</div>

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).

---

<div class="post-metadata">

**Author:** ![Jacob\_Turley](https://avatars.discourse-cdn.com/v4/letter/j/d6d6ee/32.png) [@Jacob\_Turley](https://integration.keap.com/u/Jacob_Turley)\
**Post date:** [May 12, 2017, 7:53pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/9 "2017-05-12T19:53:14Z")

</div>

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-FRAME-OPTIONS →SAMEORIGIN  
X-Mashery-Message-ID →4deece63-67bf-4646-9369-d4d851dfea92  
X-Mashery-Responder [→prod-j-worker-us-west-1b-60.mashery.com](http://xn--prod-j-worker-us-west-1b-60-2r7q.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

---

<div class="post-metadata">

**Author:** ![John\_Borelli](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/john_borelli/32/11880_2.png) [@John\_Borelli](https://integration.keap.com/u/John_Borelli)\
**Post date:** [May 12, 2017, 8:07pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/10 "2017-05-12T20:07:59Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Jacob\_Turley](https://avatars.discourse-cdn.com/v4/letter/j/d6d6ee/32.png) [@Jacob\_Turley](https://integration.keap.com/u/Jacob_Turley)\
**Post date:** [May 12, 2017, 8:27pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/11 "2017-05-12T20:27:09Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Jacob\_Turley](https://avatars.discourse-cdn.com/v4/letter/j/d6d6ee/32.png) [@Jacob\_Turley](https://integration.keap.com/u/Jacob_Turley)\
**Post date:** [May 12, 2017, 8:37pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/12 "2017-05-12T20:37:05Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![John\_Borelli](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/john_borelli/32/11880_2.png) [@John\_Borelli](https://integration.keap.com/u/John_Borelli)\
**Post date:** [May 12, 2017, 10:23pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/13 "2017-05-12T22:23:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Eric\_Berry](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/eric_berry/32/213_2.png) [@Eric\_Berry](https://integration.keap.com/u/Eric_Berry)\
**Post date:** [May 15, 2017, 3:45pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/14 "2017-05-15T15:45:08Z")

</div>

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):

```auto
# 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?

```

---

<div class="post-metadata">

**Author:** ![Sehen\_Gratis](https://avatars.discourse-cdn.com/v4/letter/s/4491bb/32.png) [@Sehen\_Gratis](https://integration.keap.com/u/Sehen_Gratis)\
**Post date:** [May 16, 2017, 11:21pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/15 "2017-05-16T23:21:04Z")

</div>

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

[![](https://us1.discourse-cdn.com/flex019/uploads/infusionsoft1/original/1X/f48da7481202bae96243999cf606741ddb983b90.jpg)](https://www.clippp.com/)

---

<div class="post-metadata">

**Author:** ![Jacob\_Turley](https://avatars.discourse-cdn.com/v4/letter/j/d6d6ee/32.png) [@Jacob\_Turley](https://integration.keap.com/u/Jacob_Turley)\
**Post date:** [May 23, 2017, 7:20pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/16 "2017-05-23T19:20:03Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Chitta\_Pattnaik](https://avatars.discourse-cdn.com/v4/letter/c/e8c25b/32.png) [@Chitta\_Pattnaik](https://integration.keap.com/u/Chitta_Pattnaik)\
**Post date:** [June 27, 2017, 12:20pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/17 "2017-06-27T12:20:12Z")

</div>

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);
}

```

---

<div class="post-metadata">

**Author:** ![Tyler\_McMaster](https://avatars.discourse-cdn.com/v4/letter/t/3ab097/32.png) [@Tyler\_McMaster](https://integration.keap.com/u/Tyler_McMaster)\
**Post date:** [July 21, 2017, 2:13pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/18 "2017-07-21T14:13:16Z")

</div>

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](http://RESTHooks.org), which outlines a “Delayed Confirmation” flow

> **[Security | REST Hooks](http://resthooks.org/docs/security/)**
>
> Home \> Docs \> Security Security in REST Hooks takes a slightly different approach than typical API access. While the...

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

This /activate action generates a 404.

The [resthooks.org](http://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 ?

---

<div class="post-metadata">

**Author:** ![mike.christianson](https://sea1.discourse-cdn.com/flex019/user_avatar/integration.keap.com/mike.christianson/32/74_2.png) [@mike.christianson](https://integration.keap.com/u/mike.christianson)\
**Post date:** [July 22, 2017, 12:06am UTC](https://integration.keap.com/t/unverified-rest-hook/375/21 "2017-07-22T00:06:26Z")

</div>

See [REST Hook Delayed Confirmation Flow: Does it work? - #6 by mike.christianson](https://integration.keap.com/t/rest-hook-delayed-confirmation-flow-does-it-work/6348/6).

---

<div class="post-metadata">

**Author:** ![Barney\_admin\_Kuntze](https://avatars.discourse-cdn.com/v4/letter/b/90db22/32.png) [@Barney\_admin\_Kuntze](https://integration.keap.com/u/Barney_admin_Kuntze)\
**Post date:** [October 1, 2017, 9:55pm UTC](https://integration.keap.com/t/unverified-rest-hook/375/22 "2017-10-01T21:55:52Z")

</div>

> 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

[Next page](https://integration.keap.com/t/unverified-rest-hook/375.md?page=2)
