diff --git a/gui/package.json b/gui/package.json
index 1e46c1cda78c745da58f541a7975f1afa5091395..f61187a1505a0e3ddd9c2529720bde1247657c08 100644
--- a/gui/package.json
+++ b/gui/package.json
@@ -20,6 +20,7 @@
     "react-router-hash-link": "^1.2.0",
     "react-scripts": "1.1.4",
     "recompose": "^0.28.2",
+    "swagger-client": "^3.8.22",
     "url-parse": "^1.4.3"
   },
   "scripts": {
diff --git a/gui/src/api.js b/gui/src/api.js
index dca128fa9baaf805ac58f7abcc0b3c38959a9725..f5c848cd961c1a48663a768dc28aaba739e57256 100644
--- a/gui/src/api.js
+++ b/gui/src/api.js
@@ -1,12 +1,25 @@
 import { UploadRequest } from '@navjobs/upload'
+import Swagger from 'swagger-client'
 import { apiBase, appStaticBase } from './config'
 
 const auth_headers = {
   Authorization: 'Basic ' + btoa('sheldon.cooper@nomad-fairdi.tests.de:password')
 }
 
-const networkError = () => {
-  throw Error('Network related error, cannot reach API or object storage.')
+const swaggerPromise = Swagger(`${apiBase}/swagger.json`, {
+  authorizations: {
+    // my_query_auth: new ApiKeyAuthorization('my-query', 'bar', 'query'),
+    // my_header_auth: new ApiKeyAuthorization('My-Header', 'bar', 'header'),
+    'HTTP Basic': {
+      username: 'sheldon.cooper@nomad-fairdi.tests.de',
+      password: 'password'
+    }
+    // cookie_: new CookieAuthorization('one=two')
+  }
+})
+
+const networkError = (e) => {
+  throw Error('Network related error, cannot reach API: ' + e)
 }
 
 const handleJsonErrors = () => {
@@ -27,19 +40,16 @@ const handleResponseErrors = (response) => {
 
 class Upload {
   constructor(json, created) {
-    this.uploading = null
+    this.uploading = 0
     this._assignFromJson(json, created)
   }
 
   uploadFile(file) {
-    console.assert(this.upload_url)
-    this.uploading = 0
-
     const uploadFileWithProgress = async() => {
-      let { error, aborted } = await UploadRequest(
+      let uploadRequest = await UploadRequest(
         {
           request: {
-            url: this.upload_url,
+            url: `${apiBase}/uploads/?name=${this.name}`,
             method: 'PUT',
             headers: {
               'Content-Type': 'application/gzip',
@@ -53,12 +63,14 @@ class Upload {
           }
         }
       )
-      if (error) {
-        networkError(error)
+      if (uploadRequest.error) {
+        networkError(uploadRequest.error)
       }
-      if (aborted) {
+      if (uploadRequest.aborted) {
         throw Error('User abort')
       }
+      this.uploading = 100
+      this.upload_id = uploadRequest.response.upload_id
     }
 
     return uploadFileWithProgress()
@@ -70,9 +82,7 @@ class Upload {
     if (this.current_task !== this.tasks[0]) {
       this.uploading = 100
       this.waiting = false
-    } else if (!created && this.uploading === null) {
-      // if data came from server during a normal get (not create) and its still uploading
-      // and the uploading is also not controlled locally then it ought to be a manual upload
+    } else {
       this.waiting = true
     }
   }
@@ -107,26 +117,16 @@ class Upload {
 }
 
 function createUpload(name) {
-  const fetchData = {
-    method: 'POST',
-    body: JSON.stringify({
-      name: name
-    }),
-    headers: {
-      'Content-Type': 'application/json',
-      ...auth_headers
-    }
-  }
-  return fetch(`${apiBase}/uploads`, fetchData)
-    .catch(networkError)
-    .then(handleResponseErrors)
-    .then(response => response.json())
-    .then(uploadJson => new Upload(uploadJson, true))
+  return new Upload({
+    name: name,
+    tasks: ['UPLOADING'],
+    current_task: 'UPLOADING'
+  }, true)
 }
 
 function getUploads() {
   return fetch(
-    `${apiBase}/uploads`,
+    `${apiBase}/uploads/`,
     {
       method: 'GET',
       headers: auth_headers
@@ -145,7 +145,7 @@ function archive(uploadHash, calcHash) {
 }
 
 function calcProcLog(archiveId) {
-  return fetch(`${apiBase}/logs/${archiveId}`)
+  return fetch(`${apiBase}/archive/logs/${archiveId}`)
     .catch(networkError)
     .then(response => {
       if (!response.ok) {
@@ -173,7 +173,7 @@ function repo(uploadHash, calcHash) {
 
 function repoAll(page, perPage, owner) {
   return fetch(
-    `${apiBase}/repo?page=${page}&per_page=${perPage}&owner=${owner || 'all'}`,
+    `${apiBase}/repo/?page=${page}&per_page=${perPage}&owner=${owner || 'all'}`,
     {
       method: 'GET',
       headers: auth_headers
@@ -246,7 +246,16 @@ async function getMetaInfo() {
   }
 }
 
+async function getUploadCommand() {
+  const client = await swaggerPromise
+  return client.apis.uploads.get_upload_command()
+    .catch(networkError)
+    .then(handleResponseErrors)
+    .then(response => response.body.upload_command)
+}
+
 const api = {
+  getUploadCommand: getUploadCommand,
   createUpload: createUpload,
   deleteUpload: deleteUpload,
   unstageUpload: unstageUpload,
diff --git a/gui/src/components/ArchiveCalc.js b/gui/src/components/ArchiveCalc.js
index 81500cdcfb0c3a23bdd3bff90349c5495791bb3d..3c6ee666cc1f49dca5c797c6e6b9214bb6c9b067 100644
--- a/gui/src/components/ArchiveCalc.js
+++ b/gui/src/components/ArchiveCalc.js
@@ -108,7 +108,7 @@ class ArchiveCalc extends React.Component {
           see a *meta-info* description.
         `}</Markdown>
         <Typography className={classes.logLink}>
-          The processing logs are available <a href="#" onClick={() => this.setState({showLogs: true})}>here</a>.
+          The processing logs are available <a href="#logs" onClick={() => this.setState({showLogs: true})}>here</a>.
         </Typography>
         <Paper className={classes.calcData}>
           {
diff --git a/gui/src/components/Documentation.js b/gui/src/components/Documentation.js
index 5ed652a68df1da9f1c685dc191c7a4313c427055..7f452964d4b171a7110d8016154338fbbea52238 100644
--- a/gui/src/components/Documentation.js
+++ b/gui/src/components/Documentation.js
@@ -25,7 +25,7 @@ class Documentation extends Component {
     return (
       <div className={classes.root}>
         <div className={classes.content}>
-          <iframe
+          <iframe title="documentation"
             frameBorder={0} width="700" height={window.innerHeight - 64}
             src={`${apiBase}/docs/index.html`}
           />
diff --git a/gui/src/components/Upload.js b/gui/src/components/Upload.js
index 1b354ad97361369d7e95580bb0cfda57d4ae12d7..aac3d3ce65122ad24387707aa0cf8fc2376554c5 100644
--- a/gui/src/components/Upload.js
+++ b/gui/src/components/Upload.js
@@ -12,7 +12,6 @@ import CalcLinks from './CalcLinks'
 import { compose } from 'recompose'
 import { withErrors } from './errors'
 import { debug } from '../config'
-import UploadCommand from './UploadCommand'
 import CalcProcLogPopper from './CalcProcLogPopper'
 
 class Upload extends React.Component {
@@ -265,7 +264,7 @@ class Upload extends React.Component {
   renderCalcTable() {
     const { classes } = this.props
     const { page, perPage, orderBy, order } = this.state.params
-    const { calcs, status, waiting, upload_command } = this.state.upload
+    const { calcs, status, waiting } = this.state.upload
     const { pagination, results } = calcs
 
     if (pagination.total === 0) {
@@ -278,7 +277,9 @@ class Upload extends React.Component {
       } else {
         if (waiting) {
           return (
-            <UploadCommand uploadCommand={upload_command} />
+            <Typography className={classes.detailsContent}>
+                Uploading ...
+            </Typography>
           )
         } else {
           return (
@@ -323,7 +324,7 @@ class Upload extends React.Component {
             <Typography color={color}>
               {(status === 'SUCCESS' || status === 'FAILURE')
                 ?
-                  <a className={classes.logLink} href="#" onClick={() => this.setState({archiveLogs:  archive_id})}>
+                  <a className={classes.logLink} href="#logs" onClick={() => this.setState({archiveLogs:  archive_id})}>
                   {status.toLowerCase()}
                   </a>
                 : status.toLowerCase()
diff --git a/gui/src/components/UploadCommand.js b/gui/src/components/UploadCommand.js
deleted file mode 100644
index b09045d538a291cfc5ab24db1a03fd952d2da654..0000000000000000000000000000000000000000
--- a/gui/src/components/UploadCommand.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-import { Typography, withStyles } from '@material-ui/core'
-
-class UploadCommand extends React.Component {
-  static propTypes = {
-    classes: PropTypes.object.isRequired,
-    uploadCommand: PropTypes.string.isRequired
-  }
-
-  static styles = theme => ({
-    root: {
-      margin: theme.spacing.unit * 2
-    },
-    uploadCommand: {
-      fontFamily: '\'Roboto mono\', monospace',
-      marginTop: theme.spacing.unit * 2
-    }
-  })
-
-  render() {
-    const { classes, uploadCommand } = this.props
-    return (
-      <div className={classes.root}>
-        <Typography>Copy and use the following command. Don't forget to replace the file name.:</Typography>
-        <Typography className={classes.uploadCommand}>{uploadCommand}</Typography>
-      </div>
-    )
-  }
-}
-
-export default withStyles(UploadCommand.styles)(UploadCommand)
diff --git a/gui/src/components/Uploads.js b/gui/src/components/Uploads.js
index 8ce6b3a0f826928fa60bbd4ee5640e6b18349e0d..b1c2e37c5acc694f0f575023169d010d2978214e 100644
--- a/gui/src/components/Uploads.js
+++ b/gui/src/components/Uploads.js
@@ -2,8 +2,7 @@ import React from 'react'
 import PropTypes from 'prop-types'
 import Markdown from './Markdown'
 import { withStyles, Paper, IconButton, FormGroup, Checkbox, FormControlLabel, FormLabel,
-  LinearProgress, InputLabel, Input, FormHelperText, Button, Popover, Grid, Typography,
-  DialogContent, DialogActions} from '@material-ui/core'
+  LinearProgress } from '@material-ui/core'
 import UploadIcon from '@material-ui/icons/CloudUpload'
 import Dropzone from 'react-dropzone'
 import api from '../api'
@@ -12,8 +11,6 @@ import { withErrors } from './errors'
 import { compose } from 'recompose'
 import DeleteIcon from '@material-ui/icons/Delete'
 import CheckIcon from '@material-ui/icons/Check'
-import AddIcon from '@material-ui/icons/Add'
-import UploadCommand from './UploadCommand'
 import ConfirmDialog from './ConfirmDialog'
 
 class Uploads extends React.Component {
@@ -62,44 +59,24 @@ class Uploads extends React.Component {
     },
     uploads: {
       marginTop: theme.spacing.unit * 2
-    },
-    uploadFormControl: {
-      margin: theme.spacing.unit * 2
-    },
-    button: {
-      margin: theme.spacing.unit
-    },
-    rightIcon: {
-      marginLeft: theme.spacing.unit
-    },
-    uploadNameInput: {
-      width: '100%'
-    },
-    uploadKindHeading: {
-      paddingBottom: theme.spacing.unit
-    },
-    uploadKindDescription: {
-      paddingTop: theme.spacing.unit,
-      paddingBottom: theme.spacing.unit * 2
-    },
-    commandUpload: {
-      height: 192
     }
   })
 
   state = {
     uploads: null,
+    uploadCommand: null,
     selectedUploads: [],
     loading: true,
-    showAccept: false,
-    uploadName: '',
-    uploadCommand: null,
-    showUploadCommand: false,
-    uploadPopperAnchor: null
+    showAccept: false
   }
 
   componentDidMount() {
     this.update()
+    api.getUploadCommand()
+      .then(command => this.setState({uploadCommand: command}))
+      .catch(error => {
+        this.props.raiseError(error)
+      })
   }
 
   update() {
@@ -115,31 +92,6 @@ class Uploads extends React.Component {
       })
   }
 
-  onCreateUploadCmdClicked(event) {
-    event.persist()
-    const existingUpload = this.state.uploads
-      .find(upload => upload.name === this.state.uploadName && upload.waiting)
-    if (existingUpload) {
-      const upload = existingUpload
-      this.setState({
-        uploadCommand: upload.upload_command,
-        showUploadCommand: true,
-        uploadPopperAnchor: event.target})
-    } else {
-      api.createUpload(this.state.uploadName)
-        .then(upload => {
-          this.setState({
-            uploads: [...this.state.uploads, upload],
-            uploadCommand: upload.upload_command,
-            showUploadCommand: true,
-            uploadPopperAnchor: event.target})
-        })
-        .catch(error => {
-          this.props.raiseError(error)
-        })
-    }
-  }
-
   onDeleteClicked() {
     this.setState({loading: true})
     Promise.all(this.state.selectedUploads.map(upload => api.deleteUpload(upload.upload_id)))
@@ -169,13 +121,9 @@ class Uploads extends React.Component {
 
   onDrop(files) {
     files.forEach(file => {
-      api.createUpload(file.name)
-        .then(upload => {
-          this.setState({uploads: [...this.state.uploads, upload]})
-          upload.uploadFile(file)
-            .catch(this.props.raiseError)
-        })
-        .catch(this.props.raiseError)
+      const upload = api.createUpload(file.name)
+      this.setState({uploads: [...this.state.uploads, upload]})
+      upload.uploadFile(file).catch(this.props.raiseError)
     })
   }
 
@@ -248,7 +196,7 @@ class Uploads extends React.Component {
 
   render() {
     const { classes } = this.props
-    const { showUploadCommand, uploadCommand, uploadPopperAnchor } = this.state
+    const { uploadCommand } = this.state
 
     return (
       <div className={classes.root}>
@@ -257,76 +205,32 @@ class Uploads extends React.Component {
           You can upload your own data. Have your code output ready in a popular archive
           format (e.g. \`*.zip\` or \`*.tar.gz\`).  Your upload can
           comprise the output of multiple runs, even of different codes. Don't worry, nomad
-          will find it.`}
+          will find it, just drop it below:`}
+        </Markdown>
+
+        <Paper className={classes.dropzoneContainer}>
+          <Dropzone
+            accept="application/zip"
+            className={classes.dropzone}
+            activeClassName={classes.dropzoneAccept}
+            rejectClassName={classes.dropzoneReject}
+            onDrop={this.onDrop.bind(this)}
+          >
+            <p>drop files here</p>
+            <UploadIcon style={{fontSize: 36}}/>
+          </Dropzone>
+        </Paper>
+
+        <Markdown>{`
+          Alternatively, you can upload files via the following shell command.
+          Replace \`<local_file>\` with your file. After executing the command,
+          return here and reload.
+
+          \`\`\`
+            ${uploadCommand}
+          \`\`\`
+          `}
         </Markdown>
-        <Grid container spacing={24}>
-          <Grid item xs>
-            <Typography variant="headline" className={classes.uploadKindHeading}>
-              Browser upload
-            </Typography>
-            <Paper className={classes.dropzoneContainer}>
-              <Dropzone
-                accept="application/zip"
-                className={classes.dropzone}
-                activeClassName={classes.dropzoneAccept}
-                rejectClassName={classes.dropzoneReject}
-                onDrop={this.onDrop.bind(this)}
-              >
-                <p>drop files here</p>
-                <UploadIcon style={{fontSize: 36}}/>
-              </Dropzone>
-            </Paper>
-            <Typography className={classes.uploadKindDescription}>
-              Just drop your file above. You know this from many other services in the internet.
-            </Typography>
-          </Grid>
-          <Grid item xs>
-            <Typography variant="headline" className={classes.uploadKindHeading}>
-              Command upload
-            </Typography>
-            <Paper className={classes.commandUpload}>
-              <DialogContent>
-                <InputLabel htmlFor="name-helper">Upload name</InputLabel>
-                <Input className={classes.uploadNameInput}
-                  id="name-helper" value={this.state.uploadName}
-                  onChange={(event) => this.setState({uploadName: event.target.value})}
-                />
-                <FormHelperText id="name-helper-text">optional, helps to track the upload</FormHelperText>
-              </DialogContent>
-              <DialogActions>
-                <Button
-                  color="primary" className={classes.button} variant="contained"
-                  onClick={this.onCreateUploadCmdClicked.bind(this)}
-                >
-                    add upload
-                  <AddIcon className={classes.rightIcon}/>
-                </Button>
-                <Popover
-                  id="upload-command-popper"
-                  onClose={() => this.setState({showUploadCommand: false})}
-                  open={showUploadCommand}
-                  anchorEl={uploadPopperAnchor}
-                  anchorOrigin={{
-                    vertical: 'bottom',
-                    horizontal: 'center'
-                  }}
-                  transformOrigin={{
-                    vertical: 'top',
-                    horizontal: 'center'
-                  }}
-                >
-                  <UploadCommand uploadCommand={uploadCommand} />
-                </Popover>
-              </DialogActions>
-            </Paper>
-            <Typography className={classes.uploadKindDescription}>
-              You can upload your file via <strong>curl</strong>. Optionally, you
-              can provide a name that will help to track different uploads.
-              Without a name, you only have the upload time to follow your uploads.
-              You can find the command by unfolding the new upload element.
-            </Typography>
-          </Grid>
-        </Grid>
 
         {this.renderUploads()}
         {this.state.loading ? <LinearProgress/> : ''}
diff --git a/gui/yarn.lock b/gui/yarn.lock
index 0f25114eeda0f2a249bfbddb351e3cb519c6a351..a9a7488e76af6fafc8ed785b2993ba874e196770 100644
--- a/gui/yarn.lock
+++ b/gui/yarn.lock
@@ -90,6 +90,16 @@
     lodash "^4.2.0"
     to-fast-properties "^2.0.0"
 
+"@kyleshockey/js-yaml@^1.0.1":
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/@kyleshockey/js-yaml/-/js-yaml-1.0.1.tgz#5c036bb67caee77fa887738e695dc02949889bfd"
+  dependencies:
+    argparse "^1.0.7"
+
+"@kyleshockey/object-assign-deep@^0.4.0":
+  version "0.4.2"
+  resolved "https://registry.yarnpkg.com/@kyleshockey/object-assign-deep/-/object-assign-deep-0.4.2.tgz#84900f0eefc372798f4751b5262830b8208922ec"
+
 "@material-ui/core@^1.5.1":
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-1.5.1.tgz#cb00cb934447ae688e08129f1dab55f54d29d87a"
@@ -474,7 +484,7 @@ async@^1.4.0, async@^1.5.2:
   version "1.5.2"
   resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
 
-async@^2.1.2, async@^2.1.4, async@^2.4.1:
+async@^2.0.1, async@^2.1.2, async@^2.1.4, async@^2.4.1:
   version "2.6.1"
   resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
   dependencies:
@@ -1434,6 +1444,10 @@ bser@^2.0.0:
   dependencies:
     node-int64 "^0.4.0"
 
+btoa@1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.1.2.tgz#3e40b81663f81d2dd6596a4cb714a8dc16cfabe0"
+
 buffer-from@^1.0.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@@ -1454,6 +1468,13 @@ buffer@^4.3.0:
     ieee754 "^1.1.4"
     isarray "^1.0.0"
 
+buffer@^5.1.0:
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6"
+  dependencies:
+    base64-js "^1.0.2"
+    ieee754 "^1.1.4"
+
 builtin-modules@^1.0.0, builtin-modules@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
@@ -1784,6 +1805,12 @@ combined-stream@1.0.6, combined-stream@~1.0.6:
   dependencies:
     delayed-stream "~1.0.0"
 
+combined-stream@^1.0.5:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
+  dependencies:
+    delayed-stream "~1.0.0"
+
 commander@2.17.x, commander@^2.11.0:
   version "2.17.1"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
@@ -1894,7 +1921,7 @@ cookie-signature@1.0.6:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
 
-cookie@0.3.1:
+cookie@0.3.1, cookie@^0.3.1:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
 
@@ -1966,6 +1993,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
     safe-buffer "^5.0.1"
     sha.js "^2.4.8"
 
+cross-fetch@0.0.8:
+  version "0.0.8"
+  resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-0.0.8.tgz#01ed94dc407df2c00f1807fde700a7cfa48a205c"
+  dependencies:
+    node-fetch "1.7.3"
+    whatwg-fetch "2.0.3"
+
 cross-spawn@5.1.0, cross-spawn@^5.0.1, cross-spawn@^5.1.0:
   version "5.1.0"
   resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
@@ -2160,6 +2194,10 @@ deep-equal@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
 
+deep-extend@^0.5.1:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.5.1.tgz#b894a9dd90d3023fbf1c55a394fb858eb2066f1f"
+
 deep-extend@^0.6.0:
   version "0.6.0"
   resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
@@ -2448,6 +2486,10 @@ emojis-list@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
 
+encode-3986@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/encode-3986/-/encode-3986-1.0.0.tgz#940d51498f8741ade184b75ad1439b317c0c7a60"
+
 encodeurl@~1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
@@ -3031,6 +3073,12 @@ fast-deep-equal@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
 
+fast-json-patch@^2.0.6:
+  version "2.0.7"
+  resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-2.0.7.tgz#55864b08b1e50381d2f37fd472bb2e18fe54a733"
+  dependencies:
+    deep-equal "^1.0.1"
+
 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"
@@ -3233,6 +3281,14 @@ 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@^1.0.0-rc3:
+  version "1.0.1"
+  resolved "http://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c"
+  dependencies:
+    async "^2.0.1"
+    combined-stream "^1.0.5"
+    mime-types "^2.1.11"
+
 form-data@~2.3.2:
   version "2.3.2"
   resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
@@ -4170,6 +4226,12 @@ isomorphic-fetch@^2.1.1:
     node-fetch "^1.0.1"
     whatwg-fetch ">=0.10.0"
 
+isomorphic-form-data@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/isomorphic-form-data/-/isomorphic-form-data-0.0.1.tgz#026f627e032b0cd8413ecc8755928b94a468b062"
+  dependencies:
+    form-data "^1.0.0-rc3"
+
 isstream@~0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@@ -4841,6 +4903,10 @@ lodash.uniq@^4.5.0:
   version "4.17.10"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
 
+lodash@^4.16.2:
+  version "4.17.11"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
+
 loglevel@^1.4.1:
   version "1.6.1"
   resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
@@ -5021,12 +5087,22 @@ mime-db@~1.35.0:
   version "1.35.0"
   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47"
 
+mime-db@~1.37.0:
+  version "1.37.0"
+  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
+
 mime-types@2.1.18:
   version "2.1.18"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
   dependencies:
     mime-db "~1.33.0"
 
+mime-types@^2.1.11:
+  version "2.1.21"
+  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
+  dependencies:
+    mime-db "~1.37.0"
+
 mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19:
   version "2.1.19"
   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0"
@@ -5172,7 +5248,7 @@ no-case@^2.2.0:
   dependencies:
     lower-case "^1.1.1"
 
-node-fetch@^1.0.1:
+node-fetch@1.7.3, node-fetch@^1.0.1:
   version "1.7.3"
   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
   dependencies:
@@ -6081,6 +6157,10 @@ qs@6.5.1:
   version "6.5.1"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
 
+qs@^6.3.0:
+  version "6.6.0"
+  resolved "https://registry.yarnpkg.com/qs/-/qs-6.6.0.tgz#a99c0f69a8d26bf7ef012f871cdabb0aee4424c2"
+
 qs@~6.5.2:
   version "6.5.2"
   resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
@@ -6092,6 +6172,10 @@ query-string@^4.1.0:
     object-assign "^4.1.0"
     strict-uri-encode "^1.0.0"
 
+querystring-browser@^1.0.4:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/querystring-browser/-/querystring-browser-1.0.4.tgz#f2e35881840a819bc7b1bf597faf0979e6622dc6"
+
 querystring-es3@^0.2.0:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@@ -7249,6 +7333,28 @@ sw-toolbox@^3.4.0:
     path-to-regexp "^1.0.1"
     serviceworker-cache-polyfill "^4.0.0"
 
+swagger-client@^3.8.22:
+  version "3.8.22"
+  resolved "https://registry.yarnpkg.com/swagger-client/-/swagger-client-3.8.22.tgz#934809e19acd09d5070fdb7ae48bd405d0a18b69"
+  dependencies:
+    "@kyleshockey/js-yaml" "^1.0.1"
+    "@kyleshockey/object-assign-deep" "^0.4.0"
+    babel-runtime "^6.26.0"
+    btoa "1.1.2"
+    buffer "^5.1.0"
+    cookie "^0.3.1"
+    cross-fetch "0.0.8"
+    deep-extend "^0.5.1"
+    encode-3986 "^1.0.0"
+    fast-json-patch "^2.0.6"
+    isomorphic-form-data "0.0.1"
+    lodash "^4.16.2"
+    qs "^6.3.0"
+    querystring-browser "^1.0.4"
+    url "^0.11.0"
+    utf8-bytes "0.0.1"
+    utfstring "^2.0.0"
+
 symbol-observable@1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
@@ -7623,6 +7729,14 @@ use@^3.1.0:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
 
+utf8-bytes@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/utf8-bytes/-/utf8-bytes-0.0.1.tgz#116b025448c9b500081cdfbf1f4d6c6c37d8837d"
+
+utfstring@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/utfstring/-/utfstring-2.0.0.tgz#b331f7351e9be1c46334cc7518826cda3b44242a"
+
 util-deprecate@~1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
diff --git a/nomad/api/app.py b/nomad/api/app.py
index 1c81c9761c7e7f44f1f3df1f2277f63eee468bbd..0307ec515d935e88ac6a9c8d8c3e7c085b844dfc 100644
--- a/nomad/api/app.py
+++ b/nomad/api/app.py
@@ -29,7 +29,7 @@ base_path = config.services.api_base_path
 
 app = Flask(
     __name__,
-    static_url_path='%s/docs' % base_path,
+    static_url_path='/docs',
     static_folder=os.path.abspath(os.path.join(os.path.dirname(__file__), '../../docs/.build/html')))
 """ The Flask app that serves all APIs. """
 
diff --git a/tests/test_api.py b/tests/test_api.py
index cd5bbab839dd8923698a6f490c84445fe24a5773..eadce92c409e193f0cba2b2023278081a42cc7ba 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -380,6 +380,7 @@ class TestArchive:
 
 
 def test_docs(client):
+    rv = client.get('/docs/index.html')
     rv = client.get('/docs/introduction.html')
     assert rv.status_code == 200