-
Notifications
You must be signed in to change notification settings - Fork 1
Marvin Data Types
When you access or modify the data from your database, you can use the following documentation to know what the fields mean.
/**
* @typedef {Object} Task
* @property {String} _id - The task's unique ID. For tasks generated from recurring tasks, this is of the form `${date}-${id}` where date is YYYY-MM-DD and id is the recurring task's id.
* @property {String} title - The task's title, like "Go to market".
* @property {String} parentId - ID of parent project or category, or "unassigned".
* @property {String} dueDate - When this project should be completed, formatted as "YYYY-MM-DD". Or null if no dueDate.
* @property {String} startDate - When this task can be started, formatted as "YYYY-MM-DD". Or null if no start date.
* @property {String} endDate - When this task should be completed (soft deadline), formatted as "YYYY-MM-DD". Or null if no end date.
* @property {String} day - Which day the task is scheduled, in the format "YYYY-MM-DD", or "unassigned". Guaranteed to be "YYYY-MM-DD" if the task is done.
* @property {String} firstScheduled - Which day the task was first assigned to, formatted as "YYYY-MM-DD" or "unassigned" if it was never scheduled yet. Used to calculate how many !!! in procrastination strategy.
* @property {String} plannedWeek - Which week the task is planned for. Date of the Monday of the ISO week (Mon-Sun) formatted as "YYYY-MM-DD"
* @property {String} plannedMonth - Which month the task is planned for. "YYYY-MM"
* @property {String} sprintId - The task's sprint, null if nothing
* @property {Number} rank - The task's sort order in the day view.
* @property {Number} masterRank - The task's sort order within the master list. Having two ranks is necessary since scheduled tasks are shown in the master list, just grayed out. And completed tasks within a project are shown crossed out.
* @property {Boolean} done - True if this task has been completed.
* @property {Number|null} completedAt - Date.now() when this task was completed.
* @property {Number} duration - How long the user worked on this task (in ms). As of 1.18.0, only set when the task is done.
* @property {Number[]} times - Array of Date.now() when time tracking started (odd indexes) and stopped (even indexes). Updated when time tracking stops and when the task is marked done (or when manually edited by user).
* @property {Number} firstTracked - When this task was first tracked (Date.now()).
* @property {Number} doneAt - When this task was completed (Date.now()).
* @property {Boolean} isReward - True if this task is a reward task.
* @property {Boolean} isStarred - Used for priorities strategy. 3=red, 2=orange, 1=yellow (or true from old version).
* @property {Boolean} isFrogged - True if this task has been frogged for eatThatFrog. 1=normal, 2=baby, 3=monster.
* @property {Boolean} isPinned - Whether this task has been pinned to the master list. In other words, scheduling it will just schedule a copy, and this task will remain in the master list.
* @property {String} pinId - The pinned task that this task was copied from.
* @property {Boolean} recurring - True if this task was generated via a recurring task.
* @property {String} recurringTaskId - The recurring task that generated this task.
* @property {Boolean} echo - True if this is an "echo" task (from RecurringTask type="echo").
* @property {String} echoId - ID of task used to create this task (from RecurringTask type="echo").
* @property {String} link - System-created tasks can have links, i.e. to "/braindump". This is in the link target.
* @property {Object.<String,Subtask>} subtasks - ID => Subtask.
* @property {String} colorBar - One of null, "red", "yellow", "green" or "blue". No longer used.
* @property {String[]} labelIds - The IDs of labels assigned to the task. Any labelId that doesn't correspond to an existing label in strategySettings.labels should be ignored.
* @property {Number} timeEstimate - How long the user thinks the task will take, in ms.
* @property {String} note - Task note for "notes" strategy.
* @property {String} email - Email HTML used to create note via "email" strategy.
* @property {String} dailySection - Section used in dailyStructure.
* @property {String} bonusSection - Section used in bonusStructure.
* @property {String} customSection - Section used in customStructure.
* @property {String} timeBlockSection - Section used in plannerStructure.
* @property {Object.<String,Boolean>} dependsOn - ID => true. Task and project IDs of items that have to be completed before this item can be worked on.
* @property {Boolean} backburner - Tasks created in the backburner are given this property if they don't get the backburner status from their parent. Tasks can also be in the backburner due to a label, dependency, start date, or inheritance without having backburner=true.
* @property {String} reviewDate - Date when user wants to review a task, formatted as "YYYY-MM-DD".
* @property {Number} itemSnoozeTime - Date.now() until when task is snoozed. While snoozed the task is hidden everywhere except the master list.
* @property {String} permaSnoozeTime - Time (HH:mm) until when task is snoozed (NOT cleared on reschedule).
* @property {String} calId - ID (from Marvin) of calendar this task has been created from / assigned to.
* @property {String} calURL - Unique URL of this task in the calendar.
* @property {String} etag - Calendar etag to determine when an update is needed.
* @property {String} calData - Calendar data. This string is modified and sent to server to update when tasks in Marvin change.
* @property {Number} marvinPoints - How many kudos you got for this task.
* @property {String[]} mpNotes - Notes on how Marvin awarded you kudos when you completed the task.
* NEW REMINDER FORMAT
* @property {String} taskTime - "HH:mm" time extracted from title
* @property {Number} reminderOffset - Reminder offset, either manually set or taken from default at reminder creation.
* @property {String} reminderTime - The unix timestamp (seconds) of the first reminder (i.e. before any snoozes), computed with taskTime and reminderOffset (or defaultOffset)
* @property {Number} snooze - Snooze duration, either manually set or taken from default at reminder creation.
* @property {Number} autoSnooze - Whether to autoSnooze, either manually set or taken from default at reminder creation.
*
* OLD REMINDER FORMAT
* @property {String} remindAt - Time when user should be reminded, "YYYY-MM-DD HH:mm".
* @property {Object} reminder - How remindAt was chosen, so that if the task is renamed, the reminder can be updated.
* @property {String} reminder.time - Event time that was used to create the event.
* @property {Number} reminder.diff - Number of ms before reminder.time when remindAt is scheduled.
*/Subtasks live directly within the Task document in an Object where the key is the ID of the Subtask, and its value is an Object with the following shape:
/**
* @typedef {Object} Subtask
* @property {String} _id - The subtask's unique ID, which is the same as the key in the task's "subtasks" object.
* @property {String} title - The subtask title, like "Carrots".
* @property {Boolean} done - Whether the subtask is complete.
* @property {Number} rank - Rank within parent task.
* @property {Number} timeEstimate - Subtasks can have their own duration estimates.
*
* Reminders as in Tasks (see above).
*/Example Task JSON with Subtasks
{
"createdAt": 1612975446890,
"db": "Tasks",
"title": "Example task",
"parentId": "unassigned",
"day": "2021-02-10",
"subtasks": {
"3JTpZf4WnWvrK": {
"_id": "3JTpZf4WnWvrK",
"title": "Subtask 1",
"done": false,
"rank": 1
},
"eM93my8kteDMw": {
"_id": "eM93my8kteDMw",
"title": "Subtask 2",
"done": false,
"rank": 2
}
},
"_id": "dKG245maqNRkn58Z9SyT",
"_rev": "7-f2f224e38fd775ab49774cad0455559a"
}Marvin has infinite nesting of categories and projects. Main categories have parentId="root", and nested categories/projects have parentId equal to the _id of their parent. This storage format makes cycles and orphans a possibility, and Marvin does its best to gracefully handle these cases. If you restart Marvin then you will find orphans in your Inbox. Any orphan/cycle problems you inadvertantly create can be fixed by following this guide.
The Inbox doesn't live inside the couchdb. Tasks and Projects that live inside the Inbox have parentId="unassigned".
/**
* @typedef {Object} Task
* @property {String} _id
* @property {String} title - The category/project's title, like "Work".
* @property {String} type - Either "project" or "category".
* @property {Number} updatedAt - Date.now() when updated. This includes adding a task.
* @property {Number} workedOnAt - Date.now() when last worked on. That means completing a task within it.
* @property {String} parentId - ID of parent project or category, or "unassigned" or "root".
* @property {Number} rank - Sort rank within parent.
* @property {Number} dayRank - Sort rank within day.
* @property {String} day - Schedule date or null/undefined. Only projects can be scheduled. This might also be "unassigned", so check for both. See https://github.com/amazingmarvin/MarvinAPI/issues/11
* @property {String} firstScheduled - Which day the project was first assigned to, formatted as "YYYY-MM-DD" or "unassigned" if it was never scheduled yet. Used to calculate how many !!! in procrastination strategy.
* @property {String} dueDate - Date when project is due, formatted as "YYYY-MM-DD".
* @property {Number} timeEstimate - How long the user thinks the project will take, in ms. When shown in Marvin this is added to the child tasks' time estimates.
* @property {String} startDate - When this task can be started, formatted as "YYYY-MM-DD".
* @property {String} endDate - When this task should be completed (soft deadline), formatted as "YYYY-MM-DD".
* @property {String} plannedWeek - Which week the task is planned for. Date of the Monday of the week (Mon-Sun) "YYYY-MM-DD"
* @property {String} plannedMonth - Which month the task is planned for. "YYYY-MM"
* @property {String} sprintId - The project's sprint. Not used yet.
* @property {Boolean} done - Whether the project has been marked as done.
* @property {String} doneDate - If done, then this was the date the project/subproject (previously called milestone) was finished.
* @property {String} priority - Project only: one of "low", "mid", or "high". Used when priorities strategy is enabled. Why not isStarred like tasks? These used to be different strategies.
* @property {String} color - Color chosen by clicking icon in master list "#222222" (rrggbb).
* @property {String} icon - Icon chosen by clicking icon in master list.
* @property {String} note - note for "notes" strategy.
* @property {Boolean} recurring - True if it's a recurring project.
* @property {String} recurringTaskId - ID of RecurringTask creator.
* @property {Boolean} echo - True if created by RecurringTask with type="echo".
* @property {Boolean} isFrogged - True if this project has been frogged for eatThatFrog. 1=normal, 2=baby, 3=monster.
* @property {String} reviewDate - Date when user wants to review a project.
* @property {Number} marvinPoints - How many kudos you got for this project. Always 500.
* @property {String[]} mpNotes - Notes on how Marvin awarded you kudos when you completed the project. Always ["PROJECT"].
*/- Warning! This will probably change in the future. Click for current documentation.
The IDs of MIPs are stored in profile.MIP:
GET /api/doc?id=MIP
=>
[
"afh310hf12f213",
"f1n02nksaljfi0",
]Notes:
- Each string in this array is a project ID
- This document might be missing if no MIPs have been added yet.
- This document may contain completed project IDs, which are no longer considered MIPs within Marvin
- In the future this document will be ignored and
project.mip=trueorproject.isMip=trueor something like that.
/**
* @typedef {Object} Label
* @property {String} _id - Unique ID like "qoq4xtw653fGv", used in task.labelIds array
* @property {String} title - Label name like "quick"
* @property {String} groupId - ID of label group (see below)
* @property {Number} createdAt - Date.now() when created, like 1595057624899
* @property {String} color - Label color, like "#29224a"
* @property {String} icon - Label icon, like "inbox"
* @property {String} showAs - One of "text", "icon", or "both".
* @property {Boolean} isAction - If true, then this is an action label. Removing the label creates a task.
* @property {Boolean} isHidden - If true, then this label won't show in task/project metadata. Still useful for smart lists, etc.
*//**
* @typedef {Object} LabelGroup
* @property {String} _id - Unique ID like "qoq4xtw653fGv", used in label.groupId
* @property {String} title - Group name like "Example group"
* @property {Number} rank - Like 1, order within label organizer
* @property {Number} createdAt - Date.now() when created, like 1595057624899
* @property {Boolean} isExclusive - If true, then a task/project can only have one label from this group at a time
* @property {String} color - Label color, like "#29224a"
* @property {String} icon - Label icon, like "inbox"
* @property {Boolean} isMenu - No longer used. Use hover button strategy settings instead.
*/The master for time tracking data is the account database at serv.amazingmarvin.com, not the couchdb database. But this data is cached in task.times (in the couchdb database) whenever you stop time tracking or mark the task done.
/**
* @property {Number[]} task.times - Array of Date.now() when time tracking started (odd indexes) and stopped (even indexes). Updated when time tracking stops and when the task is marked done (or when manually edited by user).
*/Basically the current unix timestamp (in milliseconds) is appended to this array whenever you start and stop time tracking. So if an odd number of numbers are in the array, this should be the task you are currently tracking. If you add up the difference between each consecutive pair of numbers, you should get the total time track duration of the task, in milliseconds.
Timers don't live in Marvin's database, just in its app state. But knowing the structure may help you if you are using Marvin's timer webhooks.
/**
* A timer starts with elapsed=0 and progress=0 and runs up to elapsed=duration
* and progress=1.
*
* @typedef {Object} Timer
* @property {Number} elapsed - Number of milliseconds that have elapsed so far.
* @property {Number} progress - Timer progress between 0 and 1.
* @property {Number} duration - Total timer duration in milliseconds.
* @property {String} taskId - The ID of the task this timer is linked to. This can happen when there's a time in the task's title, like "30m" and you click on it.
* @property {Number} beepCount - How many times this task should beep.
* @property {Boolean} done - Set to true when the timer has finished.
*//**
* A tomato timer starts with elapsed=0, progress=0, and isWork=true. Once
* elapsed runs up to workDuration and progress up to 1, then elapsed and
* progress are both set to 0 and isWork is set to false.
*
* @typedef {Object} TomatoTimer
* @property {Number} elapsed - How long into the current work or break cycle the timer is, in milliseconds.
* @property {Number} progress - Timer progress between 0 and 1.
* @property {Number} workDuration - How long the work session is, in milliseconds.
* @property {Number} breakDuration - How long the break is, in milliseconds.
* @property {Number} cycle - For repeating timers. This is 0 the first session, then 1, etc.
* @property {Number} repeat - The total number of repeat cycles configured.
* @property {Number} beepCount - How many times this task should beep.
* @property {Boolean} isWork - Set to true during the work session, then false during the break session.
* @property {Boolean} done - Set to true when the work session and break are both completed. If repeat, then only set to true when ALL work sessions and breaks are completed.
*/The following values are possible in the mpNotes array and describe how Marvin awarded you kudos when completing the task/project.
{
SLOW_DOWN: { type: "Slow Down!", reason: "You hit the point cap for today. Save some for the rest of us! Try adding time estimates or tracking time if you do lots of small tasks." },
HIGH_WEIGHT: { type: "Good One", reason: "Great task!", modifierType: 1 },
DREADED: { type: "Congrats", reason: `You did something you dreaded.`, modifierType: 1 },
IMPORTANT: { type: "Congrats", reason: `You did something important.`, modifierType: 1 },
COMBO: { type: "Combo", reason: "Multiple tasks completed today.", modifierType: 1 },
STREAK: { type: "Streak", reason: `Tasks completed multiple days in a row!`, modifierType: 1 },
NO_PROC: { type: "Impressive", reason: "You didn't procrastinate :).", modifierType: 1 },
PROC: { type: "Oops", reason: "You procrastinated :(.", modifierType: -1 },
WAY_EARLY: { type: "Great", reason: "You completed the task way early!", modifierType: 1 },
EARLY: { type: "Great", reason: "You completed the task early!", modifierType: 1 },
ON_TIME: { type: "Great", reason: "You met the deadline.", modifierType: 1 },
MISSED_DEADLINE: { type: "Oops", reason: "You missed the deadline.", modifierType: -1 },
SOFT_ON_TIME: { type: "Great", reason: "You met the soft deadline.", modifierType: 1 },
MISSED_SOFT: { type: "Oops", reason: "You missed the soft deadline.", modifierType: 1 },
SHORT: { type: "Short", reason: "Nice and quick.", modifierType: 0 },
LONG: { type: "Long", reason: "That was a long one.", modifierType: 0 },
DOUBLE: { type: "Wow", reason: "Marvin smiles! 2x kudos!", modifierType: 1 },
TRIPLE: { type: "Wow!", reason: "Marvin winks! 3x kudos!", modifierType: 1 },
BONUS: { type: "Bonus", reason: "Marvin gave you 500 bonus kudos! Good tasks are most likely to get a bonus.", modifierType: 1 },
FROG_BONUS: { type: "Bonus", reason: "Marvin gave you 500 bonus kudos for eating the frog first!", modifierType: 1 },
PROJECT: { type: "Project", reason: "500 kudos for completing a project.", modifierType: 0 },
}Some basic profile information is available at the /api/me endpoint (see Marvin API#Me)
type Profile struct {
UserId int64 `json:"userId,string"` // Your user ID, encoded as a string (since it may be more than 53 bits).
Email string `json:"email"` // Your signup email.
ParentEmail string `json:"parentEmail"` // It's possible your account is linked with another for payment. If so this field is that account's email address.
EmailConfirmed bool `json:"emailConfirmed"` // True if you confirmed your email address
BillingPeriod string `json:"billingPeriod"` // One of "TRIAL", "MONTH", "YEAR", "ONCE", or "PAID"
PaidThrough time.Time `json:"paidThrough"` // Account paid through this date.
IosSub bool `json:"iosSub"` // True if you have a linked ios Sub
MarvinPoints int `json:"marvinPoints"` // Total Marvin kudos
NextMultiplier int `json:"nextMultiplier"` // If you complete a task, the next task might be worth more.
RewardPointsEarned float64 `json:"rewardPointsEarned"` // Total rewardPoints earned by this user
RewardPointsSpent float64 `json:"rewardPointsSpent"` // Total rewardPoints spent by this user
RewardPointsEarnedToday float64 `json:"rewardPointsEarnedToday"` // Points earned today; based on Date provided by user when claiming/spending
RewardPointsSpentToday float64 `json:"rewardPointsSpentToday"` // Points spent today; based on Date provided by user when claiming/spending
RewardPointsLastDate string `json:"rewardPointsLastDate"` // Date like "2020-08-25"; changes when the user claims/spends points; used to figure out whether RewardPointsEarned/SpentToday still valid
Tomatoes int `json:"tomatoes"` // Lifetime work timers completed
TomatoesToday int `json:"tomatoesToday"` // Work timers completed today. Check tomatoDate to see if it's actually still today.
TomatoTime int64 `json:"tomatoTime"` // Lifetime tomato work time (in ms)
TomatoTimeToday int64 `json:"tomatoTimeToday"` // Work time (in ms) today. Check tomatoDate to see if it's actually still today.
TomatoDate string `json:"tomatoDate"` // Date like "2020-09-29". Changes when the user adds a tomato.
DefaultSnooze int `json:"defaultSnooze"` // Default snooze duration, in minutes. 0=use default of 5 minutes
DefaultAutoSnooze bool `json:"defaultAutoSnooze"` // Whether to autoSnooze by default. Defaults to false.
DefaultOffset int `json:"defaultOffset"` // Default reminder offset, in minutes. Defaults to 0 which is to remind at the task time
CurrentVersion string `json:"currentVersion"` // Current front-end version
SignupAppVersion string `json:"signupAppVersion"` // The current Marvin version when you signed up
}
© 2020-2023 Amazing GmbH
Use of Amazing Marvin's API falls under our T&C
All documentation text is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License