diff --git a/api-ref/source/conf.py b/api-ref/source/conf.py
new file mode 100644
index 0000000..83c3146
--- /dev/null
+++ b/api-ref/source/conf.py
@@ -0,0 +1,138 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import openstackdocstheme
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['os_api_ref']
+
+# Add any paths that contain templates here, relative to this directory.
+# templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Valet API Reference'
+copyright = u'2017-present, Valet authors'
+author = u'Valet authors'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+# language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This patterns also effect to html_static_path and html_extra_path
+exclude_patterns = []
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# If true, `todo` and `todoList` produce output, else they produce nothing.
+todo_include_todos = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'openstackdocs'
+html_theme_path = [openstackdocstheme.get_html_theme_path()]
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#
+html_theme_options = {
+    "sidebar_mode": "toc",
+}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+# html_static_path = ['_static']
+
+
+# -- Options for HTMLHelp output ------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'ValetAPIreferencedoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+    # The paper size ('letterpaper' or 'a4paper').
+    #
+    # 'papersize': 'letterpaper',
+
+    # The font size ('10pt', '11pt' or '12pt').
+    #
+    # 'pointsize': '10pt',
+
+    # Additional stuff for the LaTeX preamble.
+    #
+    # 'preamble': '',
+
+    # Latex figure (float) alignment
+    #
+    # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+    (master_doc, 'ValetAPIreference.tex', u'Valet API reference Documentation',
+     u'Valet authors', 'manual'),
+]
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    (master_doc, 'valetapireference', u'Valet API reference Documentation',
+     [author], 1)
+]
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+    (master_doc, 'ValetAPIreference', u'Valet API reference Documentation',
+     author, 'ValetAPIreference', 'One line description of project.',
+     'Miscellaneous'),
+]
diff --git a/api-ref/source/index.rst b/api-ref/source/index.rst
new file mode 100644
index 0000000..efdb3bd
--- /dev/null
+++ b/api-ref/source/index.rst
@@ -0,0 +1,15 @@
+Welcome to Valet API documentation!
+===================================
+
+.. toctree::
+   :maxdepth: 1
+
+   v1/index
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/api-ref/source/status.yaml b/api-ref/source/status.yaml
new file mode 100644
index 0000000..f27b863
--- /dev/null
+++ b/api-ref/source/status.yaml
@@ -0,0 +1,60 @@
+---
+200:
+  default: |
+    Request was successful.
+201:
+  default: |
+    Resource was created and is ready to use.
+202:
+  default: |
+    Request was accepted for processing, but the processing has not been
+    completed. A 'location' header is included in the response which contains
+    a link to check the progress of the request.
+204:
+  default: |
+    The server has fulfilled the request.
+300:
+  default: |
+    There are multiple choices for resources. The request has to be more
+    specific to successfully retrieve one of these resources.
+400:
+  default: |
+    Some content in the request was invalid.
+401:
+  default: |
+    User must authenticate before making a request.
+403:
+  default: |
+    Policy does not allow current user to do this operation.
+404:
+  default: |
+    The requested resource could not be found.
+405:
+  default: |
+    Method is not valid for this endpoint.
+406:
+  default: |
+    The requested API version is not supported by the API.
+409:
+  default: |
+    This operation conflicted with another operation on this resource.
+413:
+  default: |
+    The request is larger than the server is willing or able to process.
+415:
+  default: |
+    The request entity has a media type which the server or resource does
+    not support.
+500:
+  default: |
+    Something went wrong inside the service. This should not happen usually.
+    If it does happen, it means the server has experienced some serious
+    problems.
+501:
+  default: |
+    The server either does not recognize the request method, or it lacks the
+    ability to fulfill the request.
+503:
+  default: |
+    Service is not available. This is mostly caused by service configuration
+    errors which prevents the service from successful start up.
diff --git a/api-ref/source/template.inc b/api-ref/source/template.inc
new file mode 100644
index 0000000..f11bd5f
--- /dev/null
+++ b/api-ref/source/template.inc
@@ -0,0 +1,40 @@
+.. -*- rst -*-
+
+======
+Groups
+======
+
+List groups
+===========
+
+.. rest_method:: GET /v1/groups
+
+Lists groups.
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+
+.. rest_status_code:: error ../status.yaml
+
+
+Request Parameters
+------------------
+
+.. rest_parameters:: parameters.yaml
+
+
+
+Response Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+
+Response Example
+----------------
+
+.. literalinclude:: ./samples/something.json
+   :language: javascript
diff --git a/api-ref/source/v1/groups.inc b/api-ref/source/v1/groups.inc
new file mode 100644
index 0000000..9ebdd13
--- /dev/null
+++ b/api-ref/source/v1/groups.inc
@@ -0,0 +1,343 @@
+.. -*- rst -*-
+
+======
+Groups
+======
+
+Create a group
+==============
+
+.. rest_method:: POST /v1/groups
+
+Creates a group.
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 201
+
+.. rest_status_code:: error ../status.yaml
+
+   - 400
+   - 401
+   - 500
+
+Request Parameters
+------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - name: group_name
+   - description: group_description
+   - type: group_type
+
+Request Example
+---------------
+
+.. literalinclude:: ./samples/create_group_request.json
+   :language: json
+
+Response Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - description: group_description
+   - id: group_id_body
+   - members: group_members
+   - name: group_name
+   - type: group_type
+
+Response Parameters
+-------------------
+
+.. literalinclude:: ./samples/create_group_response.json
+   :language: json
+
+
+List groups
+===========
+
+.. rest_method:: GET /v1/groups
+
+Lists groups.
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 200
+
+.. rest_status_code:: error ../status.yaml
+
+   - 401
+
+Response Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - description: group_description
+   - id: group_id_body
+   - members: group_members
+   - name: group_name
+   - type: group_type
+
+Response Example
+----------------
+
+.. literalinclude:: ./samples/list_groups_response.json
+   :language: json
+
+Show group
+==========
+
+.. rest_method:: GET /v1/groups/{group_id}
+
+Lists groups.
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 200
+
+.. rest_status_code:: error ../status.yaml
+
+   - 401
+   - 404
+
+Request Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - group_id: group_id_query
+
+Response Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - description: group_description
+   - id: group_id_body
+   - members: group_members
+   - name: group_name
+   - type: group_type
+
+Response Example
+----------------
+
+.. literalinclude:: ./samples/show_group_response.json
+   :language: json
+
+
+Update a group
+==============
+
+.. rest_method:: PUT /v1/groups/{group_id}
+
+Updates a group.
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 201
+
+.. rest_status_code:: error ../status.yaml
+
+   - 400
+   - 401
+   - 404
+
+Request Parameters
+------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - group_id: group_id_query
+   - description: group_description
+
+Response Example
+----------------
+
+.. literalinclude:: ./samples/update_group_request.json
+   :language: json
+
+Response Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - description: group_description
+   - id: group_id_body
+   - members: group_members
+   - name: group_name
+   - type: group_type
+
+Response Example
+----------------
+
+.. literalinclude:: ./samples/update_group_response.json
+   :language: json
+
+Delete group
+============
+
+.. rest_method:: DELETE /v1/groups/{group_id}
+
+Lists groups.
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 204
+
+.. rest_status_code:: error ../status.yaml
+
+   - 400
+   - 401
+   - 404
+   - 409
+
+Request Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - group_id: group_id_query
+
+Add members to group
+====================
+
+.. rest_method:: PUT /v1/groups/{group_id}/members
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 201
+
+.. rest_status_code:: error ../status.yaml
+
+   - 400
+   - 401
+   - 404
+   - 409
+
+Request Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - group_id: group_id_query
+   - members: group_members
+
+Response Example
+----------------
+
+.. literalinclude:: ./samples/add_members_request.json
+   :language: json
+
+Response Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - description: group_description
+   - id: group_id_body
+   - members: group_members
+   - name: group_name
+   - type: group_type
+
+Response Example
+----------------
+
+.. literalinclude:: ./samples/add_members_response.json
+   :language: json
+
+Verify membership in a group
+============================
+
+.. rest_method:: GET /v1/groups/{group_id}/members/{member_id}
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 200
+
+.. rest_status_code:: error ../status.yaml
+
+   - 400
+   - 401
+   - 404
+
+Request Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - group_id: group_id_query
+   - member_id: member_id_query
+
+Delete all members from a group
+===============================
+
+.. rest_method:: DELETE /v1/groups/{group_id}/members
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 204
+
+.. rest_status_code:: error ../status.yaml
+
+   - 400
+   - 401
+   - 404
+
+Request Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - group_id: group_id_query
+
+Delete a member from group
+==========================
+
+.. rest_method:: DELETE /v1/groups/{group_id}/members/{member_id}
+
+Response Codes
+--------------
+
+.. rest_status_code:: success ../status.yaml
+
+   - 204
+
+.. rest_status_code:: error ../status.yaml
+
+   - 400
+   - 401
+   - 404
+
+Request Parameters
+-------------------
+
+.. rest_parameters:: parameters.yaml
+
+   - group_id: group_id_query
+   - member_id: member_id_query
diff --git a/api-ref/source/v1/index.rst b/api-ref/source/v1/index.rst
new file mode 100644
index 0000000..492bf9b
--- /dev/null
+++ b/api-ref/source/v1/index.rst
@@ -0,0 +1,13 @@
+:tocdepth: 2
+
+=======================
+ Valet API v1 (CURRENT)
+=======================
+
+This page lists the Valet API operations in the following order:
+
+* `Groups`_
+
+.. rest_expand_all::
+
+.. include:: groups.inc
diff --git a/api-ref/source/v1/parameters.yaml b/api-ref/source/v1/parameters.yaml
new file mode 100644
index 0000000..24b5824
--- /dev/null
+++ b/api-ref/source/v1/parameters.yaml
@@ -0,0 +1,50 @@
+# Parameters in header
+
+# Parameters in query
+group_id_query:
+  description: |
+    The UUID of a group
+  in: query
+  required: true
+  type: string
+member_id_query:
+  description: |
+    The UUID of a member
+  in: query
+  required: true
+  type: string
+
+# Parameters in body
+group_description:
+  description: |
+    Description of a group.
+  in: body
+  required: true
+  type: string
+group_id_body:
+  description: |
+    The UUID of a group
+  in: body
+  required: true
+  type: UUID
+group_members:
+  description: |
+    List of group member UUIDs.
+  in: body
+  required: true
+  type: list
+group_name:
+  description: |
+    Name for a group.  Must contain only letters (A-Za-z), numbers (0-9),
+    hypens (-), periods (.), underscores (_), and tildes (~).  See
+    RFC 3986, Section 2.3.  This parameter is immutable.
+  in: body
+  required: true
+  type: string
+group_type:
+  description: |
+    Type of a group.  Currently, the only valid value is ``exclusivity``.
+    This parameter is immutable.
+  in: body
+  required: true
+  type: string
diff --git a/api-ref/source/v1/samples/add_members_request.json b/api-ref/source/v1/samples/add_members_request.json
new file mode 100644
index 0000000..0c2f7d3
--- /dev/null
+++ b/api-ref/source/v1/samples/add_members_request.json
@@ -0,0 +1,5 @@
+{
+  "members": [
+    "b7d0e9b175294b649464caa3411adb3f"
+  ]
+}
diff --git a/api-ref/source/v1/samples/add_members_response.json b/api-ref/source/v1/samples/add_members_response.json
new file mode 100644
index 0000000..787ce83
--- /dev/null
+++ b/api-ref/source/v1/samples/add_members_response.json
@@ -0,0 +1,10 @@
+{
+  "description": "My Awesome Group",
+  "type": "exclusivity",
+  "id": "bf49803b-48b6-4a13-9191-98dde1dbd5e4",
+  "members": [
+    "b7d0e9b175294b649464caa3411adb3f",
+    "65c3e5ee5ee0428caa5e5275c58ead61"
+  ],
+  "name": "group"
+}
diff --git a/api-ref/source/v1/samples/create_group_request.json b/api-ref/source/v1/samples/create_group_request.json
new file mode 100644
index 0000000..48d1573
--- /dev/null
+++ b/api-ref/source/v1/samples/create_group_request.json
@@ -0,0 +1,5 @@
+{
+  "name": "group",
+  "description": "My Awesome Group",
+  "type": "exclusivity"
+}
diff --git a/api-ref/source/v1/samples/create_group_response.json b/api-ref/source/v1/samples/create_group_response.json
new file mode 100644
index 0000000..5a79531
--- /dev/null
+++ b/api-ref/source/v1/samples/create_group_response.json
@@ -0,0 +1,7 @@
+{
+  "description": "My Awesome Group",
+  "type": "exclusivity",
+  "id": "7de4790e-08f2-44b7-8332-7a41fab36a41",
+  "members": [],
+  "name": "group"
+}
diff --git a/api-ref/source/v1/samples/list_groups_response.json b/api-ref/source/v1/samples/list_groups_response.json
new file mode 100644
index 0000000..ea8465e
--- /dev/null
+++ b/api-ref/source/v1/samples/list_groups_response.json
@@ -0,0 +1,9 @@
+{
+  "group": {
+    "description": "My Awesome Group",
+    "type": "exclusivity",
+    "id": "7de4790e-08f2-44b7-8332-7a41fab36a41",
+    "members": [],
+    "name": "group"
+  }
+}
diff --git a/api-ref/source/v1/samples/show_group_response.json b/api-ref/source/v1/samples/show_group_response.json
new file mode 100644
index 0000000..ea8465e
--- /dev/null
+++ b/api-ref/source/v1/samples/show_group_response.json
@@ -0,0 +1,9 @@
+{
+  "group": {
+    "description": "My Awesome Group",
+    "type": "exclusivity",
+    "id": "7de4790e-08f2-44b7-8332-7a41fab36a41",
+    "members": [],
+    "name": "group"
+  }
+}
diff --git a/api-ref/source/v1/samples/update_group_request.json b/api-ref/source/v1/samples/update_group_request.json
new file mode 100644
index 0000000..dffa8db
--- /dev/null
+++ b/api-ref/source/v1/samples/update_group_request.json
@@ -0,0 +1,3 @@
+{
+  "description": "My Extra Awesome Group"
+}
diff --git a/api-ref/source/v1/samples/update_group_response.json b/api-ref/source/v1/samples/update_group_response.json
new file mode 100644
index 0000000..21900ef
--- /dev/null
+++ b/api-ref/source/v1/samples/update_group_response.json
@@ -0,0 +1,7 @@
+{
+  "description": "My Extra Awesome Group",
+  "type": "exclusivity",
+  "id": "7de4790e-08f2-44b7-8332-7a41fab36a41",
+  "members": [],
+  "name": "group"
+}
diff --git a/tox.ini b/tox.ini
index 8a7d996..4b4a744 100644
--- a/tox.ini
+++ b/tox.ini
@@ -46,6 +46,11 @@ commands = sphinx-build -a -W -E -d releasenotes/build/doctrees -b html releasen
 [testenv:bandit]
 commands = bandit -r valet -x tests -n 5 -l
 
+[testenv:api-ref]
+basepython = python2.7
+commands =
+    sphinx-build -W -b html -d api-ref/build/doctrees api-ref/source api-ref/build/html
+
 [flake8]
 filename = *.py
 show-source = true