Stitchflow
Asana logo

Asana User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedFeb 27, 2026

Summary and recommendation

Asana's REST API (base URL: `https://app.asana.com/api/1.0`) supports OAuth 2.0 and Personal Access Tokens for auth. The `default` scope covers all standard user read/write operations. List endpoints return compact objects by default - always append `?opt_fields=name,email` or required fields will be silently omitted.

Pagination uses an opaque offset token, not page numbers; follow `next_page.offset` in each response until `next_page` is null. Rate limits are 150 req/min on free plans and 1,500 req/min on Starter through Enterprise+; HTTP 429 responses include a `Retry-After` header - implement exponential backoff.

For teams managing Asana alongside a broader identity stack, Stitchflow's MCP server with ~100 deep IT/identity integrations handles cross-app user lifecycle orchestration without requiring custom glue code per integration.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 or Personal Access Token (PAT)
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredEnterprise

Authentication

Auth method: OAuth 2.0 or Personal Access Token (PAT)

Setup steps

  1. Register an application at https://app.asana.com/0/developer-console to obtain a client_id and client_secret.
  2. For OAuth 2.0: redirect users to https://app.asana.com/-/oauth_authorize with response_type=code, client_id, redirect_uri, and scope.
  3. Exchange the returned authorization code for an access token at https://app.asana.com/-/oauth_token.
  4. For PAT: generate a token in My Profile Settings > Apps > Manage Developer Apps and pass it as a Bearer token in the Authorization header.
  5. Include the token in all requests: Authorization: Bearer {token}.

Required scopes

Scope Description Required for
default Grants access to all standard API endpoints on behalf of the user, including reading and writing tasks, projects, and user data. All general API operations including user reads
openid OpenID Connect scope for identity verification. OIDC-based authentication flows
email Access to the authenticated user's email address. Retrieving user email via OIDC
profile Access to the authenticated user's name and profile photo. Retrieving user profile info via OIDC

User object / data model

Field Type Description On create On update Notes
gid string Globally unique identifier for the user. system-generated immutable Use this as the primary key for all user references.
resource_type string Always 'user' for user objects. system-generated immutable
name string Full name of the user. required updatable Read-only via REST API for other users; users can update their own name.
email string Primary email address of the user. required read-only via REST Email changes must be done by the user or via SCIM.
photo object Map of photo sizes (image_21x21, image_27x27, image_36x36, image_60x60, image_128x128) to URLs. optional updatable
workspaces array List of workspace/organization objects the user belongs to. system-managed managed via membership endpoints Each entry contains gid, name, resource_type.
teams array Teams the user is a member of (returned via team membership endpoints). managed via team endpoints managed via team endpoints Not returned on the base user object; requires separate call.

Core endpoints

Get current user

  • Method: GET
  • URL: https://app.asana.com/api/1.0/users/me
  • Watch out for: Returns data for the authenticated token's user only. Requires no additional scopes beyond 'default'.

Request example

GET /api/1.0/users/me
Authorization: Bearer {token}

Response example

{
  "data": {
    "gid": "12345",
    "resource_type": "user",
    "name": "Jane Doe",
    "email": "jane@example.com"
  }
}

Get a user by GID

  • Method: GET
  • URL: https://app.asana.com/api/1.0/users/{user_gid}
  • Watch out for: You can also use the user's email address as the {user_gid} path parameter.

Request example

GET /api/1.0/users/12345
Authorization: Bearer {token}

Response example

{
  "data": {
    "gid": "12345",
    "name": "Jane Doe",
    "email": "jane@example.com",
    "workspaces": [{"gid": "99", "name": "Acme Corp"}]
  }
}

List users in a workspace

  • Method: GET
  • URL: https://app.asana.com/api/1.0/workspaces/{workspace_gid}/users
  • Watch out for: Returns compact user objects by default. Use ?opt_fields=email,name,photo to expand fields.

Request example

GET /api/1.0/workspaces/99/users?limit=50
Authorization: Bearer {token}

Response example

