Stitchflow
Todoist logo

Todoist User Management API Guide

API workflow

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

UpdatedMar 16, 2026

Summary and recommendation

Todoist exposes two distinct API surfaces: REST v2 (`https://api.todoist.com/rest/v2`) for resource-level operations and Sync v9 (`https://api.todoist.com/sync/v9/sync`) for incremental state sync.

Both surfaces are strictly user-scoped - all operations execute in the context of the authenticated token holder.

There is no admin or service-account API for managing, listing, or deprovisioning other workspace members.

Auth is Bearer token via personal API token or OAuth 2.0;

personal tokens do not expire and OAuth tokens do not expire unless explicitly revoked via `POST /oauth/revoke_token`.

For identity graph construction, the available user-level fields are `id`, `email`, `full_name`, `is_premium`, `premium_until`, `team_inbox_id`, `timezone`, and `lang`.

Cross-user identity resolution is limited: the `/projects/{project_id}/collaborators` endpoint returns only `id`, `name`, and `email` per collaborator - not the full user object - and only for projects where `is_shared: true`.

There is no endpoint to enumerate all workspace members or retrieve an arbitrary user profile by ID.

API quick reference

Has user APIYes
Auth methodBearer token (personal API token or OAuth 2.0 access token)
Base URLOfficial docs
SCIM availableNo
SCIM plan requiredBusiness

Authentication

Auth method: Bearer token (personal API token or OAuth 2.0 access token)

Setup steps

  1. Personal token: Log in to Todoist → Settings → Integrations → Developer → copy the API token.
  2. OAuth 2.0: Register an application at https://developer.todoist.com/appconsole.html to obtain client_id and client_secret.
  3. OAuth flow: Redirect user to https://todoist.com/oauth/authorize with client_id, scope, and state parameters.
  4. Exchange the returned code at https://todoist.com/oauth/access_token for an access_token.
  5. Include the token in all requests as: Authorization: Bearer

Required scopes

Scope Description Required for
data:read Read-only access to all user data (tasks, projects, labels, etc.). Reading user profile and task data
data:read_write Read and write access to all user data. Creating, updating, and deleting tasks, projects, and user settings
data:delete Permission to delete user data. Deleting tasks, projects, and other resources
project:delete Permission to delete projects. Project deletion operations

User object / data model

Field Type Description On create On update Notes
id string Unique user identifier. system-assigned immutable Stable identifier across all API versions.
email string User's email address. required updatable Used as login credential.
full_name string User's display name. required updatable
avatar_big string (URL) URL to the large avatar image. system-assigned read-only via API Also available as avatar_medium, avatar_small, avatar_s640.
premium_until string (ISO 8601) | null Timestamp until which the user has premium access; null if free plan. system-assigned read-only
is_premium boolean Whether the user currently has a premium (Pro or Business) subscription. system-assigned read-only
inbox_project_id string ID of the user's Inbox project. system-assigned read-only
team_inbox_id string | null ID of the team inbox project if user belongs to a team. system-assigned read-only
lang string User's language setting (e.g., 'en'). optional updatable
timezone string User's timezone (e.g., 'America/New_York'). optional updatable
start_day integer Day the week starts for the user (1=Monday, 7=Sunday). optional updatable
next_week integer Day used as 'next week' in date shortcuts. optional updatable
date_format integer Date display format preference (0=DD-MM-YYYY, 1=MM-DD-YYYY). optional updatable
time_format integer Time display format (0=24h, 1=12h). optional updatable
sort_order integer Default task sort order preference. optional updatable
daily_goal integer User's daily task completion goal. optional updatable
weekly_goal integer User's weekly task completion goal. optional updatable
karma float User's Todoist Karma score. system-assigned read-only
karma_trend string Direction of karma trend ('up', 'down', or empty). system-assigned read-only
token string User's personal API token (only returned in Sync API user resource). system-assigned read-only Returned by Sync API; not exposed in REST API v2 user endpoint.

Core endpoints

Get current user

  • Method: GET
  • URL: https://api.todoist.com/rest/v2/user
  • Watch out for: Returns only the authenticated user's own profile. There is no admin endpoint to retrieve arbitrary users.

Request example

curl -X GET https://api.todoist.com/rest/v2/user \
  -H "Authorization: Bearer $TOKEN"

Response example

{
  "id": "2671355",
  "email": "user@example.com",
  "full_name": "Jane Doe",
  "is_premium": true,
  "timezone": "America/New_York",
  "karma": 12345.0
}

Update current user

  • Method: POST
  • URL: https://api.todoist.com/rest/v2/user/update
  • Watch out for: Uses POST, not PATCH. Only the authenticated user can update their own profile.

Request example

curl -X POST https://api.todoist.com/rest/v2/user/update \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"full_name": "Jane Smith", "lang": "en"}'

