diff --git a/ironic_python_agent/api/app.py b/ironic_python_agent/api/app.py
index 40b0f5f50..5b5601028 100644
--- a/ironic_python_agent/api/app.py
+++ b/ironic_python_agent/api/app.py
@@ -19,6 +19,7 @@ from ironic_python_agent.api import config
 
 
 class AgentHook(hooks.PecanHook):
+    """Hook to attach agent instance to API requests."""
     def __init__(self, agent, *args, **kwargs):
         super(AgentHook, self).__init__(*args, **kwargs)
         self.agent = agent
@@ -28,12 +29,22 @@ class AgentHook(hooks.PecanHook):
 
 
 def get_pecan_config():
-    # Set up the pecan configuration
+    """Set up the pecan configuration.
+
+    :returns: pecan configuration object.
+    """
     filename = config.__file__.replace('.pyc', '.py')
     return pecan.configuration.conf_from_file(filename)
 
 
-def setup_app(pecan_config=None, extra_hooks=None, agent=None):
+def setup_app(pecan_config=None, agent=None):
+    """Set up the API app.
+
+    :param pecan_config: a pecan configuration object.
+    :param agent: an :class:`ironic_python_agent.agent.IronicPythonAgent`
+                  instance.
+    :returns: wsgi app object.
+    """
     app_hooks = [AgentHook(agent)]
 
     if not pecan_config:
@@ -53,6 +64,8 @@ def setup_app(pecan_config=None, extra_hooks=None, agent=None):
 
 
 class VersionSelectorApplication(object):
+    """WSGI application that handles multiple API versions."""
+
     def __init__(self, agent):
         pc = get_pecan_config()
         self.v1 = setup_app(pecan_config=pc, agent=agent)
diff --git a/ironic_python_agent/api/controllers/v1/command.py b/ironic_python_agent/api/controllers/v1/command.py
index 26cc82ac7..e4483e292 100644
--- a/ironic_python_agent/api/controllers/v1/command.py
+++ b/ironic_python_agent/api/controllers/v1/command.py
@@ -22,6 +22,8 @@ from ironic_python_agent.api.controllers.v1 import base
 
 
 class CommandResult(base.APIBase):
+    """Object representing the result of a given command."""
+
     id = types.text
     command_name = types.text
     command_params = types.DictType(types.text, base.json_type)
@@ -31,6 +33,13 @@ class CommandResult(base.APIBase):
 
     @classmethod
     def from_result(cls, result):
+        """Convert a BaseCommandResult object to a CommandResult object.
+
+        :param result: a :class:`ironic_python_agent.extensions.base.
+                       BaseCommandResult` object.
+        :returns: a :class:`ironic_python_agent.api.controllers.v1.command.
+                  CommandResult` object.
+        """
         instance = cls()
         for field in ('id', 'command_name', 'command_params', 'command_status',
                       'command_error', 'command_result'):
@@ -39,10 +48,18 @@ class CommandResult(base.APIBase):
 
 
 class CommandResultList(base.APIBase):
+    """An object representing a list of CommandResult objects."""
     commands = [CommandResult]
 
     @classmethod
     def from_results(cls, results):
+        """Convert a list of BaseCommandResult objects to a CommandResultList.
+
+        :param results: a list of :class:`ironic_python_agent.extensions.base.
+                       BaseCommandResult` objects.
+        :returns: a :class:`ironic_python_agent.api.controllers.v1.command.
+                  CommandResultList` object.
+        """
         instance = cls()
         instance.commands = [CommandResult.from_result(result)
                              for result in results]
@@ -50,7 +67,7 @@ class CommandResultList(base.APIBase):
 
 
 class Command(base.APIBase):
-    """A command representation."""
+    """A representation of a command."""
     name = types.wsattr(types.text, mandatory=True)
     params = types.wsattr(base.MultiType(dict), mandatory=True)
 
@@ -60,12 +77,20 @@ class CommandController(rest.RestController):
 
     @wsme_pecan.wsexpose(CommandResultList)
     def get_all(self):
+        """Get all command results."""
         agent = pecan.request.agent
         results = agent.list_command_results()
         return CommandResultList.from_results(results)
 
     @wsme_pecan.wsexpose(CommandResult, types.text, types.text)
     def get_one(self, result_id, wait=None):
+        """Get a command result by ID.
+
+        :param result_id: the ID of the result to get.
+        :param wait: if 'true', block until the command completes.
+        :returns: a :class:`ironic_python_agent.api.controller.v1.command.
+                  CommandResult` object.
+        """
         agent = pecan.request.agent
         result = agent.get_command_result(result_id)
 
@@ -76,6 +101,14 @@ class CommandController(rest.RestController):
 
     @wsme_pecan.wsexpose(CommandResult, types.text, body=Command)
     def post(self, wait=None, command=None):
+        """Post a command for the agent to run.
+
+        :param wait: if 'true', block until the command completes.
+        :param command: the command to execute. If None, an InvalidCommandError
+                        will be returned.
+        :returns: a :class:`ironic_python_agent.api.controller.v1.command.
+                  CommandResult` object.
+        """
         # the POST body is always the last arg,
         # so command must be a kwarg here
         if command is None:
diff --git a/ironic_python_agent/api/controllers/v1/status.py b/ironic_python_agent/api/controllers/v1/status.py
index 0c7c152b7..84efc6a49 100644
--- a/ironic_python_agent/api/controllers/v1/status.py
+++ b/ironic_python_agent/api/controllers/v1/status.py
@@ -22,11 +22,20 @@ from ironic_python_agent.api.controllers.v1 import base
 
 
 class AgentStatus(base.APIBase):
+    """An object representing an agent instance's status."""
+
     started_at = base.MultiType(float)
     version = types.text
 
     @classmethod
     def from_agent_status(cls, status):
+        """Convert an object representing agent status to an AgentStatus.
+
+        :param status: An :class:`ironic_python_agent.agent.
+                       IronicPythonAgentStatus` object.
+        :returns: An :class:`ironic_python_agent.api.controllers.v1.status.
+                  AgentStatus` object.
+        """
         instance = cls()
         for field in ('started_at', 'version'):
             setattr(instance, field, getattr(status, field))
@@ -38,6 +47,7 @@ class StatusController(rest.RestController):
 
     @wsme_pecan.wsexpose(AgentStatus)
     def get_all(self):
+        """Get current status of the running agent."""
         agent = pecan.request.agent
         status = agent.get_status()
         return AgentStatus.from_agent_status(status)