Skip to main content

Todos via the API

Create, list, modify and delete a user's to-do list items with Web API v3

Written by Marie Xhauflair

The Todos endpoints allow listing, creation, modification and deletion of a user's to-do list items. A todo can be attached to either a module or a journey.

Part of Web API v3 for user management. You need a token with the v3:todos:read or v3:todos:write scope, see Authenticating with the Web API v3.

🚧 Be careful

Creating a todo does not make the module or journey available to the user. If they do not already have access through an automation, a group membership or a programme, they will not see the todo until they gain access. Arrange content availability separately through automations.


Listing todos

List todos using the /api/v3/public/todos/ GET endpoint. You can filter on user_uuid, module_uuid, journey_uuid, completed, is_mandatory and due_date.

Field

Description

uuid

Uniquely identifies a todo. Read-only.

user_uuid

The uuid of the user this todo is for.

data

Describes what the todo is attached to, for example {"type": "module", "uuid": "..."} or {"type": "journey", "uuid": "..."}. A journey must be a top-level journey, sections can not be selected.

is_mandatory

Indicates whether the user is required to complete this item.

due_date

An optional date by which the todo should be completed.

completed_at

Set automatically once the user completes the module or journey the todo is attached to, or immediately if they had already completed it before the todo was created. Read-only.

created_at

The date-time the todo was created. Read-only.


Creating todos

With a POST request to /api/v3/public/todos/ you can add a todo for a user, specifying user_uuid and data, and optionally is_mandatory and due_date.

👀 Good to know

If the user already has an open todo for the same user_uuid and data, that existing todo is returned instead of a duplicate being created. Repeating the same request is safe.


Bulk creating todos

POST a user_uuid and a list of items to /api/v3/public/todos/bulk/ to create multiple todos for one user in a single request, for example to assign a set of modules from an external system at once.

Each item accepts the same fields as a single todo: data, is_mandatory and due_date.

As with single creation, items for which the user already has an open todo are skipped rather than duplicated.

🚧 Be careful

If any item in the list is invalid, the whole request is rejected and nothing is created.


Modifying todos

With a PUT or PATCH request to /api/v3/public/todos/<uuid>/ you can modify is_mandatory and due_date. The PUT requires all writable fields to be included, while the PATCH only updates provided fields.

data and user_uuid can not be changed after creation. If the user or the attachment needs to change, delete the todo and create a new one.


Deleting todos

Send a DELETE to /api/v3/public/todos/<uuid>/ to remove a todo.

Mandatory todos can be deleted through this endpoint, unlike in the learner-facing interface.


Limitations

  • Only module and journey todos can be created or modified through this API. A journey must be a top-level journey, sections can not be selected.

  • Other todo types that exist internally, such as a periodic learning feedback survey nudge or a skill nudge, may still appear when listing a user's todos, but can not be created through this API.

  • Creating a todo does not grant the user access to the module or journey it points to. This must be arranged separately, for example through an automation.


Example

This continues from the Python example in Web API v3 for user management, reusing the same token and headers from the login step. Extend the scope requested at login to include v3:todos:read v3:todos:write.

# create a todo for the first user, attached to a module
payload = {
    "user_uuid": first_user["uuid"],
    "data": {"type": "module", "uuid": "<<module uuid>>"},
}
response = requests.post(f"{base_url}/api/v3/public/todos/",
    json=payload, headers=headers).json()
print("Created todo", response["uuid"], "for", first_user["first_name"])
Did this answer your question?