diff --git a/raml/schemas/definitions/avatars.json b/raml/schemas/definitions/avatars.json
index 7b32957cb86e657096685b1ead8e2e1b5018c5fe..11b6ad8d22c91dfb706e8710a095974f2964656d 100644
--- a/raml/schemas/definitions/avatars.json
+++ b/raml/schemas/definitions/avatars.json
@@ -1,6 +1,6 @@
 {
   "$schema": "http://json-schema.org/draft-04/schema#",
-  "title": "Group",
+  "title": "Avatar",
   "type": "object",
   "properties": {
     "gravatar":         {"type": ["string", "null"], "format": "uri" },
diff --git a/raml/schemas/input/device.json b/raml/schemas/input/device.json
index c5de39df6857b6b20fa8281ee82a747873a48111..ea54fede5bc43678d2e1d7c8dc30c72aeb39db13 100644
--- a/raml/schemas/input/device.json
+++ b/raml/schemas/input/device.json
@@ -1,4 +1,7 @@
 {
   "$schema": "http://json-schema.org/draft-04/schema#",
-  "allOf":[{"$ref":"../definitions/device.json#/definitions/device-input"}]
+  "allOf":[{"$ref":"../definitions/device.json#/definitions/device-input"}],
+  "example": {
+  	"$ref": "../../examples/input/device.json"
+  }
 }
diff --git a/raml/schemas/input/download.json b/raml/schemas/input/download.json
index 6482555fda08c72e9e4b087d9687aace7fe3b362..fc5141878216d414d87c1998cd59b916479cfd69 100644
--- a/raml/schemas/input/download.json
+++ b/raml/schemas/input/download.json
@@ -21,6 +21,9 @@
     },
     "title": "Download",
     "type": "object",
+    "example": {
+        "$ref": "../../examples/create_download_incomplete_and_dicom.json"
+    },
     "properties": {
         "optional": {
             "type": "boolean"
diff --git a/raml/schemas/input/group-new.json b/raml/schemas/input/group-new.json
index 878f19c119278506e7ee6d39b3659be860fd3b1c..a91eeab7b0c1993a37370397e76cb476e1e162d8 100644
--- a/raml/schemas/input/group-new.json
+++ b/raml/schemas/input/group-new.json
@@ -3,5 +3,8 @@
   "allOf":[
     {"$ref":"../definitions/group.json#/definitions/group-input"}
   ],
-  "required": ["_id"]
+  "required": ["_id"],
+  "example": {
+  	"$ref": "../../examples/input/group-new.json"
+  }
 }
diff --git a/raml/schemas/input/group-update.json b/raml/schemas/input/group-update.json
index 8cd10d1acf5a05fed72e539fedc3aa8267d0ddc9..ca78a1358dc28f14e2b28ae2766faaf73e1503e4 100644
--- a/raml/schemas/input/group-update.json
+++ b/raml/schemas/input/group-update.json
@@ -1,4 +1,7 @@
 {
     "$schema": "http://json-schema.org/draft-04/schema#",
-    "allOf":[{"$ref":"../definitions/group.json#/definitions/group-input"}]
+    "allOf":[{"$ref":"../definitions/group.json#/definitions/group-input"}],
+    "example": {
+    	"$ref": "../../examples/input/group-update.json"
+    }
 }
diff --git a/raml/schemas/input/permission.json b/raml/schemas/input/permission.json
index 85172151f6a9a4fd75849b5c7944b1178b7af734..0a609c4498d68ac149c7e7393884b40c87b3df30 100644
--- a/raml/schemas/input/permission.json
+++ b/raml/schemas/input/permission.json
@@ -3,5 +3,8 @@
   "type": "object",
   "allOf":[{"$ref":"../definitions/permission.json#/definitions/permission"}],
   "key_fields": ["_id"],
-  "required": ["_id", "access"]
+  "required": ["_id", "access"],
+  "example": {
+  	"$ref": "../../examples/input/permission.json"
+  }
 }
diff --git a/raml/schemas/input/tag.json b/raml/schemas/input/tag.json
index 5d61819e921c2f22b0296e070dfff47cd86071c8..b540ddbc0ef934632bcacb8a1cee8c790171b2f1 100644
--- a/raml/schemas/input/tag.json
+++ b/raml/schemas/input/tag.json
@@ -1,4 +1,7 @@
 {
   "$schema": "http://json-schema.org/draft-04/schema#",
-  "allOf":[{"$ref":"../definitions/tag.json#/definitions/tag"}]
+  "allOf":[{"$ref":"../definitions/tag.json#/definitions/tag"}],
+  "example": {
+  	"$ref": "../../examples/input/tag.json"
+  }
 }
diff --git a/raml/schemas/input/user-new.json b/raml/schemas/input/user-new.json
index 0d1be60e3e16ffd27e41f4ebcd3c21e41ce3d494..7e8d50cf76ba9cb62548fb066b9f7b3a714ae306 100644
--- a/raml/schemas/input/user-new.json
+++ b/raml/schemas/input/user-new.json
@@ -2,5 +2,8 @@
   "$schema": "http://json-schema.org/draft-04/schema#",
   "type": "object",
   "allOf":[{"$ref":"../definitions/user.json#/definitions/user-input"}],
-  "required":["_id", "firstname", "lastname"]
+  "required":["_id", "firstname", "lastname"],
+  "example": {
+    "$ref": "../../examples/input/user-new.json"
+  }
 }
