Skip to content

Microsoft To-Do

Manage Microsoft To-Do tasks and task lists via the Graph API — CRUD, due-date lookahead, and cleanup of completed tasks.


Tasks & Task Lists

Manage tasks

Microsoft To-Do — manage task lists, tasks, and checklist items.

# Task lists
lists = client.me.todo.lists.get().execute_query()

# Create a task list
task_list = client.me.todo.lists.add("Demo").execute_query()

# Add a task with a due date and importance
task = task_list.tasks.add(
    title="Write docs",
    due_date_time=datetime.now(timezone.utc) + timedelta(days=3),
    importance=Importance.high,
).execute_query()

# Mark it completed
task.status = TaskStatus.completed
task.update().execute_query()

List task lists

List all task lists with their task counts.

lists = client.me.todo.lists.get().execute_query()
for lst in lists:
    tasks = lst.tasks.get().execute_query()
    print(f"{lst.display_name}  ({len(tasks)} tasks)")

Tasks due soon

Find tasks due within a specified number of days.

cutoff = (datetime.now(timezone.utc) + timedelta(days=7)).strftime("%Y-%m-%dT%H:%M:%SZ")

for lst in client.me.todo.lists.get().execute_query():
    for task in lst.tasks.filter(f"dueDateTime/dateTime le '{cutoff}'").get().execute_query():
        print(f"[{lst.display_name}]  {task.title}  due={task.due_date_time}")

Clean up completed tasks

Delete completed tasks older than a specified number of days.

cutoff = datetime.now(timezone.utc) - timedelta(days=30)

for lst in client.me.todo.lists.get().execute_query():
    for task in lst.tasks.get().execute_query():
        if task.status == TaskStatus.completed and task.last_modified_date_time < cutoff:
            print(f"[{lst.display_name}]  {task.title}")
            task.delete_object().execute_query()

Attach a file

Attach a file to a task — small files are posted directly, larger ones use an upload session with chunked uploads.

task = client.me.todo.lists[list_id].tasks[task_id].get().execute_query()
attachment = task.upload_attachment("./report.pdf", progress=lambda p: print(p.done, p.total))
print(attachment.name, attachment.size)