A.nnotate API reference

This reference documents the A.nnotate API used for controlling A.nnotate from another application. The API allows you to list documents and notes and upload new documents. You can also integrate your existing user authentication system with A.nnotate user accounts, allowing you to automatically log in users from your current system. Sample code and examples are available in PHP and Java for accessing the API remotely; the HTTP REST web service could also be used from other programming languages.

This is part 1 of the reference; A.nnotate API Part 2 includes the calls for creating users, uploading documents and adding notes; A.nnotate API Part 3 - Folders includes the API methods for manipulating folders.

Sample code is available for using the API (see Getting started below for a download link). This includes test calls of all API functions using PHP from the command line. There is also example source code in Java for invoking the API. Because the API uses standard HTTP GET and POST calls, it can also be used from other programming languages. If you are not using PHP or Java, you might find useful links on JSON tools from www.json.org; the authentication signing mechanism uses similar HMAC/SHA1 hashing to Amazon's S3 service.

0. Getting started with the sample API code

Before starting with the API, you need to have access to a local A.nnotate installation; see A.nnotate local server installation for details. You can use the API samples from any machine with web access to your a.nnotate server.

The sample code demonstrates how to use the various API calls from PHP; there is also sample Java source for accessing the API. Some of the samples are intended to be run from the command line, and others should be run from a web browser, so it is useful to extract in a web area: e.g.

% cd /var/www/annotate                     # ... or your web area
% tar xvfz api-sample.3.1.15.tgz   
... extracts to the "api/" subfolder

You should then be able to view the API sample instructions by pointing your web browser somewhere like: http://localhost/annotate/api/index.html For production use, you will want to restrict access to this api directory (e.g. using .htaccess or moving it elsewhere).

The rest of this reference guide describes the API security model and lists the available API functions.

1. Authentication

Each API request needs to be signed by the api-user using a secret api-key. The api user is the email address of the administrator A.nnotate account (on standalone installations), or the group admin user (for group accounts on a.nnotate.com). The api key is shown in the advanced section of your A.nnotate account page.

Requests can be made by the api user to view the documents of a particular annotate user as long as the api user has permission. The request signature is a list of HTTP GET parameters to add to the request, e.g. to list the documents of user 'jill@example.com':

  http://yoursite.com/annotate/php/listDocuments.php?
    api-user=joe@example.com               # The admin user for the account
    &api-requesttime=123456                # the Unix timestamp (GMT)
    &api-annotateuser=jill@example.com     # The user's account
    &api-auth=xyz1234543983jeflgnwefgdgd   # The signed hash code.

The request time is the unix timestamp (seconds since Jan 1st 1970), and requests expire after a few minutes. The api-auth code is a Base-64 encoded HMAC-SHA1 digest of the string:

  $phpfn . "\n". $apiuser. "\n". $requesttime. "\n". $annotateuser

