Task-level "changed" events no longer emitted (webhooks and /events) since ~Aug 1

Since around Friday, August 1, 2026, we stopped receiving any task-level events with action: "changed" — both via webhooks and via the Events API. Story events still arrive normally, so the change is silently invisible until you notice the automation no longer fires.

This affects every field we tested, not just custom fields, so it does not look like the known custom-field webhook quirks.

What we expect

Changing an enum custom field on a task used to produce two events: the story, and the task-level change.

{
  "action": "changed",
  "resource": { "gid": "<task>", "resource_type": "task" },
  "change": {
    "field": "custom_fields",
    "action": "changed",
    "new_value": { "gid": "<custom_field>", "resource_type": "custom_field" }
  }
}

What we get

Only the story event. Example, unassigning a user:

{
  "created_at": "2026-08-05T18:30:58.007Z",
  "action": "added",
  "resource": {
    "gid": "1217201409263416",
    "resource_type": "story",
    "resource_subtype": "unassigned"
  },
  "parent": {
    "gid": "1217169183327062",
    "resource_type": "task",
    "resource_subtype": "default_task"
  }
}

Same for an enum custom field change — only resource_subtype: "enum_custom_field_changed", no paired task-level event.

Reproduction via Events API (bypasses webhooks entirely)

To rule out our webhook, our server and our integration, we reproduced this with the Events API using a different token than the one that owns our webhooks.

  1. Establish sync tokens on three resources at once: two projects and one task.
  2. In the task: change the assignee, then change an enum custom field. Both changes confirmed visible in the UI.
  3. Poll all three streams for 2 minutes.

Aggregate over 33 events (including unrelated activity in the project):

('story', 'added')      25
('task',  'added')       6
('task',  'removed')     2
('task',  'changed')     0

Not a single event in the entire capture contained a change key.

Our two actions did register — both appear at 18:43:15Z and 18:43:19Z as story/added in all three streams. Only the paired task/changed events are missing.

Note that task/added and task/removed are delivered normally, so task events as a class are fine. It is specifically action: "changed" that is gone.

Environment

  • Workspace: 732612588386273
  • Projects observed: 1211709508194061, 1209139123416412
  • Task used for the test: 1217169183327062
  • Observed window: 2026-08-05, 16:30–18:45 UTC
  • First noticed: Friday 2026-08-01

Webhooks themselves are healthy — story events keep arriving at the same endpoint, so this is not a delivery, handshake or webhook-expiry problem.

Questions

  1. Is this a known regression? It lines up with the scheduled database maintenance on Aug 2, 03:00–05:00 UTC.
  2. Was action: "changed" for tasks intentionally changed or deprecated? We could not find anything in the changelog or the API docs, which still document the change object as-is.
  3. If this is the new intended behaviour, what is the recommended way to detect a specific custom field changing on a task? Right now the only signal we get is a story, which requires an extra GET /stories/{gid} per event just to learn which field changed.

Happy to provide raw captures if useful.

Hi @Aleksei_Panin, thanks for the detailed writeup and welcome to the forum. This should be resolved now.

We’re still evaluating the cause, apologies for the disruption this caused. In the meantime, the recommended remediation is to re-fetch affected data via the API, the data layer wasn’t affected.

It looks like Asana stopped emitting task‑level “changed” events via webhooks since August 1, which has impacted integrations relying on those updates. The current guidance is to adjust to the new event model or use alternative endpoints, and many users are sharing feedback so Asana can clarify or restore functionality.

Hi @shawn39foley,

As @Mikhail_Melikhov noted above, it was an issue but is resolved now. See Asana Status - Webhooks and event streams partial data loss

Hi all,

Since around August 2, 2026, the polling Events API (GET /events?resource=<project_gid>) has stopped delivering task changed events for most field changes in our workspace. Our integration syncs custom field values off change.field == "custom_fields" events, exactly as described in the Events reference, and those events simply no longer arrive.

What we tested

Fully scripted, reproduced several times on 2026-08-04. Workspace 1212889913907655 (developer sandbox domain), plain PAT.

  1. Create a plain project via the API (no template, no portfolio), create a text custom field via POST /custom_fields, attach it with addCustomFieldSetting, create a task.
  2. Establish an events sync token for the project and drain the setup events (those arrive fine).
  3. PUT /tasks/{task} changing only name → a changed event with change.field: "name" arrives within ~10 seconds. :white_check_mark:
  4. PUT /tasks/{task} changing only the custom field value → the write succeeds (200, value confirmed by reading the task back), but no event of any kind arrives within 120+ seconds — no task changed event, not even a story event. :cross_mark:

Results across field types (each change made in isolation, same event stream):

Field changed Task changed event Story event
name :white_check_mark: arrives
custom field (text and enum tested) :cross_mark: none :cross_mark: none
notes :cross_mark: none :cross_mark: none
due_on :cross_mark: none story added only
completed :cross_mark: none story added only
section membership :white_check_mark: added/removed arrive :white_check_mark: arrives

For due_on and completed, the only signal left is the added event for the activity-feed story, which carries change: null and no field information. For custom fields and notes there is no signal at all.

Things we ruled out

  • Not the token: a freshly created PAT for the same user reproduces it identically.
  • Not the project or field setup: happens both on template-instantiated projects and on plain API-created projects with API-created fields.
  • Not rate limiting: no 429s anywhere, all requests return 200, and the missing events would have come through the same successful polling responses that deliver the name/section events.
  • The integration received these events correctly until at least August 2, 2026, with no changes on our side.

