← Back to docs

Microsoft To Do

Language: EN | EN | SV

Microsoft To Do

Tools now includes a personal Microsoft To Do integration for authenticated users.

What it does

  • Connects your Microsoft account to Tools through Microsoft OAuth.
  • Mirrors your Microsoft To Do lists into Tools.
  • Mirrors your Microsoft To Do tasks into Tools.
  • Pushes changes made in Tools back to Microsoft To Do.
  • Pulls remote changes from Microsoft To Do back into Tools.
  • Exposes authenticated JSON endpoints under /api/microsoft-todo/* for apps and other clients.

Web UI

  • Path: /settings/integrations/microsoft-todo
  • Auth: auth:web

From this page a user can:

  • connect their Microsoft account,
  • run a manual sync,
  • create, rename, and delete lists,
  • create, edit, complete, and delete tasks,
  • disconnect the local Microsoft To Do connection.

Configuration

The shared platform Azure app can now be handled in two ways:

  1. Environment-managed through MICROSOFT_TODO_* values, or
  2. database-backed platform app settings saved directly from /settings/integrations/microsoft-todo by an acknowledged admin.

Environment values still take precedence when they are present.

The page now shows a configuration diagnostics panel with:

  • whether the platform app is currently available,
  • whether it is managed via environment or database,
  • which required fields are still missing,
  • the effective redirect URI,
  • and the recommended callback URL for the current host.

When the platform app is not environment-managed, acknowledged admins can save/update the shared Microsoft To Do platform app directly from that page through an AJAX form. The client secret is never echoed back; the page only reports whether a secret is already stored.

Environment values remain:

MICROSOFT_TODO_TENANT=common
MICROSOFT_TODO_CLIENT_ID=
MICROSOFT_TODO_CLIENT_SECRET=
MICROSOFT_TODO_REDIRECT_URI=
MICROSOFT_TODO_DEFAULT_SCOPES="offline_access openid profile User.Read Tasks.ReadWrite"

The callback URL for the current environment is shown on the web page and is also available via the route:

  • /oauth/microsoft-todo/callback

OAuth routes

Start OAuth flow

  • Route name: oauth.microsoft_todo.start
  • Path: /oauth/microsoft-todo/start
  • Method: POST
  • Auth: auth:web

OAuth callback

  • Route name: oauth.microsoft_todo.callback
  • Path: /oauth/microsoft-todo/callback
  • Method: GET
  • Auth: auth:web

API endpoints

These endpoints accept either:

  • a normal logged-in web session, or
  • a JWT bearer token from POST /api/account/login.

GET /api/microsoft-todo/status

Returns connection state, account display name, local counts, and whether the platform app is available.

The response now also includes additive platform_app diagnostics with non-secret configuration metadata such as:

  • managed_via
  • env_managed
  • client_id_configured
  • client_secret_configured
  • tenant
  • redirect_uri
  • recommended_callback_url
  • default_scopes
  • missing_fields[]
  • status_message

Example response:

{
  "ok": true,
  "connected": true,
  "app_available": true,
  "connect_web_url": "/settings/integrations/microsoft-todo",
  "connection": {
    "status": "connected",
    "status_label": "Connected",
    "status_description": "Connected to Microsoft account \"user@example.com\".",
    "provider_account_name": "user@example.com",
    "expires_at": "2026-03-30T13:15:00+00:00",
    "last_connected_at": "2026-03-30T12:58:00+00:00"
  },
  "counts": {
    "lists": 4,
    "tasks": 22,
    "dirty_lists": 0,
    "dirty_tasks": 1
  }
}

POST /api/microsoft-todo/sync

Runs an immediate push/pull synchronization.

Example response:

{
  "ok": true,
  "message": "Microsoft To Do sync complete.",
  "sync": {
    "ok": true,
    "lists_pushed": 1,
    "tasks_pushed": 2,
    "lists_pulled": 4,
    "tasks_pulled": 22,
    "errors": []
  }
}

GET /api/microsoft-todo/lists

Returns local mirrored lists. By default tasks are included.

Optional query parameters:

  • include_tasks=1 (default)
  • include_tasks=0

POST /api/microsoft-todo/lists

Create a list and sync it to Microsoft To Do.

Request body:

{
  "display_name": "Work"
}

PATCH /api/microsoft-todo/lists/{listId}

Rename a synced list.

Request body:

{
  "display_name": "Work Projects"
}

DELETE /api/microsoft-todo/lists/{listId}

Delete the list both locally and remotely.

GET /api/microsoft-todo/lists/{listId}/tasks

Returns the tasks for one local mirrored list.

POST /api/microsoft-todo/lists/{listId}/tasks

Create a task in the given list.

Request body:

{
  "title": "Follow up with customer",
  "body_text": "Remember to attach the report.",
  "importance": "high",
  "status": "notStarted",
  "due_at": "2026-04-02 09:00:00",
  "reminder_at": "2026-04-02 08:30:00"
}

PATCH /api/microsoft-todo/tasks/{taskId}

Update a task.

Request body:

{
  "title": "Follow up with customer",
  "body_text": "Report sent, waiting for reply.",
  "importance": "normal",
  "status": "inProgress",
  "due_at": "2026-04-03 09:00:00",
  "reminder_at": null
}

DELETE /api/microsoft-todo/tasks/{taskId}

Delete a task both locally and remotely.

Sync behavior

The synchronization model is intentionally simple and predictable:

  1. Local dirty lists are pushed first.
  2. Local dirty tasks are pushed second.
  3. The remote Microsoft To Do snapshot is pulled back into Tools.
  4. Remote deletes are reflected locally when the local row is not dirty.
  5. Local dirty rows are not overwritten by the pull step.

A scheduled sync also runs automatically every 15 minutes through:

  • php artisan microsoft-todo:sync

Notes

  • The initial Microsoft OAuth connect flow currently starts from the web UI.
  • After a user is connected, mobile or other clients can use the authenticated /api/microsoft-todo/* endpoints.
  • If Microsoft token refresh fails, the user may need to reconnect from the web page.