docs: function(key, file, options) {
        options = opts(this, options);
        if (!key) key = this.keygen();
        if (!options.filename) options.filename = key;
  
        // Warning: may not necessarily use ajax to perform upload.
        var apicall = new APICall({
          action: 'binary/' + key,
          type: 'post',
          later: true,
          encoding: 'binary',
          options: options,
          processResponse: APICall.basicResponse
        });
  
        function upload(data, type) {
          if (!options.contentType) options.contentType = type || defaultType;
          APICall.binaryUpload(apicall, data, options.filename, options.contentType).done();
        }
  
        if (isString(file) || (Buffer && file instanceof Buffer)) {
          // Upload by filename
  
          if (isNode) {
            if (isString(file)) file = fs.readFileSync(file);
            upload(file);
          }
          else NotSupported();
        } else if (file.toDataURL) {
          // Canvas will have a toDataURL function.
          upload(file, 'image/png');
        } else if (CanvasRenderingContext2D && file instanceof CanvasRenderingContext2D) {
          upload(file.canvas, 'image/png');
        } else if (isBinary(file)) {
          // Binary files are base64 encoded from a buffer.
          var reader = new FileReader();
  
          /** @private */
          reader.onabort = function() {
            apicall.setData("FileReader aborted").abort();
          }
  
          /** @private */
          reader.onerror = function(e) {
            apicall.setData(e.target.error).abort();
          }
  
          /** @private */
          reader.onload = function(e) {
            upload(e.target.result);
          }
  
          // Don't need to transform Files to Blobs.
          if (File && file instanceof File) {
            if (!options.contentType && file.type != "") options.contentType = file.type;
          } else {
            file = new Blob([ new Uint8Array(file) ], {type: options.contentType || defaultType});
          }
  
          reader.readAsDataURL(file);
        } else NotSupported();
  
        return apicall;
      }