signed using the secret api-key. The authentication algorithm is similar to that used for signing Amazon S3 requests, so you may be able to adapt the sample code for your preferred programming language from the Amazon developer site. A PHP function which implements it is shown below: (see the Crypt_HMAC() documentation; this function is included in the sample code.

  // ==== Pseudocode =====
  # Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of( StringToSign ) ) );


  // ==== PHP sample code ====
  function signRequest( $phpfn, $apiuser, $apikey, $annotateuser ) {
    $requesttime = time();
    $stringToSign = "$phpfn\n$apiuser\n$requesttime\n$annotateuser";  
    $hasher =& new Crypt_HMAC($apikey, "sha1");
    $signature = hex2b64($hasher->hash($stringToSign));
    return "api-user=".rawurlencode($apiuser).
       "&api-requesttime=".$requesttime.
       "&api-annotateuser=".rawurlencode($annotateuser).
       "&api-auth=".rawurlencode($signature);
  }

The authentication mechanism in Java is similar:-

    // ===== Sample JAVA code for authenticating an A.nnotate API request =====
    import sun.misc.BASE64Encoder;
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import java.net.URLEncoder;
    import java.util.Date;
    import java.net.URL;
    import java.io.*;

    // Make a base64 encoded HMAC / SHA1 hash of a string.
    public static String sign(String apikey, String data) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA1");
        byte[] keyBytes = apikey.getBytes("UTF8");
        SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA1");
        mac.init(signingKey);
        byte[] signBytes = mac.doFinal(data.getBytes("UTF8"));
        String signature = (new BASE64Encoder()).encode(signBytes).replaceAll("\n","");
        return signature; 
    }

    public static String signRequest( String phpfn, 
                                      String apiuser, 
                                      String apikey, 
                                      String annotateuser,
                                      long validfor)  throws Exception {        
        long requesttime = (new Date()).getTime() + validfor;
   
        String stringToSign = phpfn + "\n" + apiuser+ "\n"+ requesttime + "\n" + annotateuser;
        String signature = sign(apikey, stringToSign);
        
        return "api-user=" + URLEncoder.encode(apiuser, "UTF-8") + 
            "&api-requesttime=" + URLEncoder.encode(""+requesttime, "UTF-8") + 
            "&api-annotateuser=" + URLEncoder.encode(annotateuser, "UTF-8") + 
            "&api-auth=" + URLEncoder.encode(signature, "UTF-8");
    }    

2. Data format and error handling

Structured data is returned from requests in Javascript Object Notation (JSON) format. This is a simple language independent data interchange format with libraries for all major languages (see www.json.org), and is a simpler and more efficient alternative to XML.

If there is an error with the request (e.g. with authentication), the return value from the GET request will be the string "ERR" + an error message, otherwise it will return a valid JSON string. You can test the response value with code like:

    // Sample PHP code for testing the API response
    $req = signRequest("listDocuments.php", "joe@example.com", 
                       "...your-secret-api-key...", "jill@example.com");
    $txt = file_get_contents("http://your.server.com/annotate/php/listDocuments.php?".$req);
    if (substr($txt, 0, 3) == "ERR") {
      print "Problem with request: $txt\n":
    }
    else {
      // OK, parse as JSON object:
      $obj = json_decode($txt);
      print_r($obj);
    }

3. Listing documents for a user

To fetch a list of the documents for a user, use an HTTP GET call to listDocuments.php. The parameters are as below - api-annotateuser specifies the user whose documents you want to list, the api-user is the admin API user account. Details for documents uploaded in each month are returned in a separate array; you can provide 'from' and 'to' months to restrict the number of documents returned.

    http://your.server.com/annotate/php/listDocuments.php?    
     api-user=joe@example.com
     &api-requesttime=1234566
     &api-annotateuser=jill@example.com
     &api-auth=ABC123...

     &from=2008_01                # YYYY_MM   (optional)
     &to=2009_01                  # YYYY_MM   (optional)
     &withmeta=0                  # include metadata for each document  (optional)
     &withnotes=0                 # include notes on each document  (optional)
     &p=                          # filter by parent folder ID (optional - *new* Sept 2009)

The return value is an array (by month) of arrays (by document) of basic document information:

   [ // outer array: list of months
      [   // list of document metadata for 1st month
        {    // document info for a single document:
          code: "abc123",
          date: "2008-01-01",
          name: "doc123.pdf",
          owner: "joe@example.com",
          type: "pdf",    // "pdf" for all uploaded documents (incl .pdf, .doc, .xls etc)
          parentid: ""   // The parent folder ID, or "" for Home folder.
        },
        {
          code: "abc456",
          date: "2008-01-02",
          name: "BBC news story"
          owner: "joe@example.com",
          type: "snap",  // "snap" for web snapshots
          parentid: "2008-01-01/abc789"   // The parent folder id.

        }
      ],
      [  // list of document metadata for 2nd month
        {
          code: // ... etc
        }
      ]
   ] 

Each document has a date (when uploaded to A.nnotate, format YYYY-MM-DD) and a code, a random string which allows access to the document. The owner is the email address of the person who uploaded the document. the type is either 'pdf' or 'snap'; 'pdf' is used for all documents (PDF, Word, Excel etc) which are displayed using the paginated PDF viewer, and 'snap' is used for snapshots of web pages. Each document can also be in a folder - the parentid field specifies the folder id. If this is the empty string "", then the document is in the user's top level Home folder.

