diff --git a/docs/API.md b/docs/API.md
new file mode 100644
index 0000000..a174dd6
--- /dev/null
+++ b/docs/API.md
@@ -0,0 +1,545 @@
+### Modules / API
+
+The noVNC client is a composed of several modular components that handle
+rendering, input, networking, etc. Each of the modules is designed to
+be cross-browser and be useful as a standalone library in other
+projects (see LICENSE.txt).
+
+
+### Module List
+
+* **Mouse** (core/input/devices.js): Mouse input event handler with
+limited touch support.
+
+* **Keyboard** (core/input/devices.js): Keyboard input event handler with
+non-US keyboard support. Translates keyDown and keyUp events to X11
+keysym values.
+
+* **Display** (core/display.js): Efficient 2D rendering abstraction
+layered on the HTML5 canvas element.
+
+* **Websock** (core/websock.js): Websock client from websockify
+with transparent binary data support.
+[Websock API](https://github.com/kanaka/websockify/wiki/websock.js) wiki page.
+
+* **RFB** (core/rfb.js): Main class that implements the RFB
+protocol and stitches the other classes together.
+
+
+### Configuration Attributes
+
+The Mouse, Keyboard, Display and RFB classes have a similar API for
+configuration options. Each configuration option has a default value,
+which can be overridden by a a configuration object passed to the
+constructor. Configuration options can then be read and modified after
+initialization with "get_*" and "set_*" methods respectively. For
+example, the following initializes an RFB object with the 'encrypt'
+configuration option enabled, then confirms it was set, then disables
+it.
+
+ var rfb = new RFB({'encrypt': true});
+ if (rfb.get_encrypt()) {
+ alert("Encryption is set");
+ }
+ rfb.set_encrypt(false);
+
+Some attributes are read-only and cannot be changed. For example, the
+Display 'render_mode' option will throw an exception if an attempt is
+made to set it. The attribute mode is one of the following:
+
+ RO - read only
+ RW - read write
+ WO - write once
+
+
+### Methods
+
+In addition to the getter and setter methods to modify configuration
+attributes, each of the modules has other methods that are available
+in the object instance. For example, the Display module has method
+named 'blitImage' which takes an array of pixel data and draws it to
+the 2D canvas.
+
+### Callbacks
+
+Each of the modules has certain events that can be hooked with
+callback functions. For the Mouse, Keyboard, Display and RFB classes
+the callback functions are assigned to configuration attributes. The
+WebSock module has a method named 'on' that takes two parameters: the
+callback event name, and the callback function.
+
+
+#### Mouse Module
+
+
+
+ | Configuration Attributes |
+
+
+ | name | type | mode | default |
+ description |
+
+
+ | target | DOM | WO | |
+ Canvas element for rendering |
+
+
+ | context | raw | RO | |
+ Canvas 2D context for rendering |
+
+
+ | logo | raw | RW | |
+ Logo to display when cleared: {"width": width, "height": height, "type": mime-type, "data": data} |
+
+
+ | scale | float | RW | 1.0 |
+ Display area scale factor 0.0 - 1.0 |
+
+
+ | viewport | bool | RW | false |
+ Use viewport clipping |
+
+
+ | width | int | RO | |
+ Display area width |
+
+
+ | height | int | RO | |
+ Display area height |
+
+
+ | render_mode | str | RO | '' |
+ Canvas rendering mode |
+
+
+ | prefer_js | str | RW | |
+ Prefer JavaScript over canvas methods |
+
+
+ | cursor_uri | raw | RW | |
+ Can we render cursor using data URI |
+
+ | |
+
+ | Methods |
+
+
+ | name | parameters | description |
+
+
+ | viewportChangePos | (deltaX, deltaY) |
+ Move the viewport relative to the current location |
+
+
+ | viewportChangeSize | (width, height) |
+ Change size of the viewport |
+
+
+ | absX | (x) |
+ Return X relative to the remote display |
+
+
+ | absY | (y) |
+ Return Y relative to the remote display |
+
+
+ | resize | (width, height) |
+ Set width and height |
+
+
+ | flip | (from_queue) |
+ Update the visible canvas with the contents of the rendering canvas |
+
+
+ | clear | () |
+ Clear the display (show logo if set) |
+
+
+ | pending | () |
+ Check if there are waiting items in the render queue |
+
+
+ | flush | () |
+ Resume processing the render queue unless it's empty |
+
+
+ | fillRect | (x, y, width, height, color, from_queue) |
+ Draw a filled in rectangle |
+
+
+ | copyImage | (old_x, old_y, new_x, new_y, width, height, from_queue) |
+ Copy a rectangular area |
+
+
+ | imageRect | (x, y, mime, arr) |
+ Draw a rectangle with an image |
+
+
+ | startTile | (x, y, width, height, color) |
+ Begin updating a tile |
+
+
+ | subTile | (tile, x, y, w, h, color) |
+ Update a sub-rectangle within the given tile |
+
+
+ | finishTile | () |
+ Draw the current tile to the display |
+
+
+ | blitImage | (x, y, width, height, arr, offset, from_queue) |
+ Blit pixels (of R,G,B,A) to the display |
+
+
+ | blitRgbImage | (x, y, width, height, arr, offset, from_queue) |
+ Blit RGB encoded image to display |
+
+
+ | blitRgbxImage | (x, y, width, height, arr, offset, from_queue) |
+ Blit RGBX encoded image to display |
+
+
+ | drawImage | (img, x, y) |
+ Draw image and track damage |
+
+
+ | changeCursor | (pixels, mask, hotx, hoty, w, h) |
+ Change cursor appearance |
+
+
+ | defaultCursor | () |
+ Restore default cursor appearance |
+
+
+ | disableLocalCursor | () |
+ Disable local (client-side) cursor |
+
+
+ | clippingDisplay | () |
+ Check if the remote display is larger than the client display |
+
+
+ | autoscale | (containerWidth, containerHeight, downscaleOnly) |
+ Scale the display |
+
+ | |
+
+ | Callbacks |
+
+
+ | name | parameters | description |
+
+
+ | onFlush | () |
+ A display flush has been requested and we are now ready to resume FBU processing |
+
+
+
+
+#### RFB Module
+
+
+
+ | Configuration Attributes |
+
+
+ | name | type | mode | default |
+ description |
+
+
+ | target | DOM | WO | null |
+ Canvas element for rendering (passed to Display and Mouse) |
+
+
+ | focusContainer | DOM | WO | document |
+ DOM element that captures keyboard input (passed to Keyboard) |
+
+
+ | encrypt | bool | RW | false |
+ Use TLS/SSL encryption |
+
+
+ | local_cursor | bool | RW | false |
+ Request locally rendered cursor |
+
+
+ | shared | bool | RW | true |
+ Request shared VNC mode |
+
+
+ | view_only | bool | RW | false |
+ Disable client mouse/keyboard |
+
+
+ | xvp_password_sep | str | RW | '@' |
+ Separator for XVP password fields |
+
+
+ | disconnectTimeout | int | RW | 3 |
+ Time (in seconds) to wait for disconnection |
+
+
+ | wsProtocols | arr | RW | ['binary'] |
+ Protocols to use in the WebSocket connection |
+
+
+ | repeaterID | str | RW | '' |
+ UltraVNC RepeaterID to connect to |
+
+
+ | viewportDrag | bool | RW | false |
+ Move the viewport on mouse drags |
+
+ | |
+
+ | Methods |
+
+
+ | name | parameters | description |
+
+
+ | connect | (host, port, password, path) |
+ Connect to the given host:port/path. Optional password and path. |
+
+
+ | disconnect | () |
+ Disconnect |
+
+
+ | sendPassword | (passwd) |
+ Send password after onPasswordRequired callback |
+
+
+ | sendCtrlAltDel | () |
+ Send Ctrl-Alt-Del key sequence |
+
+
+ | xvpOp | (ver, op) |
+ Send a XVP operation (2=shutdown, 3=reboot, 4=reset) |
+
+
+ | xvpShutdown | () |
+ Send XVP shutdown. |
+
+
+ | xvpReboot | () |
+ Send XVP reboot. |
+
+
+ | xvpReset | () |
+ Send XVP reset. |
+
+
+ | sendKey | (keysym, down) |
+ Send a key press event. If down not specified, send a down and up event. |
+
+
+ | clipboardPasteFrom | (text) |
+ Send a clipboard paste event |
+
+
+ | requestDesktopSize | (width, height) |
+ Send a request to change the remote desktop size. |
+
+ | |
+
+ | Callbacks |
+
+
+ | name | parameters | description |
+
+
+ | onUpdateState | (rfb, state, oldstate) |
+ Connection state change (see details below) |
+
+
+ | onNotification | (rfb, msg, level, options) |
+ Notification for the UI (optional options) |
+
+
+ | onDisconnected | (rfb, reason) |
+ Disconnection finished with an optional reason. No reason specified means normal disconnect. |
+
+
+ | onPasswordRequired | (rfb, msg) |
+ VNC password is required (use sendPassword), optionally comes with a message. |
+
+
+ | onClipboard | (rfb, text) |
+ RFB clipboard contents received |
+
+
+ | onBell | (rfb) |
+ RFB Bell message received |
+
+
+ | onFBUReceive | (rfb, fbu) |
+ RFB FBU received but not yet processed (see details below) |
+
+
+ | onFBUComplete | (rfb, fbu) |
+ RFB FBU received and processed (see details below) |
+
+
+ | onFBResize | (rfb, width, height) |
+ Frame buffer (remote desktop) size changed |
+
+
+ | onDesktopName | (rfb, name) |
+ VNC desktop name recieved |
+
+
+ | onXvpInit | (version) |
+ XVP extensions active for this connection. |
+
+
+
+
+**RFB onUpdateState callback details**
+
+The RFB module has an 'onUpdateState' callback that is invoked after
+the noVNC connection state changes. Here is a list of the states that
+are reported.
+
+