Sales & outboundpattern
Two-step task creation that defeats Asana's project default-template
Asana's project default-template silently overwrites your task body. Two API calls per task and the right HTML tags fix it.
What
Asana projects that have a default-task template silently overwrite html_notes at creation time. The fix is two API calls per task: POST /tasks with the name + project memberships + assignee + every custom-field GID populated; then PUT /tasks/{gid} with the real html_notes. The body uses only Asana's whitelisted HTML tags (<body><h1><hr/><ul><li><strong><em><a>) — no <p> or <br>; each paragraph is wrapped in <ul><li>...</li></ul>.
Why it matters
Eliminates the 5-minute manual fill of ~12 custom fields per deal. At 50 deals per week that's roughly four hours saved per week, with zero "forgot to set the vertical" errors.
End-to-end
- Discover custom-field GIDs once:
GET /projects/{gid}/tasks?opt_fields=custom_fields.gid,custom_fields.name,custom_fields.enum_options.name,custom_fields.enum_options.gid. - Hardcode the
GID → name → option_gidmap per project in code (one dict per enum field). - POST
/taskswithdata.custom_fields = {gid: option_gid_or_value}, plusmemberships: [{project, section}]to land in the correct section. - PUT
/tasks/{gid}withdata.html_notes = "<body>...</body>"built from the four-section template (Team / Product / Traction / Competitors).
Gotchas
- The
html_noteswhitelist is undocumented and the project-template overwrite is undocumented — both were reverse-engineered. Asana admins adding or disabling enum options will silently break the hardcoded GID map; re-run the discovery query whenever the option set changes.
Tools
- Asana Personal Access Token
- Python
httpx(or any HTTP client)
← All casesB-009