Skip to content

Marvin API

Amazing Marvin edited this page Mar 26, 2022 · 44 revisions

Use Marvin's API to access data that doesn't live in your user database, or for simplicity's sake. We will be adding more endpoints soon.

Basic structure

Marvin's API involves GET and POST requests to https://serv.amazingmarvin.com/api/:endpoint. POST bodies and most responses are encoded as JSON.

Credentials

Include an HTTP header X-API-Token using the API_TOKEN found here if the endpoint requires limited access, or the header X-Full-Access-Token using the FULL_ACCESS_TOKEN also found here if the endpoint requires full access. The idea behind this system is that you might want to give Zapier the ability to create tasks, but not to read your data. If there's user demand then we'll make a proper OAuth system with permissions.

Rotation

Accidentally exposed an API_TOKEN? You can get rotate your credentials in the API strategy settings within Marvin.

Endpoints

Test credentials

stable

You can test whether your credentials are correct with a POST:

POST /api/test
X-API-Token: XYZ
=>
"OK"

Create a task

stable, but new document's _id and _rev will be included in the response in the future

You can quickly create a task with a POST request:

Note: send actual JSON. The following has inline documentation.

POST /api/addTask
X-API-Token: XYZ
{
  "done": false,
  "day": "2020-07-17",
  "title": "Work 30m homework #School", // supports some autocompletion (parent, day, dueDate, plannedWeek, plannedMonth, timeEstimate, labels, isStarred)
  "parentId": "xyz", // ID of parent category/project
  "labelIds": ["abc", "def"], // IDs of labels
  "firstScheduled": "2020-07-17",
  "rank": 999,
  "dailySection": "Morning",
  "bonusSection": "Essential", // or "Bonus"
  "customSection": "a3gnaiN31mz", // ID of custom section (from profile.strategySettings.customStructure)
  "timeBlockSection": "b00m3feaMbeaz", // ID of time block
  "note": "Problems 1-4",
  "dueDate": "2020-07-20",
  "timeEstimate": 3600000, // ms
  "isReward": false,
  "isStarred": 3,
  "isFrogged": 2,
  "plannedWeek": "2020-07-12",
  "plannedMonth": "2020-07",
  "rewardPoints": 1.25,
  "rewardId": "anbeN3mRneam", // Unique ID of attached Reward
  "backburner": true, // Manually put in backburner (can also be backburner from label, start date, etc.)
  "reviewDate": "2020-09-09",
  "timeEstimate": 300000, // duration estimate in ms
  "itemSnoozeTime": 1599577206923, // Date.now() until when it's snoozed
  "permaSnoozeTime": "09:00",


  // Time offset in minutes
  //
  // Added to time to fix time zone issues.  So if the user is in Pacific time,
  // this would be -8*60.  If the user added a task with +today at 22:00 local
  // time 2019-12-05, then we want to create the task on 2019-12-05 and not
  // 2019-12-06 (which is the server date).
  "timeZoneOffset": 60,
}

The title will be processed similar to autocompletion within Marvin. So if you use "Example task +today", then the task will be scheduled for today and " +today" will be removed from the title. If you put "#Parent Category" or "@label1 @label2" in the title, they will be resolved to their IDs when you open Marvin.

See Marvin data types for documentation about how these fields work. Only the above fields are consumed by this API. If you want to set other fields, add directly to the couchdb.

Working sample code (just change the API token):

curl -H 'X-API-Token: test' -XPOST -d '{"title": "Example API task +today"}' https://serv.amazingmarvin.com/api/addTask 

Create a project

stable

You can quickly create a project with a POST request:

Note: send actual JSON. The following has inline documentation.

POST /api/addProject
X-API-Token: XYZ
{
  "done": false,
  "day": "2020-07-17",
  "title": "Work 30m homework #School", // supports some autocompletion (parent, dueDate, labels)
  "parentId": "xyz", // ID of parent category/project
  "labelIds": ["abc", "def"], // IDs of labels
  "firstScheduled": "2020-07-17",
  "rank": 999,
  "dailySection": "Morning",
  "bonusSection": "Essential", // or "Bonus"
  "customSection": "a3gnaiN31mz", // ID of custom section (from profile.strategySettings.customStructure)
  "timeBlockSection": "b00m3feaMbeaz", // ID of time block
  "note": "Problems 1-4",
  "dueDate": "2020-07-20",
  "timeEstimate": 3600000, // ms
  "isReward": false,
  "priority": "high", // "high", "mid", or "low"
  "isFrogged": 2,
  "plannedWeek": "2020-07-12",
  "plannedMonth": "2020-07",
  "rewardPoints": 1.25,
  "rewardId": "anbeN3mRneam", // Unique ID of attached Reward
  "backburner": true, // Manually put in backburner (can also be backburner from label, start date, etc.)
  "reviewDate": "2020-09-09",
  "timeEstimate": 300000, // duration estimate in ms
  "itemSnoozeTime": 1599577206923, // Date.now() until when it's snoozed
  "permaSnoozeTime": "09:00",

  // Time offset in minutes
  //
  // Added to time to fix time zone issues.  So if the user is in Pacific time,
  // this would be -8*60.  If the user added a task with +today at 22:00 local
  // time 2019-12-05, then we want to create the task on 2019-12-05 and not
  // 2019-12-06 (which is the server date).
  "timeZoneOffset": 60,
}

