Microsoft To Do ExecModule
Overview
MicrosoftToDoModule connects ValkyrAI workflows to Microsoft Graph v1.0. It uses the native map I/O ExecModule ABI, appears in the annotation-backed Workflow Studio catalog as MicrosoftToDoModule, and resolves OAuth credentials only from an IntegrationAccount.
The connector implements the complete list, task, and linked-resource behavior represented by n8n's built-in Microsoft To Do node:
- task lists:
list_lists,get_list,create_list,update_list,delete_list - tasks:
list_tasks,get_task,create_task,update_task,delete_task - linked resources:
list_linked_resources,get_linked_resource,create_linked_resource,update_linked_resource,delete_linked_resource
The Microsoft Graph origin, OAuth token, allowed payload fields, retry boundary, and response limits cannot be overridden by mapped workflow input.
Usage
- Register or select a Microsoft Entra application that can call Microsoft Graph.
- Grant the minimum delegated or application task scopes needed by the workflow.
- Store the current OAuth access token in a Microsoft To Do
IntegrationAccountSecureField and keep the account inREADYstatus. - Add
MicrosoftToDoModuleto a workflow and bind the account throughExecModuleConfig.authConfig.integrationAccount. - Set
operationand the operation-specific fields in module configuration or map them from upstream workflow state.
Leave userId blank for delegated /me operations. Set an authorized user object ID or user principal name only when the token can operate through /users/{id}. Linked-resource writes require delegated task write access; Microsoft Graph does not support application permissions for that API family.
Inputs
| Name | Type | Required for | Default | Constraints |
|---|---|---|---|---|
operation | string | Every execution | None | One of the 15 documented operations. |
userId | string | Optional explicit-user access | /me | Opaque object ID or UPN; no path, query, fragment, or control characters. |
listId | string | List read/update/delete and every task operation | None | Opaque Graph task-list ID, at most 2,048 characters. |
taskId | string | Task read/update/delete and every linked-resource operation | None | Opaque Graph task ID. |
linkedResourceId | string | Linked-resource read/update/delete | None | Opaque Graph linked-resource ID. |
displayName | string | List create/update and linked-resource create | None | 1–255 characters. |
title | string | Task create; optional task update | None | 1–255 characters. |
bodyContent | string | Optional task create/update | None | Up to 64 KiB; an explicitly empty update clears the body. |
bodyContentType | string | When body is supplied | text | text or html. |
importance | string | Optional task create/update | Provider default | low, normal, or high. |
taskStatus | string | Optional task create/update | Provider default | notStarted, inProgress, completed, waitingOnOthers, or deferred. |
categories | array | Optional task create/update | Provider default | Up to 25 non-empty strings, each at most 255 characters. |
dueDateTime / startDateTime / reminderDateTime | string | Optional task scheduling | None | ISO-8601 date-time; an explicitly empty update clears that field. |
dueTimeZone / startTimeZone / reminderTimeZone | string | Corresponding non-empty date-time | UTC | Windows or IANA label, at most 255 characters. |
isReminderOn | boolean | Optional task create/update | Provider default | Automatically true when a reminder date is supplied unless explicitly set. |
applicationName | string | Linked-resource create; optional update | None | 1–255 characters. |
externalId | string | Linked-resource create; optional update | None | Partner-system ID, at most 2,048 characters. |
webUrl | string | Linked-resource create; optional update | None | HTTPS URL without credentials or fragment, at most 4,096 characters. |
etag | string | Optional update/delete concurrency | None | Sent as If-Match; at most 1,024 characters. |
cursor | string | Optional list resume point | None | Opaque token: continuation returned by this module. |
limit | integer | List operations | 100 | 1–10,000 total returned items. |
returnAll | boolean | List operations | false | Follows provider pages until exhaustion or limit. |
confirmDelete | boolean | Every delete operation | false | Must be true because provider deletion is permanent. |
Outputs
Every execution returns stable status, operation, and attempts fields.
| Name | Type | When present | Description |
|---|---|---|---|
status | string | Always | success or error. |
operation | string | Always | Normalized operation name. |
attempts | integer | Always | Provider HTTP attempts, including paginated reads. |
httpStatus | integer | Provider response received | Last Microsoft Graph HTTP status. |
data | object | Single-resource, mutation, or deletion success | Provider object or a stable {deleted, id} receipt. |
id | string | Single-resource or deletion success | Provider resource identifier. |
etag | string | Provider returns @odata.etag | Concurrency value for a later update or delete. |
items | array | List success | Bounded list, task, or linked-resource objects. |
count | integer | List success | Number of returned items. |
hasMore | boolean | List success | Whether Graph returned another supported continuation. |
nextCursor | string | Another page exists | Opaque continuation for a later execution. |
requestId | string | Graph supplies one | Bounded provider request reference for support. |
error | object | Failure | Safe {code, message, httpStatus?, retryable} details. |
OAuth tokens are never returned. Provider errors are bounded and redacted through the shared workflow sensitive-data policy.
IntegrationAccount Requirements
| Setting | Requirement |
|---|---|
| Provider | Microsoft To Do / Microsoft Graph |
| Auth mechanism | OAuth 2.0 bearer access token |
accountName | Human-readable Microsoft account or tenant label |
apiKey | Preferred encrypted SecureField containing the access token |
password | Legacy token fallback only; prefer apiKey |
status | Must be READY; all other states fail closed |
Use the least-privilege scopes applicable to the selected operations:
- delegated reads:
Tasks.Read - delegated creates, updates, deletes, and linked-resource operations:
Tasks.ReadWrite - application reads through
userId:Tasks.Read.All - application writes: only where the current Microsoft Graph operation explicitly supports the applicable application task permission
See Microsoft Graph To Do permissions. Never place tokens in parameters, mapped workflow input, examples, logs, or outputs. Use the platform OAuth refresh flow to rotate expired access tokens.
Configuration
Module-specific fields belong in ExecModulePayloadConfig.parameters; retries and timeouts use existing normalized configuration groups.
{
"version": "1.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:microsoft-todo-primary"
},
"retryPolicy": {
"maxAttempts": 3,
"backoffStrategy": "EXPONENTIAL",
"initialDelayMs": 1000,
"maxDelayMs": 60000,
"jitter": false
},
"executionConfig": {
"timeoutMs": 30000
},
"payloadConfig": {
"parameters": "{\"operation\":\"list_tasks\",\"listId\":\"list-1\",\"limit\":100}"
}
}
The relationship value is illustrative. Persisted workflows bind the generated IntegrationAccount relationship, never a plaintext token.
Operations
| Operation | Provider behavior | Side effect and retry behavior |
|---|---|---|
list_lists | Lists task lists for /me or an authorized explicit user. | Read-only; retries transient failures and supports opaque pagination. |
get_list | Reads one task list. | Read-only; retries and verifies a returned ID when present. |
create_list | Creates a list with a bounded display name. | Write; single attempt. |
update_list | Renames one task list and optionally sends If-Match. | Write; single attempt. |
delete_list | Permanently deletes one task list. | Irreversible; requires confirmation; single attempt. |
list_tasks | Lists tasks in one list. | Read-only; retries and paginates. |
get_task | Reads one task. | Read-only; retries and verifies returned identity. |
create_task | Creates a typed task with optional body, categories, schedule, reminder, importance, and status. | Write; single attempt. |
update_task | Patches only supplied typed task fields and optionally sends If-Match. | Write; requires at least one field; single attempt. |
delete_task | Permanently deletes one task. | Irreversible; requires confirmation; single attempt. |
list_linked_resources | Lists partner resources associated with a task. | Read-only; retries and paginates. |
get_linked_resource | Reads one linked resource. | Read-only; retries and verifies identity. |
create_linked_resource | Attaches an HTTPS partner resource to a task. | Write; single attempt; delegated permission required. |
update_linked_resource | Patches supplied partner metadata. | Write; requires at least one field; single attempt. |
delete_linked_resource | Permanently removes one association. | Irreversible; requires confirmation; single attempt. |
Errors and Failure Modes
| Code | Typical cause | Retryable | Resolution |
|---|---|---|---|
VALIDATION_ERROR | Missing or invalid ID, payload, schedule, cursor, URL, etag, or delete confirmation. | No | Correct inputs; no unsafe request was sent. |
UNSUPPORTED_OPERATION | Unknown operation. | No | Select a documented operation. |
INTEGRATION_ACCOUNT_REQUIRED | No account is bound. | No | Bind a Microsoft To Do IntegrationAccount. |
INTEGRATION_ACCOUNT_NOT_READY | Account status is not READY. | No | Reconnect or repair the account. |
MICROSOFT_TODO_HTTP_401 | OAuth token is expired or invalid. | No | Refresh the token. |
MICROSOFT_TODO_HTTP_403 | Required scope, user access, or linked-resource permission is absent. | No | Grant least privilege or choose an accessible principal. |
MICROSOFT_TODO_HTTP_404 | List, task, linked-resource, or user ID is wrong or invisible. | No | Verify resource IDs and principal. |
MICROSOFT_TODO_HTTP_409 / 412 | Stale etag or provider write conflict. | No | Read current state, reconcile, and intentionally retry. |
MICROSOFT_TODO_HTTP_429 | Graph throttling. | Yes for reads | Honor provider guidance and retry later. |
RESPONSE_TOO_LARGE | Response exceeded 5 MiB. | No | Lower limit or narrow the workflow. |
NETWORK_ERROR | DNS, TLS, timeout, or connectivity failure. | Yes for reads | Verify connectivity and retry. |
INVALID_PROVIDER_RESPONSE | Graph returned a collection without value[]. | No | Capture request ID and check API compatibility. |
Example
Create an approved customer follow-up task:
{
"operation": "create_task",
"listId": "customer-success-list",
"title": "Follow up with Acme",
"bodyContent": "Review the signed proposal and confirm onboarding dates.",
"bodyContentType": "text",
"importance": "high",
"categories": ["Sales", "Approved"],
"dueDateTime": "2026-08-20T09:00:00-07:00",
"dueTimeZone": "America/Los_Angeles",
"reminderDateTime": "2026-08-20T08:30:00-07:00",
"reminderTimeZone": "America/Los_Angeles"
}
Expected result shape:
{
"status": "success",
"operation": "create_task",
"attempts": 1,
"httpStatus": 201,
"id": "task-9",
"etag": "provider-etag",
"data": {
"id": "task-9",
"title": "Follow up with Acme",
"importance": "high"
}
}
Notes
- Pagination: list operations request at most 100 items per Graph page.
returnAll=truefollows only provider continuations whose opaque$skiptokencan be extracted; requests are rebuilt against the fixed Graph origin and hard-capped at 10,000 results. - Rate limits: GET operations retry HTTP 408, 429, and 5xx responses according to the normalized retry configuration and bounded
Retry-After. Creates, updates, and deletes are never automatically retried. - API limits: the module covers Graph task lists, tasks, and linked resources. It does not implement Outlook flagged-email tasks, checklist items, file attachments, delta queries, subscriptions, batch requests, or provider-specific recurrence builders.
- Idempotency: provider creates do not accept a caller-controlled idempotency key. After a timeout, list/read and reconcile by immutable provider IDs or stable business fields before replaying.
- Concurrency:
etagis optional because Graph support differs by operation; when supplied for update/delete it is sent asIf-Match. A 409 or 412 requires read-and-reconcile handling. - Destructive behavior: all three delete operations are permanent, require
confirmDelete=true, and use one provider attempt. - Application permissions:
/users/{id}supports authorized application access for applicable Graph task operations. Linked-resource operations remain delegated-only according to the current Microsoft contract. - External verification: local tests use a deterministic mock Graph server. Live Microsoft behavior remains unverified until an authorized Microsoft To Do credential is supplied.
- Functional reference: n8n's current built-in Microsoft To Do node supports list, task, and linked-resource create/get/get-all/update/delete flows, OAuth Graph credentials, explicit-user app access, and opaque pagination. ValkyrAI adds bounded payloads and responses, fixed-host continuation rebuilding, provider identity checks, explicit destructive confirmation, concurrency headers, redaction, and read-only retry boundaries.