Skip to Content

Asana

Sync data from your warehouse to Asana. Zeotap creates and updates tasks in your Asana projects, keeping your work management tool enriched with the latest customer, operational, or campaign data.

Prerequisites

  • An Asana account on a Workspace (or Organization) you have access to
  • An Asana project where tasks will be created or updated
  • A Personal Access Token (PAT) with permission to read the workspace and write to the target project

Permissions

The user who generates the Personal Access Token must have:

  • Comment access or higher on the target project to create and update tasks
  • Membership in the workspace that contains the project
  • Access to any assignees, tags, or custom fields referenced during the sync

Tasks created through the API are owned by the PAT’s user and are subject to that user’s visibility and permissions.

Authentication

Asana uses Personal Access Token (PAT) authentication. Each token is tied to a single user account and inherits that user’s permissions across workspaces.

Generating a Personal Access Token

  1. Log in to Asana
  2. Open the Asana Developer Console  (or Profile Photo > My Settings > Apps > Manage Developer Apps)
  3. Click Create new token
  4. Enter a descriptive label (e.g., “Zeotap Integration”)
  5. Review and accept the API terms
  6. Copy the generated token — it begins with 0/ or 1/ and is only shown once

Store the token securely. Anyone with the token can act on behalf of the user who created it.

Configuring in Zeotap

  1. Navigate to Destinations in the left sidebar
  2. Click Add Destination and select Asana
  3. Paste the Personal Access Token you generated above
  4. Enter the Project GID of the destination project
  5. Click Test Connection to verify

Configuration

FieldTypeRequiredDescription
Project GIDTextYesThe globally unique identifier of the Asana project where tasks will be created or updated. Only numeric digits are accepted.

Finding the Project GID

Open the project in Asana. The URL looks like:

https://app.asana.com/0/1234567890123456/list

The long numeric value after /0/ is the Project GID (1234567890123456 in the example above). You can also locate it via Project menu > Copy project link and extract the numeric segment.

Supported Operations

Sync Modes

ModeSupported
UpsertYes
InsertYes
UpdateYes
Mirror
  • Insert: Creates a new task in the configured project for every row in the sync.
  • Update: Updates existing tasks. Each row must include a task_gid field containing the Asana task GID.
  • Upsert: Rows with a non-empty task_gid are updated; rows without are created as new tasks in the configured project.

Audience Sync Modes

Asana does not support audience sync modes. Tasks are not membership-based entities, and Asana has no list/audience/segment API for adding or removing members.

Features

  • Field Mapping: Yes — map warehouse columns to Asana task fields
  • Schema Introspection: No — use the default field list or enter field names manually

Required Mapping Fields

FieldDescription
nameThe task title. Required for all new tasks.

Default Destination Fields

FieldTypeDescription
namestringTask title
notesstringTask description (plain text)
html_notesstringTask description with Asana-flavored HTML formatting
due_onstringDue date in YYYY-MM-DD format
due_atstringDue datetime in ISO 8601 format (e.g., 2025-12-31T17:00:00Z)
start_onstringStart date in YYYY-MM-DD format
assigneestringAssignee GID or email address
tagsstringComma-separated list of tag GIDs
completedstringWhether the task is completed (true/false)
custom_fieldsstringJSON object mapping custom field GIDs to values
task_gidstringTask GID used to address existing tasks for update/upsert

To find user GIDs, tag GIDs, and custom field GIDs, use the Asana API (/users, /workspaces/{gid}/tags, /projects/{gid}/custom_field_settings) or copy IDs from task URLs in the Asana UI.

