Asana API

Getting access, Developing, Testing

Back to Asana

Establish A Webhook

Establishing a webhook is a two-part process. First, a simple HTTP POST request initiates the creation similar to creating any other resource.

Next, in the middle of this request comes the confirmation handshake. When a webhook is created, we will send a test POST to the target with an X-Hook-Secret header. The target must respond with a 200 OK or 204 No Content and a matching X-Hook-Secret header to confirm that this webhook subscription is indeed expected. We strongly recommend storing this secret to be used to verify future webhook event signatures.

The POST request to create the webhook will then return with the status of the request. If you do not acknowledge the webhook’s confirmation handshake it will fail to setup, and you will receive an error in response to your attempt to create it. This means you need to be able to receive and complete the webhook while the POST request is in-flight (in other words, have a server that can handle requests asynchronously).

Invalid hostnames like localhost will recieve a 403 Forbidden status code.

# Request
curl -H "Authorization: Bearer <personal_access_token>" \
-X POST https://app.asana.com/api/1.0/webhooks \
-d "resource=8675309" \
-d "target=https://example.com/receive-webhook/7654"
# Handshake sent to https://example.com/
POST /receive-webhook/7654
X-Hook-Secret: b537207f20cbfa02357cf448134da559e8bd39d61597dcd5631b8012eae53e81
# Handshake response sent by example.com
HTTP/1.1 200
X-Hook-Secret: b537207f20cbfa02357cf448134da559e8bd39d61597dcd5631b8012eae53e81
# Response
HTTP/1.1 201
{
  "data": {
    "gid": "43214",
    "resource": {
      "gid": "8675309",
      "name": "Bugs"
    },
    "target": "https://example.com/receive-webhook/7654",
    "active": false,
    "last_success_at": null,
    "last_failure_at": null,
    "last_failure_content": null
  }
}

Input

type: object properties: parameters: type: object properties: opt_pretty: type: boolean description: >- Provides “pretty” output. Provides the response in a “pretty” format. In the case of JSON this means doing proper line breaking and indentation to make it readable. This will take extra time and increase the response size so it is advisable only to use this during debugging. opt_fields: type: array items: type: string description: >- Defines fields to return. Some requests return *compact* representations of objects in order to conserve resources and complete the request more efficiently. Other times requests return more information than you may need. This option allows you to list the exact set of fields that the API should be sure to return for the objects. The field names should be provided as paths, described below. The id of included objects will always be returned, regardless of the field options. title: Parameters data: type: object properties: data: type: object properties: resource: description: >- A resource ID to subscribe to. Many Asana resources are valid to create webhooks on, but higher-level resources require filters. type: string example: '12345' target: description: >- The URL to receive the HTTP POST. The full URL will be used to deliver events from this webhook (including parameters) which allows encoding of application-specific state when the webhook is created. type: string format: uri example: >- https://example.com/receive-webhook/7654?app_specific_param=app_specific_value filters: type: array description: >- An array of WebhookFilter objects to specify a whitelist of filters to apply to events from this webhook. If a webhook event passes any of the filters the event will be delivered; otherwise no event will be sent to the receiving server. items: type: object properties: resource_type: type: string description: >- The type of the resource which created the event when modified; for example, to filter to changes on regular tasks this field should be set to `task`. example: task resource_subtype: description: >- The resource subtype of the resource that the filter applies to. This should be set to the same value as is returned on the `resource_subtype` field on the resources themselves. type: string example: milestone action: type: string description: >- The type of change on the **resource** to pass through the filter. For more information refer to `Event.action` in the [event](/reference/events) schema. This can be one of `changed`, `added`, `removed`, `deleted`, and `undeleted` depending on the nature of what has occurred on the resource. example: changed fields: type: array items: type: string title: Data

Output

type: object properties: data: type: object properties: gid: description: Globally unique identifier of the resource, as a string. type: string readOnly: true example: '12345' x-insert-after: false resource_type: description: The base type of this resource. type: string readOnly: true example: task x-insert-after: gid active: description: >- If true, the webhook will send events - if false it is considered inactive and will not generate events. type: boolean readOnly: true example: false resource: type: object properties: gid: description: Globally unique identifier of the resource, as a string. type: string readOnly: true example: '12345' x-insert-after: false resource_type: description: The base type of this resource. type: string readOnly: true example: task x-insert-after: gid name: description: The name of the object. type: string example: Bug Task target: description: The URL to receive the HTTP POST. type: string format: uri readOnly: true example: https://example.com/receive-webhook/7654 created_at: description: The time at which this resource was created. type: string format: date-time readOnly: true example: '2012-02-22T02:06:58.147Z' last_failure_at: description: >- The timestamp when the webhook last received an error when sending an event to the target. type: string format: date-time readOnly: true example: '2012-02-22T02:06:58.147Z' last_failure_content: description: >- The contents of the last error response sent to the webhook when attempting to deliver events to the target. type: string readOnly: true example: 500 Server Error\n\nCould not complete the request last_success_at: description: >- The timestamp when the webhook last successfully sent an event to the target. type: string format: date-time readOnly: true example: '2012-02-22T02:06:58.147Z' filters: description: >- Whitelist of filters to apply to events from this webhook. If a webhook event passes any of the filters the event will be delivered; otherwise no event will be sent to the receiving server. type: array items: type: object properties: resource_type: type: string description: >- The type of the resource which created the event when modified; for example, to filter to changes on regular tasks this field should be set to `task`. example: task resource_subtype: description: >- The resource subtype of the resource that the filter applies to. This should be set to the same value as is returned on the `resource_subtype` field on the resources themselves. type: string example: milestone action: type: string description: >- The type of change on the **resource** to pass through the filter. For more information refer to `Event.action` in the [event](/reference/events) schema. This can be one of `changed`, `added`, `removed`, `deleted`, and `undeleted` depending on the nature of what has occurred on the resource. example: changed fields: type: array items: type: string