3.1 Linking to a document

If you have fetched a list of documents, and would like to create a URL link to display a document on your A.nnotate server, you can create an href link like:

    // for PDF documents:
    http://your.server.com/annotate/php/pdfnotate.php?d=2008-01-01&c=abc123

    // for web snapshots:
    http://your.server.com/annotate/docs/2008-01-01/abc123/index.html

Substitute the appropriate value for the document's date and code in the parameters d= and c=.

The original uploaded files for an office / pdf document are stored in a folder like:

    // sample uploaded file:
    http://your.server.com/annotate/docs/2009-01-01/abc123/file123.doc

    // PDF version of uploaded file:
    http://your.server.com/annotate/docs/2009-01-01/abc123/file123.pdf

    // Document metadata (JSON format) for a document:
    http://your.server.com/annotate/docs/2009-01-01/abc123/docmeta.js

You can get the filename from the srcname field of the document metadata object (the name field has the filename of the PDF version). The document metadata object is available from the docmeta.js file in the document's folder; you can also fetch it using the listDocuments.php API call described in the next section.

3.2 Fetching lists of complete document metadata

To fetch the extended document metadata (the description, notes, tags, readers etc), you can set withmeta=1 in the call to listDocuments.php. For each document returned you will get an extra field "meta" containing the information. For large numbers of documents, this API request will be slower than fetching the basic information, so for scalability you may wish to restrict requests to a few months at a time.