{
  "data": [
    {"gid": "12345", "name": "Jane Doe", "resource_type": "user"}
  ],
  "next_page": {"offset": "abc123", "path": "/workspaces/99/users?offset=abc123"}
}

List users in a team

  • Method: GET
  • URL: https://app.asana.com/api/1.0/teams/{team_gid}/users
  • Watch out for: Team GID must be known in advance; use GET /organizations/{org_gid}/teams to list teams first.

Request example

GET /api/1.0/teams/77/users
Authorization: Bearer {token}

Response example

{
  "data": [
    {"gid": "12345", "name": "Jane Doe", "resource_type": "user"}
  ]
}

Add user to a team

  • Method: POST
  • URL: https://app.asana.com/api/1.0/teams/{team_gid}/addUser
  • Watch out for: User must already be a member of the workspace/organization. Adding to a team does not add to the workspace.

Request example

POST /api/1.0/teams/77/addUser
Content-Type: application/json

{"data": {"user": "12345"}}

Response example

{
  "data": {
    "gid": "12345",
    "name": "Jane Doe",
    "resource_type": "user"
  }
}

Remove user from a team

  • Method: POST
  • URL: https://app.asana.com/api/1.0/teams/{team_gid}/removeUser
  • Watch out for: Returns an empty data object on success. Does not remove the user from the workspace.

Request example

POST /api/1.0/teams/77/removeUser
Content-Type: application/json

{"data": {"user": "12345"}}

Response example

{
  "data": {}
}

Add user to a workspace

  • Method: POST
  • URL: https://app.asana.com/api/1.0/workspaces/{workspace_gid}/addUser
  • Watch out for: For organizations (not free workspaces), this sends an invitation email. The user is not fully provisioned until they accept.

Request example

POST /api/1.0/workspaces/99/addUser
Content-Type: application/json

{"data": {"user": "jane@example.com"}}

Response example

{
  "data": {
    "gid": "12345",
    "name": "Jane Doe",
    "email": "jane@example.com"
  }
}

Remove user from a workspace

  • Method: POST
  • URL: https://app.asana.com/api/1.0/workspaces/{workspace_gid}/removeUser
  • Watch out for: This deactivates the user from the workspace. Tasks assigned to them remain but become unassigned or stay assigned depending on workspace settings.

Request example

POST /api/1.0/workspaces/99/removeUser
Content-Type: application/json

{"data": {"user": "12345"}}

Response example

{
  "data": {}
}

Rate limits, pagination, and events

  • Rate limits: Asana enforces rate limits per API key/token. The standard limit is 1,500 requests per minute for most plans. Premium/Business/Enterprise may have higher limits. Concurrent request limits also apply.
  • Rate-limit headers: Yes
  • Retry-After header: Yes
  • Rate-limit notes: When rate limited, Asana returns HTTP 429. The Retry-After header indicates when to retry. Response headers include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.
  • Pagination method: offset
  • Default page size: 20
  • Max page size: 100
  • Pagination pointer: offset
Plan Limit Concurrent
Free / Personal 150 requests/minute 0
Starter / Advanced 1500 requests/minute 0
Enterprise / Enterprise+ 1500 requests/minute (higher limits available on request) 0
  • Webhooks available: Yes
  • Webhook notes: Asana supports webhooks for resource-level events. Webhooks can be registered on workspaces, projects, tasks, and other resources. User-related events (e.g., membership changes) can be captured via workspace-level webhooks.
  • Alternative event strategy: Poll GET /workspaces/{workspace_gid}/users periodically if webhooks are not feasible.
  • Webhook events: user.added_to_workspace, user.removed_from_workspace, user.added_to_team, user.removed_from_team, task.assigned, task.unassigned

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Enterprise

  • Endpoint: https://app.asana.com/api/1.0/scim/v2

  • Supported operations: GET /Users – list users, GET /Users/{id} – get user by SCIM ID, POST /Users – provision new user, PUT /Users/{id} – replace user attributes, PATCH /Users/{id} – update user attributes, DELETE /Users/{id} – deprovision user, GET /Groups – list groups (teams), POST /Groups – create group, PATCH /Groups/{id} – update group membership, DELETE /Groups/{id} – delete group