How It Works

  1. Create operations send POST https://app.asana.com/api/1.0/tasks with a data object containing the mapped fields. The configured Project GID is automatically added to every create request through the projects array, so tasks always land in the correct project.

  2. Update operations send PUT https://app.asana.com/api/1.0/tasks/{task_gid} with the mapped fields. Only mapped fields are sent — unmapped fields remain unchanged on the task. The task_gid itself is used to address the task and is never written as a field.

  3. Upsert operations split rows based on whether task_gid is present and non-empty. Rows with a GID are updated; rows without are created as new tasks.

  4. Task creation is sequential. Asana does not offer a bulk create endpoint, so Zeotap issues one request per row. Throughput is gated by the API rate limit rather than by batch size.

  5. Field normalization happens automatically:

    • completed accepts booleans or the strings "true" / "false" (case-insensitive)
    • tags is split on commas and trimmed before being sent as an array
    • custom_fields must be a JSON object string; it is parsed and forwarded as-is
  6. Any unmapped row key is passed through directly to the Asana API. This means you can add support for additional Asana fields (such as parent, workspace, or resource_subtype) by mapping a column with the matching key.

Rate Limits

Asana enforces per-token rate limits to protect API stability:

  • Free workspaces are typically limited to 150 requests per minute
  • Premium, Business, and Enterprise workspaces generally see higher limits (around 1,500 requests per minute)
  • Per-endpoint limits may also apply for heavy endpoints like search

When a request hits a rate limit, Asana returns HTTP 429 Too Many Requests with a Retry-After header indicating the number of seconds to wait. The response body looks like:

{ "errors": [ { "message": "You've made too many requests and hit a rate limit. Please retry after the given amount of time." } ] }

Zeotap retries rate-limited requests automatically with exponential backoff. For large syncs, schedule them off-peak or split them across multiple runs to stay within your workspace quota.

Best Practices

  • Use upsert mode when keeping tasks in sync — include the Asana task_gid for rows that already have corresponding tasks.
  • Map task_gid in your model to enable updates. Without it, upsert mode treats every row as a new task and can create duplicates.
  • Use GIDs for assignee, tags, and custom field references. Display names and labels are not accepted by the Asana API — email addresses are only accepted for assignee.
  • Format dates correctly: due_on and start_on must be YYYY-MM-DD; due_at must be full ISO 8601 with a timezone.
  • Keep html_notes valid: Asana only accepts a subset of HTML (see the Asana Rich Text docs). Malformed HTML causes the whole task to fail.
  • Test on a sandbox project first to verify field mappings, custom field GIDs, and tag GIDs before pointing at a production project.
  • Scope the PAT to a dedicated integration user where possible so revoking or rotating the token does not affect a real team member.

Troubleshooting

Authentication failed: invalid personal access token

Verify the token has not been revoked from My Profile Settings > Apps > Manage Developer Apps. Personal Access Tokens are tied to a single user — if that user is deprovisioned from the workspace, the token stops working. Generate a new token and update the destination credentials.

Project not found — verify the project GID

The Project GID must contain only digits and correspond to a project the PAT user can access. Open the project in Asana, copy the numeric segment from the URL after /0/, and paste it into the configuration. If the user was recently added to the project, wait a few minutes for permissions to propagate.

Access denied to project

The authenticating user does not have at least comment-level access to the project. Either grant the PAT user access to the project in Asana, or move the integration to a user with the appropriate permissions.

Task creation fails with a validation error

Ensure name is mapped and non-empty — Asana rejects tasks without a title. Check that any due_on value is YYYY-MM-DD and any due_at value is ISO 8601. Custom field payloads must be a JSON object keyed by custom field GID (not label).

Assignee field rejected

assignee must be either a user GID or an email address of a user who belongs to the workspace. Display names are not accepted. If using email, the user must already be a member of the Asana workspace — Asana will not auto-invite new users through the API.

Tags not applying

Tag values must be GIDs, not tag names. Fetch them with GET /workspaces/{workspace_gid}/tags and store the mapping alongside your source data. Provide a comma-separated string (e.g., 1111,2222,3333) — Zeotap trims whitespace and splits on commas.

Custom fields not saving

Custom fields must be provided as a JSON object string mapping custom field GIDs to values (e.g., {"1234567890":"High","9876543210":42}). The GIDs must belong to a custom field that is enabled on the target project. Project-local custom fields cannot be written on tasks in other projects.

Rate limit errors (HTTP 429)

Zeotap retries automatically when Asana returns 429 with a Retry-After header. If rate limits persist, reduce sync concurrency, stagger sync schedules, or request higher limits from Asana support for Business/Enterprise workspaces.

Last updated on