diff --git a/raml/schemas/input/user-update.json b/raml/schemas/input/user-update.json
index 6ce8b01726a6fdd1b9d1a7da85a0cbaf566e3cbd..1a9ca4a648024848af80eae499a51fa9eba2d1b8 100644
--- a/raml/schemas/input/user-update.json
+++ b/raml/schemas/input/user-update.json
@@ -4,5 +4,8 @@
   "type": "object",
   "allOf":[
     {"$ref":"../definitions/user.json#/definitions/user-input"}
-  ]
+  ],
+  "example": {
+  	"$ref": "../../examples/input/user-update.json"
+  }
 }
diff --git a/raml/schemas/output/user-list.json b/raml/schemas/output/user-list.json
index 1e7f11e1fd6f19f1e90ff3ae0f16a9ec6361eef0..5a6eb1fdc48d6b1cd8cd89cdd8470bfad030449c 100644
--- a/raml/schemas/output/user-list.json
+++ b/raml/schemas/output/user-list.json
@@ -9,5 +9,8 @@
        "_id", "firstname", "lastname",
        "root", "email", "created", "modified"
     ]
+  },
+  "example": {
+    "$ref": "../../examples/user-list.json"
   }
 }
diff --git a/raml/schemas/output/user-new.json b/raml/schemas/output/user-new.json
index f4cb59603fb44101bb4397b9c7e7489b9218b9ac..3279fda1c83df826d108138395338bfbf5433aba 100644
--- a/raml/schemas/output/user-new.json
+++ b/raml/schemas/output/user-new.json
@@ -8,5 +8,8 @@
   },
   "required": [
     "_id"
-  ]
+  ],
+  "example": {
+    "$ref": "../../examples/output/user-new.json"
+  }
 }
diff --git a/swagger/Gruntfile.js b/swagger/Gruntfile.js
index 1fb0ec8029803b761fb1c12adaeacb8d1df9b397..b13ddfb68cd10c4e7fd00500abf6b48eb7930763 100644
--- a/swagger/Gruntfile.js
+++ b/swagger/Gruntfile.js
@@ -23,6 +23,12 @@ module.exports = function(grunt) {
 						cwd: '../raml/schemas', 
 						src: ['**'], 
 						dest: 'build/schemas' 
+					},
+					{
+						expand: true,
+						cwd: '../raml/examples',
+						src: ['**'],
+						dest: 'build/examples'
 					}
 				]
 			},