Response example

{
  "id": "2671355",
  "email": "user@example.com",
  "full_name": "Jane Smith",
  "lang": "en"
}

Get all projects

  • Method: GET
  • URL: https://api.todoist.com/rest/v2/projects
  • Watch out for: Returns projects visible to the authenticated user only; no cross-user project listing.

Request example

curl -X GET https://api.todoist.com/rest/v2/projects \
  -H "Authorization: Bearer $TOKEN"

Response example

[
  {
    "id": "220474322",
    "name": "Inbox",
    "is_shared": false,
    "is_team_inbox": false
  }
]

Get project collaborators

  • Method: GET
  • URL: https://api.todoist.com/rest/v2/projects/{project_id}/collaborators
  • Watch out for: Only returns collaborators for shared projects. Returns empty array for personal projects.

Request example

curl -X GET https://api.todoist.com/rest/v2/projects/220474322/collaborators \
  -H "Authorization: Bearer $TOKEN"

Response example

[
  {
    "id": "2671355",
    "name": "Jane Doe",
    "email": "user@example.com"
  }
]

Sync user data (Sync API)

  • Method: POST
  • URL: https://api.todoist.com/sync/v9/sync
  • Watch out for: Sync API returns the user's personal API token in the response. Use sync_token='*' for full sync; subsequent calls use the returned sync_token for incremental updates.

Request example

curl -X POST https://api.todoist.com/sync/v9/sync \
  -H "Authorization: Bearer $TOKEN" \
  -d 'sync_token=*&resource_types=["user"]'

Response example

{
  "sync_token": "VHJhbnNhY3Rpb24...",
  "user": {
    "id": "2671355",
    "email": "user@example.com",
    "token": "abc123..."
  }
}

Revoke OAuth access token

  • Method: POST
  • URL: https://todoist.com/oauth/revoke_token
  • Watch out for: Revokes the specified OAuth access token. Does not revoke the user's personal API token.

Request example

curl -X POST https://todoist.com/oauth/revoke_token \
  -d 'client_id=CLIENT_ID&client_secret=CLIENT_SECRET&access_token=TOKEN'

Response example

{}

Get tasks (for user activity auditing)

  • Method: GET
  • URL: https://api.todoist.com/rest/v2/tasks
  • Watch out for: Scoped to the authenticated user. No admin-level cross-user task listing is available via REST API.

Request example

curl -X GET "https://api.todoist.com/rest/v2/tasks?project_id=220474322" \
  -H "Authorization: Bearer $TOKEN"

Response example

[
  {
    "id": "2995104339",
    "content": "Buy milk",
    "creator_id": "2671355",
    "assignee_id": null
  }
]

Exchange OAuth authorization code for access token

  • Method: POST
  • URL: https://todoist.com/oauth/access_token
  • Watch out for: Authorization code is single-use and short-lived. The returned access_token does not expire unless explicitly revoked.

Request example

curl -X POST https://todoist.com/oauth/access_token \
  -d 'client_id=CLIENT_ID&client_secret=CLIENT_SECRET&code=AUTH_CODE'

Response example

{
  "access_token": "0123456789abcdef...",
  "token_type": "Bearer"
}

Rate limits, pagination, and events

  • Rate limits: Todoist enforces a rate limit of 1000 requests per 15-minute window per user token. Exceeding the limit returns HTTP 429.
  • Rate-limit headers: No
  • Retry-After header: No
  • Rate-limit notes: Official docs state the 1000/15-min limit. No explicit documentation of rate-limit response headers or Retry-After header behavior was found in current official docs.
  • Pagination method: cursor
  • Default page size: 0
  • Max page size: 0
  • Pagination pointer: cursor
Plan Limit Concurrent
All plans 1000 requests per 15 minutes per token 0
  • Webhooks available: Yes
  • Webhook notes: Todoist supports webhooks via the app console. Webhooks deliver event payloads via HTTP POST to a configured endpoint URL when specified events occur.
  • Alternative event strategy: Polling the Sync API with incremental sync_token is the alternative for detecting changes without webhooks.
  • Webhook events: item:added, item:updated, item:deleted, item:completed, item:uncompleted, note:added, note:updated, note:deleted, project:added, project:updated, project:deleted, project:archived, project:unarchived, label:added, label:updated, label:deleted, filter:added, filter:updated, filter:deleted, reminder:fired

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: Business
  • Endpoint: Not documented

