Skip to main content

Todoist ExecModule

Overview

TodoistModule connects ValkyrAI workflows to Todoist API v1 through the native map I/O ExecModule ABI. Workflow Studio discovers it as TodoistModule; API and OAuth access tokens are resolved only from an encrypted IntegrationAccount.

This release provides project, collaborator, section, task, and comment operations:

  • list_projects, get_project, list_collaborators, list_sections
  • list_tasks, get_task, create_task, update_task
  • close_task, reopen_task, delete_task
  • list_comments, add_comment

List operations follow Todoist's opaque cursor pagination. Provider errors are bounded and redacted. Only reads are eligible for automatic retry; creates, updates, close/reopen actions, comments, and deletion run once so an ambiguous timeout cannot repeat a mutation.

Usage

  1. Create a dedicated Todoist automation identity or OAuth application.
  2. Grant only the project and task access needed by the workflow.
  3. Store the Todoist API token or OAuth access token in the encrypted apiKey field of an IntegrationAccount.
  4. Bind that account through ExecModuleConfig.authConfig.integrationAccount.
  5. Add TodoistModule to a workflow, select an operation, and use IDs returned by discovery operations.

Workflow inputs can provide resource IDs, task fields, filters, pagination controls, and explicit destructive confirmation. They cannot provide credentials or redirect requests away from Todoist's trusted API endpoint.

Inputs

NameTypeRequirementDefaultDescriptionConstraints
operationstringRequiredNoneOperation to execute.One of the thirteen operations above.
projectIdstringOperation-specificNoneTodoist project ID.Required for project reads/collaborators; optional task, section, and comment scope.
sectionIdstringOptionalNoneTodoist section ID.Filters tasks or assigns a created task.
taskIdstringOperation-specificNoneTodoist task ID.Required for task reads/updates/close/reopen/delete and task comments.
parentIdstringOptionalNoneParent task ID.Filters subtasks or assigns a created task.
contentstringRequired for createNoneTask title/content.1–500 characters for creation.
descriptionstringOptionalNonePlain-text task description.Maximum 16,384 characters.
taskobject or JSON stringOptionalNoneAdditional Todoist task fields.256 KiB cap; allowlisted fields only.
labelsarray or JSON stringOptionalNoneTask label names.At most 100 bounded strings.
priorityintegerOptionalOmittedTodoist priority.1–4.
dueStringstringOptionalNoneNatural-language due expression.Maximum 1,024 characters.
dueDatedateOptionalNoneDue date.YYYY-MM-DD.
dueDatetimetimestampOptionalNoneDue timestamp.ISO 8601 with an offset.
labelstringOptionalNoneTask-list label filter.Maximum 255 characters.
commentTextstringRequired for commentNonePlain-text task or project comment.1–15,000 characters.
cursorstringOptionalNoneOpaque continuation token.Maximum 4,096 characters.
limitintegerOptional50Maximum returned items.1–10,000; provider page size is at most 200.
returnAllbooleanOptionalfalseContinue until exhaustion.Safety-capped at 10,000 items.
requestIdstringOptionalNoneCaller correlation/idempotency key.Maximum 128 characters; sent as X-Request-Id.
confirmDeletebooleanRequired for deletionfalsePermanent-delete acknowledgement.Must be true before delete_task sends a request.

The task object accepts only content, description, project_id, section_id, parent_id, order, labels, priority, assignee_id, due_string, due_date, due_datetime, due_lang, duration, duration_unit, and deadline_date. Typed inputs override matching fields. Only one due selector may be present.

Outputs

NameTypeWhen presentDescription
statusstringAlwayssuccess or error.
operationstringAlwaysNormalized operation name.
attemptsintegerAlwaysTotal Todoist HTTP attempts across all pages.
httpStatusintegerProvider response receivedLast HTTP status.
dataobjectSingle-resource/mutation successResource or empty object for 204 responses.
id / urlstringResource response includes itConvenience resource fields.
items / countarray / integerList successReturned resources and count.
hasMore / nextCursorboolean / stringList successContinuation state and opaque cursor.
requestIdstringProvider supplies oneProvider trace/correlation reference.
errorobjectFailureSafe {code, message, httpStatus?, retryable} details.

Tokens and authorization headers never enter outputs. Provider messages pass through the shared workflow sensitive-data policy.

IntegrationAccount Requirements

SettingAPI token or OAuth requirement
ProviderTodoist or Todoist OAuth 2.0
AuthenticationAuthorization: Bearer <token>
accountNameHuman-readable automation identity label
apiKeyPreferred encrypted SecureField containing the token
passwordLegacy token fallback only; prefer apiKey
statusready or unset legacy status; closed and error fail closed

An API token acts with its owning user's permissions. Prefer a dedicated automation identity and explicitly shared projects. Use data:read for read-only OAuth workflows and data:read_write for task/comment mutations. Token refresh happens before execution; workflow payloads cannot replace credentials.

Configuration

