X-Hook-Secret only 32 chars

Hi Asana Community,

actually I am developing an macOS App for Asana Notifications.
I am wondering that a webhook create request only response 32 chars in X-Hook-Secret.
Is that correct? Shouldn’t it be 64 chars?

[X-Hook-Secret] => fe0264e04156f317bb92f11006973ccf

And another question: To get the assigned “task count” of a user: Is the only way to each trough the workspaces, get the tasks of that workspace (REST request for each workspace?) and each trough the tasks to fetch the tasks that are “not completed”?

How about the inbox? How do I fetch the Inbox items?
For that I think the webhook is the right solution?

Want to make push notifications work with macOS.

Thanks and best regards,

1 Like

I do not get that to work.
Error message all the time:

help = "For more information on API status codes and how to handle them, read the docs on errors: https://asana.com/developers/documentation/getting-started/errors";

message = "Could not complete activation handshake with target URL. Please ensure that the receiving server is accepting connections and supports SSL";

curl --header "X-Hook-Secret: 57d1fe9846241d45d5df2ac76389b504" https://www.......de/_as_webhook/index.php -v -X POST
*   Trying
* Connected to www.......de ( port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: ......de
* Server certificate: Let's Encrypt Authority X3
* Server certificate: DST Root CA X3
> POST /_as_webhook/index.php HTTP/1.1
> Host: www.......de
> User-Agent: curl/7.54.0
> Accept: */*
> X-Hook-Secret: 57d1fe9846241d45d5df2ac76389b504
< HTTP/1.1 200 OK
< Date: Wed, 19 Jul 2017 15:09:47 GMT
< Server: Apache
< X-Powered-By: PHP/7.0.21
< X-Hook-Secret: 57d1fe9846241d45d5df2ac76389b504
< Upgrade: h2,h2c
< Connection: Upgrade
< X-Powered-By: PleskLin
< MS-Author-Via: DAV
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
* Connection #0 to host www.......de left intact

CURL proves that everything is correct… :-/

Hey there @Kevin_Lieser,

You are right, the secret we provide is 32 hex characters long, and webhook signatures (which we pass as with the X-Hook-Signature header) is 64 characters long. (We have a note to fix this in our next pass through our documentation, sorry for any confusion :frowning: )

As far as the activation handshake problem, this is most commonly encountered when attempting to set up the webhook from within the same thread as will respond to incoming webhook deliveries.

The ordering of the webhook handshake goes like this:

client                    server (Asana)
|-- POST /api/1.0/webhooks --->|
|<--- POST {yourcallback} ---- |
|                              |
|--- 200 OK [with secret] ---> |
<--------- 200 OK -------------|

That is, the callback happens inside of the original request before the original request returns.

This is great for getting assurance that the webhook is established, because the return from the first request will be either success or failure depending on what happened with the handshake. However, this also means that your server needs to be able to respond to the incoming handshake request before the first request returns.

This has implications for single-threaded servers that block on the return of the first request - namely, they are blocked! They can’t respond to the second request until that first request returns. That means the handshake really does encounter a server that isn’t responding.

The solution is to kick off the first request in a thread, which frees up the second thread to occur, or to run multiple servers in parallel somehow (like Apache’s mpm_worker_module ) so that a server in process 2 can handle the handshake while process 1 is blocked.

Hopefully this makes sense!

We don’t have a specific way to get a particular user’s inbox, but you can query for incomplete tasks for a particular user. I’d approach getting task counts like this:

If you’re using an authorization for a particular user (say, a personal access token) you can get all their workspaces by making a request to the /users/me endpoint:

curl --header "Authorization: Bearer $ASANA_PERSONAL_ACCESS_TOKEN" "https://app.asana.com/api/1.0/users/me"

This will return, amongst other things, the list of workspaces for that user.

A note of warning: this may not always be quite so simple; at some point in the future, each authorization may be scoped to a single workspace. This means that integrations will have to authorize and get credentials for each user-workspace pair. This is still under development, so the exact implementation is still in progress, but it’s good to know for the future.

(We’re considering the implications of having some API endpoints, like the /users/me one, have the ability to see cross-workspace data like this, so this may never end up changing for you. Just calling it out.

For each workspace, get the list of incomplete tasks for that user in that workspace:

curl --header “Authorization: Bearer $ASANA_PERSONAL_ACCESS_TOKEN” “https://app.asana.com/api/1.0/tasks?assignee=[user_id]&completed_since=now&wo

The tricky or unintuitive part of this is the “completed_since=now”, which will return incomplete tasks. It’s sort of like “tasks that will be completed at a date later than now”, but is definitely something that looks odd at first glance.

Then you just count those tasks, and you’re good to go! Hopefully this helps - and saves you from having to pull all the data from Asana for several entire workspaces every time you want to count a user’s open tasks :wink:


Hi @Matt_Bramlage,

the way you described for the webhook creation (and also is described in the docs) is exactly the same as I am trying. See the CURL output above – it is from the “live server”. The X-Hook-Secret get responded correctly. Also 200 OK. And for sure this request is running “while my macOS App is waiting for the webhook response” – for sure the process runs – I am receiving a test e-mail which I set up in the PHP script while waiting for the webhook response.

I think everything is setted up right. The PHP script returns the X-Hook-Secret Header as it should – but server side said there are problem while handshaking…

No clue what went wrong…

Hey @Matt_Bramlage,

is it possible that my Lets Encrypt Certificate is the problem?
Does the Handshake work with LE Certs?

Cool, we can see if we can reproduce the certificate thing, but I want to double check and see if I can clarify a bit more, since this looks so much like something that is really easy to do and you definitely wouldn’t be the first to run into it.

If you have PHP code to:

1 listen to POST requests on https://www…de/_as_webhook/index.php from Asana and give it back the header

and in the same PHP code to

2 make a POST request to “https://app.asana.com/api/1.0/webhooks” to ask to create the webhook

you will definitely see this error unless you explicitly set your PHP code to run those two actions in different threads or processes. This is notably very “gotcha”- esque, because when you curl your own PHP server from the outside everything is fine, because it’s not at that moment blocked on asking Asana to create the webhook, it’s idly waiting by for any incoming requests. It’s only when your script is waiting for the response from Asana while creating the webhook that it happens.

So, I guess I would ask if you have tried making that second request, the one to ask Asana to create the webhook, from curl? The response from curl against your PHP server looks fine, so if you can try to create the webhook and get a 200 OK response I think that’s how we’ll know that this is the PHP-is-blocked case.

Hi @Matt_Bramlage,

1 listen to POST requests on https://www…de/_as_webhook/index.php from Asana and give it back the header

That definately works – as you said the curl response look fine. I know…

and in the same PHP code to

The “same”? This means you mean the create POST has do get sent via the same PHP script? I don’t think that is correct. Because…

2 make a POST request to “ https://app.asana.com/api/1.0/webhooks ” to ask to create the webhook

This Create POST request is send from my macOS application. Not from PHP or anywhere. PHP is just the target for the webhook. So there should be no blocked PHP processes. The other thing is that my webserver is multithreading – with PHP FPM. So I think this was never the problem.


Hey @Matt_Bramlage,

any ideas what is going wrong here?

Hey @Kevin_Lieser,

It certainly sounds like your script shouldn’t be the problem. It does indeed then seem like it might be a certificate problem.

I know it’s a bit annoying, but you could try something like using ngrok to proxy incoming requests to a local machine. When you run ngrok locally it, ngrok will give you a subdomain (like 12abc4f.ngrok.io) that tunnels to your local machine (this is handy for not having a publicly-addressible URL as well).

When you make the request to create the webhook, give it the ngrok subdomain as your domain name and whatever route you are handling locally. In this case, it’d be something like https://12abc4f.ngrok.io/_as_webhook/index.php and (when running) ngrok will forward this to a port (given on the command line) at localhost, so http://localhost:8080/_as_webhook/index.php (note that this doesn’t need to be https when running on localhost; it’s secure to ngrok’s servers, then tunneled securely to your machine, then unencrypted from the tunnel to your PHP script)

This extra layer is a bit annoying to set up, but it would allow you to effectively use ngrok’s certificate, which I know we have no trouble talking to.

I would advise, however, just as a bit of hygeine, to use temporary credentials to ngrok. While I believe them to be secure and with good intentions, they are a man-in-the-middle, so revoking your credentials as soon as you’re done is just good practice.

With this setup, if you successfully set up a webhook, I think we can call it your certificate.


1 Like

Hi @Matt_Bramlage,

thanks for your reply!

Thats it! With ngrok its working fine…

So Lets Encrypt do not work – also I bought an Comodo certificate to test a week ago – that do also not work. Is there a way to get these working so I do not have to buy the next certificate?

Best regards,

Bought also an GoDaddy certificate… but it’s not working on my server.
Now setting up an dedicated IP for that subdomain – maybe thats the issue?!

Found the problem: mod_h2… Had http2 active on my webserver.
Are you able to fix that? Actually I am running on http/1.1 again.

Best regards,


You are right, the secret we provide is 32 hex characters long, and webhook signatures (which we pass as with the X-Hook-Signature header) is 64 characters long. (We have a note to fix this in our next pass through our documentation, sorry for any confusion :frowning: )

was the above issue addressed ? still facing the same :worried:

@Bharath as I said one post before yours: I had these issues because of http/2 (mod_h2).