If not scheduled, use day=null.

Create an event

experimental

You can quickly create an event with a POST request:

Note: send actual JSON. The following has inline documentation.

Note: calendar sync happens on the client. You must have Marvin running on one of your devices in order for this event to be calendar synced!

POST /api/addEvent
X-API-Token: XYZ
{
  "title": "Haircut",
  "note": "Problems 1-4", // Use markdown
  "length": 3600000, // ms
  "start": "2021-08-21T14:30:00.000Z", // ISO formatted start time
}

Read any doc

stable

With the fullAccessToken you can GET any individual document in the couchdb database by ID.

Bug fix / breaking change: in the past this API only worked when reading ProfileItems since it returned the val field directly. Now the entire document is returned, even when db="ProfileItems".

GET /api/doc?id=strategySettings.labelSettings.groups
X-Full-Access-Token: ABC
=>
{
   "_id" : "strategySettings.labelSettings.groups",
   "_rev" : "12-8dcc836705e9f1ae98f1525092b82b31",
   "createdAt" : 1564154150216,
   "db" : "ProfileItems",
   "fieldUpdates" : {
      "createdAt" : 1568180186429,
      "db" : 1568180586429,
      "updatedAt" : 1568180536429,
      "val" : 1582132559581
   },
   "updatedAt" : 1582132559548,
   "val" : {
      "84fYiqsxgZadr" : {
         "_id" : "81fYbqsxGZadr",
         "createdAt" : 1564159272192,
         "icon" : "cxicons8-circled-7",
         "isExclusive" : false,
         "isMenu" : true,
         "rank" : 4,
         "title" : "numbers"
      }
   }
}

Update any doc

experimental

With the fullAccessToken you can update any doc.

POST /api/update
X-Full-Access-Token: ABC
{
  "itemId": "xy12n3i123",
  "setters": [
    { "key": "done", "val": true },
    { "key": "fieldUpdates.done", "val": 1648122403647 },
    { "key": "updatedAt", "val": 1648122403647 }
  ]
}
=>
{
  "_id": "xy12n3i123",
  "_rev": "2-xyz",
  "done": true,
  "fieldUpdates": {
    "done": 1648122403647
  },
  "updatedAt": 1648122403647,
  "title": "Example task",
  ...
}

Get the currently tracked task

stable, but will be extended to include how long tracked

GET /api/trackedItem
X-API-Token: XYZ
=>
{
  "_id": "a12345",
  "db": "Tasks",
  "title": "Work 30m on homework"
}

Get tasks and projects scheduled today (including rollover/auto-schedule due items if enabled)

stable, but improvements coming

GET /api/todayItems
X-API-Token: XYZ
=>
[...]

Time zone issues are possible here (the server is UTC+0), so it's best to provide a date. This can either be done using a query parameter or the X-Date header. In both cases, use the date format "YYYY-MM-DD".

GET /api/todayItems?date=2021-11-15
X-API-Token: XYZ
=>
[...]

OR

GET /api/todayItems
X-API-Token: XYZ
X-Date: 2021-11-15
=>
[...]

Get tasks and projects that are due today

stable, but improvements coming

GET /api/dueItems
X-API-Token: XYZ
=>
[...]

Get a list of all categories

stable

You can access a list of all your categories with a GET request. See Categories for documentation of the data format.

GET /api/categories
X-API-Token: XYZ
=>
[{ "_id": "a4123412", "title": "Work", "parentId": "root", "color": "#4184a0", ... }, ...]

Get a list of all labels

stable

Get a list of all labels, in their sort order (used in sort by label).

GET /api/labels
X-API-Token: XYZ
=>
[{ "_id": "abcdefg1234", "title": "quick", "color": "#f0a0a0", "icon": "tag", "groupId": "5421fabcdae" }, ...]