Limitations:

  • Todoist does not offer a native SCIM 2.0 API endpoint.
  • SSO (SAML) is available on the Business plan via Okta and OneLogin, but automated user provisioning/deprovisioning via SCIM is not natively supported.
  • User provisioning must be handled manually or via third-party integration platforms (e.g., Okta SCIM connector if available through the IdP's app catalog).
  • Business plan is required for SSO; pricing increased in December 2025 to $10/user/mo (monthly) or $8/user/mo (annual).

Common scenarios

Three integration patterns are well-supported by the current API surface.

First, authenticated user profile retrieval: GET /rest/v2/user returns the full user object for the token holder;

parse id, email, full_name, is_premium, and timezone for downstream identity enrichment.

Second, collaborator enumeration across shared projects: chain GET /rest/v2/projects (filter on is_shared: true) with GET /rest/v2/projects/{project_id}/collaborators per shared project to build a partial identity graph of active collaborators;

note that returned objects are minimal (id, name, email only).

Third, OAuth 2.0 integration lifecycle: register at https://developer.todoist.com/appconsole.html, drive the standard authorization code flow to https://todoist.com/oauth/authorize, exchange at https://todoist.com/oauth/access_token, and revoke explicitly at https://todoist.com/oauth/revoke_token - validate the state parameter to prevent CSRF.

Rate limit is 1,000 requests per 15-minute window per token;

HTTP 429 is returned on breach, with no documented Retry-After header behavior.

Retrieve and display authenticated user profile

  1. Obtain a Bearer token (personal API token from Settings → Integrations, or OAuth 2.0 access token).
  2. GET https://api.todoist.com/rest/v2/user with Authorization: Bearer .
  3. Parse the returned JSON for id, email, full_name, is_premium, timezone, and karma fields.
  4. Display or store the profile data as needed.

Watch out for: Only the authenticated user's own profile is accessible. No endpoint exists to fetch another user's profile by ID.

List collaborators on a shared project

  1. Authenticate with a token that has data:read scope.
  2. GET https://api.todoist.com/rest/v2/projects to retrieve project IDs.
  3. Identify shared projects by checking is_shared: true in the response.
  4. GET https://api.todoist.com/rest/v2/projects/{project_id}/collaborators for each shared project.
  5. Collect collaborator objects (id, name, email) from the response array.

Watch out for: Returns an empty array for non-shared projects. Collaborator objects contain only id, name, and email - not the full user profile.

Implement OAuth 2.0 authorization for a third-party integration

  1. Register the application at https://developer.todoist.com/appconsole.html; obtain client_id and client_secret.
  2. Redirect the user to https://todoist.com/oauth/authorize?client_id=CLIENT_ID&scope=data:read_write&state=RANDOM_STATE.
  3. After user approves, receive the authorization code at the configured redirect_uri.
  4. POST to https://todoist.com/oauth/access_token with client_id, client_secret, and code to exchange for access_token.
  5. Store the access_token securely; include it as Authorization: Bearer in all subsequent API requests.
  6. To revoke access, POST to https://todoist.com/oauth/revoke_token with client_id, client_secret, and access_token.

Watch out for: OAuth access tokens do not expire automatically. Implement explicit revocation on user disconnect. The state parameter should be validated to prevent CSRF attacks.

Why building this yourself is a trap

The primary integration trap is assuming the REST API can support admin-level user management - it cannot. There is no endpoint to list workspace members, fetch another user's profile by ID, or programmatically remove a user from the workspace.

Developers building identity graph pipelines should expect collaborator coverage to be partial: only users who appear as collaborators on shared projects accessible to the token holder will surface, and only with minimal fields. SCIM 2.0 is not natively available; SSO via SAML (Okta, OneLogin) is Business-plan-only but does not include automated provisioning.

The Sync API (v9) and REST API (v2) have different base URLs and different response shapes, and the Sync API returns the user's personal API token in its response payload - a credential exposure risk if Sync API responses are logged or forwarded without scrubbing. OAuth scopes are coarse-grained (data:read, data:read_write, data:delete, project:delete);

there are no admin-scoped or user-management-scoped grants.

Automate Todoist 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

UpdatedMar 16, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

Abnormal Security logo

Abnormal Security

API Only
AutomationAPI only
Last updatedMar 2026

Abnormal Security is an enterprise email security platform focused on detecting and investigating threats such as phishing, account takeover (ATO), and vendor email compromise. It does not support SCIM provisioning, which means every app in your stack

ActiveCampaign logo

ActiveCampaign

API Only
AutomationAPI only
Last updatedFeb 2026

ActiveCampaign uses a group-based permission model: every user belongs to exactly one group, and all feature-area access (Contacts, Campaigns, Automations, Deals, Reports, Templates) is configured at the group level, not per individual. The default Adm

ADP logo

ADP

API Only
AutomationAPI only
Last updatedFeb 2026

ADP Workforce Now is a mid-market to enterprise HCM platform that serves as the HR source of record for employee data — payroll, benefits, time, and talent. User access is governed by a hybrid permission model: predefined security roles (Security Maste