I know the events system is documented as at-most-once delivery, but this is deterministic 100% suppression of entire event classes, not occasional loss.

Was there an intentional change to which field changes emit events? If so, where is it documented, and what is the recommended way to detect custom field value changes on tasks going forward? If not, this looks like a regression.

Repro script
"""Repro: which task field changes still emit Events API events?

Creates a scratch project + text custom field + task, then changes
name / custom field / due_on / notes / completed one at a time,
polling the project's event stream between each. Cleans up at the end.
"""

import json
import os
import time
import urllib.error
import urllib.parse
import urllib.request

PAT = os.environ["ASANA_PAT"]
WORKSPACE = os.environ["ASANA_WORKSPACE_GID"]
TEAM = os.environ["ASANA_TEAM_GID"]
BASE = "https://app.asana.com/api/1.0"


def call(method, path, data=None, params=None):
    """Make an Asana API request and return the parsed JSON body (errors included)."""
    url = f"{BASE}{path}"
    if params:
        url += "?" + urllib.parse.urlencode(params)
    body = json.dumps({"data": data}).encode() if data is not None else None
    req = urllib.request.Request(url, data=body, method=method)
    req.add_header("Authorization", f"Bearer {PAT}")
    req.add_header("Content-Type", "application/json")
    try:
        with urllib.request.urlopen(req) as resp:
            return json.load(resp)
    except urllib.error.HTTPError as e:
        return json.load(e)


def poll_until(project_gid, token, label, timeout=120):
    """Poll events every 10s until any arrive or timeout; print them. Returns newest token."""
    deadline = time.time() + timeout
    while time.time() < deadline:
        time.sleep(10)
        resp = call("GET", "/events", params={"resource": project_gid, "sync": token})
        token = resp.get("sync", token)
        events = resp.get("data", [])
        if events:
            print(f"  [{label}] {len(events)} event(s):")
            for ev in events:
                print("   ", json.dumps({
                    "action": ev.get("action"),
                    "type": (ev.get("resource") or {}).get("resource_type"),
                    "change": ev.get("change"),
                }))
            return token
    print(f"  [{label}] NO events within {timeout}s")
    return token


project_gid = call("POST", "/projects", {"name": "Event Repro", "team": TEAM})["data"]["gid"]
field_gid = call("POST", "/custom_fields", {
    "name": "Repro Text Field", "resource_subtype": "text", "workspace": WORKSPACE,
})["data"]["gid"]
call("POST", f"/projects/{project_gid}/addCustomFieldSetting", {"custom_field": field_gid})
task_gid = call("POST", "/tasks", {"name": "Repro Task", "projects": [project_gid]})["data"]["gid"]
print("project:", project_gid, "field:", field_gid, "task:", task_gid)

token = call("GET", "/events", params={"resource": project_gid}).get("sync")
token = poll_until(project_gid, token, "drain-setup", timeout=30)

MUTATIONS = [
    ("name", {"name": "Repro Task RENAMED"}),
    ("custom_field", {"custom_fields": {field_gid: "hello-events"}}),
    ("due_on", {"due_on": "2026-08-15"}),
    ("notes", {"notes": "repro notes body"}),
    ("completed", {"completed": True}),
]
for label, payload in MUTATIONS:
    print(f"\n== change {label} ==")
    result = call("PUT", f"/tasks/{task_gid}", payload)
    print("  PUT:", "ok" if "errors" not in result else result["errors"])
    token = poll_until(project_gid, token, label)

print("\ncleanup:")
print("  delete project:", "ok" if "errors" not in call("DELETE", f"/projects/{project_gid}") else "FAILED")
print("  delete field:", "ok" if "errors" not in call("DELETE", f"/custom_fields/{field_gid}") else "FAILED")

Thanks!

Thanks!

Hi @Mark_Hashimoto,

I merged your post with an existing thread on this topic.

As reported here, it was verified as an Asana issue, and I’ve verified this with our Flowsana app, it should be fixed now.

Hey there everyone,

Well, the weekend of the 1st to 2nd August, our webhook integration stopped receiving custom field change events.

It seems like the feature was completely wiped / abandoned.

Quick background:

  • we have quite an extensive board setup, in which tasks are in 2 boards (1x client + 1x the corresponding department)
  • To automate editing / moving of tasks, we setup quite an extensive set of n8n automations that draws whom to add etc. from our erp (that’s the reason why we didn’t do the native automations)
  • That system relied entirely on the custom fields: operators toggle the fields => task moves

**
What we relied on:** webhooks with the filter

{ “resource_type”: “task”, “resource_subtype”: “default_task”, “action”: “changed”, “fields”: [“custom_fields”] }
These delivered a task / changed event (with change.field: “custom_fields” and change.new_value) whenever a single-select custom field changed on a task.

What changed: those webhooks now receive only heartbeats — no custom-field events. Changing a single-select custom field now emits only a story event with resource_subtype: “enum_custom_field_changed”. The old task / changed + custom_fields event is no longer delivered to webhooks.

How we confirmed it (to rule out a stale subscription): on one project we registered two fresh webhooks at the same time — one with the old task/changed/custom_fields filter, one with story/added + enum_custom_field_changed — then changed a custom field once. Only the story webhook fired. The Events API on the project shows the same: only the story event, no task/changed event.

Is this a known error? was the feature deliberately removed? Any smart workarounds (we switched it to using the stories, but it’s meh)

Best regards, Paul

Hi @Paul_Volkwein and welcome to the forum,

I’ve merged your post with an existing thread on this topic. Please see the above posts in the thread for the explanation (and link to the Asana incident).