@@ -125,6 +131,7 @@ module.exports = function(grunt) {
 
 	/**
 	 * Build swagger-ui
+	 * TODO: Put the distributed version of swagger-ui in the ../docs folder
 	 */
 	grunt.registerTask('build-ui', [
 		'build-schema',
diff --git a/swagger/common/tags.yaml b/swagger/common/tags.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d227f5afb45d15c4288bdcdd749c2444e36983df
--- /dev/null
+++ b/swagger/common/tags.yaml
@@ -0,0 +1,31 @@
+add-tag-parameters:
+  - name: body
+    in: body
+    schema:
+      $ref: schemas/input/tag.json
+
+modify-tag-parameters:
+  - name: body
+    in: body
+    schema:
+      $ref: schemas/input/tag.json
+
+modify-tag-responses:
+  '200':
+    $ref: '#/responses/200:modified-with-count'
+  '400':
+    $ref: '#/responses/400:invalid-body-json'
+
+delete-tag-responses:
+  '200':
+    $ref: '#/responses/200:modified-with-count'
+
+get-tag-responses:
+  '200':
+    description: Returns a single tag by name
+    schema:
+      $ref: schemas/output/tag.json
+    examples:
+      response:
+        $ref: examples/output/tag.json
+
diff --git a/swagger/index.yaml b/swagger/index.yaml
index 37df084bd125b6fb45fe17c8d965a30a077dfea2..bebc3d88dc3a43aa02097e66d3ddb82bb6cdc1b1 100644
--- a/swagger/index.yaml
+++ b/swagger/index.yaml
@@ -2,17 +2,62 @@ swagger: '2.0'
 info:
   version: 0.0.1
   title: SciTran
+host: 'dev.flywheel.io'
 basePath: '/api'
 schemes: 
-- 'api'
+- 'https'
 produces:
 - 'application/json'
 consumes:
 - 'application/json'
+
+tags:
+  - name: files
+    description: File upload/download operations
+  - name: devices
+    description: Device operations
+  - name: users
+    description: User operations
+  - name: gears
+    description: Gear operations
+  - name: groups
+    description: Group operations
+  - name: jobs
+    description: Job operations
+
 paths:
   $ref: ./paths/index.yaml
-definitions:
+# definitions:
   #  $ref: ./definitions/index.yaml
 
+securityDefinitions:
+  ApiKey:
+    type: apiKey
+    in: header
+    name: Authorization
+    description: |
+      Your API key is available on your Profile page from within the Flywheel Application.
+      **NOTE:** The API key should be prefixed with `scitran-user` if you're testing APIs on this page.
+      
+      e.g. `scitran-user dev.flywheel.io:DFCAds356sdvd`.
 
+security: 
+  - ApiKey: []
 
+responses:
+  $ref: ./responses/index.yaml
+
+definitions:
+  filterDefinition:
+    type: object
+    additionalProperties: false
+    properties:
+      +:
+        $ref: '#/definitions/filterItems'
+      '-':
+        $ref: '#/definitions/filterItems'
+  filterItems:
+    minItems: 1
+    type: array
+    items:
+      type: string
\ No newline at end of file
diff --git a/swagger/paths/clean-packfiles.yaml b/swagger/paths/clean-packfiles.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4ea212c3a605e224b6591e065aa9a272afbef016
--- /dev/null
+++ b/swagger/paths/clean-packfiles.yaml
@@ -0,0 +1,11 @@
+clean-packfiles:
+  post:
+    summary: Clean up expired upload tokens and invalid token directories.
+    operationId: clean_packfiles
+    responses:
+      '200':
+        description: 'Expired and invalid tokens have been cleaned'
+        schema:
+          example:
+            tokens: 5
+            directories: 3
\ No newline at end of file
diff --git a/swagger/paths/config-js.yaml b/swagger/paths/config-js.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8456e325113f33ad2d02d2c7125736fef6551345
--- /dev/null
+++ b/swagger/paths/config-js.yaml
@@ -0,0 +1,28 @@
+config-js:
+  get:
+    summary: Return public Scitran configuration information in javascript format.
+    operationId: get_config_js
+    produces:
+      - text/html
+    responses:
+      '200':
+        description: ''
+        schema:
+          example: |
+            config = {
+                  "auth": {
+                      "auth_endpoint": "https://accounts.google.com/o/oauth2/auth",
+                      "client_id": "949263322061-6q4fqi0m4ihkp1v5n6v8q9bef4gd0f1k.apps.googleusercontent.com",
+                      "id_endpoint": "https://www.googleapis.com/plus/v1/people/me/openIdConnect",
+                      "verify_endpoint": "https://www.googleapis.com/oauth2/v1/tokeninfo"
+                  },
+                  "created": "2016-03-31T16:30:00.852000+00:00",
+                  "modified": "2016-03-31T16:30:00.852000+00:00",
+                  "site": {
+                      "api_url": "https://10.240.0.2:443/api",
+                      "central_url": "https://sdmc.scitran.io/api",
+                      "id": "local",
+                      "name": "BaliDemo",
+                      "registered": false,
+                      "ssl_cert": null
+                  } 
diff --git a/swagger/paths/config.yaml b/swagger/paths/config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..74c3fdd914251900d1daaa76747783723719e6db
--- /dev/null
+++ b/swagger/paths/config.yaml
@@ -0,0 +1,12 @@
+config:
+  get:
+    summary: Return public Scitran configuration information
+    operationId: get_config
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/config.json
+        examples:
+          response:
+            $ref: examples/scitran_config.json
diff --git a/swagger/paths/devices.yaml b/swagger/paths/devices.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..767f52adcba6d29c6d997193e4b1332629346594
--- /dev/null
+++ b/swagger/paths/devices.yaml
@@ -0,0 +1,85 @@
+devices:
+  get:
+    summary: List all devices.
+    description: Requires login.
+    operationId: get_all_devices
+    tags:
+    - devices
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/device-list.json
+        examples:
+          response:
+            $ref: examples/output/device-list.json
+  post:
+    summary: Modify a device's interval, info or set errors.
+    description: |
+      Will modify the device record of device making the request.
+      Request must be drone request.
+    operationId: update_device
+    tags:
+    - devices
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            modified: '1'
+    parameters:
+      - name: body
+        in: body
+        schema:
+          $ref: schemas/input/device.json
+devices-self:
+  get:
+    summary: Get device document for device making the request.
+    description: Request must be a drone request.
+    operationId: get_current_device
+    tags:
+    - devices
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/device.json
+        examples:
+          response:
+              $ref: examples/output/device.json
+devices-status:
+  get:
+    summary: Get status for all known devices.
+    description: ok - missing - error - unknown
+    operationId: get_all_devices_status
+    tags:
+    - devices
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/device-status.json
+        examples:
+          response:
+            $ref: examples/output/device-status.json
+devices-device:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: DeviceId
+  get:
+    summary: Get device details
+    operationId: get_device
+    tags:
+    - devices
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/device.json
+        examples:
+          response:
+            $ref: examples/output/device.json
+      '404':
+        description: DeviceId not found
diff --git a/swagger/paths/download.yaml b/swagger/paths/download.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..98cffd7900a97fe2ac8a2c200570e6c5993f3ce9
--- /dev/null
+++ b/swagger/paths/download.yaml
@@ -0,0 +1,55 @@
+download:
+  post:
+    summary: Create a download ticket
+    description: |
+      Use filters in the payload to exclude/include files.
+      To pass a single filter, each of its conditions should be satisfied.
+      If a file pass at least one filter, it is included in the targets.
+    operationId: create_download_ticket
+    tags:
+    - files
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            ticket: 579e97738120be2ada087feb
+            file_cnt: 3
+            size: 64523904
+    parameters:
+      - name: prefix
+        in: query
+        description: |
+          A string to customize the name of the download
+          in the format <prefix>_<timestamp>.tar.gz.
+          Defaults to "scitran".
+        type: string                
+      - name: body
+        in: body
+        schema:
+          $ref: schemas/input/download.json
+        description: Download files with tag 'incomplete' OR type 'dicom'
+  get:
+    summary: Download files listed in the given ticket.
+    description: |
+      You can use POST to create a download ticket
+      The files listed in the ticket are put into a tar archive,
+      which is then compressed with gzip (.tar.gz)
+    operationId: download_ticket
+    tags:
+    - files
+    parameters:
+      - required: true
+        description: ID of the download ticket
+        type: string
+        in: query
+        name: ticket
+    produces:
+      - application/octet-stream
+    responses:
+      '200':
+        description: The requested tarball download as a binary stream
+      '400':
+        description: Ticket not for this source IP
+      '404':
+        description: No such ticket
diff --git a/swagger/paths/engine.yaml b/swagger/paths/engine.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ddd947e636c219fa3f7176ee412284ed65d65f19
--- /dev/null
+++ b/swagger/paths/engine.yaml
@@ -0,0 +1,52 @@
+engine:
+  post:
+    summary: Upload a list of file fields.
+    description: |
+      ### Default behavior:
+       >Uploads a list of file fields sent as file1, file2, etc to an existing
+        container and updates fields of the files, the container and it's
+        parents as specified in the metadata fileformfield using the
+        engine placer class
+
+      ### When ``level`` is ``analysis``:
+      > Uploads a list of files to an existing analysis object, marking
+        all files as ``output=true`` using the job-based analyses placer
+        class.  See schemas/input/analysis.json
+    operationId: engine_upload
+    responses:
+      '200':
+        description: A list of FileInfo objects
+        schema:
+          example:
+            $ref: examples/file_info_list.json
+    parameters:
+      - in: body
+        name: body
+        description: >
+          Object encoded as a JSON string.
+
+          By default JSON must match the specified enginemetadata.json schema
+
+          If ``level`` is ``analysis``, JSON must match AnalysisUploadMetadata schema
+        schema:
+          $ref: schemas/input/enginemetadata.json
+      - required: true
+        description: Which level to store files in
+        enum:
+          - project
+          - session
+          - acquisition
+          - analysis
+        type: string
+        in: query
+        name: level
+      - required: true
+        description: The ID of the container to place files in
+        type: string
+        in: query
+        name: id
+      - description: Required if ``level`` is ``analysis``
+        type: string
+        in: query
+        name: job
+        required: true
\ No newline at end of file
diff --git a/swagger/paths/gears.yaml b/swagger/paths/gears.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bda09189b88348c2f7befcd04d23f46074fd5d90
--- /dev/null
+++ b/swagger/paths/gears.yaml
@@ -0,0 +1,53 @@
+gears:
+  get:
+    summary: List all gears
+    operationId: get_all_gears
+    tags:
+    - gears
+    responses:
+      default:
+        description: ''
+gears-gear-by-name:
+  parameters:
+    - required: true
+      description: Name of the gear to interact with
+      type: string
+      in: path
+      name: GearName
+  post:
+    summary: Create or update a gear.
+    description: |
+      If no existing gear is found, one will be created
+      Otherwise, the specified gear will be updated
+    operationId: add_gear
+    tags:
+    - gears
+    responses:
+      default:
+        description: ''
+gears-gear:
+  parameters:
+    - required: true
+      description: Id of the gear to interact with
+      type: string
+      in: path
+      name: GearId
+  get:
+    summary: Retrieve details about a specific gear
+    operationId: get_gear
+    tags:
+    - gears
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            $ref: examples/gear_full.json
+  delete:
+    summary: Delete a gear (not recommended)
+    operationId: delete_gear
+    tags:
+    - gears
+    responses:
+      '200':
+        description: Gear was deleted
diff --git a/swagger/paths/groups.yaml b/swagger/paths/groups.yaml
index 1e6ca475d017cf282ab893cdcacee0a4d93076ca..c850fce7a6a2ed6f67766e6007a621165c59c18c 100644
--- a/swagger/paths/groups.yaml
+++ b/swagger/paths/groups.yaml
@@ -1,9 +1,211 @@
-get:
-  summary: 'List all groups on the site'
-  operationId: 'getAllGroups'
-  responses:
-    200:
-      description: 'OK'
-      schema:
-        $ref: "./schemas/output/groups-list.json"
-
+groups:
+  get:
+    summary: List all groups
+    operationId: get_all_groups
+    tags:
+    - groups
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/groups-list.json
+        examples:
+          response:
+            $ref: examples/output/groups-list.json
+  post:
+    summary: Add a group
+    operationId: add_group
+    tags:
+    - groups
+    parameters:
+      - name: body
+        in: body 
+        schema:
+          $ref: schemas/input/group-new.json
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/group-new.json
+      '400':
+        $ref: '#/responses/400:invalid-body-json'
+groups-group:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: GroupId
+  get:
+    summary: Get group info
+    operationId: get_group
+    tags:
+    - groups
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/group.json
+        examples:
+          response:
+            $ref: examples/output/group.json
+  put:
+    summary: Update group
+    operationId: modify_group
+    tags:
+    - groups
+    parameters:
+      - in: body
+        name: body
+        schema:
+          $ref: schemas/input/group-update.json
+    responses:
+      '400':
+        $ref: '#/responses/400:invalid-body-json'
+  delete:
+    summary: Delete a group
+    operationId: delete_group
+    tags:
+    - groups
+    responses:
+      '200':
+        $ref: '#/responses/200:deleted-with-count'
+groups-group-permissions:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: GroupId
+  post:
+    summary: Add a permission
+    operationId: add_group_permission
+    tags:
+    - groups
+    parameters:
+      - in: body
+        name: body
+        schema:
+          $ref: schemas/input/permission.json
+    responses:
+      '200':
+        $ref: "#/responses/200:modified-with-count"
+      '400':
+        $ref: '#/responses/400:invalid-body-json'
+groups-group-permissions-user:
+  parameters:
+    - required: true
+      description: User which is granted the permission
+      type: string
+      in: path
+      name: UserId
+    - required: true
+      type: string
+      in: path
+      name: GroupId
+  get:
+    summary: List a user's permissions for this group.
+    operationId: get_group_user_permission
+    tags:
+    - groups
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/permission.json
+        examples:
+          response:
+            $ref: examples/output/permission.json
+  put:
+    summary: Update a user's permission for this group.
+    operationId: modify_group_user_permission
+    tags:
+    - groups
+    parameters:
+      - in: body
+        name: body
+        schema:
+          $ref: schemas/input/permission.json
+    responses:
+      '200':
+        $ref: "#/responses/200:modified-with-count"
+      '400':
+        $ref: '#/responses/400:invalid-body-json'
+  delete:
+    summary: Delete a permission
+    operationId: delete_group_user_permission
+    tags:
+    - groups
+    responses:
+      '200':
+        $ref: "#/responses/200:modified-with-count"
+groups-group-tags:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: GroupId
+  post:
+    summary: Add a tag to a group.
+    description: Progates changes to projects, sessions and acquisitions
+    operationId: add_group_tag
+    tags:
+    - groups
+    responses:
+      '200':
+        $ref: "#/responses/200:modified-with-count"
+      '400':
+        $ref: '#/responses/400:invalid-body-json'
+    parameters:
+      $ref: ../common/tags.yaml#/add-tag-parameters
+groups-group-tags-tag:
+  parameters:
+    - required: true
+      description: The tag to interact with
+      type: string
+      in: path
+      name: TagValue
+    - required: true
+      type: string
+      in: path
+      name: GroupId
+  get:
+    summary: Get the value of a group tag, by name.
+    operationId: get_group_tag
+    tags:
+    - groups
+    responses:
+        $ref: '../common/tags.yaml#/get-tag-responses'
+  put:
+    summary: Rename a tag on a group.
+    operationId: rename_group_tag
+    tags:
+    - groups
+    parameters:
+      $ref: ../common/tags.yaml#/modify-tag-parameters
+    responses:
+      $ref: ../common/tags.yaml#/modify-tag-responses
+  delete:
+    summary: Delete a tag on a group
+    operationId: delete_group_tag
+    tags:
+    - groups
+    responses:
+      $ref: ../common/tags.yaml#/delete-tag-responses
+groups-group-projects:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: GroupId
+  get:
+    summary: Get all projects in a group
+    operationId: get_group_projects
+    tags:
+    - groups
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/project-list.json
+        examples:
+          response:
+            $ref: examples/output/project-list.json
diff --git a/swagger/paths/index.yaml b/swagger/paths/index.yaml
index 95c3495c36f1d31f00a40584218296348b77e7b2..950bc2f49c0860d75eaeef8dd783c687c08a96a7 100644
--- a/swagger/paths/index.yaml
+++ b/swagger/paths/index.yaml
@@ -1,3 +1,90 @@
+/login:
+  $ref: login.yaml#/login
+/logout:
+  $ref: login.yaml#/logout
+/download:
+  $ref: download.yaml#/download
+/upload/label:
+  $ref: upload-by-label.yaml#/upload-by-label
+/upload/uid:
+  $ref: upload-by-uid.yaml#/upload-by-uid
+/upload/uid-match:
+  $ref: upload-match-uid.yaml#/upload-match-uid
+/clean-packfiles:
+  $ref: clean-packfiles.yaml#/clean-packfiles
+/engine:
+  $ref: engine.yaml#/engine
+/config:
+  $ref: config.yaml#/config
+/config-js:
+  $ref: config-js.yaml#/config-js
+/version:
+  $ref: version.yaml#/version
+
+/users:
+  $ref: users.yaml#/users
+/users/self:
+  $ref: users.yaml#/users-self
+/users/self/avatar:
+  $ref: users.yaml#/users-self-avatar
+'/users/{UserId}':
+  $ref: users.yaml#/users-user
+'/users/{UserId}/groups':
+  $ref: users.yaml#/users-user-groups
+'/users/{UserId}/acquisitions':
+  $ref: users.yaml#/users-user-acquisitions
+'/users/{UserId}/collections':
+  $ref: users.yaml#/users-user-collections
+'/users/{UserId}/projects':
+  $ref: users.yaml#/users-user-projects
+'/users/{UserId}/sessions':
+  $ref: users.yaml#/users-user-sessions
+
+/jobs/add:
+  $ref: jobs.yaml#/jobs-add
+/jobs/next:
+  $ref: jobs.yaml#/jobs-next
+/jobs/stats:
+  $ref: jobs.yaml#/jobs-stats
+/jobs/reap:
+  $ref: jobs.yaml#/jobs-reap
+'/jobs/{JobId}':
+  $ref: jobs.yaml#/jobs-job
+'/jobs/{JobId}/retry':
+  $ref: jobs.yaml#/jobs-job-retry
+'/jobs/{JobId}/config.json':
+  $ref: jobs.yaml#/jobs-job-config-json
+
+/gears:
+  $ref: gears.yaml#/gears
+'/gears/{GearName}':
+  $ref: gears.yaml#/gears-gear-by-name
+'/gears/{GearId}':
+  $ref: gears.yaml#/gears-gear
+
+/devices:
+  $ref: devices.yaml#/devices
+/devices/self:
+  $ref: devices.yaml#/devices-self
+/devices/status:
+  $ref: devices.yaml#/devices-status
+'/devices/{DeviceId}':
+  $ref: devices.yaml#/devices-device  
+
 /groups:
-  $ref: ./groups.yaml
+  $ref: groups.yaml#/groups
+'/groups/{GroupId}':
+  $ref: groups.yaml#/groups-group
+'/groups/{GroupId}/permissions':
+  $ref: groups.yaml#/groups-group-permissions
+'/groups/{GroupId}/permissions/{UserId}':
+  $ref: groups.yaml#/groups-group-permissions-user
+'/groups/{GroupId}/tags':
+  $ref: groups.yaml#/groups-group-tags
+'/groups/{GroupId}/tags/{TagValue}':
+  $ref: groups.yaml#/groups-group-tags-tag
+'/groups/{GroupId}/projects':
+  $ref: groups.yaml#/groups-group-projects
+
+
 
diff --git a/swagger/paths/jobs.yaml b/swagger/paths/jobs.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7e4f6e0f9ad9d5462d8728fbfb06cee7381e19a8
--- /dev/null
+++ b/swagger/paths/jobs.yaml
@@ -0,0 +1,139 @@
+jobs-add:
+  post:
+    summary: Add a job
+    operationId: add_job
+    tags:
+    - jobs
+    parameters:
+      - name: body
+        in: body
+        schema:
+          example:
+            $ref: examples/input/job-new.json
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/job-new.json
+        examples:
+          response:
+            _id: 573cb66b135d87002660597c
+jobs-next:
+  get:
+    summary: Get the next job in the queue
+    description: Used by the engine.
+    operationId: get_next_job
+    tags:
+    - jobs
+    responses:
+      default:
+        description: ''
+jobs-stats:
+  get:
+    summary: Get stats about all current jobs
+    operationId: get_jobs_stats
+    tags:
+    - jobs
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            $ref: examples/job_stats.json
+jobs-reap:
+  post:
+    summary: Reap stale jobs
+    operationId: reap_jobs
+    tags:
+    - jobs
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            orphaned: 3
+jobs-job:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: JobId
+  get:
+    summary: Get job details
+    operationId: get_job
+    tags:
+    - jobs
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/job.json
+        examples:
+          response:
+            $ref: examples/output/job.json
+      '404':
+        description: JobId not found
+  put:
+    summary: Update a job.
+    description: >
+      Updates timestamp.
+
+      Enforces a valid state machine transition, if any.
+
+      Rejects any change to a job that is not currently in 'pending' or
+      'running' state.
+
+      Accepts the same body as /api/jobs/add , except all fields are optional.
+    operationId: update_job
+    tags:
+    - jobs
+    responses:
+      '200':
+        description: Job was updated.  No value is returned
+    parameters:
+      - name: body
+        in: body
+        schema:
+          example:
+            $ref: examples/input/job-update.json
+jobs-job-retry:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: JobId
+  post:
+    summary: Retry a job.
+    description: >
+      The job must have a state of 'failed', and must not have already been
+      retried.
+
+      The failed jobs config is copied to a new job.
+
+      The ID of the new job is returned
+    operationId: retry_job
+    tags:
+    - jobs
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            _id: 57a35c118120be0e8d1f3f5f
+jobs-job-config-json:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: JobId
+  get:
+    summary: Get a job's config
+    operationId: get_job_config
+    tags:
+    - jobs
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            $ref: examples/output/job-config.json
diff --git a/swagger/paths/login.yaml b/swagger/paths/login.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b328f12cfd3046b40512148a3dd873da18d346de
--- /dev/null
+++ b/swagger/paths/login.yaml
@@ -0,0 +1,22 @@
+login:
+  post:
+    summary: Login
+    description: Scitran Authentication
+    operationId: login
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            success: true
+logout:
+  post:
+    summary: Log Out
+    description: Remove authtokens for user
+    operationId: logout
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            auth_tokens_removed: 2
\ No newline at end of file
diff --git a/swagger/paths/upload-by-label.yaml b/swagger/paths/upload-by-label.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f4427bcee64825599e69e9ba37fcf6080a23fff8
--- /dev/null
+++ b/swagger/paths/upload-by-label.yaml
@@ -0,0 +1,28 @@
+upload-by-label:
+  post:
+    summary: Multipart form upload with N file fields, each with their desired filename.
+    description: >
+      For technical reasons, no form field names can be repeated. Instead, use
+      (file1, file2) and so forth.
+
+      A non-file form field called "metadata" is also required, which must be
+      a string containing JSON.
+
+      See api/schemas/input/labelupload.json for the format of this metadata.
+    operationId: upload_by_label
+    tags:
+    - files
+    responses:
+      '200':
+        description: ''
+        schema:
+          example: 
+            $ref: examples/file_info_list.json
+      '402':
+        description: Uploads must be from an authorized drone
+    consumes:
+      - multipart/form-data
+    parameters:
+      - in: formData
+        name: formData
+        type: string
\ No newline at end of file
diff --git a/swagger/paths/upload-by-uid.yaml b/swagger/paths/upload-by-uid.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1642564d99dfe7f68b800611b67facedf1645bf0
--- /dev/null
+++ b/swagger/paths/upload-by-uid.yaml
@@ -0,0 +1,24 @@
+upload-by-uid:
+  post:
+    summary: Multipart form upload with N file fields, each with their desired filename.
+    description: >
+      Same behavior as /api/upload/label,
+       except the metadata field must be uid format
+       See api/schemas/input/uidupload.json for the format of this metadata.
+    operationId: upload_by_uid
+    tags:
+    - files
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            $ref: examples/file_info_list.json
+      '402':
+        description: Uploads must be from an authorized drone
+    consumes:
+      - multipart/form-data
+    parameters:
+      - in: formData
+        name: formData
+        type: string
\ No newline at end of file
diff --git a/swagger/paths/upload-match-uid.yaml b/swagger/paths/upload-match-uid.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f09868bf622502b4378024f30356efffe5b26ffa
--- /dev/null
+++ b/swagger/paths/upload-match-uid.yaml
@@ -0,0 +1,28 @@
+upload-match-uid:
+  post:
+    summary: Multipart form upload with N file fields, each with their desired filename.
+    description: >
+      Accepts uploads to an existing data hierarchy, matched via Session
+
+      and Acquisition UID
+
+      See api/schemas/input/uidmatchupload.json for the format of this metadata.
+    operationId: upload_match_uid
+    tags:
+    - files
+    responses:
+      '200':
+        description: ''
+        schema:
+          example:
+            $ref: examples/file_info_list.json
+      '402':
+        description: Uploads must be from an authorized drone
+      '404':
+        description: Session or Acquisition with uid does not exist
+    consumes:
+      - multipart/form-data
+    parameters:
+      - in: formData
+        name: formData
+        type: string
\ No newline at end of file
diff --git a/swagger/paths/users.yaml b/swagger/paths/users.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c8e8885d4644e14adfb5fbffa43a34eaa4542179
--- /dev/null
+++ b/swagger/paths/users.yaml
@@ -0,0 +1,221 @@
+users:
+  get:
+    summary: Return a list of all users
+    operationId: get_all_users
+    tags:
+    - users
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/user-list.json
+  post:
+    summary: Add a new user
+    operationId: add_user
+    tags:
+    - users
+    parameters:
+      - name: body
+        in: body
+        schema:
+          $ref: schemas/input/user-new.json
+    responses:
+      '200':
+        description: 'The user was created sucessfully'
+        schema:
+          $ref: schemas/output/user-new.json
+      '400':
+        $ref: '#/responses/400:invalid-body-json'
+users-self:
+  get:
+    summary: Get information about the current user
+    operationId: get_current_user
+    tags:
+    - users
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/user-self.json
+          type: object
+        examples:
+          response:
+            $ref: examples/user_jane_doe.json
+users-self-avatar:
+  get:
+    summary: Get the avatar of the current user
+    operationId: get_current_user_avatar
+    tags:
+    - users
+    responses:
+      '307':
+        description: |
+          Redirects to the image file of the current user's avatar
+users-user:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: UserId
+  get:
+    summary: Get information about the specified user
+    operationId: get_user
+    tags:
+    - users
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/user.json
+          type: object
+        examples:
+          response:
+            $ref: examples/user_jane_doe.json
+  put:
+    summary: Update the specified user
+    operationId: modify_user
+    tags:
+    - users
+    parameters:
+      - name: body
+        in: body
+        schema: 
+          $ref: schemas/input/user-update.json
+        description: >
+          Accepts an object matching the User type except all fields are
+          optional
+    responses:
+      '200':
+        description: 'Returns the number of users modified'
+        schema:
+          $ref: schemas/output/user-update.json
+        examples:
+          response: 
+            $ref: examples/output/user-update.json
+      '400':
+        $ref: '#/responses/400:invalid-body-json'
+  delete:
+    summary: Delete a user
+    operationId: delete_user
+    tags:
+    - users
+    responses:
+      '200':
+        description: User was deleted
+        schema:
+          $ref: schemas/output/user-delete.json
+        examples:
+          response:
+            $ref: examples/output/user-delete.json
+      '404':
+        description: User not found
+users-user-groups:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: UserId
+  get:
+    summary: List all groups the specified user is a member of
+    operationId: get_user_groups
+    tags:
+    - users
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/groups-list.json
+        examples:
+          response:
+            $ref: examples/output/groups-list.json
+users-user-avatar:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: UserId
+  get:
+    summary: Get the avatar of the specified user
+    operationId: get_user_avatar
+    tags:
+    - users
+    responses:
+      '307':
+        description: |
+          Redirects to the image file of the specified user's avatar
+users-user-acquisitions:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: UserId
+  get:
+    summary: Get all acquisitions that belong to the given user.
+    operationId: get_user_acquisitions
+    tags:
+    - users
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/acquisition-list.json
+        examples:
+          response:
+            $ref: examples/output/acquisition-list.json
+users-user-collections:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: UserId
+  get:
+    summary: Get all collections that belong to the given user.
+    operationId: get_user_collections
+    tags:
+    - users
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/collection-list.json
+        examples:
+          response:
+            $ref: examples/output/collection-list.json
+users-user-projects:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: UserId
+  get:
+    summary: Get all projects that belong to the given user.
+    operationId: get_user_projects
+    tags:
+    - users
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/project-list.json
+        examples:
+          response:
+            $ref: examples/output/project-list.json
+users-user-sessions:
+  parameters:
+    - required: true
+      type: string
+      in: path
+      name: UserId
+  get:
+    summary: Get all sessions that belong to the given user.
+    operationId: get_user_sessions
+    tags:
+    - users
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/session-list.json
+        examples:
+          response:
+            $ref: examples/output/session-list.json
diff --git a/swagger/paths/version.yaml b/swagger/paths/version.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..67d4b09b8bbde21a25f2b55ddb1a8b1acda0f1e2
--- /dev/null
+++ b/swagger/paths/version.yaml
@@ -0,0 +1,12 @@
+version:
+  get:
+    description: Get database schema version info
+    operationId: get_version
+    responses:
+      '200':
+        description: ''
+        schema:
+          $ref: schemas/output/version.json
+        example: |
+          {"_id": "version", "database": 2}
+          
diff --git a/swagger/responses/index.yaml b/swagger/responses/index.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bd2d076f3585d8fa91f2b34dbff82bc4cd02f6ec
--- /dev/null
+++ b/swagger/responses/index.yaml
@@ -0,0 +1,27 @@
+'200:deleted-with-count':
+  description: The given number of records were deleted.
+  schema:
+    type: object
+    properties:
+      deleted:
+        type: integer
+    required:
+      - deleted
+    example:
+      deleted: 1
+
+'200:modified-with-count':
+  description: The given number of records were updated.
+  schema:
+    type: object
+    properties:
+      modified:
+        type: integer
+    required:
+      - modified
+    example:
+      modified: 1
+
+'400:invalid-body-json':
+  description: |
+    JSON did not validate against schema for this endpoint