The label groups can be found by reading the sync database document profile.strategySettings.labelSettings.groups.

See documentation for labels and label groups

Start/stop time tracking

You can use the /api/track endpoint to start or stop time tracking a task by its ID

POST /api/track
POST /api/time # alias you can use if "track" is in a browser extension blacklist
X-API-TOKEN: XYZ
{
 taskId: "abc",
 action: "START"
}
=>
{
 startId: "abc",
 startTimes: [1595791080814],
 stopId: "xyz", // or null
 stopTimes: [1595791066096, 1595791080814],
 issues: ["Wanted to..."],
}

Valid actions are "START" and "STOP".

NOTE: you are responsible for updating the stopped task's duration and times! Otherwise Marvin's UI will be missing data in some places. How to update? Updating documents

See Marvin data types#Tasks for documentation about duration and times.

See Marvin data types#Time Tracking for more documentation about how time tracking times are stored.

Getting time track info

Marvin caches time track data in task.times and task.duration. But if you use the API to do time tracking and don't update the task, or if something went wrong with sync, then this info might be missing. You can get the source of truth about time track data using the /api/tracks endpoint.

You can request the time track data for up to 100 tasks at once. This API will then return an array of time track data with taskId and a times array. See Marvin data types#Tasks for documentation about times.

POST /api/tracks
POST /api/times # alias you can use if "track" is in a browser extension blacklist
X-API-TOKEN: XYZ
{
  "taskIds": ["nfieamewpemnfiqe"],
}
=>
[
  { "taskId": "nfieamewpemnfiqe", "times": [1625985037144, 1625985043470, 1625985049000, 1625985054374] }
]

Claiming reward points

Completed a task or celebrating something? Claim some reward points.

POST /api/claimRewardPoints
X-API-TOKEN: XYZ
{
  "points": 1.5,
  "itemId": "an2m1n213ml", // Task ID or "MANUAL" for manual point reward
  "date": "2020-09-08", // Used to track points today
  "op": "CLAIM",
}
=> user profile

Unclaiming reward points

User error? Task marked incomplete? Unclaim the reward points.

POST /api/unclaimRewardPoints
X-API-TOKEN: XYZ
{
  "itemId": "an2m1n213ml", // Which itemId to undo (determines how many points)
  "date": "2020-09-08", // Used to track points today
  "op": "UNCLAIM",
}
=> user profile

Spending reward points

POST /api/spendRewardPoints
X-API-TOKEN: XYZ
{
  "points": 2.5,
  "date": "2020-09-08", // Used to track points spent today
  "op": "SPEND",
}
=> user profile

Reset reward points

Permanently deletes earn/spend history and resets reward points to 0.

POST /api/resetRewardPoints
X-FULL-ACCESS-TOKEN: XYZ
=> user profile

Get Marvin Kudos info

GET /api/kudos
X-API-TOKEN: XYZ
=>
{
  "kudos": 0,
  "level": 1,
  "kudosRemaining": 350
}

Me

Retrieve some information about your account.

GET /api/me
X-API-Token: XYZ
=>
{
  "email": "test@amazingmarvin.com",
  ...
}

See Marvin Data Types#Profile for documentation on which fields are available and what they mean.

Reminders

Reminders are attached to Tasks for display in Marvin (see documentation for Tasks). But they must also be set on the server in order to get push notification on your mobile device. Use the following Reminder APIs to list, set, and delete Reminders on the server. Note: if you have cloud sync disabled and don't want to share task titles with Marvin's servers, then don't use these APIs! These APIs are not used within Marvin when your cloud sync is disabled in order to avoid leaking Task data.

Get a list of all reminders

See documentation for Reminders.

GET /api/reminders
X-Full-Access-Token: ABC
=>
Reminder[]

Set reminders

See documentation for Reminders.

POST /api/reminder/set
X-API-Token: XYZ
{
  reminders: Reminder[], // Reminders to set
}
=>
"OK"
}

Delete one or more Reminders

Be sure to also delete the reminder info in the corresponding Tasks in order to keep the Marvin user interface accurate.

POST /api/reminder/delete
X-API-Token: XYZ
{
  reminderIds: String[], // IDs of Reminders to delete
}
=>
"OK"

Delete all Reminders

Be sure to also delete the reminder info in the corresponding Tasks in order to keep the Marvin user interface accurate.

POST /api/reminder/deleteAll
X-Full-Access-Token: ABC
=>
"OK"

Clone this wiki locally