diff --git a/packages/InkBackend/InkBackend.js b/packages/InkBackend/InkBackend.js
index 02820420d75dcaad6dad7712c7a0501313516406..af30d3c8319ab28fe7155a440edb8a7729801a14 100644
--- a/packages/InkBackend/InkBackend.js
+++ b/packages/InkBackend/InkBackend.js
@@ -1,214 +1,172 @@
-const config = require('config')
-const rp = require('request-promise-native')
-const Busboy = require('busboy')
-const temp = require('temp').track()
 const fs = require('fs')
 const path = require('path')
-const promiseRetry = require('promise-retry')
 const logger = require('@pubsweet/logger')
+const Busboy = require('busboy')
+const config = require('config')
+const rp = require('request-promise-native')
+const temp = require('temp')
+
+// rp.debug = true
+
+const inkConfig = config.get('pubsweet-component-ink-backend')
 
-let inkConfig = config.get('pubsweet-component-ink-backend')
-let inkEndpoint = inkConfig.inkEndpoint
-let email = inkConfig.email
-let password = inkConfig.password
-let maxRetries = inkConfig.maxRetries || 60
+// Generate the absolute URL
+const inkUrl = path => inkConfig.inkEndpoint + 'api/' + path
 
-let authRequest = {
-  uri: inkEndpoint + '/api/auth/sign_in',
+// Sign in
+const authorize = () => rp({
   method: 'POST',
-  body: {
-    email: email,
-    password: password
+  uri: inkUrl('auth/sign_in'),
+  formData: {
+    email: inkConfig.email,
+    password: inkConfig.password
   },
-  json: true,
   headers: {
     'Accept': 'application/vnd.ink.1'
   },
   resolveWithFullResponse: true
-}
+}).then(res => ({
+  'client': res.headers['client'],
+  'access-token': res.headers['access-token']
+}))
 
-// Get an access token
-let getAuth = () => {
-  return rp(authRequest).then(response => {
-    return {
-      accessToken: response.headers['access-token'],
-      client: response.headers['client']
-    }
-  }).catch(
-    err => {
-      logger.error('INK API LOGIN FAILURE:', err)
-      throw err
-    }
-  )
-}
+// Upload file to INK and execute the recipe
+const upload = (recipeId, inputFile, auth) => rp({
+  method: 'POST',
+  uri: inkUrl('recipes/' + recipeId + '/execute'),
+  headers: {
+    uid: inkConfig.email,
+    ...auth
+  },
+  formData: {
+    input_files: [inputFile]
+  },
+  json: true,
+  timeout: 60 * 60 * 1000 // 3600 seconds
+})
 
-let defaultRecipeId = null
-let recipeListUrl = inkEndpoint + '/api/recipes'
+// Download the output file (keep trying if there's a 404 response, until it's ready)
+const download = async (chain, auth, outputFileName) => {
+  const manifest = chain.input_file_manifest
 
-const getRecipeId = () => {
-  if (defaultRecipeId) return Promise.resolve(defaultRecipeId)
+  if (manifest.length === 0) {
+    throw new Error('The INK server gave a malformed response (no input files in the process chain)')
+  }
 
-  const listRequest = auth => ({
-    method: 'GET',
-    uri: recipeListUrl,
-    headers: {
-      'uid': email,
-      'access-token': auth.accessToken,
-      'client': auth.client
-    }
-  })
+  const interval = inkConfig.interval || 1000 // try once per second
 
-  return getAuth().then(
-    auth => rp(listRequest(auth))
-  ).then(
-    response => Promise.resolve(JSON.parse(response))
-  ).then(
-    response => {
-      const defaultRecipe = response.recipes.find(
-        recipe => recipe.name === 'Editoria Typescript' // XSweet recipe
-      )
-      if (!defaultRecipe) throw new Error('could not get default recipe from INK')
-      defaultRecipeId = defaultRecipe.id
-      return Promise.resolve(defaultRecipeId)
-    }
-  )
-}
+  const maxRetries = inkConfig.maxRetries || 300 // retry for up to 5 minutes
 
-getRecipeId()
-
-const inkRecipeUrl = () => getRecipeId().then(
-  recipeId => Promise.resolve(inkEndpoint + '/api/recipes/' + recipeId + '/execute')
-)
-
-const healthCheckRequest = auth => inkRecipeUrl().then(
-  recipeUrl => {
-    const opts = {
-      uri: recipeUrl,
-      method: 'OPTIONS',
-      headers: {
-        'Access-Control-Request-Method': 'POST',
-        'Access-Control-Request-Headers': 'access-token, client, expiry, token-type, uid',
-        'Origin': 'http://ink.coko.foundation',
-        'access-token': auth.accessToken,
-        'client': auth.client
-      }
-    }
-    return Promise.resolve(opts)
-  }
-)
-
-const uploadRequest = (data, auth) => inkRecipeUrl().then(
-  recipeUrl => {
-    const opts = {
-      uri: recipeUrl,
-      method: 'POST',
-      headers: {
-        'uid': email,
-        'access-token': auth.accessToken,
-        'client': auth.client
-      },
-      formData: {
-        input_files: [data]
-      }
-    }
-    return Promise.resolve(opts)
-  }
-)
+  const uri = inkUrl('process_chains/' + chain.id + '/download_output_file')
 
-// Upload file to INK and execute the recipe
-const uploadToInk = data => auth => uploadRequest(
-  data, auth
-).then(
-  rp
-).then(
-  response => Promise.resolve([auth, JSON.parse(response)])
-)
-
-// Check if INK is alive and well
-const checkInk = auth => healthCheckRequest(auth).then(
-  rp
-).then(
-  response => {
-    return Promise.resolve(auth)
+  const qs = {
+    relative_path: outputFileName || path.basename(manifest[0].path, '.docx') + '.html'
   }
-).catch(
-  err => {
-    throw err
+
+  const headers = {
+    uid: inkConfig.email,
+    ...auth
   }
-)
-
-const retryFor30SecondsUntil200 = (uri, auth) => {
-  const downloadRequest = {
-    method: 'GET',
-    uri: uri,
-    headers: {
-      'uid': email,
-      'access-token': auth.accessToken,
-      'client': auth.client
+
+  for (let i = 0; i < maxRetries; i++) {
+    // delay
+    await new Promise(resolve => setTimeout(resolve, interval))
+
+    const response = await rp({
+      uri,
+      qs,
+      headers,
+      simple: false,
+      resolveWithFullResponse: true
+    }).catch(error => {
+      logger.error('Error downloading from INK:', error.message)
+      throw error
+    })
+
+    // a successful request: return the data
+    if (response.statusCode === 200) {
+      return response.body
+    }
+
+    // not a 404 response - stop trying
+    if (response.statusCode !== 404) {
+      break
     }
   }
 
-  return promiseRetry(
-    (retry, number) => {
-      return rp(downloadRequest).catch(retry)
-    },
-    { retries: maxRetries, factor: 1, minTimeout: 3000 }
-  )
+  throw new Error('Unable to download the output from INK')
 }
 
-const downloadUrl = (chainId, relPath) => inkEndpoint +
-  '/api/process_chains/' +
-  chainId +
-  '/download_output_file?relative_path=' +
-  relPath +
-  '.html'
+const findRecipeId = (recipeKey = 'Editoria Typescript', auth) => rp({
+  method: 'GET',
+  uri: inkUrl('recipes'),
+  headers: {
+    uid: inkConfig.email,
+    ...auth
+  },
+  json: true
+}).then(data => {
+  const recipe = data.recipes.find(recipe => recipe.name === recipeKey)
 
-const downloadFromInk = ([auth, response]) => {
-  if (response.process_chain.input_file_manifest.length === 0) {
-    throw new Error('The INK server gave a malformed response (no input files in the process chain)')
-  }
-  const relPath = path.basename(response.process_chain.input_file_manifest[0].path, '.docx')
-  const url = downloadUrl(response.process_chain.id, relPath)
-  return retryFor30SecondsUntil200(url, auth)
+  return recipe ? recipe.id : null
+})
+
+const process = async (inputFile, options) => {
+  const auth = await authorize().catch(err => {
+    logger.error('INK API LOGIN FAILURE:', err.message)
+    throw err
+  })
+
+  // either use the recipe id from the configuration or search for it by name
+  const recipeId = inkConfig.recipes[options.recipe] || await findRecipeId(options.recipe, auth)
+  if (!recipeId) throw new Error('Unknown recipe')
+
+  const response = await upload(recipeId, inputFile, auth).catch(err => {
+    logger.error('INK API UPLOAD FAILURE:', err.message)
+    throw err
+  })
+
+  return download(response.process_chain, auth, options.outputFileName)
 }
 
-var InkBackend = function (app) {
+const InkBackend = function (app) {
+  // TODO: authentication on this route
   app.use('/api/ink', (req, res, next) => {
-    var fileStream = new Busboy({ headers: req.headers })
-
-    const handleErr = err => {
-      logger.error('ERROR CONVERTING WITH INK', err)
-      next(err)
-    }
+    const fileStream = new Busboy({ headers: req.headers })
 
     fileStream.on('file', (fieldname, file, filename, encoding, contentType) => {
-      var stream = temp.createWriteStream()
-      file.pipe(stream)
-
-      file.on('end', () => {
-        stream.end()
+      const stream = temp.createWriteStream()
 
-        var fileOpts = {
+      stream.on('finish', () => {
+        const inputFile = {
           value: fs.createReadStream(stream.path),
-          options: {
-            filename: filename,
-            contentType: contentType
-          }
+          options: { filename, contentType }
         }
 
-        getAuth().then(
-          checkInk
-        ).then(
-          uploadToInk(fileOpts)
-        ).then(
-          downloadFromInk
-        ).then(
-          response => res.send(response)
-        ).catch(handleErr)
+        process(inputFile, req.query).then(converted => {
+          res.json({ converted })
+
+          // clean up temp file
+          fs.unlink(stream.path, () => {
+            logger.info('Deleted temporary file', stream.path)
+          })
+        }).catch(err => {
+          logger.error('ERROR CONVERTING WITH INK:', err.message)
+          next(err)
+        })
+      })
+
+      file.pipe(stream)
+
+      file.on('end', () => {
+        stream.end()
       })
     })
 
-    fileStream.on('error', handleErr)
+    fileStream.on('error', err => {
+      logger.error(err)
+      next(err)
+    })
 
     req.pipe(fileStream)
   })
diff --git a/packages/InkBackend/package.json b/packages/InkBackend/package.json
index 94229aa9e4bea5d851f28f15d038fad067d2d9c2..80e7fd3b72d29486e0e8e2436447fc24d0503496 100644
--- a/packages/InkBackend/package.json
+++ b/packages/InkBackend/package.json
@@ -15,9 +15,8 @@
     "@pubsweet/logger": "^0.0.1",
     "busboy": "^0.2.13",
     "config": "^1.26.1",
-    "promise-retry": "^1.1.1",
-    "request": "^2.79.0",
-    "request-promise-native": "^1.0.3",
+    "request": "^2.83.0",
+    "request-promise-native": "^1.0.5",
     "temp": "^0.8.3"
   }
 }
diff --git a/packages/InkBackend/yarn.lock b/packages/InkBackend/yarn.lock
index 489024b94451f2ac8fd61b73ace657eee05f4c82..e6cbed36c05b4084eb0c76253c238eed23b7619d 100644
--- a/packages/InkBackend/yarn.lock
+++ b/packages/InkBackend/yarn.lock
@@ -9,12 +9,14 @@
     config "^1.26.2"
     joi "^10.6.0"
 
-ajv@^4.9.1:
-  version "4.11.8"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
+ajv@^5.1.0:
+  version "5.5.0"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.0.tgz#eb2840746e9dc48bd5e063a36e3fd400c5eab5a9"
   dependencies:
     co "^4.6.0"
-    json-stable-stringify "^1.0.1"
+    fast-deep-equal "^1.0.0"
+    fast-json-stable-stringify "^2.0.0"
+    json-schema-traverse "^0.3.0"
 
 asn1@~0.2.3:
   version "0.2.3"
@@ -24,19 +26,15 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
 
-assert-plus@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
-
 asynckit@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
 
-aws-sign2@~0.6.0:
-  version "0.6.0"
-  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+aws-sign2@~0.7.0:
+  version "0.7.0"
+  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
 
-aws4@^1.2.1:
+aws4@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
 
@@ -46,11 +44,17 @@ bcrypt-pbkdf@^1.0.0:
   dependencies:
     tweetnacl "^0.14.3"
 
-boom@2.x.x:
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
+boom@4.x.x:
+  version "4.3.1"
+  resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
+  dependencies:
+    hoek "4.x.x"
+
+boom@5.x.x:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
   dependencies:
-    hoek "2.x.x"
+    hoek "4.x.x"
 
 busboy@^0.2.13:
   version "0.2.14"
@@ -74,21 +78,21 @@ combined-stream@^1.0.5, combined-stream@~1.0.5:
     delayed-stream "~1.0.0"
 
 config@^1.26.1, config@^1.26.2:
-  version "1.26.2"
-  resolved "https://registry.yarnpkg.com/config/-/config-1.26.2.tgz#2466291168d8afae0aae8ab99ea4d4272f520cae"
+  version "1.28.1"
+  resolved "https://registry.yarnpkg.com/config/-/config-1.28.1.tgz#7625d2a1e4c90f131d8a73347982d93c3873282d"
   dependencies:
     json5 "0.4.0"
     os-homedir "1.0.2"
 
-core-util-is@~1.0.0:
+core-util-is@1.0.2, core-util-is@~1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
 
-cryptiles@2.x.x:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
+cryptiles@3.x.x:
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
   dependencies:
-    boom "2.x.x"
+    boom "5.x.x"
 
 dashdash@^1.12.0:
   version "1.14.1"
@@ -113,25 +117,29 @@ ecc-jsbn@~0.1.1:
   dependencies:
     jsbn "~0.1.0"
 
-err-code@^1.0.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
-
-extend@~3.0.0:
+extend@~3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
 
-extsprintf@1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
+extsprintf@1.3.0, extsprintf@^1.2.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+
+fast-deep-equal@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
+
+fast-json-stable-stringify@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
 
 forever-agent@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
 
-form-data@~2.1.1:
-  version "2.1.4"
-  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
+form-data@~2.3.1:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
   dependencies:
     asynckit "^0.4.0"
     combined-stream "^1.0.5"
@@ -143,39 +151,35 @@ getpass@^0.1.1:
   dependencies:
     assert-plus "^1.0.0"
 
-har-schema@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+har-schema@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
 
-har-validator@~4.2.1:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
+har-validator@~5.0.3:
+  version "5.0.3"
+  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
   dependencies:
-    ajv "^4.9.1"
-    har-schema "^1.0.5"
+    ajv "^5.1.0"
+    har-schema "^2.0.0"
 
-hawk@~3.1.3:
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
+hawk@~6.0.2:
+  version "6.0.2"
+  resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
   dependencies:
-    boom "2.x.x"
-    cryptiles "2.x.x"
-    hoek "2.x.x"
-    sntp "1.x.x"
-
-hoek@2.x.x:
-  version "2.16.3"
-  resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+    boom "4.x.x"
+    cryptiles "3.x.x"
+    hoek "4.x.x"
+    sntp "2.x.x"
 
 hoek@4.x.x:
   version "4.2.0"
   resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
 
-http-signature@~1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+http-signature@~1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
   dependencies:
-    assert-plus "^0.2.0"
+    assert-plus "^1.0.0"
     jsprim "^1.2.2"
     sshpk "^1.7.0"
 
@@ -216,16 +220,14 @@ jsbn@~0.1.0:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
 
+json-schema-traverse@^0.3.0:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
+
 json-schema@0.2.3:
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
 
-json-stable-stringify@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
-  dependencies:
-    jsonify "~0.0.0"
-
 json-stringify-safe@~5.0.1:
   version "5.0.1"
   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
@@ -234,34 +236,30 @@ json5@0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d"
 
-jsonify@~0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
-
 jsprim@^1.2.2:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
   dependencies:
     assert-plus "1.0.0"
-    extsprintf "1.0.2"
+    extsprintf "1.3.0"
     json-schema "0.2.3"
-    verror "1.3.6"
+    verror "1.10.0"
 
 lodash@^4.13.1:
   version "4.17.4"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
 
-mime-db@~1.27.0:
-  version "1.27.0"
-  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
+mime-db@~1.30.0:
+  version "1.30.0"
+  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
 
-mime-types@^2.1.12, mime-types@~2.1.7:
-  version "2.1.15"
-  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
+mime-types@^2.1.12, mime-types@~2.1.17:
+  version "2.1.17"
+  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
   dependencies:
-    mime-db "~1.27.0"
+    mime-db "~1.30.0"
 
-oauth-sign@~0.8.1:
+oauth-sign@~0.8.2:
   version "0.8.2"
   resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
 
@@ -273,24 +271,17 @@ os-tmpdir@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
 
-performance-now@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
-
-promise-retry@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d"
-  dependencies:
-    err-code "^1.0.0"
-    retry "^0.10.0"
+performance-now@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
 
 punycode@^1.4.1:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
 
-qs@~6.4.0:
-  version "6.4.0"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+qs@~6.5.1:
+  version "6.5.1"
+  resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
 
 readable-stream@1.1.x:
   version "1.1.14"
@@ -307,58 +298,54 @@ request-promise-core@1.1.1:
   dependencies:
     lodash "^4.13.1"
 
-request-promise-native@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.4.tgz#86988ec8eee408e45579fce83bfd05b3adf9a155"
+request-promise-native@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5"
   dependencies:
     request-promise-core "1.1.1"
     stealthy-require "^1.1.0"
-    tough-cookie ">=2.3.0"
+    tough-cookie ">=2.3.3"
 
-request@^2.79.0:
-  version "2.81.0"
-  resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
+request@^2.83.0:
+  version "2.83.0"
+  resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
   dependencies:
-    aws-sign2 "~0.6.0"
-    aws4 "^1.2.1"
+    aws-sign2 "~0.7.0"
+    aws4 "^1.6.0"
     caseless "~0.12.0"
     combined-stream "~1.0.5"
-    extend "~3.0.0"
+    extend "~3.0.1"
     forever-agent "~0.6.1"
-    form-data "~2.1.1"
-    har-validator "~4.2.1"
-    hawk "~3.1.3"
-    http-signature "~1.1.0"
+    form-data "~2.3.1"
+    har-validator "~5.0.3"
+    hawk "~6.0.2"
+    http-signature "~1.2.0"
     is-typedarray "~1.0.0"
     isstream "~0.1.2"
     json-stringify-safe "~5.0.1"
-    mime-types "~2.1.7"
-    oauth-sign "~0.8.1"
-    performance-now "^0.2.0"
-    qs "~6.4.0"
-    safe-buffer "^5.0.1"
-    stringstream "~0.0.4"
-    tough-cookie "~2.3.0"
+    mime-types "~2.1.17"
+    oauth-sign "~0.8.2"
+    performance-now "^2.1.0"
+    qs "~6.5.1"
+    safe-buffer "^5.1.1"
+    stringstream "~0.0.5"
+    tough-cookie "~2.3.3"
     tunnel-agent "^0.6.0"
-    uuid "^3.0.0"
-
-retry@^0.10.0:
-  version "0.10.1"
-  resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4"
+    uuid "^3.1.0"
 
 rimraf@~2.2.6:
   version "2.2.8"
   resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
 
-safe-buffer@^5.0.1:
+safe-buffer@^5.0.1, safe-buffer@^5.1.1:
   version "5.1.1"
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
 
-sntp@1.x.x:
-  version "1.0.9"
-  resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+sntp@2.x.x:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
   dependencies:
-    hoek "2.x.x"
+    hoek "4.x.x"
 
 sshpk@^1.7.0:
   version "1.13.1"
@@ -386,7 +373,7 @@ string_decoder@~0.10.x:
   version "0.10.31"
   resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
 
-stringstream@~0.0.4:
+stringstream@~0.0.5:
   version "0.0.5"
   resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
 
@@ -403,9 +390,9 @@ topo@2.x.x:
   dependencies:
     hoek "4.x.x"
 
-tough-cookie@>=2.3.0, tough-cookie@~2.3.0:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
+tough-cookie@>=2.3.3, tough-cookie@~2.3.3:
+  version "2.3.3"
+  resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
   dependencies:
     punycode "^1.4.1"
 
@@ -419,12 +406,14 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
   version "0.14.5"
   resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
 
-uuid@^3.0.0:
+uuid@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
 
-verror@1.3.6:
-  version "1.3.6"
-  resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
+verror@1.10.0:
+  version "1.10.0"
+  resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
   dependencies:
-    extsprintf "1.0.2"
+    assert-plus "^1.0.0"
+    core-util-is "1.0.2"
+    extsprintf "^1.2.0"
diff --git a/packages/InkFrontend/InkFrontend.jsx b/packages/InkFrontend/InkFrontend.jsx
index 78e7282be75e4125c80ef0c68fe3b136612f8f48..e18d40133a1cdac59c2817d51daa8ddb27682a92 100644
--- a/packages/InkFrontend/InkFrontend.jsx
+++ b/packages/InkFrontend/InkFrontend.jsx
@@ -3,41 +3,38 @@ import PropTypes from 'prop-types'
 import { Alert, Row, Col } from 'react-bootstrap'
 import Dropzone from 'react-dropzone'
 
-import escapeHtml from 'escape-html'
-
 export default class InkFrontend extends Component {
   constructor (props) {
     super(props)
     this.onDrop = this.onDrop.bind(this)
   }
 
+  onDrop (files) {
+    this.props.convert(files[0])
+  }
+
   render () {
-    const { ink, error } = this.props
+    const { ink } = this.props
 
     return (
       <div className='bootstrap'>
         { ink.isFetching ? <Alert bsStyle="info">INK is doing its thing...</Alert> : null }
-        { error ? <Alert bsStyle="danger">INK failed</Alert> : null }
+        { ink.error ? <Alert bsStyle="danger">INK failed</Alert> : null }
 
         <Row>
           <Col xs={12} md={2} mdOffset={5}>
             <Dropzone onDrop={this.onDrop} multiple={false}>
               <div>Try dropping some files here, or click to select files to upload.</div>
             </Dropzone>
-            { ink.converted ? <span>HERE { escapeHtml(ink.converted)}</span> : null}
+            { ink.converted ? <span>HERE { ink.converted }</span> : null}
           </Col>
         </Row>
       </div>
     )
   }
-
-  onDrop (files) {
-    this.props.actions.ink(files[0])
-  }
 }
 
 InkFrontend.propTypes = {
-  actions: PropTypes.object,
-  error: PropTypes.string,
+  convert: PropTypes.func,
   ink: PropTypes.object
 }
diff --git a/packages/InkFrontend/InkFrontendContainer.js b/packages/InkFrontend/InkFrontendContainer.js
index 77fa450973b13bce3d782de9e748c9de59d3a3ca..86e409c17a23638e0f197594d4c5573d589c79bf 100644
--- a/packages/InkFrontend/InkFrontendContainer.js
+++ b/packages/InkFrontend/InkFrontendContainer.js
@@ -1,22 +1,12 @@
-import { bindActionCreators } from 'redux'
 import { connect } from 'react-redux'
-import { ink } from './actions'
-
+import { ink as convert } from './actions'
 import InkFrontend from './InkFrontend'
 
-function mapState (state) {
-  return {
-    error: state.error,
+export default connect(
+  state => ({
     ink: state.ink
+  }),
+  {
+    convert
   }
-}
-
-function mapDispatch (dispatch) {
-  return {
-    actions: bindActionCreators({ ink }, dispatch)
-  }
-}
-
-export default connect(
-    mapState, mapDispatch
 )(InkFrontend)
diff --git a/packages/InkFrontend/actions.js b/packages/InkFrontend/actions.js
index eed368e3209a5bc871ee437d10e0e4c7ec82fa08..e5a014aa35c14937bb3a12f4fa7322e950c24e34 100644
--- a/packages/InkFrontend/actions.js
+++ b/packages/InkFrontend/actions.js
@@ -1,51 +1,43 @@
+import qs from 'query-string'
 import request from 'pubsweet-client/src/helpers/api'
-import * as T from './types'
-import config from 'config'
+import { INK_FAILURE, INK_REQUEST, INK_SUCCESS } from './types'
 
-const ENDPOINT = config['pubsweet-client']['API_ENDPOINT'].replace(/api$/, 'ink')
+export const inkRequest = () => ({
+  type: INK_REQUEST
+})
 
-function inkRequest () {
-  return {
-    type: T.INK_REQUEST,
-    isFetching: true
-  }
-}
+export const inkSuccess = converted => ({
+  type: INK_SUCCESS,
+  converted
+})
 
-function inkSuccess (converted) {
-  return {
-    type: T.INK_SUCCESS,
-    isFetching: false,
-    converted: converted
-  }
-}
+export const inkFailure = error => ({
+  type: INK_FAILURE,
+  error
+})
 
-function inkFailure (message) {
-  return {
-    type: T.INK_FAILURE,
-    isFetching: false,
-    error: message
-  }
-}
+export const ink = (file, options) => dispatch => {
+  dispatch(inkRequest())
 
-// Calls the API to get a token and
-// dispatches actions along the way
-export function ink (file) {
-  const data = new FormData()
-  data.append('file', file)
+  const body = new FormData()
+  body.append('file', file)
 
-  const options = {
-    method: 'POST',
-    body: data,
-    parse: false
-  }
+  let url = '/ink'
 
-  return dispatch => {
-    dispatch(inkRequest())
-    return request(ENDPOINT, options)
-      .then(
-        response => response.text() // TODO: return JSON from the backend
-      ).then(
-        response => dispatch(inkSuccess(response))
-      ).catch(err => dispatch(inkFailure(err)))
+  if (options) {
+    url += '?' + qs.stringify(options)
   }
+
+  return request(url, {
+    method: 'POST',
+    body
+  }).then(data => {
+    dispatch(inkSuccess(data.converted))
+
+    return data
+  }).catch(error => {
+    dispatch(inkFailure(error.message))
+
+    throw error
+  })
 }
diff --git a/packages/InkFrontend/package.json b/packages/InkFrontend/package.json
index 4a1c54406a862dbfd6b8ca82824e5fae3e437979..6ede87d3d61d3771187649c1e8ec869369cd50e7 100644
--- a/packages/InkFrontend/package.json
+++ b/packages/InkFrontend/package.json
@@ -21,8 +21,8 @@
   "author": "Collaborative Knowledge Foundation",
   "license": "MIT",
   "dependencies": {
-    "escape-html": "^1.0.3",
     "prop-types": "^15.5.10",
+    "query-string": "^5.0.1",
     "react-bootstrap": "^0.31.3",
     "react-dropzone": "^3.7.3",
     "react-redux": "^5.0.6",
diff --git a/packages/InkFrontend/reducers.js b/packages/InkFrontend/reducers.js
index a1928a81a2abfd0a757ac6377715804d259319e3..97b8298525bce7130f9782c7fe2821db5f2496bf 100644
--- a/packages/InkFrontend/reducers.js
+++ b/packages/InkFrontend/reducers.js
@@ -1,25 +1,34 @@
-import {
-  INK_REQUEST, INK_SUCCESS, INK_FAILURE
-} from './types'
+import { INK_FAILURE, INK_REQUEST, INK_SUCCESS } from './types'
 
-export default function ink (state = {
-  isFetching: false
-}, action) {
+const initialState = {
+  isFetching: false,
+  converted: null,
+  error: null
+}
+
+export default function ink (state = initialState, action) {
   switch (action.type) {
     case INK_REQUEST:
-      return Object.assign({}, state, {
-        isFetching: true
-      })
+      return {
+        isFetching: true,
+        converted: null,
+        error: null
+      }
+
     case INK_SUCCESS:
-      return Object.assign({}, state, {
+      return {
         isFetching: false,
-        converted: action.converted
-      })
+        converted: action.converted,
+        error: null
+      }
+
     case INK_FAILURE:
-      return Object.assign({}, state, {
+      return {
         isFetching: false,
+        converted: null,
         error: action.error
-      })
+      }
+
     default:
       return state
   }
diff --git a/packages/InkFrontend/types.js b/packages/InkFrontend/types.js
index ec7050e72e7ee2e4129c8458b3c61b7618906791..a521cd964b6f0e42cd62e549e4fac376abe772ae 100644
--- a/packages/InkFrontend/types.js
+++ b/packages/InkFrontend/types.js
@@ -1,5 +1,3 @@
-// Action types
-
 export const INK_REQUEST = 'INK_REQUEST'
 export const INK_SUCCESS = 'INK_SUCCESS'
 export const INK_FAILURE = 'INK_FAILURE'
diff --git a/packages/InkFrontend/yarn.lock b/packages/InkFrontend/yarn.lock
index 0c5e4b428d7e36c956354e3b024347bc8e324851..197f73df48725d29efb6fca401e2c2c5574df4ac 100644
--- a/packages/InkFrontend/yarn.lock
+++ b/packages/InkFrontend/yarn.lock
@@ -3,8 +3,8 @@
 
 
 asap@~2.0.3:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f"
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
 
 attr-accept@^1.0.3:
   version "1.1.0"
@@ -29,7 +29,11 @@ core-js@^2.4.0:
   version "2.5.1"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b"
 
-dom-helpers@^3.2.0:
+decode-uri-component@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
+
+dom-helpers@^3.2.0, dom-helpers@^3.2.1:
   version "3.2.1"
   resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a"
 
@@ -39,13 +43,9 @@ encoding@^0.1.11:
   dependencies:
     iconv-lite "~0.4.13"
 
-escape-html@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
-
-fbjs@^0.8.9:
-  version "0.8.12"
-  resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
+fbjs@^0.8.16:
+  version "0.8.16"
+  resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
   dependencies:
     core-js "^1.0.0"
     isomorphic-fetch "^2.1.1"
@@ -60,8 +60,8 @@ hoist-non-react-statics@^2.2.1:
   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
 
 iconv-lite@~0.4.13:
-  version "0.4.18"
-  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2"
+  version "0.4.19"
+  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
 
 invariant@^2.0.0, invariant@^2.1.0, invariant@^2.2.1:
   version "2.2.2"
@@ -103,13 +103,13 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
     js-tokens "^3.0.0"
 
 node-fetch@^1.0.1:
-  version "1.7.1"
-  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.1.tgz#899cb3d0a3c92f952c47f1b876f4c8aeabd400d5"
+  version "1.7.3"
+  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
   dependencies:
     encoding "^0.1.11"
     is-stream "^1.0.1"
 
-object-assign@^4.1.0:
+object-assign@^4.1.0, object-assign@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
 
@@ -125,16 +125,25 @@ prop-types-extra@^1.0.1:
   dependencies:
     warning "^3.0.0"
 
-prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8:
-  version "15.5.10"
-  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
+prop-types@^15.5.10, prop-types@^15.5.7:
+  version "15.6.0"
+  resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
   dependencies:
-    fbjs "^0.8.9"
+    fbjs "^0.8.16"
     loose-envify "^1.3.1"
+    object-assign "^4.1.1"
+
+query-string@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.0.1.tgz#6e2b86fe0e08aef682ecbe86e85834765402bd88"
+  dependencies:
+    decode-uri-component "^0.2.0"
+    object-assign "^4.1.0"
+    strict-uri-encode "^1.0.0"
 
 react-bootstrap@^0.31.3:
-  version "0.31.3"
-  resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-0.31.3.tgz#db2b7d45b00b5dac1ab8b6de3dd97feb3091b849"
+  version "0.31.5"
+  resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-0.31.5.tgz#57040fa8b1274e1e074803c21a1b895fdabea05a"
   dependencies:
     babel-runtime "^6.11.6"
     classnames "^2.2.5"
@@ -143,32 +152,25 @@ react-bootstrap@^0.31.3:
     keycode "^2.1.2"
     prop-types "^15.5.10"
     prop-types-extra "^1.0.1"
-    react-overlays "^0.7.0"
-    react-prop-types "^0.4.0"
+    react-overlays "^0.7.4"
     uncontrollable "^4.1.0"
     warning "^3.0.0"
 
 react-dropzone@^3.7.3:
-  version "3.13.3"
-  resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-3.13.3.tgz#b8bde4b5a12842f85196b45e8cc2959834b81962"
+  version "3.13.4"
+  resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-3.13.4.tgz#84da26815c40339691c49b4544c2ef7a16912ccc"
   dependencies:
     attr-accept "^1.0.3"
     prop-types "^15.5.7"
 
-react-overlays@^0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.7.0.tgz#531898ff566c7e5c7226ead2863b8cf9fbb5a981"
+react-overlays@^0.7.4:
+  version "0.7.4"
+  resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-0.7.4.tgz#ef2ec652c3444ab8aa014262b18f662068e56d5c"
   dependencies:
     classnames "^2.2.5"
-    dom-helpers "^3.2.0"
-    prop-types "^15.5.8"
-    react-prop-types "^0.4.0"
-    warning "^3.0.0"
-
-react-prop-types@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/react-prop-types/-/react-prop-types-0.4.0.tgz#f99b0bfb4006929c9af2051e7c1414a5c75b93d0"
-  dependencies:
+    dom-helpers "^3.2.1"
+    prop-types "^15.5.10"
+    prop-types-extra "^1.0.1"
     warning "^3.0.0"
 
 react-redux@^5.0.6:
@@ -199,13 +201,17 @@ setimmediate@^1.0.5:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
 
+strict-uri-encode@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
+
 symbol-observable@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.1.0.tgz#5c68fd8d54115d9dfb72a84720549222e8db9b32"
 
 ua-parser-js@^0.7.9:
-  version "0.7.13"
-  resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.13.tgz#cd9dd2f86493b3f44dbeeef3780fda74c5ee14be"
+  version "0.7.17"
+  resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
 
 uncontrollable@^4.1.0:
   version "4.1.0"