[ // array of months
  [ // array of doc meta for a month
   {  // sample extended metadata for a document:
     name: "somefile.pdf",
     code: "zvq123",
     date: "2008-05-08",
     owner: "joe@example.com",
     parentid: "",   // parent folder id, in this case "" is the Home folder.
     meta: {
        created: "2008-05-08 13:09.19",
        title: "A paper on XYZ",
        notes: "These are some notes about the whole document...",
        tags: "paper, pdf, important",
        code: "zvq123",
        date: "2008-05-08",
        pages: 10,
        cost: 50,                                     // in credits                            
        srcext: "doc",                                // e.g. 'doc' for uploaded Word docs
        srcname: "somefile.doc",                      // name of file as uploaded
        srcsize: 123456,                              // size of uploaded file (bytes) [* new in v3.0.13 *]
        name: "somefile.pdf",                         // name of file converted to pdf (if needed)
        authors: "",                                  // value of 'authors' field in doc properties 
        owner: "joe@example.com",
        readers: 
        [
           {
            email : "jill@example.com", 
            role: "guest",
            sig:  "jill"
           } 
           // , { ... more readers of this document }
        ]
        type: "pdf",
        status: "ok",  // or "trash" for deleted documents.
        payments: [ // record of payments for this document ],
        expiry: "2009-05-08"  
     }
   }
  ]
]

3.3 Listing documents in a given folder (added: Sept 2009)

By default the listDocuments call returns all documents in all folders. To list the documents in a given folder, you can set the 'p' parameter to the parent folder ID, e.g. p=2009-01-01/abc123 in the call to listDocuments.php. This will restrict the results to just those documents with the given folder as their immediate parent; note that to list subfolders you would need to do an extra call for each subfolder. You can set p=top to list just the documents in the top level folder, and leave the setting empty: p= to list all documents in all folders. You can get a list of folder ids, names and the folder hierarchy using the listFolders call described below.

  // return info on all documents in all folders (the default):
  listDocuments.php? ... &p=

  // documents with given folder as their immediate parent:
  listDocuments.php? ... &p=2009-01-01/abc123

  // documents in the top level folder:
  listDocuments.php? ... &p=top

4. Fetching the list of notes for a single document

The listNotes.php call will fetch the list of notes for a single document, as viewed by the given api-annotateuser, along with the document level metadata, e.g. for a document with date "2008-05-08" and code "zvq123", you can do a HTTP GET call like:

 
   http://your.server.com/annotate/php/listNotes.php?    
     api-user=joe@example.com
     &api-requesttime=1234566
     &api-annotateuser=jill@example.com
     &api-auth=ABC123...

     &d=2008-05-08
     &c=zvq123

The return value is a JSON encoded object with fields meta and notes. Note that different api-annotateusers may see a different set of notes if some are marked 'private' (for author only) or 'feedback' (for author and document owner).

  {
     meta : {     
        created: "2008-05-08 13:09.19",
        title: "A paper on XYZ",
        notes: "These are some notes about the whole document...",
        tags: "paper, pdf, important",
        code: "zvq123",
        date: "2008-05-08",
        // ... other document level metadata fields as above
     },
     notes : [    
        {
          pageurl: "local:2008-05-08/zvq123", 
          type: "note",               
          pagetitle: "", 
          context: "some sentence about jane bloggs and her collection of newts",
          subject: "jane bloggs",
          notetext: "this is the text of the note itself",
          author: "joe@example.com",      // userid of the note author (an email)
          signed: "joe",                  // public signature for note
          date: "2008-05-07 12:13.12",    // time note written in GMT
          tags: "person, contact",        // tags when first created
          match: "page-1:8:10",           // where note is attached (page 1, from word #8 to word #10)
          num: 1,                         // num of this note
          gid: 1,                         // ID of this note
          color: 2,                       // index of the background color of note
          mark: "h",                      // "h" - normal text highlight, "s" - strikethrough, "i" - insert, "l" - link
          state: "live",                  // "dead" for deleted notes
          finalTags : "person, contact",  // latest version of tags (maybe modified by replies)
          replies: []                     // {optional} list of replies to this note
       }       
       //  , { ... fields of 2nd note ... }
     ]
  }

4.1 The note fields in detail

The notetext field contains the text of the note; the tags contains the comma separated tags. the subject is the highlighted text; the context contains a few words either side of the highlighted text. Each note also has a gid which is unique for a particular document. Different edits of a note will have the same gid but unique num values. The signed field is the signature of the user who made the note, the author field is their full userid (an email). The date field has the time stamp (in GMT). The color field is an index into the color chooser in the GUI. The mark field stored the type of the highlight mark on the text - 'h' for normal highlight, 's' for strikethrough, 'i' for an insert mark, 'l' for an inline hyperlink (see below). Replies to a note are stored in similar note objects, with the gid field set to the id of the note they are replying to.

[New Aug 2009: Inline hyperlinks] it is now possible to set the linkTo URL field and the mark to 'l' for inline hyperlinks. These are displayed with a blue underline.

[New May 2010: freehand drawings] for freehand notes made using a tablet pen device, there is a drawing field which contains the vector drawing instructions; see section 4.5 below for details.

4.2 Attachment of notes to page text

The match field of a note determines where in the page it will be attached. For PDF documents, the coding for highlighted text is:

  match: "page-1:8:10"

indicating that this note is attached to page 1 from word index #8 to #10 inclusive. The Word indices are based on the array of words extracted from the PDF page. You can access the list of words for page 1 of a PDF document uploaded on "2008-01-15" with code "ABC123" using a HTTP GET on listWords.php (note that you do not need to sign this request as it includes the document code):

  http://your.server.com/annotate/php/listWords.php?d=2008-01-15&c=ABC123&p=1

The list of words for each page is coded as an array of arrays; each word is an array [word, x1, x2, y1, y2], with the positions in PDF coordinates e.g.:

[
["Enhancing ", 90.708, 162.276, 98.412, 111.362 ],
["documents ", 166.168, 240.844, 98.412, 111.362 ],
["with ", 244.736, 272.736, 98.412, 111.362 ],
["annotations ", 276.628, 355.966, 98.412, 111.362 ],
["and ", 359.858, 384.750, 98.412, 111.362 ],
["machine-readable ", 90.708, 209.750, 115.212, 128.162 ],
["structured ", 213.642, 282.872, 115.212, 128.162 ],
["information ", 286.764, 363.764, 115.212, 128.162 ],
// ...
]

4.3 Attachment of notes to images

For notes attached to highlighted rectangles / ovals on the page, the match encoding is as follows:

e.g.
  match: "R1:3:100:200:50:40"
refers to a region on page 3, top left coords: (100, 200), 50 wide, 40 high
The units are in PDF coordinates (points).

The match field for regions is ":" separated, and starts
with "R1"  (region version 1):
  R1:{page#}:{x}:{y}:{w}:{h} 

In addition, the border style is set with the "border" field:

  border: "B1:#000000:3:0:#ffffff:1:2:1:0"

The border field value is colon separated containing the values:
  "B1" indicates a border definition, version 1
  outer color (RGB hex format)
  outer width in pixels
  outer style (0=solid, 1=dots, 2=dashed)
  inner color (eg the dashed white line above a wider solid black border)
  inner width in pixels
  inner style(0=solid, 1=dots, 2=dashed)
  inner offset (so 1 means there is one pixel of the main border before the inner one starts)
  shape (0= square, 1=oval, 2=dotted oval)

4.4 Replies to notes

Replies to a note are included in the 'replies' array, which is an array of note objects with type set to "reply":

    
  notes: [
   {
          pageurl: "local:2008-05-08/zvq123", 
          type: "note",                  
          // ... other fields as above ...
          finalTags : "person, contact, important",  // latest version of tags (may be modified by replies)
          replies: [
             {
                pageurl: "local:2008-05-08/zvq123", 
                type: "reply",
                subject: "(reply)",
                notetext: "this is a reply to the note...",
                signed: "jack",                     // public signature for note
                date: "2008-05-07 14:13.12",        // time note written in GMT
                tags: "person, contact, important", // tags when reply created
                gid: 123,                           // ID of the note this is a reply to
                replyid: 151,                       // ID of this reply
                color: 2,                           // bg color index of this reply
                state: "live"                       // "dead" for deleted notes
             }
             // , { more replies ... }
          ]
    }
    // , { fields of note 2 ... }
  ]

The entries in the replies array are notes with type set to "reply", and the same gid value as the main note. The tags field records the tags as they were updated by the reply, so it is possible to extract the complete tag history if replies add / remove tags to the note. The finalTags field of the note records the most recent tag state of the note. The replyid field of a reply is needed for editing / deleting replies; supply it along with the gid of the original note to addNote.php to update a reply.

4.5 Freehand drawing annotations [new: May 2010]

Freehand annotations are stored in a drawing field, which contains a JSON encoded array; a sample is below:

    
// a note:
  {
     pageurl: "local:2010-01-01/abc123",
     match: "R1:4:70:500:200:200",  // rectangular region
     drawing: [                     // list of strokes
       {
         color: "#ff0000",            // RGB color, css format
         width: 2,                    // line width, in pts
         np: 42,                      // number of points
         time: 1200,                  // start time of stroke (ms)
         xpts: [10.2,13.3,15.7,10, ... ],   // X offset coords (in pts)
         ypts: [10.4,10,12,15, ... ],   // Y offset coords (in pts)
         times: [0,3,14,40,80, ...],  // timestamps (ms)
         {pressure: [30,40,45,45,20, ...]}  // (optional) pen pressure at each point (1-100)
       }, 
       {
         color: "#0000ff",
         // ... rest of fields for stroke 2
       },
       // {... more strokes}
     ]
  }

The drawing field, if present, encodes a freehand drawing as a list of pen strokes. The match field includes the highlighted rectangle within which the drawing had been done; the format of this is the same as for rectangle annotations, i.e. "R1:{page}:{x}:{y}:{w}:{h}". The drawing points xpts and ypts are relative to this rectangle; all coordinates are in PDF points (1/72 inch). If the drawing has been done on a pressure-sensitive graphics tablet, there will also be an array of pressure information - which could be displayed as opacity or line thickness in your application. Note that in order to gather pen pressure information you need to have Silverlight installed, and to use an operating system which passes pen pressure information to Silverlight; currently this is only supported by Microsoft on Windows 7, Windows Vista, and tablet PC editions of Windows XP; Silverlight on regular XP, and Mac OSX does not support variable pen pressure.

5. Folders

Documents can be added to folders, arranged in a hierarchy. These folders can be shared with several people, giving automatic access to the documents within. To list all folders for a given user, use the listFolders.php API call:

    http://your.server.com/annotate/php/listFolders.php?    
     api-user=joe@example.com
     &api-requesttime=1234566
     &api-annotateuser=jill@example.com
     &api-auth=ABC123...

The return value will either be "ERR {some error message}" or a JSON encoded object:

{
  foldersbyid: {
    "2008-11-05/abc234" : {
       name: "sample folder",
       owner: "joe@example.com",
       id: "2008-11-05/abc234",
       parentid: "",   // "" for top level, otherwise the id of the parent folder
       childids: [],   // array of child folder ids
       meta: {
         // ... detailed metadata for folder, including sharing info
       }
    },
    "2008-12-01/xyz123" : { 
      // ... details for 2nd folder
    }
  },
  topids: [ // array of folder ids at top level
    "2008-11-05/abc234",
    "2008-12-01/xyz123"
  ]
}

The object returned contains the field foldersbyid, a map of folder ID to its info, and the array topids, a list of the folders at the top level. A folderid is a string like "2008-01-02/abc234" containing the date the folder was created and a random code.

For details of API calls to create, move and rename folders, see part 3 of the reference guide. The listDocuments API call has a parameter to restrict results to documents in a given folder - see above.

6. Fetching lists of documents and all their notes

To fetch the notes for all documents uploaded in a given time frame, set withnotes=1 in the call to listDocuments.php described above in section 3. For each document returned which has notes, you will get an extra field "notes" containing an array of notes. For large numbers of documents, this API request will be slower than fetching the basic information, so for scalability you may wish to restrict requests to a few months at a time.

[ // array of months
  [ // array of doc meta for a month
    {  // sample extended metadata for a document:
      name: "10.1371_journal.ppat.0030096-S.pdf",
      code: "zvq123",
      date: "2008-05-08",
      owner: "joe@example.com",
      meta: {
        // ... meta for doc as before
      }
      notes: [ // array of notes in creation order
        {
          pageurl: "local:2008-05-08/zvq123", 
          type: "note",                   // or "reply"
          pagetitle: "", 
          context: "some sentence about jane bloggs and her collection of newts",
          subject: "jane bloggs",
          notetext: "this is the text of the note itself",
          signed: "joe",                  // public signature for note
          date: "2008-05-07 12:13.12",    // time note written in GMT
          tags: "person, contact",        // tags when first created
          match: "page-1:8:10",           // where note is attached (page 1, from word #8 to word #10)
          gid: 1,                         // ID of this note
          color: 2,                       // index of the background color of note
          state: "live",                  // "dead" for deleted notes
          finalTags : "person, contact",  // latest version of tags (maybe modified by replies)
          replies: []                     // {optional} list of replies to this note
        }
      ]
    } // end of metadata for document
  ] // end of array for month
] // end of array of months

7. Exporting PDF with notes

You can export a PDF with notes for a given uploaded document using an HTTP GET call to apiExportPdf.php:

   http://your.server.com/annotate/php/apiExportPdf.php?    
     api-user=joe@example.com
     &api-requesttime=1234566
     &api-annotateuser=jill@example.com
     &api-auth=ABC123...

     &d=2009-01-02                    // Date of pdf document
     &c=xyz123                        // Code of pdf document
     &subset=1                        // '0': all pages; '1': just those with notes
     &exportFormat=margin             // (optional - added Sep 2010): 
                                          // 'margin' : default (notes in rhs margin)
                                          // 'hand'   : for full size pages w handwriting only

The return value will either be "ERR {some error message}" or "OK {pdf_url} {modified_time}", where the pdf_url is the url of the exported PDF file (which includes a long random code), and the modified_time is the timestamp of the exported file.

// sample return string, space separated, third item is file modified time.
  OK http://yoursite.com/annotate/js/docs/xxxxxxx12345/welcome-notes.pdf 1234567

8. Exporting notes as Word Track-Changes [Added Aug 2010]

For documents uploaded as Word .docx or Word2003 .xml, you can export a new .docx (or .xml) file with the comments (and deletes and insertions) included as tracked changes, using an HTTP GET call to apiExportWord.php:

   http://your.server.com/annotate/php/apiExportWord.php?    
     api-user=joe@example.com
     &api-requesttime=1234566
     &api-annotateuser=jill@example.com
     &api-auth=ABC123...

     &d=2009-01-02                    // Date of uploaded .docx or word2003 .xml document
     &c=xyz123                        // Code of document

The return value will either be "ERR {some error message}" or "OK {word_url} {modified_time}", where the word_url is the url of the exported Word file (which includes a long random code), and the modified_time is the timestamp.

// sample return string, space separated, third item is file modified time.
  OK http://yoursite.com/annotate/js/docs/xxxxxxx12345/somedoc-export.docx 1234567

8.1 Providing the source Word document if you uploaded a PDF [Added Aug 2010]

[advanced] In order to export a new Word document with the comments, a.nnotate needs to have access to the original. This will be automatic if you uploaded the .docx file to a.nnotate (e.g. using the uploadDocument call), but if you managed the conversion to PDF using your own code, and only uploaded the pdf version, you will need to also supply the Word version if you want to be able to export track changes. This can be done using the apiProvideSourceDocument api call, providing the docurl and docname arguments. Currently this only supports .docx and word2003 .xml file formats; the binary .doc file format cannot be used.

   http://your.server.com/annotate/php/apiProvideSourceDocument.php?    
     api-user=joe@example.com
     &api-requesttime=1234566
     &api-annotateuser=jill@example.com
     &api-auth=ABC123...

     &d=2009-01-02                    // Date of uploaded PDF document
     &c=xyz123                        // Code of document

     &docurl=http://yoursite.com/somefile.docx   // http URL to fetch .docx file 
     &docname=somefile.docx                      // Filename of .docx file (or .xml word2003)

#    &docxmltype=word2003                        // optional: if uploading word2003 .xml

The return value is "OK" or "ERR + message". After calling this, you will be able to call apiExportWord above.

9. Listing a user's annotation activity timestamps

You can extract the activity log for a given user, which contains the timestamps and IDs of notes they have added. This can be useful to keep track of how much time each user has spent annotating. The admin user can also extract a log of activity by all users in the account.

   http://your.server.com/annotate/php/listActivity.php?    
     api-user=joe@example.com
     &api-requesttime=1234566
     &api-annotateuser=jill@example.com
     &api-auth=ABC123...
    
     &allusers=0       # set to 1 to return activity for all users in account

The return value will either be "ERR {some error message}" or a JSON encoded array with fields time - the date and time the note was added (GMT); type - usually "note", "reply"; docdate, doccode - the document ids; noteid the ID of the note. If allusers=1 then the user field is also set.

[
  { 
    user: "joe@example.com",     // user field only set if allusers=1
    time: "2009-02-18 16:27.46", 
    type: "note", 
    docdate: "2009-01-01",
    doccode: "abc123",
    noteid: 29
  },
  {
    // ... more activity log entries
  }
]

10. Get version number of server (added Aug 2010)

A HTTP GET call to apiGetVersion.php will return "OK " + the server version number. This api call was only added in v3.1.10 (Aug 2010), so for earlier versions you will need to check the version number in the annotate-server-x.x.x.tgz file installed.

HTTP GET call (no authentication needed):
   http://your.server.com/annotate/php/apiGetVersion.php

# Sample return value:
OK 3.1.10

API reference parts 2 and 3

Part 2 of the API reference guide includes the calls to create accounts, upload documents, add notes, and allow authorized users to annotate particular documents.

Part 3 of the API reference guide - Folders includes the calls to manipulate folders.