Asana Webhooks API

Asana Webhooks API allows developers to receive real-time updates about changes and events happening within Asana. By setting up webhooks, users can subscribe to specific events such as task creation, task completion, or project updates, and receive notifications in the form of HTTP POST requests. This allows for seamless integration and automation of workflows, as users can react to changes in Asana data immediately and trigger actions in external systems.

Operations 5

Each operation below carries the questions people ask an LLM about it and the instructions they give an agent to run it. Generated by API Evangelist overlay

GET /webhooks List my webhooks in a workspace · Get multiple webhooks #
Ask an LLM
“Which webhooks has my app registered in a workspace?”
“Can I list only the webhooks on one resource?”
Tell an agent
List my webhooks in workspace {workspace}.
Show webhooks in workspace {workspace} for resource {resource}.
POST /webhooks Subscribe to changes with a webhook · Establish a webhook #
Ask an LLM
“How do I get notified when tasks in a project change?”
“What is the handshake step when establishing a webhook?”
Tell an agent
Create a webhook on resource {resource} posting to {target}.
Establish a webhook with {details}.
GET /webhooks/{webhook_gid} Get a webhook's details · Get a webhook #
Ask an LLM
“What resource and target does a webhook point at?”
“Can I look up one webhook by its ID?”
Tell an agent
Show webhook {webhook}.
Fetch the details of webhook {webhook}.
PUT /webhooks/{webhook_gid} Change a webhook's filters · Update a webhook #
Ask an LLM
“Can I change which events a webhook receives?”
“Does updating filters replace the webhook's old filter list?”
Tell an agent
Replace the filters on webhook {webhook} with {filters}.
Update webhook {webhook} to only send {filters}.
DELETE /webhooks/{webhook_gid} Delete a webhook · Delete a webhook #
Ask an LLM
“Can I still receive events right after deleting a webhook?”
“How do I permanently stop a webhook?”
Tell an agent destructive · confirm first
Delete webhook {webhook}.
Permanently remove webhook {webhook}.

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/asana:asana-webhooks-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