{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:todoist-release-ops"
},
"retryPolicy": {
"maxAttempts": 3,
"backoffStrategy": "EXPONENTIAL",
"initialDelayMs": 1000,
"maxDelayMs": 60000,
"jitter": false
},
"executionConfig": {"timeoutMs": 30000},
"payloadConfig": {
"parameters": "{\"operation\":\"list_tasks\",\"projectId\":\"6XGgm6PHrGgMpCFX\",\"label\":\"next_action\",\"limit\":50}"
}
}

The integration account value is symbolic. Persisted workflows use the generated relationship, never a plaintext token.

Operations

OperationTodoist behaviorSide effect
list_projects / get_projectLists active projects or reads one project.Read-only; safe retries.
list_collaboratorsLists project collaborators.Read-only; safe retries.
list_sectionsLists sections, optionally by project.Read-only; safe retries.
list_tasks / get_taskLists filtered active tasks or reads one task.Read-only; safe retries.
create_taskCreates a bounded task.New task; single attempt.
update_taskUpdates explicitly supplied fields.Mutation; single attempt.
close_task / reopen_taskCompletes or restores a task.Reversible mutation; single attempt.
delete_taskPermanently deletes a task.Irreversible; confirmation required.
list_commentsLists one task's or project's comments.Read-only; safe retries.
add_commentCreates one task or project comment.New comment; single attempt.

Errors and Failure Modes

CodeTypical causeRetryableResolution
VALIDATION_ERRORMissing ID/content, invalid date/JSON, unsupported field, ambiguous comment scope, empty update, or absent confirmation.NoCorrect the input; no unsafe request was sent.
UNSUPPORTED_OPERATIONUnknown operation.NoSelect a documented operation.
INTEGRATION_ACCOUNT_REQUIREDNo account bound.NoBind a Todoist IntegrationAccount.
INTEGRATION_ACCOUNT_NOT_READYAccount status is closed/error.NoRepair or reconnect the account.
TODOIST_HTTP_400Invalid field or provider validation.NoCorrect the request using the bounded message.
TODOIST_HTTP_401 / 403Invalid token, scope, or shared-project access.NoRotate/refresh credentials or grant minimum access.
TODOIST_HTTP_404ID is wrong, completed, archived, or hidden.NoRe-run discovery under the same account.
TODOIST_HTTP_429 / 5xxRate limit or transient failure.Yes for readsHonor Retry-After; reconcile writes before retry.
NETWORK_ERRORTimeout, DNS, TLS, or connectivity failure.Yes for readsVerify connectivity and inspect writes before retry.
RESPONSE_TOO_LARGEResponse exceeded 5 MiB.NoNarrow filters or lower the limit.
INVALID_PROVIDER_RESPONSEPaginated response lacked results.NoUse requestId and verify API compatibility.

Example

{
"operation": "create_task",
"projectId": "6XGgm6PHrGgMpCFX",
"sectionId": "6fFPHV272WWh3gpW",
"content": "Verify public Todoist ExecModule launch",
"description": "Confirm documentation, article, image, and public READ grants.",
"labels": ["execmodule", "release"],
"priority": 4,
"dueDate": "2026-08-14",
"requestId": "todoist-launch-verification-20260807"
}

Expected result:

{
"status": "success",
"operation": "create_task",
"attempts": 1,
"httpStatus": 200,
"id": "6XGgmFVcrG5RRjVr",
"data": {
"id": "6XGgmFVcrG5RRjVr",
"content": "Verify public Todoist ExecModule launch",
"priority": 4
}
}

Notes

  • Pagination: list operations request at most 200 items per page and stop at limit, provider exhaustion, or 10,000 items. Reuse nextCursor only with identical filters.
  • Rate limits: reads retry HTTP 408, 429, 500, 502, 503, and 504 per policy and Retry-After. Mutations never retry automatically.
  • API limits: Todoist applies a 1 MiB POST-body limit and plan-specific limits. The module caps structured tasks at 256 KiB and responses at 5 MiB.
  • Idempotency: writes are single-attempt. Supply a durable requestId and reconcile state before repeating an ambiguous write.
  • Consistency: a created or reopened task may take time to appear in every filtered view. Use its returned ID immediately.
  • Destructive behavior: delete_task is permanent and requires confirmDelete=true. Prefer close_task for reversible completion.
  • Authentication: bearer tokens remain in IntegrationAccount SecureFields and are redacted from errors and outputs.
  • External verification: request construction, cursor pagination, validation, redaction, retry safety, and metadata discovery are tested locally. Live service permissions require a real Todoist account and are deferred.
  • Deferred operations: project/section mutations, filter queries, completed-task history, labels, reminders, attachments, activity logs, triggers, OAuth refresh, and arbitrary raw requests.
  • Functional reference: n8n's Todoist integration demonstrates agent-oriented project and task automation; this module implements its highest-value semantics through ValkyrAI's secure native ABI against Todoist API v1.