Usability - Productivity - Business - The web - Singapore & Twins

Poking around the iNotes HTTP API (Part 1)

With the rise of web applications, something interesting happened: applications gained an observable API. Delivered over HTTP(s) with a few commands (GET, POST etc.) it became easier to find out " what is going on". Tools like Wireshark, Fiddler, Charlesproxy or TCPMon sit between your HTTP consuming client and the HTTP generating server. In browser applications the build in developer tools (Ctrl-Shift-I) provide the same level of access.
So anything flowing over HTTP is effectively an API. This led to the idea of the API economy (but that's a story for another time). Intercepting HTTP(s) traffic can be easier and more fun, than trying to customise customise a backend you might not have access to. (Of course there is evil interception too). Point is case, iNotes is quite a stack:
3d view of the iNotes client

So I poked around the iNotes API, this is what I found:All URLs mentioned need to be prefixed with . There are GET and POST methods used. I haven't seen any OPTIONS, PUT or DELETE operations.
  • All interactions need to provide the cookies, so your HTTPUrlConnection won't cut it. You want use use at least the Apache HTTP client. When SAML is your access authorization of choice, you want to check the insights on Apache CXF and SAML, as well as make yourself familiar with Apache Shiro and pac4j
  • The general syntax for reading document related information is viewname/unid?OpenDocument. The interesting part is the &Form= parameter. This is what I found so far:
    • s_MailMemoReadBodyContent: Only ready the body content
    • l_JSVars: Returns all regular Notes fields in JSON format (and the names of the RTFields)
    • l_MailMessageHeader: Raw mime header, some HTML (notably <br> needs to be filtered out)
    • l_MailMessageHeader&PresetFields=FullMessage;1 : Raw complete MIME message (same as above)
  • Reading data from a view, which we usually do using ($Inbox)?ReadViewEntries is better done using iNotes/Proxy/?OpenDocument&Form=s_ReadViewEntries&PresetFields=FolderName;($Inbox),UnreadCountInfo;1. It will deliver an attribute unread="true", that makes it easy to distinguish messages. Adding UnreadOnly;1 to the PresetFields will only show unread entries
  • Retrieving a list of folders can be done using iNotes/Proxy/?EditDocument&Form=l_GetOutline_JSON&charset=UTF-8 it comes back as JavaScript snippet inside something JSON like. Some parsing required
  • Every POST required a large number of fields to complete. If they are missing it won't work. Most important: You needs a %%Nonce field with the &N: value from the ShimmerS cookie
  • Moving documents into a folder is a POST operation with the url iNotes/Mail/?EditDocument&Form=h_PageUI. The payload fields are:
    Field Value Remark
    s_ViewName ($Inbox) Folder the documents came from
    h_SetCommand h_ShimmerMoveCopyDocsToFolder That's what we want to do
    h_DestFolder UNID Name or UNID as retrieved from GetOutline
    h_Move 1 1 = move, 0 = copy
    h_EditAction h_Next Will result in a HTTP 200, form processes
    h_SetDeleteList UNID;UNID;UNID semicolon separated list of documents
    h_SetDeleteListCS that value stays empty (you need the = )
  • Deleting documents is also a POST operation with the url iNotes/Mail/?EditDocument&Form=l_HaikuErrorStatusJSON. The payload fields are:
    Field Value Remark
    s_ViewName ($Inbox) Folder the documents came from
    h_SetCommand h_DeletePages documents get deleted, not pages
    h_SetEditNextScene l_HaikuErrorStatusJSON points to the form
    h_EditAction h_Next This will return JSON for the eMails
    h_SetDeleteList UNID;UNID;UNID semicolon separated list of documents
    h_SetDeleteListCS, h_AllDocs, h_FolderStorage that values stays empty (you need the = )
    There is another parameter h_SetReturnURL we might not need
  • POST to s_GetFolderUnreadCountJSON with s_FolderListNames=FolderName&FolderName=Name|UNID;Name|UNID;Name|UNID to retrieve JSON that indicates all unread documents in the specific views
The creation of eMail and replies is another story for another time
As usual YMMV

Posted by on 24 November 2014 | Comments (1) | categories: IBM Notes


  1. posted by Juergen on Friday 17 August 2018 AD:

    Sehr interessant! Unter anderem ist das eine coole Möglichkeit, Mail-Bodies relativ formatierungs-verlustfrei aus Lotus zu exportieren, in HTML, um dann mit einem HTML-to-PDF-Konvertierer schöne PDFs zu bekommen.

    Ein kleines Problem ist mir allerdings hierbei begegnet: Es gibt bei so einem via Java realisiertem Mail-Body-Request mittels s_MailMemoReadBodyContent u. U. encoding-bedingte Abweichungen gegenüber dem, was iNotes im Vollzugriff über Browser liefert.
    Ich habe eine Mail aus Bulgarien, mit teilw. kyrillischen Zeichen. Öffne ich diese Mail in iNotes im Browser, werden die Zeichen korrekt dargestellt. Hole ich hingegen den body-Datenstrom über meine Java-Anwendung mit s_MailMemoReadBodyContent, so enthält der html-code lauter Fragezeichen an diesen Stellen.

    bin ratlos, wie ich den Requests so erweitere, dass ich verlustfrei auch solch einen Body exportieren kann. Also dass er mit geeigneten encoding-Angaben und/oder html-maskierten Zeichen geliefert wird.