Overview of Changes in Version 3 of the API

Important info! Version 2 of the Habitica API is now deprecated, so all open-source developers should switch over to version 3 of the API as soon as possible. To make this transition easier for our developers, we are still supporting API v2 for a few weeks, but we will be shutting it off in the near future. The sooner developers can migrate to the new API, the better! We will announce the date of the version 2 cutoff shortly, so stay tuned.

Server Responses


Just about every server responses will return a JSON object (exceptions for routes that return other data types, such as the csv export route). You can expect each response to include a success property with a Boolean value and a data property that is an Object or an Array which includes any relevant information back from the request. For instance, the GET /api/v3/tasks/user route would return data that looks like this:

  "success": true,
  "data": [
      id: 'the-task-id',
      type: 'habit',
      text: 'task text',
      notes: 'task notes',
      // more task properties
    // More task data

Some routes also include a message in the user's language. If your integration has a GUI, this can be helpful for presenting a confirmation message to the user that their action was a success.

  "success": true,
  "data": {
    // Some data
  "message": "A message in the user's language"


If the request returns an error, the success property will be false, and there will be an error property with the name of the error and a message property with some info about the failed request in the user's language.

  "success": false,
  "error": "NotFound",
  "message": "The task could not be found."

In the case of validation errors, there may also be an errors property which is an Array of error messages.

Changes to API v2

The backend code for API v2 had to be changed to cope with database structure changes. However, there should be no behavior changes, except that certain new fields will be in the data. If you notice any other changes, please report a bug.

The remainder of this post describes changes in API v3, except where otherwise indicated.

Changes to the User and Tasks

In version 2, tasks were stored directly on the user object. In version 3 of the API, tasks are their own collection. The user object now has a tasksOrder property which contains a list of IDs for each type of task and you can use this to determine what order the tasks should appear in.

Completed To-Dos do not appear in the tasksOrder lists (see "Completed To-Dos below").

Changes to Tasks

Task ID Uniqueness

In version 2, each user's tasks had unique IDs, but the same task ID could be used in tasks for other players. In version 3, all task IDs are unique across all players. See also "Task IDs have Changed" and "Changes to Challenge Tasks" below.

Task IDs have Changed

Because of the requirement for unique task IDs across all users, some of your task IDs may have changed. If your task ID was a valid UUID and was unique across all players, the ID remained the same. Otherwise, a newly generated unique ID replaced the original ID of the task. Update: This was our original plan, but we ended up just creating new uuid's for each task that was created.

For tasks with invalid IDs that existed before API v3 went live, the invalid old ID is stored in the _legacyId field, and this field is returned by both version 2 and version 3. This field will be removed when API v2 is decommissioned.

API v2 also returns the legacy ID in the id field so you do not need to immediately update any scripts or configuration files that have hard-coded IDs. However you will need to do that when API v2 is decommissioned.

The _legacyId field does not exist for tasks created after API v3 went live.

Custom IDs

In version 2, you could set a custom ID for the task (such as productivity). Because tasks are now their own collection, they must have a unique ID, so we've decided to drop this functionality.

When using version 2 of the API, you can still score tasks with a custom ID. When you fetch tasks with version 2, the custom ID will appear under the id property, but the database ID will be under the _id property. When using version 3, you can still specify a unique ID for your task when creating it, but it must be a valid UUID. If the ID already exists, the creation of the task will fail.

dateCreated / createdAt

We've changed the name of dateCreated to createdAt. (dateCompleted has not changed.)


Each task contains an updatedAt date field, initially equal to createdAt. It is updated when the task is edited or scored/completed/purchased, and when cron changes the task's value (cron does not affect that field for Habits that have both + and -).


Version 2 contained tag IDs as an Object. Version three contains tag IDs as an Array.

Completed To-Dos

In version 2, completed To-Dos were included when all tasks or all To-Dos were returned. In version 3, they are not returned when all tasks are requested with GET /api/v3/tasks/user or when all To-Dos are requested with GET /api/v3/tasks/user?type=todo.

Completed To-Dos can be returned using only GET /api/v3/tasks/user?type=completedTodos. They are returned in order of completion date, with the oldest first. They can not be sorted with /api/v3/tasks/:taskId/move/to/:position and do not appear in the tasksOrder lists.

Currently, only the 30 most recently completed To-Dos are returned. Soon there will be an option to return all completed To-Dos at once or an option to return all completed To-Dos in batches of 30.

Changes to Challenge Tasks

Challenge Task IDs

In version 2, when you joined a challenge, each task you were given had the same task ID as the copy in the parent challenge's document (i.e., all participants had a task with an identical ID). In version 3, task IDs are unique across all users, so when you join a challenge, each task you are given has a new ID.

The ID of the task from the parent challenge is stored in the challenge object as taskId, along with the id of the challenge itself.

  "success": true,
  "data": [
      id: 'unique-task-id',
      challenge: {
        'taskId': 'id-of-task-in-parent-challenge',
        'id': 'id-of-challenge'
      // more task properties
    // More task data


In version 2, challenges contained a members field with a list of user IDs. In version 3, they do not.

The user object contains a challenges field with an array of challenge IDs.

See also "Changes to Challenge Tasks" above.

Groups (Guilds and Parties)

In version 2, groups contained a members field with a list of user IDs. In version 3, they do not.

When a user is in a party, the user object contains a party._id field with the group ID of the user's party.

The user object contains a guilds field with an array of guild IDs.

Miscellaneous Changes

The transformation buff spookDust has been renamed to spookySparkles. All user accounts have been updated appropriately. This applies to API version 2 and 3. If you use spookDust as the skill key in the v2 route, it will still work.

The healer skill with the key heallAll has been corrected to healAll. If you use heallAll as the skill key in the v2 route, it will still work.

Miscellaneous Additions

Several new routes exist. See the API docs (available after the scheduled maintenance is over) for details.

Closing Remarks

We know these changes are significant, and that it will take some time to upgrade your integrations to be compatible, but we are very excited about the future features and integrations that we can develop using this improved API. If you have any questions, please feel free to reach out to us via the Aspiring Coders Guild and we will be happy to help.

Thank you so much for your patience, for your enthusiasm, and for being part of our open-source community. You all are the lifeblood of Habitica, and we're lucky to have you battling at our sides.