Condividi tramite


OneNote API throttling and how to avoid it

Hi there,

Sometimes, applications can be written to be too demanding of an API. If one application is using too many resources, it may accidentally cause a denial of service for other applications by making the API slow or unusable. The OneNote API protects itself against accidental denial of service in the form of preventing requests and returning a "429" HTTP response code when we detect too many - this is known as throttling.

Before I start talking about recommendations for production apps - if you're running into throttling (429's) during development, you can simply change your user or your app (this does require giving permissions again) and keep coding/testing against the API.

Throttling is something you definitely want your app to avoid - here's a couple of best practices to achieve this:

Best practice 1 - Reduce network roundtrips, especially when retrieving metadata:

Suppose you want to retrieve all of the user's notebooks, sections, and section groups in a hierarchical view.

Bad practice -  It can be tempting to do the following:

  1. Call GET ~/api/v1.0/me/notes/notebooks to get the list of notebooks
  2. For every retrieved notebook, call GET ~/api/v1.0/me/notes/notebooks/{notebookId}/sections to retrieve the list of sections
  3. For every retrieved notebook, call GET ~/api/v1.0/me/notes/notebooks/{notebookId}/sectionGroups to retrieve the list of section groups
  4. ... optionally recursively iterate through section groups

While this will work (with a few extra sequential roundtrips to our service), there is a much better alternative. See our blog post about expand for a more details.

Best practice -  One step!

  1. Call GET ~/api/v1.0/me/notes/notebooks?$expand=sections,sectionGroups($expand=sections)

This will yield the same results in one network roundtrip with way better performance - yay!

Best practice 2 - Don't retry requests to the API indefinitely, especially without inspecting the HTTP status code or OneNote API error information

Suppose you are creating some UI that will give you a string which will then be the name for a new notebook. You'll use the POST ~/me/notes/notebooks API to create a new notebook with that name.

Bad practice - Infinitely retrying without inspecting API errors// Pseudocode! bool apiSucceeded = false; while(!apiSucceeded){ try{ createNotebookApiRequest.Execute(); apiSucceeded = true; // ^_^ } catch(Exception ex){ // The API request failed! :( Retrying. } }

Tip - If our API responds with an HTTP Status Code 4xx (like 404, 400, 409), there is something wrong with the request and retrying won't help!

Best practice -  Inspect and handle errors, starting with the HTTP response code (also, we might want to set a limit on retry loops ;) ).
An example error in this category could be an invalid notebook name (which will result in an HTTP status code "400" and the OneNote API error "NotebookNameInvalidChar". When this happens, you might want to prompt your user for a different name or trim certain characters off the notebook name.

You can check out Nick's blog post on OneNote API errors to see details about how we return specific errors. Also, the list of OneNote API errors is kept up to date in our docs!

As we aim to provide a responsive, stable service for all of our users and developers, we will be enabling throttling in our API on 01/29/2016. Here's how it will work:

  • Limits will be based on the number requests classified by App and User - This means if your app is not following our best practices and ends up issuing too many requests to the OneNote API in a short period of time, it might be throttled for some time.
  • The limits are time based, so simply waiting will eventually reset the limit.
  • If you follow the best practices above, you are very unlikely to get throttled!
  • Since the limits are scoped per app and user, your app will not get throttled if it gets a lot of users. It will only get throttled if it issues a huge amount of requests in a short period of time for a particular user.

Happy coding,
Jorge

Comments

  • Anonymous
    January 14, 2016
    Hi Jorge, Thanks for the heads up. Could you tell me how best to deal with a "502 Bad Gateway" error? I have encountered this when issuing a www.onenote.com/.../section{id}/pages?top=100 particularly after creating (copying) quite a few new notebooks just before hand. So far I reissue the command until I receive a 200 OK. But I'm guessing this will get me throttled now. Cheers Steve

  • Anonymous
    January 19, 2016
    Hey Steve, I recommend you post your question on StackOverflow, where me and my fellow engineers are continuously answering questions related to the OneNote API - simply tag your question with the "onenote-api" tag. stackoverflow.com/.../onenote-api To give you a headstart, I believe this might be related to expired AUTH tokens - are you using OneDrive or O365 accounts? It is unlikely that this will affect you, as unauthenticated requests (502's fail before authentication) do not count towards this throttle. Jorge

  • Anonymous
    February 19, 2016
    When we get the page content as HTML using one note API Image sources doesn't seem to be working correctly. There is $value at the end of image source in HTML content. How do we handle this when the one note page has images?   Ex: <img width="649" height="587" src="www.onenote.com/.../0-7dcd564dd9c2472c82451536349be691!1-AA1F36752D8FDBF!14716$value" data-src-type="image/png" data-fullres-src="www.onenote.com/.../0-7dcd564dd9c2472c82451536349be691!1-AA1F36752D8FDBF!14716$value" data-fullres-src-type="image/png" />

  • Anonymous
    August 17, 2016
    Hello,20166 error on OneNote API when they do too many request in a short amount of time. How many request they can do or if they can disable the limit for their account.

  • Anonymous
    August 04, 2017
    In response body or header we don't receive any parameter which helps us in understanding how much we must wait from further trigerring this API again. How we can get this value