Limitations:

  • Requires Enterprise or Enterprise+ plan.
  • SAML SSO must be configured as a prerequisite.
  • Supported IdPs include Okta, Microsoft Entra ID (Azure AD), Google Workspace, and OneLogin.
  • SCIM provisioning manages workspace membership; team membership is managed via Groups.
  • User deprovisioning via SCIM deactivates the user but does not delete their data.
  • Custom attribute mapping is limited to standard SCIM schema attributes.

Common scenarios

Three scenarios cover the majority of programmatic user management needs:

List all workspace users with email: GET /workspaces/{workspace_gid}/users?opt_fields=name,email&limit=100 - paginate via next_page.offset until exhausted. Without opt_fields=email, email is not returned.

Deprovision a departing employee (REST only): POST /workspaces/{workspace_gid}/removeUser with the user's GID. This deactivates the user but does not delete data or reassign tasks - follow up with PATCH /tasks/{task_gid} to set a new assignee GID on open work items.

Provision via SCIM (Enterprise only): Configure your IdP against https://app.asana.com/api/1.0/scim/v2. The IdP sends POST /scim/v2/Users with userName, name.givenName, name.familyName, and active=true. Note: the user must accept an invitation email before they appear as active in REST API workspace user lists - SCIM provisioning and REST API visibility are not synchronous.

Provision a new employee into Asana via SCIM

  1. Ensure Enterprise plan is active and SAML SSO is configured.
  2. Configure your IdP (e.g., Okta) with Asana's SCIM endpoint: https://app.asana.com/api/1.0/scim/v2.
  3. Assign the user to the Asana application in your IdP.
  4. IdP sends POST /scim/v2/Users with userName (email), name.givenName, name.familyName, and active=true.
  5. Asana provisions the user into the organization; user receives an invitation email.
  6. Optionally assign the user to a SCIM Group (team) via PATCH /scim/v2/Groups/{team_gid}.

Watch out for: The user must accept the invitation before they appear as active in workspace user lists via the REST API.

List all users in a workspace with email addresses

  1. Obtain a PAT or OAuth token with 'default' scope.
  2. Call GET /api/1.0/workspaces to retrieve the workspace GID.
  3. Call GET /api/1.0/workspaces/{workspace_gid}/users?opt_fields=name,email&limit=100.
  4. Check response for next_page.offset; if present, repeat with ?offset={offset_token} until next_page is null.
  5. Collect all user objects across pages.

Watch out for: Without ?opt_fields=email, the email field is not returned in compact responses.

Deprovision a departing employee

  1. If using SCIM: deactivate or unassign the user in your IdP; IdP sends PATCH /scim/v2/Users/{id} with active=false or DELETE /scim/v2/Users/{id}.
  2. If using REST API only: call POST /api/1.0/workspaces/{workspace_gid}/removeUser with the user's GID.
  3. Verify the user no longer appears in GET /api/1.0/workspaces/{workspace_gid}/users.
  4. Reassign open tasks if needed using PATCH /api/1.0/tasks/{task_gid} with assignee set to another user's GID.

Watch out for: Removing a user from the workspace does not delete their data. Tasks remain and must be manually reassigned or handled via automation.

Why building this yourself is a trap

The REST API cannot create net-new users from scratch; POST /workspaces/{workspace_gid}/addUser sends an invitation email, and the user is not fully active until they accept. This makes fully automated, zero-touch provisioning impossible via REST alone - SCIM is required for that, and SCIM requires Enterprise plus a pre-configured SAML SSO setup.

A second trap: user email addresses cannot be updated via the REST API; use PATCH /scim/v2/Users/{id} for email changes. Finally, removing a user from a team (POST /teams/{team_gid}/removeUser) does not remove them from the workspace - workspace-level deprovisioning is a separate call and the only action that revokes access.

Automate Asana workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedFeb 27, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen