Asana
The Asana integration lets Helios agents read and change your Asana workspace through its REST API, and run agents automatically when tasks, comments, sections, projects, portfolios, goals, or memberships change.
What your agents can do
Agents use Asana's REST API to work with tasks, projects, and related resources. Helios attaches the connection's token to API requests.
- Create tasks from a request, with an assignee, a due date, a project, and a section
- Move tasks between sections, change their fields, and mark them complete
- Comment on tasks, reply to comments, and upload files as attachments
- Create and update projects, sections, tags, portfolios, and goals
- List a project's open tasks and summarize its status and blockers
Agents act as the connected Asana user and can only see and change what that user can. The agent's API tool can only reach Asana's API at app.asana.com/api/1.0. Some admin endpoints, such as the audit log, organization exports, and workspace events, accept only a service account token. See Asana Personal Access Token.
Authentication
| Method | Type | Description |
|---|---|---|
| Asana Personal Access Token | API Key | A personal access token or a service account token from Asana |
| Your own Asana OAuth app | OAuth 2.0 | An app you create in the Asana developer console |
See Integration authentication for how credentials are stored and injected.
Asana Personal Access Token
Any Asana user can create a personal access token. On Enterprise plans, admins can limit which personal access tokens can connect to Asana.
- Open the Asana developer console.
- Click + Create new token, enter a Token name, and click Create token.
- Copy the token. Asana shows it only once.
- In Helios, choose Asana Personal Access Token and paste the token into Personal Access Token.
- Optional: for triggers, enter a project's ID in Project and a workspace's ID in Workspace. See Triggers.
- Save.
Personal access tokens are long-lived. If you delete the token in Asana, the connection stops working and Asana removes its webhooks. To change the token, create a new one, enter it through Manage, and save.
Asana records every change made with the token as the user who owns it, and the token reaches every project that user can see. A separate Asana user for Helios keeps the agent's changes apart from yours.
Service accounts. The Personal Access Token field also takes a service account token. Service accounts are an Enterprise feature, and only a super admin can create one, under Apps > Service Accounts in the admin console. A service account with Full Permissions reaches all data in the domain, and its scopes can add the audit log, organization exports, and workspace events APIs. Those three APIs also need an Enterprise+ plan, or Enterprise with the Compliance Management add-on for the audit log and workspace events. See Asana's authentication guide.
Your own Asana OAuth app
You need an Asana account in the workspace that will use the app. Any member can approve the app. In Enterprise organizations, admins can approve or block apps in the admin console. If yours does, an admin has to approve the app first.
-
In the developer console, click Create new app and create the app.
-
On the app's OAuth tab, add this redirect URL:
https://api.heliosapp.com/integrations/asana/oauth_callback -
On the same tab, under Permission scopes, turn on Full permissions and save.
-
On the Manage distribution tab, choose Specific workspace, click + Add workspace, and pick your workspace. Asana only lets users approve an app that is available in their workspace.
-
In Helios, choose Your own Asana OAuth app and enter the app's Client ID and Client Secret from its OAuth tab. Optional: for triggers, enter a project's ID in Project and a workspace's ID in Workspace.
-
Save, then approve access in Asana.
Helios asks for one scope:
| Scope | What it's for |
|---|---|
default | Full permissions for API endpoints available to the approving user. Admin endpoints still require a service account token |
An app with Full permissions on can't ask for specific scopes, and an app without it can't ask for default.
Asana has no admin scopes for OAuth apps, so this method has no Admin access option.
Access tokens last an hour, and Helios renews them with the refresh token Asana issues. If you reset the client secret in Asana, enter the new one in Helios through Manage and connect again.
Triggers
Asana can start a Workflow when something happens in a project or a workspace. Helios registers the webhooks when you save the connection, so there is nothing to set up in Asana. Deleting the connection removes them.
- Project is the ID of a project to watch, the number after
/project/in the project's URL. Helios registers a webhook on that project. It receives events on the project and on the tasks, comments, and sections in it, including subtasks. - Workspace is the ID of a workspace to watch, the number after
/1/in an Asana URL such ashttps://app.asana.com/1/1234567890/project/.... Helios registers a second webhook on the workspace. It receives project, portfolio, goal, and project template events from across the workspace, and team and workspace membership events.
Both are optional. Without Project, the task, comment, story, section, attachment, project member, and time tracking events are unavailable. Without Workspace, the project, project template, portfolio, goal, and membership events are unavailable, except project.changed, project.deleted, and project.undeleted for the watched project. The trigger picker shows unavailable events and the reason.
The connected user needs access to the project and must be a member of the workspace. If Asana refuses the webhook on the project or the workspace, Helios keeps the other webhook and marks the refused webhook's events unavailable, with Asana's reason.
| Event | Description | Filters |
|---|---|---|
task.added | A task was created or added to a project, section, tag or task | parent type, subtype |
task.changed | A task was changed | changed field, subtype |
task.removed | A task was removed from a project, section, tag or task | parent type, subtype |
task.deleted | A task was deleted | subtype |
task.undeleted | A deleted task was restored | subtype |
comment.added | A comment was added to a task | None |
comment.changed | A comment was edited | changed field |
comment.removed | A comment was deleted | None |
comment.undeleted | A deleted comment was restored | None |
story.added | Activity was recorded on a task | subtype |
story.removed | An activity record was removed | subtype |
story.undeleted | A removed activity record was restored | subtype |
section.added | A section was created | None |
section.changed | A section was changed | changed field |
section.deleted | A section was deleted | None |
section.undeleted | A deleted section was restored | None |
attachment.deleted | An attachment was deleted | None |
attachment.undeleted | A deleted attachment was restored | None |
project_membership.added | A member was added to the project | None |
project_membership.removed | A member was removed from the project | None |
time_tracking_entry.added | Time was logged on a task | None |
time_tracking_entry.changed | A time entry was changed | changed field |
time_tracking_entry.deleted | A time entry was deleted | None |
project.added | A project was created or added to a team or portfolio | parent type |
project.changed | A project was changed | changed field |
project.removed | A project was removed from a team or portfolio | parent type |
project.deleted | A project was deleted | None |
project.undeleted | A deleted project was restored | None |
project_template.added | A project template was created or added to a team | parent type |
project_template.changed | A project template was changed | changed field |
project_template.removed | A project template was removed from a team | parent type |
project_template.deleted | A project template was deleted | None |
project_template.undeleted | A deleted project template was restored | None |
portfolio.added | A portfolio was created or added to another portfolio | parent type |
portfolio.removed | A portfolio was removed from another portfolio | parent type |
portfolio.deleted | A portfolio was deleted | None |
goal.added | A goal was created or added to a parent goal | parent type |
goal.changed | A goal was changed | changed field |
goal.removed | A goal was removed from a parent goal | parent type |
goal.deleted | A goal was deleted | None |
goal.undeleted | A deleted goal was restored | None |
team_membership.added | A user was added to a team in the workspace | None |
team_membership.removed | A user was removed from a team in the workspace | None |
workspace_membership.added | A user was added to the workspace | None |
workspace_membership.removed | A user was removed from the workspace | None |
All filters are optional patterns, and case matters.
- Changed field matches the name of the field Asana reports as changed, such as
assignee,due_on,completed,name,notes, orcustom_fields. To start a run when a task is completed, usetask.changedwith Changed field set tocompleted. Events without a changed field don't match when it is set. - Subtype matches the subtype of the task or the activity. Tasks are
default_task,milestone, orapproval. Activity records name what happened, such asmarked_complete,assigned,due_date_changed, orsection_changed. - Parent type matches the kind of object the item was added to or removed from, such as
project,section,task, ortag. For example,task.addedwith Parent typesectionmatches a task moved into a section. Parent typeprojectalso matches a task in the watched project being added to another project.
Asana sends compact events that name the object by ID, so the agent reads the details through the API. For comments and activity records, the event's resource is the story Asana recorded, and its parent is the task. Only added and removed events have a parent.
Deliveries are verified with the HMAC-SHA256 X-Hook-Signature header, using the secret Asana sends when each webhook is created. Helios ignores events more than a day old.
Asana's delivery rules:
- Asana retries a failed delivery for up to 24 hours. After that, it deletes the webhook. It also deletes a webhook that doesn't answer its eight-hourly check for 24 hours. Save the connection again to register new webhooks.
- Asana delivers each event at most once, so in rare cases an event never arrives.
- If the token's user loses access to the project, the webhook stays but no events arrive.
- Events arrive in under a minute on average, and most arrive within 10 minutes.
An agent's own changes can start new runs. Editing or completing a task fires task.changed, and Asana usually records the change as activity that fires story.added. A comment or reply fires comment.added, and a task the agent creates or moves fires task.added. Asana can also send a task.changed event for each keystroke while someone edits a text field. Use the filters, or say in the prompt which events to ignore, such as comments the agent wrote. See Guarding against events you don't want.
Check that it works
- The connection: after you save, the connection's status shows Connected. Error means the connection test failed. Check the error details and see Common errors.
- A trigger:
- Add
task.addedto a workflow with no filters. - Create a test task in the watched project.
- Check that a run starts. Then open the connection in Helios and click Webhook events to see the event.
- Add
- The webhooks: to see the webhooks Helios registered, ask an agent to call
GET /webhookswith your workspace ID.
Common errors
| What you see | Cause | Fix |
|---|---|---|
| The connection's status shows Error | The token was deleted, or the OAuth app's access was removed | Create a new token and enter it through Manage, or connect the OAuth app again |
Enter the project ID, the number after /project/ in the project's URL | Project contains something other than digits | Enter only the number after /project/, or leave Project empty |
Enter the workspace ID, the number after /1/ in an Asana URL | Workspace contains something other than digits | Enter only the number after /1/, or leave Workspace empty |
forbidden_scopes on Asana's approval page | The app doesn't have Full permissions on | Turn on Full permissions under OAuth > Permission scopes, then connect again |
| Asana won't let you approve the app | The app isn't available in your workspace, or your admins manage which apps can connect | Add the workspace under Manage distribution, or ask an admin to approve the app, then connect again |
Access token not found. Please complete the OAuth flow first. | The OAuth approval wasn't finished | Open the connection and connect again |
| Events show as unavailable | Project or Workspace is empty, or Asana refused the webhook on it | Enter the missing ID. If Asana refused the webhook, check the ID and that the connected user can see the project or is a member of the workspace. Then save the connection again |
| No run starts after an event | Project or Workspace is empty or wrong, the connected user can't see the object, Asana deleted the webhook after failed deliveries, your plan doesn't include the feature, or the filters don't match | Fix the cause, then save the connection again so Helios registers new webhooks. Test with no filters |
429 Too Many Requests | The token went over Asana's rate limit | Wait for the time in the Retry-After header. See Limits |
Limits
- Rate limits: Asana allows 150 requests a minute per token in free domains, and 1,500 in paid domains. Each token can also run 50 read requests and 15 write requests at once, and search allows 60 requests a minute. A separate per-minute limit on computing cost can stop costly requests sooner, such as ones that fetch many related objects. See Asana's rate limits.
- Webhooks: Asana allows 1,000 webhooks on one object and 10,000 for one token. See Asana's webhook limits.
- Plans: Portfolios, goals, and time tracking need the Advanced plan or higher. Users with a view-only license have limited access to the API.
- Projects: each connection watches one project and one workspace for triggers. Agents can still work in every project the token can see.
Last updated on