CINXE.COM
Webhooks | Help Scout Developers
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title> Webhooks | Help Scout Developers </title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="robots" content="index, follow" /> <link rel="stylesheet" href="/css/main.css?v=daae3e66227474e427a596f6bd8ce33d"> <link rel="icon" href="/img/favicon.ico" type="image/x-icon"/> <script src="/js/developer.js?v=12348d899b1ddb7a85fb4b17127a5942" async defer></script> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-R3KHRW717V"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-R3KHRW717V'); </script> <script src="/js/fontfaceobserver.js"></script> <script> (function() { var font400 = new FontFaceObserver('Aktiv Grotesk', { weight: 400 }); var font500 = new FontFaceObserver('Aktiv Grotesk', { weight: 500 }); var font700 = new FontFaceObserver('Aktiv Grotesk', { weight: 700 }); Promise.all([ font400.load(), font500.load(), font700.load(), ]).then(function() { document.documentElement.className += ' fonts-loaded'; }) .catch(function() { console.log('Aktiv Grotesk failed to load'); }); })(); </script> <script charset="ISO-8859-1" src="//fast.wistia.com/assets/external/E-v1.js" async defer></script> </head> <body class="tx-smooth"> <div class="s-docs-layout"> <aside class="s-docs-layout__sidebar t-bg-grey-200"> <div class="c-nav-sidebar"> <div class="o-scrolly"> <div class="o-scrolly__item"> <div class="c-nav-sidebar__header u-centralize t-bg-blue-500 t-tx-white"> <button class="c-button c-button--link c-nav-sidebar__toggle t-tx-white" id="js-nav-sidebar-toggle"> <i class="icon icon-menu c-icon c-icon--32"></i> </button> <div class="c-nav-sidebar__header-content"> <div class="c-logo u-pad-v-2"> <a href="/" class="u-d-block" title="Help Scout Developers"> <img src="/images/hs-developer-logo-wh.svg" width="174" height="32" title="Help Scout Developers" alt="Help Scout Developers" class="c-logo__image" /> <span class="u-sr-only"> <h1>Help Scout Developers</h1> </span> </a> </div> </div> </div> </div> <div class="o-scrolly__block"> <div class="js-SidebarNav c-nav-sidebar__menu u-mrg-b-10@md u-pad-b-5@md" id="js-nav-sidebar-menu"><div class="c-nav-header"><div class="o-flexy o-flexy--just-left o-flexy--gap-md"><div class="o-flexy__item"><a href="/" class="c-nav-header__back" title="Back"><i class="icon icon-caret-left c-icon c-icon--12 u-d-block"></i></a></div><div class="o-flexy__block tx-center u-mrg-l-0"><strong class="t-tx-charcoal-500"> Webhooks </strong></div></div></div><ul class=" c-nav c-nav--stacked c-nav--md is-active c-nav--level-1 " role="navigation" aria-label="Sidebar nav level 1"><li class=" c-nav__item is-active "><a href="/webhooks/" class=" c-nav__link js-SidebarNav__link is-active "><div class="o-flexy"><div class="o-flexy__item">Overview </div><div class="o-flexy__item"><i class="icon icon-caret-right tx-12 c-icon c-icon--12 js-nav-arrow c-nav__arrow"></i></div></div></a><ul class=" c-nav c-nav--stacked c-nav--md c-nav--sub-nav is-active c-nav--level-2 " role="navigation" aria-label="Sidebar nav level 2"><li class=" c-nav__item "><a href="/webhooks/objects/conversation/" class=" c-nav__link js-SidebarNav__link "><div class="o-flexy"><div class="o-flexy__item">Conversations </div></div></a></li><li class=" c-nav__item "><a href="/webhooks/objects/customer/" class=" c-nav__link js-SidebarNav__link "><div class="o-flexy"><div class="o-flexy__item">Customer Created </div></div></a></li><li class=" c-nav__item "><a href="/webhooks/objects/rating/" class=" c-nav__link js-SidebarNav__link "><div class="o-flexy"><div class="o-flexy__item">Rating Received </div></div></a></li><li class=" c-nav__item "><a href="/webhooks/objects/survey-response/" class=" c-nav__link js-SidebarNav__link "><div class="o-flexy"><div class="o-flexy__item">Survey Response Received </div></div></a></li></ul></li></ul></div> </div> </div> </div> </aside> <main class="s-docs-layout__main"> <div class="o-container o-container--site u-pad-t-8 u-pad-h-5@sm u-pad-h-10@lg"> <div class="o-row"> <div class="o-col-12"> <section class="s-main-content" id="content"> <div class="o-page"> <div class="s-docs"> <h1>Webhooks</h1> <p>Webhooks enable Help Scout to call a script on your server when one or more events have happened. Webhooks can be thought of as event listeners or push notifications.</p> <p>Configuring webhooks can be done through the Help Scout user interface. Simply log in, click on <strong>Manage > Apps</strong> in the top header bar, then select the Webhooks app.</p> <h2>Available Events</h2> <p>Each request body uses the object format linked in the table below. <table> <thead> <tr> <th>Type</th> <th>Event Name</th> <th>Request Header</th> <th>v2 Request Body</th> </tr> </thead> <tbody> <tr> <td rowspan="11">Conversation</td> <td>Assigned</td> <td>convo.assigned</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Created</td> <td>convo.created</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Deleted</td> <td>convo.deleted</td> <td>{id: <code>id-of-convo-that-was-deleted</code>}</td> </tr> <tr> <td>Merged</td> <td>convo.merged</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Moved</td> <td>convo.moved</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Status Updated</td> <td>convo.status</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Tags Updated</td> <td>convo.tags</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Custom Fields Updated</td> <td>convo.custom-fields</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Customer Reply</td> <td>convo.customer.reply.created</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Agent Reply</td> <td>convo.agent.reply.created</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td>Note Created</td> <td>convo.note.created</td> <td><a href="../mailbox-api/endpoints/conversations/get/#response">v2 Conversation</a> object</td> </tr> <tr> <td rowspan="3">Customer</td> <td>Created</td> <td>customer.created</td> <td><a href="../mailbox-api/endpoints/customers/get/#response">v2 Customer</a> object</td> </tr> <tr> <td>Updated</td> <td>customer.updated</td> <td><a href="../mailbox-api/endpoints/customers/get/#response">v2 Customer</a> object</td> </tr> <tr> <td>Deleted</td> <td>customer.deleted</td> <td>{id: <code>id-of-customer-that-was-deleted</code>}</td> </tr> <tr> <td>Ratings</td> <td>Rating Received</td> <td>satisfaction.ratings</td> <td><a href="../mailbox-api/endpoints/ratings/get/#response">v2 Rating</a> object</td> </tr> <tr> <td rowspan="2">Beacon Chat</td> <td>Created</td> <td>beacon.chat.created</td> <td><a href="../chat/endpoints/get/#response">Chat</a> object</td> </tr> <tr> <td>Customer Replied</td> <td>beacon.chat.customer.replied</td> <td><a href="../chat/endpoints/get/#response">Chat</a> object</td> </tr> <tr> <td rowspan="3">Tag</td> <td>Created</td> <td>tag.created</td> <td><a href="../mailbox-api/endpoints/tags/get/#response">v2 Tag</a> object</td> </tr> <tr> <td>Updated</td> <td>tag.updated</td> <td><a href="../mailbox-api/endpoints/tags/get/#response">v2 Tag</a> object</td> </tr> <tr> <td>Deleted</td> <td>tag.deleted</td> <td>{id: <code>id-of-tag-that-was-deleted</code>}</td> </tr> <tr> <td>Message</td> <td>Survey Response Received</td> <td>message.survey.response.received</td> <td><a href="objects/survey-response">Survey Response</a> object</td> </tr> </tbody> </table> <p>Please note that the <code>customer.created</code> webhook event is not filterable across specific inboxes, and will trigger on all customers created globally.</p> <h2>Headers</h2> <p>Each webhook includes two Help Scout headers:</p> <ul> <li><strong>X-HelpScout-Event</strong>: Lists the event name for which this webhook event is being generated</li> <li><strong>X-HelpScout-Signature</strong>: The computed signature generated by Help Scout. Used to know if the request is valid or not.</li> </ul> <h2 id="verifying">Verifying</h2> <p>Webhooks can be verified as coming from Help Scout by calculating a digital signature. Each webhook request contains an <strong>X-HelpScout-Signature</strong> header, which is generated using the given secret key, along with the json encoded payload data sent in the request.</p> <p>To verify if the request came from Help Scout, compute the HMAC hash and compare it to the header value sent in the request. If the computed signatures match, you can be sure the request was sent from Help Scout.</p> <p>Signatures are calculated based on the raw request body passed to your servers by Help Scout. This means that if non-ASCII characters are contained in the payload, you will need to calculate the signature based on the escaped, transliterated string passed to you by Help Scout. We recommend this as best practice in general, even for those primarily working with ASCII data.</p> <h3>PHP</h3> <figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="cp"><?php</span> <span class="nb">define</span><span class="p">(</span><span class="s1">'WEBHOOK_SECRET_KEY'</span><span class="p">,</span> <span class="s1">'my-secret-key'</span><span class="p">);</span> <span class="k">function</span> <span class="n">isFromHelpScout</span><span class="p">(</span><span class="nv">$data</span><span class="p">,</span> <span class="nv">$signature</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$calculated</span> <span class="o">=</span> <span class="nb">base64_encode</span><span class="p">(</span><span class="nb">hash_hmac</span><span class="p">(</span><span class="s1">'sha1'</span><span class="p">,</span> <span class="nv">$data</span><span class="p">,</span> <span class="no">WEBHOOK_SECRET_KEY</span><span class="p">,</span> <span class="kc">true</span><span class="p">));</span> <span class="k">return</span> <span class="nv">$signature</span> <span class="o">==</span> <span class="nv">$calculated</span><span class="p">;</span> <span class="p">}</span> <span class="nv">$signature</span> <span class="o">=</span> <span class="nv">$_SERVER</span><span class="p">[</span><span class="s1">'X-HELPSCOUT-SIGNATURE'</span><span class="p">];</span> <span class="nv">$data</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="s1">'php://input'</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="nf">isFromHelpScout</span><span class="p">(</span><span class="nv">$data</span><span class="p">,</span> <span class="nv">$signature</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// do something</span> <span class="p">}</span> <span class="cp">?></span></code></pre></figure> <p>When using the Help Scout <a href="https://github.com/helpscout/helpscout-api-php">PHP library</a>, this validation is automatically handled for you.</p> <H3>C#</H3> <p>Thanks to Chris Burch for their C# example code.</p> <figure class="highlight"><pre><code class="language-c#" data-lang="c#"><span class="n">publicclassHelpScoutAuthorization</span> <span class="p">{</span> <span class="n">privatestring</span> <span class="n">_secret</span><span class="p">;</span> <span class="nf">publicHelpScoutAuthorization</span><span class="p">(</span><span class="kt">string</span> <span class="n">secret</span><span class="p">)</span> <span class="p">{</span> <span class="n">_secret</span> <span class="p">=</span> <span class="n">secret</span><span class="p">;</span> <span class="p">}</span> <span class="c1">///<summary></span> <span class="c1">/// Use signature to validate this message is from HelpScout</span> <span class="c1">///</summary></span> <span class="c1">///<param name="jsonRequestBody">The JSON body</param></span> <span class="c1">///<param name="signature">Typically from Request.Headers["X-HelpScout-Signature"]</param></span> <span class="n">publicbool</span> <span class="nf">IsFromHelpScout</span><span class="p">(</span><span class="kt">string</span> <span class="n">jsonRequestBody</span><span class="p">,</span> <span class="kt">string</span> <span class="n">signature</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span><span class="nf">HashHmac</span><span class="p">(</span><span class="n">jsonRequestBody</span><span class="p">,</span> <span class="n">_secret</span><span class="p">)</span> <span class="p">==</span> <span class="n">signature</span><span class="p">);</span> <span class="p">}</span> <span class="n">privatestring</span> <span class="nf">HashHmac</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="kt">string</span> <span class="n">secret</span><span class="p">)</span> <span class="p">{</span> <span class="n">System</span><span class="p">.</span><span class="n">Text</span><span class="p">.</span><span class="n">Encoding</span> <span class="n">encoding</span> <span class="p">=</span> <span class="n">System</span><span class="p">.</span><span class="n">Text</span><span class="p">.</span><span class="n">Encoding</span><span class="p">.</span><span class="n">UTF8</span><span class="p">;</span> <span class="k">using</span><span class="p">(</span><span class="kt">var</span> <span class="n">hmac</span> <span class="p">=</span> <span class="k">new</span> <span class="n">System</span><span class="p">.</span><span class="n">Security</span><span class="p">.</span><span class="n">Cryptography</span><span class="p">.</span><span class="nf">HMACSHA1</span><span class="p">(</span><span class="n">encoding</span><span class="p">.</span><span class="nf">GetBytes</span><span class="p">(</span><span class="n">secret</span><span class="p">)))</span> <span class="p">{</span> <span class="kt">var</span> <span class="n">messageByteArray</span> <span class="p">=</span> <span class="n">encoding</span><span class="p">.</span><span class="nf">GetBytes</span><span class="p">(</span><span class="n">message</span><span class="p">);</span> <span class="kt">var</span> <span class="n">hash</span> <span class="p">=</span> <span class="n">hmac</span><span class="p">.</span><span class="nf">ComputeHash</span><span class="p">(</span><span class="n">messageByteArray</span><span class="p">);</span> <span class="k">return</span> <span class="n">System</span><span class="p">.</span><span class="n">Convert</span><span class="p">.</span><span class="nf">ToBase64String</span><span class="p">(</span><span class="n">hash</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span></code></pre></figure> <h3>Ruby</h3> <p>Thanks to our friends at <a href="https://parse.com/">Parse.com</a> for the Ruby example below.</p> <p>Thanks to Leo Arnold at Givve for sending us a nice Gist with a Ruby vulnerability fix.</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1">#!/usr/bin/ruby -rrubygems</span> <span class="c1">#</span> <span class="nb">require</span> <span class="s1">'base64'</span> <span class="nb">require</span> <span class="s1">'hmac-sha1'</span> <span class="c1"># gem install ruby-hmac</span> <span class="nb">require</span> <span class="s1">'rack/utils'</span> <span class="c1"># gem install rack</span> <span class="no">WEBHOOK_SECRET_KEY</span> <span class="o">=</span> <span class="s2">"your secret key"</span> <span class="c1"># Returns true if the webhook request is verified to have come from Help Scout.</span> <span class="c1">#</span> <span class="c1"># data String The data posted by Help Scout to the webhook.</span> <span class="c1"># signature String Value for the http-x-helpscout-signature header.</span> <span class="c1">#</span> <span class="k">def</span> <span class="nf">is_from_help_scout</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">signature</span><span class="p">)</span> <span class="n">hmac</span> <span class="o">=</span> <span class="no">HMAC</span><span class="o">::</span><span class="no">SHA1</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">WEBHOOK_SECRET_KEY</span><span class="p">)</span> <span class="n">hmac</span><span class="p">.</span><span class="nf">update</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Utils</span><span class="p">.</span><span class="nf">secure_compare</span><span class="p">(</span><span class="no">Base64</span><span class="p">.</span><span class="nf">encode64</span><span class="p">(</span><span class="s2">"</span><span class="si">#{</span><span class="n">hmac</span><span class="p">.</span><span class="nf">digest</span><span class="si">}</span><span class="s2">"</span><span class="p">).</span><span class="nf">strip</span><span class="p">,</span> <span class="n">signature</span><span class="p">.</span><span class="nf">strip</span><span class="p">)</span> <span class="k">end</span> <span class="c1"># Usage Example</span> <span class="n">signature</span> <span class="o">=</span> <span class="s2">"+oNIxipGoqx4t2BmkBHbXKc6VHM="</span> <span class="n">data</span> <span class="o">=</span> <span class="s1">'{"ticket":{"id":"1","number":"2"},"customer":{"id":"1","fname":"Jackie","lname":"Chan","email":"jackie.chan@somewhere.com","emails":["jackie.chan@somewhere.com"]}}'</span> <span class="nb">puts</span> <span class="s2">"This request came from Help Scout:"</span> <span class="nb">puts</span> <span class="n">is_from_help_scout</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">signature</span><span class="p">)</span></code></pre></figure> <p>And an updated ruby example using openssl (instead of hmac-sha1):</p> <figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1">#!/usr/bin/ruby -rrubygems</span> <span class="nb">require</span> <span class="s1">'openssl'</span> <span class="nb">require</span> <span class="s1">'base64'</span> <span class="nb">require</span> <span class="s1">'rack/utils'</span> <span class="no">WEBHOOK_SECRET_KEY</span> <span class="o">=</span> <span class="s2">"your secret key"</span> <span class="k">def</span> <span class="nf">is_from_help_scout?</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">signature</span><span class="p">)</span> <span class="k">return</span> <span class="kp">false</span> <span class="k">if</span> <span class="n">data</span><span class="p">.</span><span class="nf">nil?</span> <span class="o">||</span> <span class="n">signature</span><span class="p">.</span><span class="nf">nil?</span> <span class="n">digest</span> <span class="o">=</span> <span class="no">OpenSSL</span><span class="o">::</span><span class="no">HMAC</span><span class="p">.</span><span class="nf">digest</span><span class="p">(</span><span class="s1">'sha1'</span><span class="p">,</span> <span class="no">WEBHOOK_SECRET_KEY</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Utils</span><span class="p">.</span><span class="nf">secure_compare</span><span class="p">(</span><span class="no">Base64</span><span class="p">.</span><span class="nf">encode64</span><span class="p">(</span><span class="s2">"</span><span class="si">#{</span><span class="n">digest</span><span class="si">}</span><span class="s2">"</span><span class="p">).</span><span class="nf">strip</span><span class="p">,</span> <span class="n">signature</span><span class="p">.</span><span class="nf">strip</span><span class="p">)</span> <span class="k">end</span> <span class="n">data</span> <span class="o">=</span> <span class="s1">'{"ticket":{"id":"1","number":"2"},"customer":{"id":"1","fname":"Jackie","lname":"Chan","email":"jackie.chan@somewhere.com","emails":["jackie.chan@somewhere.com"]}}'</span> <span class="n">signature</span> <span class="o">=</span> <span class="n">request</span><span class="p">.</span><span class="nf">headers</span><span class="p">[</span><span class="s1">'X-Helpscout-Signature'</span><span class="p">]</span> <span class="c1"># or use signature = 'I1KlvGppYqvFTJgJ9jezdQMDiyI=' which is an actual signature of the data above</span> <span class="nb">puts</span> <span class="s2">"This request came from Help Scout:"</span> <span class="nb">puts</span> <span class="n">is_from_help_scout?</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">signature</span><span class="p">)</span></code></pre></figure> <h3 id="nodejs">Node.js:</h3> <p>Thanks to one of our Help Scout customers for the following Node.js example.</p> <figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="cm">/*jshint node: true */</span> <span class="dl">'</span><span class="s1">use strict</span><span class="dl">'</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">crypto</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">crypto</span><span class="dl">'</span><span class="p">),</span> <span class="nx">config</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="dl">'</span><span class="s1">../lib/config</span><span class="dl">'</span><span class="p">).</span><span class="nx">config</span><span class="p">;</span> <span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">secret</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">next</span><span class="p">)</span> <span class="p">{</span> <span class="nx">req</span><span class="p">.</span><span class="nx">isHelpScout</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">hsSignature</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">header</span><span class="p">(</span><span class="dl">'</span><span class="s1">X-HelpScout-Signature</span><span class="dl">'</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="nx">hsSignature</span><span class="p">)</span> <span class="p">{</span> <span class="nx">req</span><span class="p">.</span><span class="nx">hsHasher</span> <span class="o">=</span> <span class="nx">crypto</span><span class="p">.</span><span class="nx">createHmac</span><span class="p">(</span><span class="dl">'</span><span class="s1">sha1</span><span class="dl">'</span><span class="p">,</span> <span class="nx">secret</span><span class="p">);</span> <span class="nx">req</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">)</span> <span class="p">{</span> <span class="nx">req</span><span class="p">.</span><span class="nx">hsHasher</span><span class="p">.</span><span class="nx">update</span><span class="p">(</span><span class="nx">chunk</span><span class="p">);</span> <span class="p">});</span> <span class="nx">req</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">end</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">hash</span> <span class="o">=</span> <span class="nx">req</span><span class="p">.</span><span class="nx">hsHasher</span><span class="p">.</span><span class="nx">digest</span><span class="p">(</span><span class="dl">'</span><span class="s1">base64</span><span class="dl">'</span><span class="p">);</span> <span class="nx">req</span><span class="p">.</span><span class="nx">isHelpScout</span> <span class="o">=</span> <span class="nx">hash</span> <span class="o">===</span> <span class="nx">hsSignature</span> <span class="p">?</span> <span class="kc">true</span> <span class="p">:</span> <span class="kc">false</span><span class="p">;</span> <span class="p">});</span> <span class="p">}</span> <span class="nx">next</span><span class="p">();</span> <span class="p">};</span> <span class="p">};</span></code></pre></figure> <h3>Java</h3> <p>A java example can be found in the <a href="https://github.com/helpscout/helpscout-api-java/blob/master/src/main/java/net/helpscout/api/Webhook.java">Webhook.java</a> class in the Help Scout <a href="https://github.com/helpscout/helpscout-api-java">Java library</a>.</p> <h2>Responses</h2> <p>Anything returned in the body of the response will be discarded. In order to know the webhook was successful, an HTTP status code between <code>200</code> and <code>299</code> must be returned.</p> <p>A status code of <code>410</code> will cause the webhook to get deactivated/deleted.</p> <p>Any status code other than something between <code>200</code> and <code>299</code> or <code>410</code> is a failure of some kind. A failed event is retried up to 10 times (with an increasing timeout period in between each retry). If the event fails all 10 retries, it is discarded.</p> <p>Webhooks are automatically deactivated if ten or more events get discarded.</p> <p><b>Note:</b> The Agent Reply event will only return data for User-generated threads. Auto Reply messages are not included in this event.</p> </div> </div> </section> <div class="u-pad-t-10 u-mrg-t-10 u-mrg-b-0"> <span class="u-mrg-r-2 t-tx-charcoal-200">↑</span><a href="#" class="t-tx-charcoal-200 tx-sm">Back to top</a> </div> <hr class="u-mrg-t-10 u-mrg-b-2"> <div class="u-pad-b-10"> <div class="o-flexy@md u-pad-b-8"> <div class="o-flexy__item"> <ul class="c-list c-list--inline"> <li class="u-mrg-r-6"> <a href="https://secure.helpscout.net" class="tx-sm c-link c-link--plain t-tx-charcoal-200">Customer Login</a> </li> <li class="u-mrg-r-6"> <a href="https://www.helpscout.net" class="tx-sm c-link c-link--plain t-tx-charcoal-200">Visit Help Scout</a> </li> <li class="u-mrg-r-6"> <a href="http://status.helpscout.net" class="tx-sm c-link c-link--plain t-tx-charcoal-200">Status</a> </li> </ul> </div> <div class="o-flexy__item"> <div class="u-mrg-v-5 t-tx-charcoal-200 tx-sm"> © <a href="http://helpscout.net" class="c-link c-link--plain t-tx-charcoal-200 tx-sm">Help Scout</a> 2025 </div> </div> </div> </div> <div id="c-overlay" class="c-overlay"> <div class="c-overlay__content"></div> <div class="c-overlay__background"></div> </div> </div> </div> </div> </main> </div> <script type="text/javascript"> var SEEDDATA = { packs: [ ]}; </script> <!-- beacon embed --> <script type="text/javascript">!function(e,n){window.Beacon=n=function(e,n,d){window.Beacon.readyQueue.push({method:e,options:n,data:d})},n.readyQueue=[];var t=e.getElementsByTagName("script")[0],o=e.createElement("script");o.type="text/javascript",o.async=!0,o.src="https://beacon-v2.helpscout.net",t.parentNode.insertBefore(o,t)}(document,window.Beacon||function(){})</script> <script>window.Beacon('init', 'aa90d610-923a-4528-95cc-934136cc7712')</script> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-5226593-6', 'helpscout.net'); ga('send', 'pageview'); </script> </body> </html>