asana-webhooks-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  description: This is the interface for interacting with the Asana Platform. Our API reference is generated from our [OpenAPI spec] (https://raw.githubusercontent.com/Asana/developer-docs/master/defs/asana_oas.yaml).
  x-public-description: This is the interface for interacting with the [Asana Platform](https://developers.asana.com). Our API reference is generated from our [OpenAPI spec] (https://raw.githubusercontent.com/Asana/developer-docs/master/defs/asana_oas.yaml).
  title: Asana Webhooks API
  termsOfService: https://asana.com/terms
  contact:
    name: Asana Support
    url: https://asana.com/support
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
  version: '1.0'
  x-docs-schema-whitelist:
  - AsanaResource
  - AsanaNamedResource
  - AuditLogEvent
  - AttachmentResponse
  - AttachmentCompact
  - BatchResponse
  - CustomFieldSettingResponse
  - CustomFieldSettingCompact
  - CustomFieldResponse
  - CustomFieldCompact
  - EnumOption
  - EventResponse
  - ErrorResponse
  - GoalResponse
  - GoalCompact
  - GoalMembershipCompact
  - GoalMembershipBase
  - GoalMembershipResponse
  - GoalRelationshipResponse
  - GoalRelationshipCompact
  - JobResponse
  - JobCompact
  - OrganizationExportResponse
  - OrganizationExportCompact
  - PortfolioMembershipResponse
  - PortfolioMembershipCompact
  - PortfolioResponse
  - PortfolioCompact
  - ProjectBriefResponse
  - ProjectBriefCompact
  - ProjectMembershipResponse
  - ProjectMembershipCompact
  - ProjectResponse
  - ProjectCompact
  - ProjectStatusResponse
  - ProjectStatusCompact
  - ProjectTemplateCompact
  - ProjectTemplateResponse
  - SectionResponse
  - SectionCompact
  - StatusUpdateResponse
  - StatusUpdateCompact
  - StoryResponse
  - StoryCompact
  - TagResponse
  - TagCompact
  - TaskResponse
  - TaskCompact
  - TaskCountResponse
  - TeamMembershipResponse
  - TeamMembershipCompact
  - TeamResponse
  - TeamCompact
  - TimePeriodResponse
  - TimePeriodCompact
  - UserTaskListResponse
  - UserTaskListCompact
  - UserResponse
  - UserCompact
  - WebhookFilter
  - WebhookResponse
  - WebhookCompact
  - WorkspaceMembershipResponse
  - WorkspaceMembershipCompact
  - WorkspaceResponse
  - WorkspaceCompact
servers:
- url: https://app.asana.com/api/1.0
  description: Main endpoint.
security:
- personalAccessToken: []
- oauth2: []
tags:
- name: Webhooks
  description: 'Webhooks allow you to subscribe to notifications about events that occur on Asana resources (e.g., tasks, projects, stories, etc.).


    For a more detailed explanation of webhooks see the overview of webhooks.'
paths:
  /webhooks:
    parameters:
    - $ref: '#/components/parameters/pretty'
    - $ref: '#/components/parameters/fields'
    get:
      summary: Get multiple webhooks
      description: Get the compact representation of all webhooks your app has registered for the authenticated user in the given workspace.
      tags:
      - Webhooks
      operationId: getWebhooks
      parameters:
      - $ref: '#/components/parameters/limit'
      - $ref: '#/components/parameters/offset'
      - name: workspace
        in: query
        required: true
        description: The workspace to query for webhooks in.
        schema:
          type: string
        example: '1331'
      - name: resource
        in: query
        description: Only return webhooks for the given resource.
        schema:
          type: string
        example: '51648'
      responses:
        200:
          description: Successfully retrieved the requested webhooks.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/WebhookResponse'
        400:
          $ref: '#/components/responses/BadRequest'
        401:
          $ref: '#/components/responses/Unauthorized'
        403:
          $ref: '#/components/responses/Forbidden'
        404:
          $ref: '#/components/responses/NotFound'
        500:
          $ref: '#/components/responses/InternalServerError'
    post:
      summary: Establish a webhook
      description: '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 " \

        -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

        }

        }

        ```'
      tags:
      - Webhooks
      operationId: createWebhook
      requestBody:
        description: The webhook workspace and target.
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  $ref: '#/components/schemas/WebhookRequest'
      responses:
        201:
          description: Successfully created the requested webhook.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/WebhookResponse'
        400:
          $ref: '#/components/responses/BadRequest'
        401:
          $ref: '#/components/responses/Unauthorized'
        403:
          $ref: '#/components/responses/Forbidden'
        404:
          $ref: '#/components/responses/NotFound'
        500:
          $ref: '#/components/responses/InternalServerError'
  /webhooks/{webhook_gid}:
    parameters:
    - $ref: '#/components/parameters/webhook_path_gid'
    - $ref: '#/components/parameters/pretty'
    - $ref: '#/components/parameters/fields'
    get:
      summary: Get a webhook
      description: Returns the full record for the given webhook.
      tags:
      - Webhooks
      operationId: getWebhook
      responses:
        200:
          description: Successfully retrieved the requested webhook.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/WebhookResponse'
        400:
          $ref: '#/components/responses/BadRequest'
        401:
          $ref: '#/components/responses/Unauthorized'
        403:
          $ref: '#/components/responses/Forbidden'
        404:
          $ref: '#/components/responses/NotFound'
        500:
          $ref: '#/components/responses/InternalServerError'
    put:
      summary: Update a webhook
      description: An existing webhook's filters can be updated by making a PUT request on the URL for that webhook. Note that the webhook's previous `filters` array will be completely overwritten by the `filters` sent in the PUT request.
      tags:
      - Webhooks
      operationId: updateWebhook
      requestBody:
        description: The updated filters for the webhook.
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                data:
                  $ref: '#/components/schemas/WebhookUpdateRequest'
      responses:
        200:
          description: Successfully updated the webhook.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/WebhookResponse'
        400:
          $ref: '#/components/responses/BadRequest'
        401:
          $ref: '#/components/responses/Unauthorized'
        403:
          $ref: '#/components/responses/Forbidden'
        404:
          $ref: '#/components/responses/NotFound'
        500:
          $ref: '#/components/responses/InternalServerError'
    delete:
      summary: Delete a webhook
      description: This method *permanently* removes a webhook. Note that it may be possible to receive a request that was already in flight after deleting the webhook, but no further requests will be issued.
      tags:
      - Webhooks
      operationId: deleteWebhook
      responses:
        200:
          description: Successfully retrieved the requested webhook.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/EmptyResponse'
        400:
          $ref: '#/components/responses/BadRequest'
        401:
          $ref: '#/components/responses/Unauthorized'
        403:
          $ref: '#/components/responses/Forbidden'
        404:
          $ref: '#/components/responses/NotFound'
        500:
          $ref: '#/components/responses/InternalServerError'
components:
  parameters:
    webhook_path_gid:
      name: webhook_gid
      in: path
      description: Globally unique identifier for the webhook.
      required: true
      schema:
        type: string
      example: '12345'
      x-env-variable: webhook
    limit:
      name: limit
      in: query
      description: 'Results per page.

        The number of objects to return per page. The value must be between 1 and 100.'
      example: 50
      schema:
        type: integer
    fields:
      name: opt_fields
      in: query
      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.'
      example:
      - followers
      - assignee
      required: false
      schema:
        type: array
        items:
          type: string
      style: form
      explode: false
    pretty:
      name: opt_pretty
      in: query
      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.'
      required: false
      allowEmptyValue: true
      schema:
        type: boolean
      style: form
      example: true
    offset:
      name: offset
      in: query
      description: 'Offset token.

        An offset to the next page returned by the API. A pagination request will return an offset token, which can be used as an input parameter to the next request. If an offset is not passed in, the API will return the first page of results.

        ''Note: You can only pass in an offset that was returned to you via a previously paginated request.'''
      example: eyJ0eXAiOJiKV1iQLCJhbGciOiJIUzI1NiJ9
      schema:
        type: string
  responses:
    InternalServerError:
      description: There was a problem on Asana’s end. In the event of a server error the response body should contain an error phrase. These phrases can be used by Asana support to quickly look up the incident that caused the server error. Some errors are due to server load, and will not supply an error phrase.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: The authentication and request syntax was valid but the server is refusing to complete the request. This can happen if you try to read or write to objects or properties that the user does not have access to.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: A valid authentication token was not provided with the request, so the API could not associate a user with the request.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    BadRequest:
      description: This usually occurs because of a missing or malformed parameter. Check the documentation and the syntax of your request and try again.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: Either the request method and path supplied do not specify a known action in the API, or the object specified by the request does not exist.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  schemas:
    Error:
      type: object
      properties:
        message:
          type: string
          readOnly: true
          description: Message providing more detail about the error that occurred, if available.
          example: 'project: Missing input'
        help:
          type: string
          readOnly: true
          description: Additional information directing developers to resources on how to address and fix the problem, if available.
          example: 'For more information on API status codes and how to handle them, read the docs on errors: https://asana.github.io/developer-docs/#errors'''
        phrase:
          type: string
          readOnly: true
          description: '*500 errors only*. A unique error phrase which can be used when contacting developer support to help identify the exact occurrence of the problem in Asana’s logs.'
          example: 6 sad squid snuggle softly
    WebhookRequest:
      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:
            allOf:
            - $ref: '#/components/schemas/WebhookFilter'
            - description: A set of filters to specify a whitelist for what types of events will be delivered.
            - type: object
      required:
      - resource
      - target
    AsanaNamedResource:
      allOf:
      - $ref: '#/components/schemas/AsanaResource'
      - type: object
        properties:
          name:
            description: The name of the object.
            type: string
            example: Bug Task
    WebhookFilter:
      type: object
      description: A WebhookFilter can be passed on creation of a webhook in order to filter the types of actions that trigger delivery of an [Event](/docs/tocS_Event)
      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](/docs/tocS_Event) 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
          description: '*Conditional.* A whitelist of fields for events which will pass the filter when the resource is changed. These can be any combination of the fields on the resources themselves. This field is only valid for `action` of type `changed`'
          items:
            type: string
          example:
          - due_at
          - due_on
          - dependencies
    WebhookCompact:
      allOf:
      - $ref: '#/components/schemas/AsanaResource'
      - type: object
        description: Webhook objects represent the state of an active subscription for a server to be updated with information from Asana. This schema represents the subscription itself, not the objects that are sent to the server. For information on those please refer to the [Event](/docs/tocS_Event) schema.
        x-docs-overrides:
          properties.resource_type.example: webhook
        properties:
          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:
            $ref: '#/components/schemas/AsanaNamedResource'
          target:
            description: The URL to receive the HTTP POST.
            type: string
            format: uri
            readOnly: true
            example: https://example.com/receive-webhook/7654
    WebhookResponse:
      allOf:
      - $ref: '#/components/schemas/WebhookCompact'
      - type: object
        properties:
          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:
              allOf:
              - $ref: '#/components/schemas/WebhookFilter'
              - description: A set of filters to specify a whitelist for what types of events will be delivered.
              - type: object
    WebhookUpdateRequest:
      type: object
      properties:
        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:
            allOf:
            - $ref: '#/components/schemas/WebhookFilter'
            - description: A set of filters to specify a whitelist for what types of events will be delivered.
            - type: object
    EmptyResponse:
      type: object
      description: An empty object. Some endpoints do not return an object on success. The success is conveyed through a 2-- status code and returning an empty object.
    AsanaResource:
      description: A generic Asana Resource, containing a globally unique identifier.
      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
    ErrorResponse:
      description: 'Sadly, sometimes requests to the API are not successful. Failures can

        occur for a wide range of reasons. In all cases, the API should return

        an HTTP Status Code that indicates the nature of the failure,

        with a response body in JSON format containing additional information.



        In the event of a server error the response body will contain an error

        phrase. These phrases are automatically generated using the

        [node-asana-phrase

        library](https://github.com/Asana/node-asana-phrase) and can be used by

        Asana support to quickly look up the incident that caused the server

        error.'
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    personalAccessToken:
      type: http
      description: A personal access token allows access to the api for the user who created it. This should be kept a secret and be treated like a password.
      scheme: bearer
    oauth2:
      type: oauth2
      description: 'We require that applications designed to access the Asana API on behalf of multiple users implement OAuth 2.0.

        Asana supports the Authorization Code Grant flow.'
      flows:
        authorizationCode:
          authorizationUrl: https://app.asana.com/-/oauth_authorize
          tokenUrl: https://app.asana.com/-/oauth_token
          refreshUrl: https://app.asana.com/-/oauth_token
          scopes:
            default: Provides access to all endpoints documented in our API reference. If no scopes are requested, this scope is assumed by default.
            openid: Provides access to OpenID Connect ID tokens and the OpenID Connect user info endpoint.
            email: Provides access to the user’s email through the OpenID Connect user info endpoint.
            profile: Provides access to the user’s name and profile photo through the OpenID Connect user info endpoint.
x-readme:
  proxy-enabled: false
x-provenance:
  method: harvested
  publisher: Asana
  source: https://raw.githubusercontent.com/Asana/developer-docs/master/defs/asana_oas.yaml
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)