(BETA) Get OneNote entities in one roundtrip using $expand

Update: $expand is now available in PROD. We’ve also updated our Android and iOS pickers to use this feature.

------------------------------------

Hi everyone! Jorge here. I'm excited to announce that we are shipping a new beta feature: $expand. $expand is part of the OData v4 standard and is a way of requesting related entities to be loaded inline in the response payload (e.g. sections inside notebooks). $expand lets you get more data in your API calls so you can avoid extra roundtrips.

Imagine you are displaying the user's notebooks and sections in a UI. To get those entities using the OneNote API without expand, you would need to:

1. Call GET https://www.onenote.com/api/v1.0/Notebooks
2. For each notebook returned, call https://www.onenote.com/api/v1.0/Notebooks/{NotebookId}/sections

With expand, you can simplify that logic into a single call! Notice how every notebook entity contains a section array with all the sections inside the notebook. Less API calls = Easier coding + Better performance.

// Get the user's Notebooks and all sections inside of them
GET www.onenote.com/api/beta/Notebooks?$expand=sections

    1: {
    2:    "@odata.context":"https://www.onenote.com/api/beta/$metadata#notebooks",
    3:    "value":[
    4:       {
    5:          "isDefault":true,
    6:          "userRole":"Owner",
    7:          "isShared":false,
    8:          "sectionsUrl":"https://www.onenote.com/api/beta/notebooks/0-2C1D0B837C428511!172/sections",
    9:          "sectionGroupsUrl":"https://www.onenote.com/api/beta/notebooks/0-2C1D0B837C428511!172/sectionGroups",
   10:          "links":{
   11:             "oneNoteClientUrl":{
   12:                "href":"onenote:https://d.docs.live.net/2c1d0b837c428511/Documents/My%20Notebook"
   13:             },
   14:             "oneNoteWebUrl":{
   15:                "href":"https://onedrive.live.com/redir.aspx?cid=2c1d0b837c428511&page=edit&resid=2C1D0B837C428511!172&parId=2C1D0B837C428511!135"
   16:             }
   17:          },
   18:          "name":"My Notebook",
   19:          "createdBy":"Someone",
   20:          "lastModifiedBy":"Someone",
   21:          "lastModifiedTime":"2014-02-13T22:04:40.44Z",
   22:          "id":"0-2C1D0B837C428511!172",
   23:          "self":"https://www.onenote.com/api/beta/notebooks/0-2C1D0B837C428511!172",
   24:          "createdTime":"2013-12-12T04:19:57.247Z",
   25:          "sections":[
   26:             {
   27:                "isDefault":false,
   28:                "pagesUrl":"https://www.onenote.com/api/beta/sections/0-2C1D0B837C428511!178/pages",
   29:                "name":"Quick Notes",
   30:                "createdBy":"Someone",
   31:                "lastModifiedBy":"Someone",
   32:                "lastModifiedTime":"2014-02-13T22:04:40.44Z",
   33:                "id":"0-2C1D0B837C428511!178",
   34:                "self":"https://www.onenote.com/api/beta/sections/0-2C1D0B837C428511!178",
   35:                "createdTime":"2013-12-17T02:47:49.603Z"
   36:             }
   37:          ]
   38:       },
   39:       {
   40:          "isDefault":false,
   41:          "userRole":"Owner",
   42:          "isShared":false,
   43:          "sectionsUrl":"https://www.onenote.com/api/beta/notebooks/0-2C1D0B837C428511!180/sections",
   44:          "sectionGroupsUrl":"https://www.onenote.com/api/beta/notebooks/0-2C1D0B837C428511!180/sectionGroups",
   45:          "links":{
   46:             "oneNoteClientUrl":{
   47:                "href":"onenote:https://d.docs.live.net/2c1d0b837c428511/Documents/This%20is%20the%20test%20notebook"
   48:             },
   49:             "oneNoteWebUrl":{
   50:                "href":"https://onedrive.live.com/redir.aspx?cid=2c1d0b837c428511&page=edit&resid=2C1D0B837C428511!180&parId=2C1D0B837C428511!135"
   51:             }
   52:          },
   53:          "name":"This is the test notebook",
   54:          "createdBy":"Someone",
   55:          "lastModifiedBy":"Someone",
   56:          "lastModifiedTime":"2014-06-11T20:32:40.27Z",
   57:          "id":"0-2C1D0B837C428511!180",
   58:          "self":"https://www.onenote.com/api/beta/notebooks/0-2C1D0B837C428511!180",
   59:          "createdTime":"2014-06-11T20:16:11.807Z",
   60:          "sections":[
   61:             {
   62:                "isDefault":false,
   63:                "pagesUrl":"https://www.onenote.com/api/beta/sections/0-2C1D0B837C428511!183/pages",
   64:                "name":"Top level section",
   65:                "createdBy":"Someone",
   66:                "lastModifiedBy":"Someone",
   67:                "lastModifiedTime":"2014-06-11T20:16:39.553Z",
   68:                "id":"0-2C1D0B837C428511!183",
   69:                "self":"https://www.onenote.com/api/beta/sections/0-2C1D0B837C428511!183",
   70:                "createdTime":"2014-06-11T20:16:27.207Z"
   71:             }
   72:          ]
   73:       }
   74:    ]
   75: }

But wait, there's more! You can also expand other properties on other entities:

// Get the user's notebooks with all sections and sectionGroups (with their sections too)

GET www.onenote.com/api/beta/Notebooks?$expand=sections,sectionGroups($expand=sections)

// For a known section with id 0-2C1D0B837C428511!172, get its parent Notebook.

GET www.onenote.com/api/beta/Sections/0-2C1D0B837C428511!172?$expand=parentNotebook

// For a known notebook with id 0-2C1D0B837C428511!178, expand all sections and sectionGroups

GET www.onenote.com/api/beta/Notebooks/0-2C1D0B837C428511!172?$expand=sections,sectionGroups($expand=sections)

// (*magic*) Use $levels for a recursive $expand that gives you the whole OneNote hierarchy (all notebooks, sections, and section groups)

GET www.onenote.com/api/beta/Notebooks?$expand=sections,sectionGroups($expand=sections,sectionGroups($levels=max;$expand=sections))

Here's a quick list showing what you can expand in all of our GET endpoints:

Entity Can be expanded on…
Notebook sections, sectionGroups
Section parentNotebook, parentSectionGroup
Section Group sections, sectionGroups, parentNotebook, parentSectionGroup

When we ship this to PROD, we'll update our iOS picker and Android picker to take advantage of this new feature. Give it a try, and feel free to ping us here or on twitter @onenotedev. Happy expanding!

Jorge