Repository: watson-developer-cloud/python-sdk

Issue:
Add Intents, Examples and Counterexamples to Conversation SDK
The API has been updated early February and not all features are supported by the Python SDK.

https://www.ibm.com/watson/developercloud/conversation/api/v1/#versioning

Discussion:

Patch:
diff --git a/examples/conversation_v1.py b/examples/conversation_v1.py
index 235f80de..1efb9ce3 100644
--- a/examples/conversation_v1.py
+++ b/examples/conversation_v1.py
@@ -1,6 +1,10 @@
 import json
 from watson_developer_cloud import ConversationV1
 
+#########################
+# message
+#########################
+
 conversation = ConversationV1(
     username='YOUR SERVICE USERNAME',
     password='YOUR SERVICE PASSWORD',
@@ -19,3 +23,117 @@ print(json.dumps(response, indent=2))
 # 'text': 'turn the wipers on'},
 #                                context=response['context'])
 # print(json.dumps(response, indent=2))
+
+#########################
+# workspaces
+#########################
+
+response = conversation.create_workspace(name='test_workspace',
+                                         description='Test workspace.',
+                                         language='en',
+                                         metadata={})
+print(json.dumps(response, indent=2))
+
+workspace_id = response['workspace_id']
+
+response = conversation.get_workspace(workspace_id=workspace_id, export=True)
+print(json.dumps(response, indent=2))
+
+response = conversation.list_workspaces()
+print(json.dumps(response, indent=2))
+
+response = conversation.update_workspace(workspace_id=workspace_id,
+                                         description='Updated test workspace.')
+print(json.dumps(response, indent=2))
+
+# see cleanup section below for delete_workspace example
+
+#########################
+# intents
+#########################
+
+response = conversation.create_intent(workspace_id=workspace_id,
+                                      intent='test_intent',
+                                      description='Test intent.')
+print(json.dumps(response, indent=2))
+
+response = conversation.get_intent(workspace_id=workspace_id,
+                                   intent='test_intent',
+                                   export=True)
+print(json.dumps(response, indent=2))
+
+response = conversation.list_intents(workspace_id=workspace_id,
+                                     export=True)
+print(json.dumps(response, indent=2))
+
+response = conversation.update_intent(workspace_id=workspace_id,
+                                      intent='test_intent',
+                                      new_intent='updated_test_intent',
+                                      new_description='Updated test intent.')
+print(json.dumps(response, indent=2))
+
+# see cleanup section below for delete_intent example
+
+#########################
+# examples
+#########################
+
+response = conversation.create_example(workspace_id=workspace_id,
+                                       intent='updated_test_intent',
+                                       text='Gimme a pizza with pepperoni')
+print(json.dumps(response, indent=2))
+
+response = conversation.get_example(workspace_id=workspace_id,
+                                    intent='updated_test_intent',
+                                    text='Gimme a pizza with pepperoni')
+print(json.dumps(response, indent=2))
+
+response = conversation.list_examples(workspace_id=workspace_id,
+                                      intent='updated_test_intent')
+print(json.dumps(response, indent=2))
+
+response = conversation.update_example(workspace_id=workspace_id,
+                                       intent='updated_test_intent',
+                                       text='Gimme a pizza with pepperoni',
+                                       new_text='Gimme a pizza with pepperoni')
+print(json.dumps(response, indent=2))
+
+response = conversation.delete_example(workspace_id=workspace_id,
+                                       intent='updated_test_intent',
+                                       text='Gimme a pizza with pepperoni')
+print(json.dumps(response, indent=2))
+
+#########################
+# counterexamples
+#########################
+
+response = conversation.create_counterexample(workspace_id=workspace_id,
+                                              text='I want financial advice today.')
+print(json.dumps(response, indent=2))
+
+response = conversation.get_counterexample(workspace_id=workspace_id,
+                                           text='I want financial advice today.')
+print(json.dumps(response, indent=2))
+
+response = conversation.list_counterexamples(workspace_id=workspace_id)
+print(json.dumps(response, indent=2))
+
+response = conversation.update_counterexample(workspace_id=workspace_id,
+                                              text='I want financial advice today.',
+                                              new_text='I want financial advice today.')
+print(json.dumps(response, indent=2))
+
+response = conversation.delete_counterexample(workspace_id=workspace_id,
+                                              text='I want financial advice today.')
+print(json.dumps(response, indent=2))
+
+#########################
+# clean-up
+#########################
+
+response = conversation.delete_intent(workspace_id=workspace_id,
+                                      intent='updated_test_intent')
+print(json.dumps(response, indent=2))
+
+response = conversation.delete_workspace(workspace_id=workspace_id)
+print(json.dumps(response, indent=2))
diff --git a/examples/notebooks/conversation_v1.ipynb b/examples/notebooks/conversation_v1.ipynb
index 73515bc7..053631b9 100644
--- a/examples/notebooks/conversation_v1.ipynb
+++ b/examples/notebooks/conversation_v1.ipynb
@@ -1,13 +1,16 @@
 {
  "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Conversation Service"
+   ]
+  },
   {
    "cell_type": "code",
-   "execution_count": 23,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 1,
+   "metadata": {},
    "outputs": [],
    "source": [
     "import json\n",
@@ -19,11 +22,9 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 2,
    "metadata": {
-    "collapsed": true,
-    "deletable": true,
-    "editable": true
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -33,12 +34,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 3,
+   "metadata": {},
    "outputs": [],
    "source": [
     "conversation = watson_developer_cloud.ConversationV1(username=USERNAME,\n",
@@ -46,222 +43,321 @@
     "                                                     version='2016-09-20')"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Pizza Chatbot"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Let's create and chat with a simple pizza bot. We'll start by defining the bot's workspace, then add intents and examples to recognize pizza orders. Once the chatbot is configured, we'll send a message to converse with our pizza bot."
+   ]
+  },
   {
    "cell_type": "code",
-   "execution_count": 28,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 4,
+   "metadata": {},
    "outputs": [
     {
-     "data": {
-      "text/plain": [
-       "{'pagination': {'refresh_url': '/v1/workspaces?version=2016-09-20'},\n",
-       " 'workspaces': [{'created': '2017-02-09T19:46:26.792Z',\n",
-       "   'description': 'yo dawg',\n",
-       "   'language': 'en',\n",
-       "   'metadata': None,\n",
-       "   'name': 'development',\n",
-       "   'updated': '2017-02-09T20:00:38.558Z',\n",
-       "   'workspace_id': '8c8ee3b3-6149-4bc0-ba66-6517fd6c976a'}]}"
-      ]
-     },
-     "execution_count": 28,
-     "metadata": {},
-     "output_type": "execute_result"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"name\": \"example_workspace\",\n",
+      "  \"created\": \"2017-04-17T18:55:39.740Z\",\n",
+      "  \"updated\": \"2017-04-17T18:55:39.740Z\",\n",
+      "  \"language\": \"en\",\n",
+      "  \"metadata\": null,\n",
+      "  \"description\": \"An example workspace.\",\n",
+      "  \"workspace_id\": \"0247c2f5-4155-4be5-bd51-167de32f2f39\"\n",
+      "}\n"
+     ]
     }
    ],
    "source": [
-    "conversation.list_workspaces()"
+    "# define the dialog for our example workspace\n",
+    "dialog_nodes = [{'conditions': '#order_pizza',\n",
+    "                 'context': None,\n",
+    "                 'description': None,\n",
+    "                 'dialog_node': 'YesYouCan',\n",
+    "                 'go_to': None,\n",
+    "                 'metadata': None,\n",
+    "                 'output': {'text': {'selection_policy': 'random',\n",
+    "                                     'values': ['Yes You can!', 'Of course!']}},\n",
+    "                 'parent': None,\n",
+    "                 'previous_sibling': None,}]\n",
+    "\n",
+    "# create an example workspace\n",
+    "workspace = conversation.create_workspace(name='example_workspace',\n",
+    "                                          description='An example workspace.',\n",
+    "                                          language='en',\n",
+    "                                          dialog_nodes=dialog_nodes)\n",
+    "\n",
+    "# print response and save workspace_id\n",
+    "print(json.dumps(workspace, indent=2))\n",
+    "workspace_id=workspace['workspace_id']"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 5,
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "{'name': 'my experimental workspace', 'created': '2017-02-09T21:48:35.245Z', 'updated': '2017-02-09T21:48:35.245Z', 'language': 'en', 'metadata': None, 'description': 'an experimental workspace', 'workspace_id': 'dbd1211f-3abb-4165-8a67-8bfa95410aa9'}\n"
+      "{\n",
+      "  \"intent\": \"order_pizza\",\n",
+      "  \"created\": \"2017-04-17T18:55:40.899Z\",\n",
+      "  \"updated\": \"2017-04-17T18:55:40.899Z\",\n",
+      "  \"description\": \"A pizza order.\"\n",
+      "}\n"
      ]
     }
    ],
    "source": [
-    "new_workspace = conversation.create_workspace(name='my experimental workspace',\n",
-    "                                              description='an experimental workspace',\n",
-    "                                              language='en',\n",
-    "                                              intents=[{\n",
-    "                                                      \"intent\": \"orderpizza\",\n",
-    "                                                      \"examples\": [\n",
-    "                                                            {\n",
-    "                                                              \"text\": \"can I order a pizza?\"\n",
-    "                                                            },\n",
-    "                                                            {\n",
-    "                                                              \"text\": \"I want to order a pizza\"\n",
-    "                                                            },\n",
-    "                                                            {\n",
-    "                                                              \"text\": \"pizza order\"\n",
-    "                                                            },\n",
-    "                                                            {\n",
-    "                                                              \"text\": \"pizza to go\"\n",
-    "                                                            }\n",
-    "                                                          ],\n",
-    "                                                          \"description\": \"pizza intents\"\n",
-    "                                                        }\n",
-    "                                               ],\n",
-    "                                              dialog_nodes=[{'conditions': '#orderpizza',\n",
-    "                                                             'context': None,\n",
-    "                                                             'description': None,\n",
-    "                                                             'dialog_node': 'YesYouCan',\n",
-    "                                                             'go_to': None,\n",
-    "                                                             'metadata': None,\n",
-    "                                                             'output':  {'text': {'selection_policy': 'random',\n",
-    "                                                                                   'values': \n",
-    "                                                                                   ['Yes You can!', 'Of course!']}},\n",
-    "                                                             'parent': None,\n",
-    "                                                             'previous_sibling': None,}])\n",
-    "print(new_workspace)"
+    "# add an intent to the workspace\n",
+    "intent = conversation.create_intent(workspace_id=workspace_id,\n",
+    "                                    intent='order_pizza',\n",
+    "                                    description='A pizza order.')\n",
+    "print(json.dumps(intent, indent=2))"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 6,
+   "metadata": {},
    "outputs": [
     {
-     "data": {
-      "text/plain": [
-       "{'created': '2017-02-09T21:48:35.245Z',\n",
-       " 'description': 'an experimental workspace',\n",
-       " 'language': 'en',\n",
-       " 'metadata': None,\n",
-       " 'name': 'my experimental workspace',\n",
-       " 'status': 'Training',\n",
-       " 'updated': '2017-02-09T21:48:35.245Z',\n",
-       " 'workspace_id': 'dbd1211f-3abb-4165-8a67-8bfa95410aa9'}"
-      ]
-     },
-     "execution_count": 31,
-     "metadata": {},
-     "output_type": "execute_result"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"text\": \"Can I order a pizza?\",\n",
+      "  \"created\": \"2017-04-17T18:55:41.755Z\",\n",
+      "  \"updated\": \"2017-04-17T18:55:41.755Z\"\n",
+      "}\n",
+      "{\n",
+      "  \"text\": \"I want to order a pizza.\",\n",
+      "  \"created\": \"2017-04-17T18:55:42.172Z\",\n",
+      "  \"updated\": \"2017-04-17T18:55:42.172Z\"\n",
+      "}\n",
+      "{\n",
+      "  \"text\": \"pizza order\",\n",
+      "  \"created\": \"2017-04-17T18:55:42.606Z\",\n",
+      "  \"updated\": \"2017-04-17T18:55:42.606Z\"\n",
+      "}\n",
+      "{\n",
+      "  \"text\": \"pizza to go\",\n",
+      "  \"created\": \"2017-04-17T18:55:43.018Z\",\n",
+      "  \"updated\": \"2017-04-17T18:55:43.018Z\"\n",
+      "}\n"
+     ]
     }
    ],
    "source": [
-    "conversation.get_workspace(workspace_id=new_workspace['workspace_id'])"
+    "# add examples to the intent\n",
+    "example1 = conversation.create_example(workspace_id=workspace_id,\n",
+    "                                       intent='order_pizza',\n",
+    "                                       text='Can I order a pizza?')\n",
+    "example2 = conversation.create_example(workspace_id=workspace_id,\n",
+    "                                       intent='order_pizza',\n",
+    "                                       text='I want to order a pizza.')\n",
+    "example3 = conversation.create_example(workspace_id=workspace_id,\n",
+    "                                       intent='order_pizza',\n",
+    "                                       text='pizza order')\n",
+    "example4 = conversation.create_example(workspace_id=workspace_id,\n",
+    "                                       intent='order_pizza',\n",
+    "                                       text='pizza to go')\n",
+    "\n",
+    "print(json.dumps(example1, indent=2))\n",
+    "print(json.dumps(example2, indent=2))\n",
+    "print(json.dumps(example3, indent=2))\n",
+    "print(json.dumps(example4, indent=2))"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 9,
+   "metadata": {},
    "outputs": [
     {
-     "data": {
-      "text/plain": [
-       "{'created': '2017-02-09T21:39:30.390Z',\n",
-       " 'description': 'an experimental workspace',\n",
-       " 'language': 'en',\n",
-       " 'metadata': None,\n",
-       " 'name': 'changed name',\n",
-       " 'updated': '2017-02-09T21:39:59.124Z',\n",
-       " 'workspace_id': '66e78807-13fa-47ae-9251-dd8c89c8fd19'}"
-      ]
-     },
-     "execution_count": 20,
-     "metadata": {},
-     "output_type": "execute_result"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The workspace status is: Available\n",
+      "Ready to chat!\n"
+     ]
     }
    ],
    "source": [
-    "new_workspace['name'] = 'changed name'\n",
-    "conversation.update_workspace(new_workspace['workspace_id'], name=new_workspace['name'])"
+    "# check workspace status (wait for training to complete)\n",
+    "workspace = conversation.get_workspace(workspace_id=workspace_id)\n",
+    "print('The workspace status is: {0}'.format(workspace['status']))\n",
+    "if workspace['status'] == 'Available':\n",
+    "    print('Ready to chat!')\n",
+    "else:\n",
+    "    print('The workspace should be available shortly. Please try again in 30s.')\n",
+    "    print('(You can send messages, but not all functionality will be supported yet.)')"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 10,
+   "metadata": {},
    "outputs": [
     {
-     "data": {
-      "text/plain": [
-       "{'counterexamples': [],\n",
-       " 'created': '2017-02-09T21:48:35.245Z',\n",
-       " 'description': 'an experimental workspace',\n",
-       " 'dialog_nodes': [{'conditions': '#orderpizza',\n",
-       "   'context': None,\n",
-       "   'created': '2017-02-09T21:48:35.245Z',\n",
-       "   'description': None,\n",
-       "   'dialog_node': 'YesYouCan',\n",
-       "   'go_to': None,\n",
-       "   'metadata': None,\n",
-       "   'output': {'text': {'selection_policy': 'random',\n",
-       "     'values': ['Yes You can!', 'Of course!']}},\n",
-       "   'parent': None,\n",
-       "   'previous_sibling': None,\n",
-       "   'updated': '2017-02-09T21:48:35.245Z'}],\n",
-       " 'entities': [],\n",
-       " 'intents': [{'created': '2017-02-09T21:48:35.245Z',\n",
-       "   'description': 'pizza intents',\n",
-       "   'examples': [{'created': '2017-02-09T21:48:35.245Z',\n",
-       "     'text': 'can I order a pizza?',\n",
-       "     'updated': '2017-02-09T21:48:35.245Z'},\n",
-       "    {'created': '2017-02-09T21:48:35.245Z',\n",
-       "     'text': 'I want to order a pizza',\n",
-       "     'updated': '2017-02-09T21:48:35.245Z'},\n",
-       "    {'created': '2017-02-09T21:48:35.245Z',\n",
-       "     'text': 'pizza order',\n",
-       "     'updated': '2017-02-09T21:48:35.245Z'},\n",
-       "    {'created': '2017-02-09T21:48:35.245Z',\n",
-       "     'text': 'pizza to go',\n",
-       "     'updated': '2017-02-09T21:48:35.245Z'}],\n",
-       "   'intent': 'orderpizza',\n",
-       "   'updated': '2017-02-09T21:48:35.245Z'}],\n",
-       " 'language': 'en',\n",
-       " 'metadata': None,\n",
-       " 'name': 'my experimental workspace',\n",
-       " 'status': 'Available',\n",
-       " 'updated': '2017-02-09T21:48:35.245Z',\n",
-       " 'workspace_id': 'dbd1211f-3abb-4165-8a67-8bfa95410aa9'}"
-      ]
-     },
-     "execution_count": 32,
-     "metadata": {},
-     "output_type": "execute_result"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"intents\": [\n",
+      "    {\n",
+      "      \"intent\": \"order_pizza\",\n",
+      "      \"confidence\": 1\n",
+      "    }\n",
+      "  ],\n",
+      "  \"entities\": [],\n",
+      "  \"input\": {\n",
+      "    \"text\": \"Can I order a pizza?\"\n",
+      "  },\n",
+      "  \"output\": {\n",
+      "    \"log_messages\": [],\n",
+      "    \"text\": [\n",
+      "      \"Yes You can!\"\n",
+      "    ],\n",
+      "    \"nodes_visited\": [\n",
+      "      \"YesYouCan\"\n",
+      "    ]\n",
+      "  },\n",
+      "  \"context\": {\n",
+      "    \"conversation_id\": \"a84cbf65-d41d-4092-8450-e03c986a3340\",\n",
+      "    \"system\": {\n",
+      "      \"dialog_stack\": [\n",
+      "        {\n",
+      "          \"dialog_node\": \"root\"\n",
+      "        }\n",
+      "      ],\n",
+      "      \"dialog_turn_counter\": 1,\n",
+      "      \"dialog_request_counter\": 1,\n",
+      "      \"_node_output_map\": {\n",
+      "        \"YesYouCan\": [\n",
+      "          0,\n",
+      "          0,\n",
+      "          1\n",
+      "        ]\n",
+      "      },\n",
+      "      \"branch_exited\": true,\n",
+      "      \"branch_exited_reason\": \"completed\"\n",
+      "    }\n",
+      "  }\n",
+      "}\n"
+     ]
     }
    ],
    "source": [
-    "conversation.get_workspace(new_workspace['workspace_id'], export=True)"
+    "# start a chat with the pizza bot\n",
+    "message_input = {'text': 'Can I order a pizza?'}\n",
+    "response = conversation.message(workspace_id=workspace_id,\n",
+    "                                message_input=message_input)\n",
+    "print(json.dumps(response, indent=2))"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"intents\": [\n",
+      "    {\n",
+      "      \"intent\": \"order_pizza\",\n",
+      "      \"confidence\": 1\n",
+      "    }\n",
+      "  ],\n",
+      "  \"entities\": [],\n",
+      "  \"input\": {\n",
+      "    \"text\": \"medium\"\n",
+      "  },\n",
+      "  \"output\": {\n",
+      "    \"log_messages\": [],\n",
+      "    \"text\": [\n",
+      "      \"Of course!\"\n",
+      "    ],\n",
+      "    \"nodes_visited\": [\n",
+      "      \"YesYouCan\"\n",
+      "    ]\n",
+      "  },\n",
+      "  \"context\": {\n",
+      "    \"conversation_id\": \"a84cbf65-d41d-4092-8450-e03c986a3340\",\n",
+      "    \"system\": {\n",
+      "      \"dialog_stack\": [\n",
+      "        {\n",
+      "          \"dialog_node\": \"root\"\n",
+      "        }\n",
+      "      ],\n",
+      "      \"dialog_turn_counter\": 2,\n",
+      "      \"dialog_request_counter\": 2,\n",
+      "      \"_node_output_map\": {\n",
+      "        \"YesYouCan\": [\n",
+      "          1,\n",
+      "          0,\n",
+      "          1\n",
+      "        ]\n",
+      "      },\n",
+      "      \"branch_exited\": true,\n",
+      "      \"branch_exited_reason\": \"completed\"\n",
+      "    }\n",
+      "  }\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# continue a chat with the pizza bot\n",
+    "# (when you send multiple requests for the same conversation,\n",
+    "#  then include the context object from the previous response)\n",
+    "message_input = {'text': 'medium'}\n",
+    "response = conversation.message(workspace_id=workspace_id,\n",
+    "                                message_input=message_input,\n",
+    "                                context=response['context'])\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Operation Examples"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The following examples demonstrate each operation of the Conversation service. They use the pizza chatbot workspace configured above."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Message"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -270,13 +366,13 @@
       "{\n",
       "  \"intents\": [\n",
       "    {\n",
-      "      \"intent\": \"orderpizza\",\n",
+      "      \"intent\": \"order_pizza\",\n",
       "      \"confidence\": 1\n",
       "    }\n",
       "  ],\n",
       "  \"entities\": [],\n",
       "  \"input\": {\n",
-      "    \"text\": \"can I order a pizza?\"\n",
+      "    \"text\": \"Can I order a pizza?\"\n",
       "  },\n",
       "  \"output\": {\n",
       "    \"log_messages\": [],\n",
@@ -288,7 +384,7 @@
       "    ]\n",
       "  },\n",
       "  \"context\": {\n",
-      "    \"conversation_id\": \"972f212d-be0f-47fd-a82d-a6f917e16cfd\",\n",
+      "    \"conversation_id\": \"bceff6eb-f89b-48d3-9190-99e9cca6a3e7\",\n",
       "    \"system\": {\n",
       "      \"dialog_stack\": [\n",
       "        {\n",
@@ -303,28 +399,724 @@
       "          1,\n",
       "          0\n",
       "        ]\n",
-      "      }\n",
+      "      },\n",
+      "      \"branch_exited\": true,\n",
+      "      \"branch_exited_reason\": \"completed\"\n",
       "    }\n",
-      "  },\n",
-      "  \"alternate_intents\": false\n",
+      "  }\n",
       "}\n"
      ]
     }
    ],
    "source": [
-    "response = conversation.message(workspace_id=new_workspace['workspace_id'],\n",
-    "                                message_input={'text': 'can I order a pizza?'})\n",
+    "message_input = {'text': 'Can I order a pizza?'}\n",
+    "response = conversation.message(workspace_id=workspace_id,\n",
+    "                                message_input=message_input)\n",
     "print(json.dumps(response, indent=2))"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Workspaces"
+   ]
+  },
   {
    "cell_type": "code",
-   "execution_count": 35,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"name\": \"test_workspace\",\n",
+      "  \"created\": \"2017-04-17T18:57:41.168Z\",\n",
+      "  \"updated\": \"2017-04-17T18:57:41.168Z\",\n",
+      "  \"language\": \"en\",\n",
+      "  \"metadata\": {},\n",
+      "  \"description\": \"Test workspace.\",\n",
+      "  \"workspace_id\": \"d8cc32e4-5fb4-47ec-944c-0d7fcd59651c\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.create_workspace(name='test_workspace',\n",
+    "                                         description='Test workspace.',\n",
+    "                                         language='en',\n",
+    "                                         metadata={})\n",
+    "print(json.dumps(response, indent=2))\n",
+    "test_workspace_id = response['workspace_id']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.delete_workspace(workspace_id=test_workspace_id)\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"name\": \"example_workspace\",\n",
+      "  \"created\": \"2017-04-17T18:55:39.740Z\",\n",
+      "  \"intents\": [\n",
+      "    {\n",
+      "      \"intent\": \"order_pizza\",\n",
+      "      \"created\": \"2017-04-17T18:55:40.899Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:43.018Z\",\n",
+      "      \"examples\": [\n",
+      "        {\n",
+      "          \"text\": \"Can I order a pizza?\",\n",
+      "          \"created\": \"2017-04-17T18:55:41.755Z\",\n",
+      "          \"updated\": \"2017-04-17T18:55:41.755Z\"\n",
+      "        },\n",
+      "        {\n",
+      "          \"text\": \"I want to order a pizza.\",\n",
+      "          \"created\": \"2017-04-17T18:55:42.172Z\",\n",
+      "          \"updated\": \"2017-04-17T18:55:42.172Z\"\n",
+      "        },\n",
+      "        {\n",
+      "          \"text\": \"pizza order\",\n",
+      "          \"created\": \"2017-04-17T18:55:42.606Z\",\n",
+      "          \"updated\": \"2017-04-17T18:55:42.606Z\"\n",
+      "        },\n",
+      "        {\n",
+      "          \"text\": \"pizza to go\",\n",
+      "          \"created\": \"2017-04-17T18:55:43.018Z\",\n",
+      "          \"updated\": \"2017-04-17T18:55:43.018Z\"\n",
+      "        }\n",
+      "      ],\n",
+      "      \"description\": \"A pizza order.\"\n",
+      "    }\n",
+      "  ],\n",
+      "  \"updated\": \"2017-04-17T18:55:43.018Z\",\n",
+      "  \"entities\": [],\n",
+      "  \"language\": \"en\",\n",
+      "  \"metadata\": null,\n",
+      "  \"description\": \"An example workspace.\",\n",
+      "  \"dialog_nodes\": [\n",
+      "    {\n",
+      "      \"go_to\": null,\n",
+      "      \"output\": {\n",
+      "        \"text\": {\n",
+      "          \"values\": [\n",
+      "            \"Yes You can!\",\n",
+      "            \"Of course!\"\n",
+      "          ],\n",
+      "          \"selection_policy\": \"random\"\n",
+      "        }\n",
+      "      },\n",
+      "      \"parent\": null,\n",
+      "      \"context\": null,\n",
+      "      \"created\": \"2017-04-17T18:55:39.740Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:39.740Z\",\n",
+      "      \"metadata\": null,\n",
+      "      \"conditions\": \"#order_pizza\",\n",
+      "      \"description\": null,\n",
+      "      \"dialog_node\": \"YesYouCan\",\n",
+      "      \"previous_sibling\": null\n",
+      "    }\n",
+      "  ],\n",
+      "  \"workspace_id\": \"0247c2f5-4155-4be5-bd51-167de32f2f39\",\n",
+      "  \"counterexamples\": [],\n",
+      "  \"status\": \"Available\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.get_workspace(workspace_id=workspace_id, export=True)\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"workspaces\": [\n",
+      "    {\n",
+      "      \"name\": \"Car_Dashboard\",\n",
+      "      \"created\": \"2016-07-19T16:31:17.236Z\",\n",
+      "      \"updated\": \"2017-04-11T02:29:46.290Z\",\n",
+      "      \"language\": \"en\",\n",
+      "      \"metadata\": {\n",
+      "        \"runtime_version\": \"2016-09-20\"\n",
+      "      },\n",
+      "      \"description\": \"Cognitive Car workspace which allows multi-turn conversations to perform tasks in the car.\",\n",
+      "      \"workspace_id\": \"8d869397-411b-4f0a-864d-a2ba419bb249\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"name\": \"example_workspace\",\n",
+      "      \"created\": \"2017-04-17T18:07:47.842Z\",\n",
+      "      \"updated\": \"2017-04-17T18:07:47.842Z\",\n",
+      "      \"language\": \"en\",\n",
+      "      \"metadata\": null,\n",
+      "      \"description\": \"An example workspace.\",\n",
+      "      \"workspace_id\": \"a7196fc9-c458-4b75-963c-dc4a3dc32ef7\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"name\": \"example_workspace\",\n",
+      "      \"created\": \"2017-04-17T18:42:40.986Z\",\n",
+      "      \"updated\": \"2017-04-17T18:54:21.407Z\",\n",
+      "      \"language\": \"en\",\n",
+      "      \"metadata\": null,\n",
+      "      \"description\": \"An example workspace for ordering pizza.\",\n",
+      "      \"workspace_id\": \"88a4327b-421c-436f-b54a-5e00df6b8e8b\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"name\": \"example_workspace\",\n",
+      "      \"created\": \"2017-04-17T18:55:39.740Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:43.018Z\",\n",
+      "      \"language\": \"en\",\n",
+      "      \"metadata\": null,\n",
+      "      \"description\": \"An example workspace.\",\n",
+      "      \"workspace_id\": \"0247c2f5-4155-4be5-bd51-167de32f2f39\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"name\": \"LaForge POC\",\n",
+      "      \"created\": \"2016-09-07T19:01:46.271Z\",\n",
+      "      \"updated\": \"2016-11-29T21:46:38.969Z\",\n",
+      "      \"language\": \"en\",\n",
+      "      \"metadata\": {\n",
+      "        \"runtime_version\": \"2016-09-20\"\n",
+      "      },\n",
+      "      \"description\": null,\n",
+      "      \"workspace_id\": \"4f4046a6-50c5-4a52-9247-b2538f0fe7ac\"\n",
+      "    }\n",
+      "  ],\n",
+      "  \"pagination\": {\n",
+      "    \"refresh_url\": \"/v1/workspaces?version=2016-09-20\"\n",
+      "  }\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.list_workspaces()\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"name\": \"example_workspace\",\n",
+      "  \"created\": \"2017-04-17T18:55:39.740Z\",\n",
+      "  \"updated\": \"2017-04-17T18:57:45.626Z\",\n",
+      "  \"language\": \"en\",\n",
+      "  \"metadata\": null,\n",
+      "  \"description\": \"An example workspace for ordering pizza.\",\n",
+      "  \"workspace_id\": \"0247c2f5-4155-4be5-bd51-167de32f2f39\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.update_workspace(workspace_id=workspace_id,\n",
+    "                                         description='An example workspace for ordering pizza.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Intents"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"intent\": \"test_intent\",\n",
+      "  \"created\": \"2017-04-17T18:57:47.513Z\",\n",
+      "  \"updated\": \"2017-04-17T18:57:47.513Z\",\n",
+      "  \"description\": \"Test intent.\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.create_intent(workspace_id=workspace_id,\n",
+    "                                      intent='test_intent',\n",
+    "                                      description='Test intent.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.delete_intent(workspace_id=workspace_id,\n",
+    "                                      intent='test_intent')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"intent\": \"order_pizza\",\n",
+      "  \"created\": \"2017-04-17T18:55:40.899Z\",\n",
+      "  \"updated\": \"2017-04-17T18:55:43.018Z\",\n",
+      "  \"examples\": [\n",
+      "    {\n",
+      "      \"text\": \"Can I order a pizza?\",\n",
+      "      \"created\": \"2017-04-17T18:55:41.755Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:41.755Z\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"text\": \"I want to order a pizza.\",\n",
+      "      \"created\": \"2017-04-17T18:55:42.172Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:42.172Z\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"text\": \"pizza order\",\n",
+      "      \"created\": \"2017-04-17T18:55:42.606Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:42.606Z\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"text\": \"pizza to go\",\n",
+      "      \"created\": \"2017-04-17T18:55:43.018Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:43.018Z\"\n",
+      "    }\n",
+      "  ],\n",
+      "  \"description\": \"A pizza order.\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.get_intent(workspace_id=workspace_id,\n",
+    "                                   intent='order_pizza',\n",
+    "                                   export=True)\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"intents\": [\n",
+      "    {\n",
+      "      \"intent\": \"order_pizza\",\n",
+      "      \"created\": \"2017-04-17T18:55:40.899Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:43.018Z\",\n",
+      "      \"examples\": [\n",
+      "        {\n",
+      "          \"text\": \"Can I order a pizza?\",\n",
+      "          \"created\": \"2017-04-17T18:55:41.755Z\",\n",
+      "          \"updated\": \"2017-04-17T18:55:41.755Z\"\n",
+      "        },\n",
+      "        {\n",
+      "          \"text\": \"I want to order a pizza.\",\n",
+      "          \"created\": \"2017-04-17T18:55:42.172Z\",\n",
+      "          \"updated\": \"2017-04-17T18:55:42.172Z\"\n",
+      "        },\n",
+      "        {\n",
+      "          \"text\": \"pizza order\",\n",
+      "          \"created\": \"2017-04-17T18:55:42.606Z\",\n",
+      "          \"updated\": \"2017-04-17T18:55:42.606Z\"\n",
+      "        },\n",
+      "        {\n",
+      "          \"text\": \"pizza to go\",\n",
+      "          \"created\": \"2017-04-17T18:55:43.018Z\",\n",
+      "          \"updated\": \"2017-04-17T18:55:43.018Z\"\n",
+      "        }\n",
+      "      ],\n",
+      "      \"description\": \"A pizza order.\"\n",
+      "    }\n",
+      "  ],\n",
+      "  \"pagination\": {\n",
+      "    \"refresh_url\": \"/v1/workspaces/0247c2f5-4155-4be5-bd51-167de32f2f39/intents?version=2016-09-20&export=true\"\n",
+      "  }\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.list_intents(workspace_id=workspace_id,\n",
+    "                                     export=True)\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"intent\": \"order_pizza\",\n",
+      "  \"created\": \"2017-04-17T18:55:40.899Z\",\n",
+      "  \"updated\": \"2017-04-17T18:57:52.129Z\",\n",
+      "  \"description\": \"Order a pizza.\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.update_intent(workspace_id=workspace_id,\n",
+    "                                      intent='order_pizza',\n",
+    "                                      new_intent='order_pizza',\n",
+    "                                      new_description='Order a pizza.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Examples"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"text\": \"Gimme a pizza with pepperoni\",\n",
+      "  \"created\": \"2017-04-17T18:57:54.817Z\",\n",
+      "  \"updated\": \"2017-04-17T18:57:54.817Z\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.create_example(workspace_id=workspace_id,\n",
+    "                                       intent='order_pizza',\n",
+    "                                       text='Gimme a pizza with pepperoni')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.delete_example(workspace_id=workspace_id,\n",
+    "                                       intent='order_pizza',\n",
+    "                                       text='Gimme a pizza with pepperoni')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"text\": \"I want to order a pizza.\",\n",
+      "  \"created\": \"2017-04-17T18:55:42.172Z\",\n",
+      "  \"updated\": \"2017-04-17T18:55:42.172Z\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.get_example(workspace_id=workspace_id,\n",
+    "                                    intent='order_pizza',\n",
+    "                                    text='I want to order a pizza.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"examples\": [\n",
+      "    {\n",
+      "      \"text\": \"Can I order a pizza?\",\n",
+      "      \"created\": \"2017-04-17T18:55:41.755Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:41.755Z\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"text\": \"I want to order a pizza.\",\n",
+      "      \"created\": \"2017-04-17T18:55:42.172Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:42.172Z\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"text\": \"pizza order\",\n",
+      "      \"created\": \"2017-04-17T18:55:42.606Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:42.606Z\"\n",
+      "    },\n",
+      "    {\n",
+      "      \"text\": \"pizza to go\",\n",
+      "      \"created\": \"2017-04-17T18:55:43.018Z\",\n",
+      "      \"updated\": \"2017-04-17T18:55:43.018Z\"\n",
+      "    }\n",
+      "  ],\n",
+      "  \"pagination\": {\n",
+      "    \"refresh_url\": \"/v1/workspaces/0247c2f5-4155-4be5-bd51-167de32f2f39/intents/order_pizza/examples?version=2016-09-20\"\n",
+      "  }\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.list_examples(workspace_id=workspace_id,\n",
+    "                                      intent='order_pizza')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"text\": \"I want to order a pizza with pepperoni.\",\n",
+      "  \"created\": \"2017-04-17T18:55:42.172Z\",\n",
+      "  \"updated\": \"2017-04-17T18:58:00.647Z\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.update_example(workspace_id=workspace_id,\n",
+    "                                       intent='order_pizza',\n",
+    "                                       text='I want to order a pizza.',\n",
+    "                                       new_text='I want to order a pizza with pepperoni.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Counterexamples"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"text\": \"I want financial advice today.\",\n",
+      "  \"created\": \"2017-04-17T18:58:03.340Z\",\n",
+      "  \"updated\": \"2017-04-17T18:58:03.340Z\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.create_counterexample(workspace_id=workspace_id,\n",
+    "                                              text='I want financial advice today.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"text\": \"I want financial advice today.\",\n",
+      "  \"created\": \"2017-04-17T18:58:03.340Z\",\n",
+      "  \"updated\": \"2017-04-17T18:58:03.340Z\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.get_counterexample(workspace_id=workspace_id,\n",
+    "                                           text='I want financial advice today.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"counterexamples\": [\n",
+      "    {\n",
+      "      \"text\": \"I want financial advice today.\",\n",
+      "      \"created\": \"2017-04-17T18:58:03.340Z\",\n",
+      "      \"updated\": \"2017-04-17T18:58:03.340Z\"\n",
+      "    }\n",
+      "  ],\n",
+      "  \"pagination\": {\n",
+      "    \"refresh_url\": \"/v1/workspaces/0247c2f5-4155-4be5-bd51-167de32f2f39/counterexamples?version=2016-09-20\"\n",
+      "  }\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.list_counterexamples(workspace_id=workspace_id)\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{\n",
+      "  \"text\": \"I want financial advice for tomorrow.\",\n",
+      "  \"created\": \"2017-04-17T18:58:03.340Z\",\n",
+      "  \"updated\": \"2017-04-17T18:58:09.403Z\"\n",
+      "}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.update_counterexample(workspace_id=workspace_id,\n",
+    "                                              text='I want financial advice today.',\n",
+    "                                              new_text='I want financial advice for tomorrow.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{}\n"
+     ]
+    }
+   ],
+   "source": [
+    "response = conversation.delete_counterexample(workspace_id=workspace_id,\n",
+    "                                              text='I want financial advice for tomorrow.')\n",
+    "print(json.dumps(response, indent=2))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Cleanup (Delete Pizza Chatbot)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Let's cleanup by deleting the pizza chatbot, since it is no longer needed."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
    "outputs": [
     {
      "data": {
@@ -332,13 +1124,14 @@
        "{}"
       ]
      },
-     "execution_count": 35,
+     "execution_count": 33,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "conversation.delete_workspace(new_workspace['workspace_id'])"
+    "# clean-up by deleting the workspace\n",
+    "conversation.delete_workspace(workspace_id=workspace_id)"
    ]
   }
  ],
@@ -358,7 +1151,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.6.0"
+   "version": "3.6.1"
   }
  },
  "nbformat": 4,
diff --git a/watson_developer_cloud/conversation_v1.py b/watson_developer_cloud/conversation_v1.py
index 408c225b..f44a6423 100644
--- a/watson_developer_cloud/conversation_v1.py
+++ b/watson_developer_cloud/conversation_v1.py
@@ -1,4 +1,4 @@
-# Copyright 2016 IBM All Rights Reserved.
+# Copyright 2017 IBM All Rights Reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -11,171 +11,536 @@
 # 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.
+
 """
-The Conversation v1 service
-(https://www.ibm.com/watson/developercloud/conversation.html)
+The IBM Watson Conversation service combines machine learning, natural
+language understanding, and integrated dialog tools to create conversation
+flows between your apps and your users.
 """
 
 from .watson_developer_cloud_service import WatsonDeveloperCloudService
 
-
 class ConversationV1(WatsonDeveloperCloudService):
-    """Client for the Conversation service"""
+    """Client for the Conversation service."""
 
     default_url = 'https://gateway.watsonplatform.net/conversation/api'
-    latest_version = '2016-09-20'
+    latest_version = '2017-02-03'
 
     def __init__(self, version, url=default_url, **kwargs):
         WatsonDeveloperCloudService.__init__(self, 'conversation', url,
                                              **kwargs)
         self.version = version
 
-    def list_workspaces(self):
+    #########################
+    # counterexamples
+    #########################
+
+    def create_counterexample(self, workspace_id, text):
         """
-        List workspaces available.
-        This includes pagination info.
+        Create counterexample.
+        :param workspace_id: The workspace ID.
+        :param text: The text of a user input example.
         """
         params = {'version': self.version}
-        return self.request(method='GET',
-                            url='/v1/workspaces',
-                            params=params,
-                            accept_json=True)
+        data = {}
+        data['text'] = text
+        return self.request(
+            method='POST',
+            url='/v1/workspaces/{0}/counterexamples'.format(workspace_id),
+            params=params,
+            json=data,
+            accept_json=True)
 
-    def get_workspace(self, workspace_id, export=False):
+    def delete_counterexample(self, workspace_id, text):
         """
-        Get a specific workspace
-        :param: workspace_id  the guid of the workspace
-        :param: export (optional) return all workspace data
+        Delete counterexample.
+        :param workspace_id: The workspace ID.
+        :param text: The text of a user input counterexample (for example,
+            `What are you wearing?`).
         """
         params = {'version': self.version}
-        if export:
-            params['export'] = True
+        return self.request(
+            method='DELETE',
+            url='/v1/workspaces/{0}/counterexamples/{1}'.format(
+                workspace_id, text),
+            params=params,
+            accept_json=True)
 
-        return self.request(method='GET',
-                            url='/v1/workspaces/{0}'.format(workspace_id),
-                            params=params,
-                            accept_json=True)
+    def get_counterexample(self, workspace_id, text):
+        """
+        Get counterexample.
+        :param workspace_id: The workspace ID.
+        :param text: The text of a user input counterexample (for example,
+            `What are you wearing?`).
+        """
+        params = {'version': self.version}
+        return self.request(
+            method='GET',
+            url='/v1/workspaces/{0}/counterexamples/{1}'.format(
+                workspace_id, text),
+            params=params,
+            accept_json=True)
 
-    def delete_workspace(self, workspace_id):
+    def list_counterexamples(self,
+                             workspace_id,
+                             page_limit=None,
+                             include_count=None,
+                             sort=None,
+                             cursor=None):
         """
-        Deletes a given workspace.
-        :param: workspace_id the guid of the workspace_id
+        List counterexamples.
+        :param workspace_id: The workspace ID.
+        :param page_limit: The number of records to return in each page of
+            results. The default page limit is 100.
+        :param include_count: Whether to include information about the number
+            of records returned.
+        :param sort: The sort order that determines the behavior of the
+            pagination cursor.
+        :param cursor: A token identifying the last value from the previous
+            page of results.
         """
         params = {'version': self.version}
-        return self.request(method='DELETE',
-                            url='/v1/workspaces/{0}'.format(workspace_id),
-                            params=params,
-                            accept_json=True)
+        params['page_limit'] = page_limit
+        params['include_count'] = include_count
+        params['sort'] = sort
+        params['cursor'] = cursor
+        return self.request(
+            method='GET',
+            url='/v1/workspaces/{0}/counterexamples'.format(workspace_id),
+            params=params,
+            accept_json=True)
 
-    def create_workspace(self, name, description, language,
-                         intents=None,
-                         entities=None,
-                         dialog_nodes=None,
-                         counterexamples=None,
-                         metadata=None):
+    def update_counterexample(self, workspace_id, text, new_text=None):
+        """
+        Update counterexample.
+        :param workspace_id: The workspace ID.
+        :param text: The text of a user input counterexample (for example,
+            `What are you wearing?`).
+        :param new_text: The new text of a user input counterexample.
+        """
+        params = {'version': self.version}
+        data = {}
+        data['text'] = new_text
+        return self.request(
+            method='POST',
+            url='/v1/workspaces/{0}/counterexamples/{1}'.format(
+                workspace_id, text),
+            params=params,
+            json=data,
+            accept_json=True)
+
+    #########################
+    # examples
+    #########################
+
+    def create_example(self, workspace_id, intent, text):
+        """
+        Create user input example.
+        :param workspace_id: The workspace ID.
+        :param intent: The intent name (for example, `pizza_order`).
+        :param text: The text of a user input example.
+        """
+        params = {'version': self.version}
+        data = {}
+        data['text'] = text
+        return self.request(
+            method='POST',
+            url='/v1/workspaces/{0}/intents/{1}/examples'.format(
+                workspace_id, intent),
+            params=params,
+            json=data,
+            accept_json=True)
+
+    def delete_example(self, workspace_id, intent, text):
+        """
+        Delete user input example.
+        :param workspace_id: The workspace ID.
+        :param intent: The intent name (for example, `pizza_order`).
+        :param text: The text of the user input example.
+        """
+        params = {'version': self.version}
+        return self.request(
+            method='DELETE',
+            url='/v1/workspaces/{0}/intents/{1}/examples/{2}'.format(
+                workspace_id, intent, text),
+            params=params,
+            accept_json=True)
+
+    def get_example(self, workspace_id, intent, text):
+        """
+        Get user input example.
+        :param workspace_id: The workspace ID.
+        :param intent: The intent name (for example, `pizza_order`).
+        :param text: The text of the user input example.
+        """
+        params = {'version': self.version}
+        return self.request(
+            method='GET',
+            url='/v1/workspaces/{0}/intents/{1}/examples/{2}'.format(
+                workspace_id, intent, text),
+            params=params,
+            accept_json=True)
+
+    def list_examples(self,
+                      workspace_id,
+                      intent,
+                      page_limit=None,
+                      include_count=None,
+                      sort=None,
+                      cursor=None):
+        """
+        List user input examples.
+        :param workspace_id: The workspace ID.
+        :param intent: The intent name (for example, `pizza_order`).
+        :param page_limit: The number of records to return in each page of
+            results. The default page limit is 100.
+        :param include_count: Whether to include information about the number
+            of records returned.
+        :param sort: The sort order that determines the behavior of the
+            pagination cursor.
+        :param cursor: A token identifying the last value from the previous
+            page of results.
+        """
+        params = {'version': self.version}
+        params['page_limit'] = page_limit
+        params['include_count'] = include_count
+        params['sort'] = sort
+        params['cursor'] = cursor
+        return self.request(
+            method='GET',
+            url='/v1/workspaces/{0}/intents/{1}/examples'.format(
+                workspace_id, intent),
+            params=params,
+            accept_json=True)
+
+    def update_example(self, workspace_id, intent, text, new_text=None):
+        """
+        Update user input example.
+        :param workspace_id: The workspace ID.
+        :param intent: The intent name (for example, `pizza_order`).
+        :param text: The text of the user input example.
+        :param new_text: The new text of the user input example.
+        """
+        params = {'version': self.version}
+        data = {}
+        data['text'] = new_text
+        return self.request(
+            method='POST',
+            url='/v1/workspaces/{0}/intents/{1}/examples/{2}'.format(
+                workspace_id, intent, text),
+            params=params,
+            json=data,
+            accept_json=True)
+
+    #########################
+    # intents
+    #########################
+
+    def create_intent(self,
+                      workspace_id,
+                      intent,
+                      description=None,
+                      examples=None):
+        """
+        Create intent.
+        :param workspace_id: The workspace ID.
+        :param intent: The name of the intent.
+        :param description: The description of the intent.
+        :param examples: An array of user input examples.
+        """
+        params = {'version': self.version}
+        data = {}
+        data['intent'] = intent
+        data['description'] = description
+        data['examples'] = examples
+        return self.request(
+            method='POST',
+            url='/v1/workspaces/{0}/intents'.format(workspace_id),
+            params=params,
+            json=data,
+            accept_json=True)
+
+    def delete_intent(self, workspace_id, intent):
         """
-        Create a new workspace
-        :param name: Name of the workspace
-        :param description: description of the worksspace
-        :param language: language code
-        :param entities: an array of entities (optional)
-        :param dialog_nodes: an array of dialog notes (optional)
-        :param counterexamples: an array of counterexamples (optional)
-        :param metadata: metadata dictionary (optional)
+        Delete intent.
+        :param workspace_id: The workspace ID.
+        :param intent: The intent name (for example, `pizza_order`).
         """
-        payload = {'name': name,
-                   'description': description,
-                   'language': language}
-        if intents is not None:
-            payload['intents'] = intents
+        params = {'version': self.version}
+        return self.request(
+            method='DELETE',
+            url='/v1/workspaces/{0}/intents/{1}'.format(workspace_id, intent),
+            params=params,
+            accept_json=True)
 
-        if entities is not None:
-            payload['entities'] = entities
+    def get_intent(self, workspace_id, intent, export=None):
+        """
+        Get intent.
+        :param workspace_id: The workspace ID.
+        :param intent: The intent name (for example, `pizza_order`).
+        :param export: Whether to include all element content in the
+            returned data. If export=`false`, the returned data includes
+            only information about the element itself. If export=`true`,
+            all content, including subelements, is included. The default
+            value is `false`.
+        """
+        params = {'version': self.version}
+        params['export'] = export
+        return self.request(
+            method='GET',
+            url='/v1/workspaces/{0}/intents/{1}'.format(workspace_id, intent),
+            params=params,
+            accept_json=True)
 
-        if dialog_nodes is not None:
-            payload['dialog_nodes'] = dialog_nodes
+    def list_intents(self,
+                     workspace_id,
+                     export=None,
+                     page_limit=None,
+                     include_count=None,
+                     sort=None,
+                     cursor=None):
+        """
+        List intents.
+        :param workspace_id: The workspace ID.
+        :param export: Whether to include all element content in the
+            returned data. If export=`false`, the returned data includes
+            only information about the element itself. If export=`true`,
+            all content, including subelements, is included. The default
+            value is `false`.
+        :param page_limit: The number of records to return in each page of
+            results. The default page limit is 100.
+        :param include_count: Whether to include information about the
+            number of records returned.
+        :param sort: The sort order that determines the behavior of the
+            pagination cursor.
+        :param cursor: A token identifying the last value from the previous
+            page of results.
+        """
+        params = {'version': self.version}
+        params['export'] = export
+        params['page_limit'] = page_limit
+        params['include_count'] = include_count
+        params['sort'] = sort
+        params['cursor'] = cursor
+        return self.request(
+            method='GET',
+            url='/v1/workspaces/{0}/intents'.format(workspace_id),
+            params=params,
+            accept_json=True)
 
-        if counterexamples is not None:
-            payload['counterexamples'] = counterexamples
+    def update_intent(self,
+                      workspace_id,
+                      intent,
+                      new_intent=None,
+                      new_description=None,
+                      new_examples=None):
+        """
+        Update intent.
+        :param workspace_id: The workspace ID.
+        :param intent: The intent name (for example, `pizza_order`).
+        :param new_intent: The new intent name.
+        :param new_description: The new description of the intent.
+        :param new_examples: An array of new user input examples.
+        """
+        params = {'version': self.version}
+        data = {}
+        data['intent'] = new_intent
+        data['description'] = new_description
+        data['examples'] = new_examples
+        return self.request(
+            method='POST',
+            url='/v1/workspaces/{0}/intents/{1}'.format(workspace_id, intent),
+            params=params,
+            json=data,
+            accept_json=True)
 
-        if metadata is not None:
-            payload['metadata'] = metadata
+    #########################
+    # message
+    #########################
 
+    def message(self,
+                workspace_id,
+                message_input,
+                alternate_intents=None,
+                context=None,
+                entities=None,
+                intents=None,
+                output=None):
+        """
+        Get a response to a user's input.
+        :param workspace_id: Unique identifier of the workspace.
+        :param message_input: An input object that includes the input text.
+        :param alternate_intents: Whether to return more than one intent.
+            Set to `true` to return all matching intents.
+        :param context: State information for the conversation. Include the
+            context object from the previous response when you send multiple
+            requests for the same conversation.
+        :param entities: Include the entities from the previous response when
+            they do not need to change and to prevent Watson from trying to
+            identify them.
+        :param intents: An array of name-confidence pairs for the user input.
+            Include the intents from the previous response when they do not
+            need to change and to prevent Watson from trying to identify them.
+        :param output: System output. Include the output from the request
+            when you have several requests within the same Dialog turn to
+            pass back in the intermediate information.
+        """
         params = {'version': self.version}
-        return self.request(method='POST',
-                            url='/v1/workspaces',
-                            json=payload,
-                            params=params,
-                            accept_json=True)
+        data = {}
+        data['input'] = message_input
+        data['alternate_intents'] = alternate_intents
+        data['context'] = context
+        data['entities'] = entities
+        data['intents'] = intents
+        data['output'] = output
+        return self.request(
+            method='POST',
+            url='/v1/workspaces/{0}/message'.format(workspace_id),
+            params=params,
+            json=data,
+            accept_json=True)
+
+    #########################
+    # workspaces
+    #########################
 
-    def update_workspace(self, workspace_id,
+    def create_workspace(self,
                          name=None,
                          description=None,
                          language=None,
+                         metadata=None,
                          intents=None,
                          entities=None,
                          dialog_nodes=None,
-                         counterexamples=None,
-                         metadata=None):
-        """
-        Update an existing workspace
-        :param workspace_id: the guid of the workspace to update
-        :param name: Name of the workspace
-        :param description: description of the worksspace
-        :param language: language code
-        :param entities: an array of entities (optional)
-        :param dialog_nodes: an array of dialog notes (optional)
-        :param counterexamples: an array of counterexamples (optional)
-        :param metadata: metadata dictionary (optional)
-        """
-        params = {'version': self.version}
-        payload = {'name': name,
-                   'description': description,
-                   'language': language}
-        if intents is not None:
-            payload['intents'] = intents
-
-        if entities is not None:
-            payload['entities'] = entities
-
-        if dialog_nodes is not None:
-            payload['dialog_nodes'] = dialog_nodes
-
-        if counterexamples is not None:
-            payload['counterexamples'] = counterexamples
-
-        if metadata is not None:
-            payload['metadata'] = metadata
-
-        params = {'version': self.version}
-        return self.request(method='POST',
-                            url='/v1/workspaces/{0}'.format(workspace_id),
-                            json=payload,
-                            params=params,
-                            accept_json=True)
-
-    def message(self, workspace_id, message_input=None, context=None,
-                entities=None, intents=None, output=None,
-                alternate_intents=False):
-        """
-        Retrieves information about a specific classifier.
-        :param workspace_id: The workspace to use
-        :param message_input: The input, usually containing a text field
-        :param context: The optional context object
-        :param entities: The optional entities
-        :param intents: The optional intents
-        :param alternate_intents: Whether to return more than one intent.
-        :param output: The optional output object
+                         counterexamples=None):
+        """
+        Create workspace.
+        :param name: The name of the workspace.
+        :param description: The description of the workspace.
+        :param language: The language of the workspace.
+        :param metadata: Any metadata that is required by the workspace.
+        :param intents: An array of CreateIntent objects defining the
+            intents for the workspace.
+        :param entities: An array of CreateEntity objects defining the
+            entities for the workspace.
+        :param dialog_nodes: An array of CreateDialogNode objects defining
+            the nodes in the workspace dialog.
+        :param counterexamples: An array of CreateExample objects defining
+            input examples that have been marked as irrelevant input.
         """
+        params = {'version': self.version}
+        data = {}
+        data['name'] = name
+        data['description'] = description
+        data['language'] = language
+        data['metadata'] = metadata
+        data['intents'] = intents
+        data['entities'] = entities
+        data['dialog_nodes'] = dialog_nodes
+        data['counterexamples'] = counterexamples
+        return self.request(
+            method='POST',
+            url='/v1/workspaces',
+            params=params,
+            json=data,
+            accept_json=True)
 
+    def delete_workspace(self, workspace_id):
+        """
+        Delete workspace.
+        :param workspace_id: The workspace ID.
+        """
+        params = {'version': self.version}
+        return self.request(
+            method='DELETE',
+            url='/v1/workspaces/{0}'.format(workspace_id),
+            params=params,
+            accept_json=True)
+
+    def get_workspace(self, workspace_id, export=None):
+        """
+        Get information about a workspace.
+        :param workspace_id: The workspace ID.
+        :param export: Whether to include all element content in the
+            returned data. If export=`false`, the returned data includes
+            only information about the element itself. If export=`true`,
+            all content, including subelements, is included. The default
+            value is `false`.
+        """
+        params = {'version': self.version}
+        params['export'] = export
+        return self.request(
+            method='GET',
+            url='/v1/workspaces/{0}'.format(workspace_id),
+            params=params,
+            accept_json=True)
+
+    def list_workspaces(self,
+                        page_limit=None,
+                        include_count=None,
+                        sort=None,
+                        cursor=None):
+        """
+        List workspaces.
+        :param page_limit: The number of records to return in each page of
+            results. The default page limit is 100.
+        :param include_count: Whether to include information about the number
+            of records returned.
+        :param sort: The sort order that determines the behavior of the
+            pagination cursor.
+        :param cursor: A token identifying the last value from the previous
+            page of results.
+        """
+        params = {'version': self.version}
+        params['page_limit'] = page_limit
+        params['include_count'] = include_count
+        params['sort'] = sort
+        params['cursor'] = cursor
+        return self.request(
+            method='GET',
+            url='/v1/workspaces',
+            params=params,
+            accept_json=True)
+
+    def update_workspace(self,
+                         workspace_id,
+                         name=None,
+                         description=None,
+                         language=None,
+                         metadata=None,
+                         intents=None,
+                         entities=None,
+                         dialog_nodes=None,
+                         counterexamples=None):
+        """
+        Update workspace.
+        :param workspace_id: The workspace ID.
+        :param name: The name of the workspace.
+        :param description: The description of the workspace.
+        :param language: The language of the workspace.
+        :param metadata: Any metadata that is required by the workspace.
+        :param intents: An array of CreateIntent objects defining the
+            intents for the workspace.
+        :param entities: An array of CreateEntity objects defining the
+            entities for the workspace.
+        :param dialog_nodes: An array of CreateDialogNode objects defining
+            the nodes in the workspace dialog.
+        :param counterexamples: An array of CreateExample objects defining
+            input examples that have been marked as irrelevant input.
+        """
         params = {'version': self.version}
-        data = {'input': message_input,
-                'context': context,
-                'entities': entities,
-                'intents': intents,
-                'alternate_intents': alternate_intents,
-                'output': output}
-        return self.request(method='POST',
-                            url='/v1/workspaces/{0}/message'.format(
-                                workspace_id), params=params,
-                            json=data, accept_json=True)
+        data = {}
+        data['name'] = name
+        data['description'] = description
+        data['language'] = language
+        data['metadata'] = metadata
+        data['intents'] = intents
+        data['entities'] = entities
+        data['dialog_nodes'] = dialog_nodes
+        data['counterexamples'] = counterexamples
+        return self.request(
+            method='POST',
+            url='/v1/workspaces/{0}'.format(workspace_id),
+            params=params,
+            json=data,
+            accept_json=True)


Test patch:
diff --git a/test/test_conversation_v1.py b/test/test_conversation_v1.py
index fb8d494a..361fe4e0 100644
--- a/test/test_conversation_v1.py
+++ b/test/test_conversation_v1.py
@@ -1,235 +1,666 @@
+# Copyright 2017 IBM All Rights Reserved.
+#
+# 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 json
 import responses
 import watson_developer_cloud
 
-platform_url = "https://gateway.watsonplatform.net"
-conversation_path = "/conversation/api/v1"
-base_url = "{0}{1}".format(platform_url, conversation_path)
+platform_url = 'https://gateway.watsonplatform.net'
+service_path = '/conversation/api'
+base_url = '{0}{1}'.format(platform_url, service_path)
+
+#########################
+# counterexamples
+#########################
 
 
 @responses.activate
-def test_list_worksapces():
-    workspace_url = "{0}{1}".format(base_url, "/workspaces")
-    message_response = {"workspaces": [],
-                        "pagination": {
-                            "refresh_url":
-                                "/v1/workspaces?version=2016-09-20"}}
-    responses.add(responses.GET, workspace_url,
-                  body=json.dumps(message_response), status=200,
-                  content_type='application/json')
-    conversation = watson_developer_cloud.ConversationV1(username="username",
-                                                         password="password",
-                                                         version='2016-09-20')
-    workspaces = conversation.list_workspaces()
-    assert 'workspaces' in workspaces
-    assert len(workspaces['workspaces']) == 0
+def test_create_counterexample():
+    endpoint = '/v1/workspaces/{0}/counterexamples'.format('boguswid')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "text": "I want financial advice today.",
+        "created": "2016-07-11T16:39:01.774Z",
+        "updated": "2015-12-07T18:53:59.153Z"
+    }
+    responses.add(
+        responses.POST,
+        url,
+        body=json.dumps(response),
+        status=201,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    counterexample = service.create_counterexample(
+        workspace_id='boguswid', text='I want financial advice today.')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert counterexample == response
 
 
 @responses.activate
-def test_get_workspace():
-    workspace_url = "{0}{1}/boguswid".format(base_url, "/workspaces")
-    message_response = {
-                        "name": "development",
-                        "created": "2017-02-09T18:41:19.890Z",
-                        "updated": "2017-02-09T18:41:19.890Z",
-                        "language": "en",
-                        "metadata": None,
-                        "description": "this is a workspace",
-                        "workspace_id": "boguswid",
-                        "status": 'Training',
-                        }
-    responses.add(responses.GET, workspace_url,
-                  body=json.dumps(message_response), status=200,
-                  content_type='application/json')
-    conversation = watson_developer_cloud.ConversationV1(username="username",
-                                                         password="password",
-                                                         version='2016-09-20')
-    workspace = conversation.get_workspace(workspace_id='boguswid')
-    assert workspace['name'] == 'development'
-    assert workspace['workspace_id'] == 'boguswid'
-    assert workspace['status'] == 'Training'
-
-    workspace = conversation.get_workspace(workspace_id='boguswid',
-                                           export=True)
-    assert workspace['status'] == 'Training'
+def test_delete_counterexample():
+    endpoint = '/v1/workspaces/{0}/counterexamples/{1}'.format(
+        'boguswid', 'I%20want%20financial%20advice%20today')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {}
+    responses.add(
+        responses.DELETE,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    counterexample = service.delete_counterexample(
+        workspace_id='boguswid', text='I want financial advice today')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert counterexample == response
 
 
 @responses.activate
-def test_delete_workspace():
-    workspace_url = "{0}{1}/boguswid".format(base_url, "/workspaces")
-    message_response = {}
-    responses.add(responses.DELETE, workspace_url,
-                  body=json.dumps(message_response), status=200,
-                  content_type='application/json')
-    conversation = watson_developer_cloud.ConversationV1(username="username",
-                                                         password="password",
-                                                         version='2016-09-20')
-    workspace = conversation.delete_workspace(workspace_id='boguswid')
+def test_get_counterexample():
+    endpoint = '/v1/workspaces/{0}/counterexamples/{1}'.format(
+        'boguswid', 'What%20are%20you%20wearing%3F')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "text": "What are you wearing?",
+        "created": "2016-07-11T23:53:59.153Z",
+        "updated": "2016-12-07T18:53:59.153Z"
+    }
+    responses.add(
+        responses.GET,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    counterexample = service.get_counterexample(
+        workspace_id='boguswid', text='What are you wearing%3F')
     assert len(responses.calls) == 1
-    assert workspace == {}
+    assert responses.calls[0].request.url.startswith(url)
+    assert counterexample == response
 
 
 @responses.activate
-def test_create_workspace():
-    workspace_data = {
-                      "name": "development",
-                      "intents": [
-                                  {
-                                   "intent": "orderpizza",
-                                   "examples": [
-                                                {
-                                                 "text": "can I order a pizza?"
-                                                }, {
-                                                 "text": "want order a pizza"
-                                                }, {
-                                                 "text": "pizza order"
-                                                }, {
-                                                 "text": "pizza to go"
-                                                }],
-                                   "description": None
-                                  }],
-                      "entities": [{'entity': 'just for testing'}],
-                      "language": "en",
-                      "metadata": {'thing': 'something'},
-                      "description": "this is a development workspace",
-                      "dialog_nodes": [{'conditions': '#orderpizza',
-                                        'context': None,
-                                        'description': None,
-                                        'dialog_node': 'YesYouCan',
-                                        'go_to': None,
-                                        'metadata': None,
-                                        'output':  {'text': {'selection_policy': 'random',
-                                                             'values': ['Yes You can!', 'Of course!']}},
-                                                             'parent': None,
-                                                             'previous_sibling': None}],
-                      "counterexamples": [{'counter': 'counterexamples for test'}]
-                      }
-
-    workspace_url = "{0}{1}".format(base_url, "/workspaces")
-    message_response = workspace_data
-    message_response["workspace_id"] = 'bogusid'
-    responses.add(responses.POST, workspace_url,
-                  body=json.dumps(message_response), status=200,
-                  content_type='application/json')
-    conversation = watson_developer_cloud.ConversationV1(username="username",
-                                                         password="password",
-                                                         version='2016-09-20')
-    workspace = conversation.create_workspace(name=workspace_data['name'],
-                                              description=workspace_data['description'],
-                                              language=workspace_data['language'],
-                                              intents=workspace_data['intents'],
-                                              metadata=workspace_data['metadata'],
-                                              counterexamples=workspace_data['counterexamples'],
-                                              dialog_nodes=workspace_data['dialog_nodes'],
-                                              entities=workspace_data['entities'])
-    assert workspace == message_response
+def test_list_counterexamples():
+    endpoint = '/v1/workspaces/{0}/counterexamples'.format('boguswid')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "counterexamples": [{
+            "text": "I want financial advice today.",
+            "created": "2016-07-11T16:39:01.774Z",
+            "updated": "2015-12-07T18:53:59.153Z"
+        }, {
+            "text": "What are you wearing today",
+            "created": "2016-07-11T16:39:01.774Z",
+            "updated": "2015-12-07T18:53:59.153Z"
+        }],
+        "pagination": {
+            "refresh_url":
+            "/v1/workspaces/pizza_app-e0f3/counterexamples?version=2017-12-18&page_limit=2",
+            "next_url":
+            "/v1/workspaces/pizza_app-e0f3/counterexamples?cursor=base64=&version=2017-12-18&page_limit=2"
+        }
+    }
+    responses.add(
+        responses.GET,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    counterexamples = service.list_counterexamples(workspace_id='boguswid')
     assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert counterexamples == response
 
 
 @responses.activate
-def test_update_workspace():
-    workspace_data = {
-                      "name": "development",
-                      "intents": [
-                                  {
-                                   "intent": "orderpizza",
-                                   "examples": [
-                                                {
-                                                 "text": "can I order a pizza?"
-                                                }, {
-                                                 "text": "want order a pizza"
-                                                }, {
-                                                 "text": "pizza order"
-                                                }, {
-                                                 "text": "pizza to go"
-                                                }],
-                                   "description": None
-                                  }],
-                      "entities": [],
-                      "language": "en",
-                      "metadata": {},
-                      "description": "this is a development workspace",
-                      "dialog_nodes": [],
-                      "counterexamples": [],
-                      "workspace_id": 'boguswid'
-                      }
-
-    workspace_url = "{0}{1}".format(base_url, "/workspaces/boguswid")
-    message_response = workspace_data
-    responses.add(responses.POST, workspace_url,
-                  body=json.dumps(message_response), status=200,
-                  content_type='application/json')
-    conversation = watson_developer_cloud.ConversationV1(username="username",
-                                                         password="password",
-                                                         version='2016-09-20')
-    workspace = conversation.update_workspace('boguswid',
-                                              name=workspace_data['name'],
-                                              description=workspace_data['description'],
-                                              language=workspace_data['language'],
-                                              intents=workspace_data['intents'],
-                                              metadata=workspace_data['metadata'],
-                                              counterexamples=workspace_data['counterexamples'],
-                                              dialog_nodes=workspace_data['dialog_nodes'],
-                                              entities=workspace_data['entities'])
-    assert len(responses.calls) == 1
-    assert workspace == message_response
+def test_update_counterexample():
+    endpoint = '/v1/workspaces/{0}/counterexamples/{1}'.format(
+        'boguswid', 'What%20are%20you%20wearing%3F')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "text": "What are you wearing?",
+        "created": "2016-07-11T23:53:59.153Z",
+        "updated": "2015-12-07T18:53:59.153Z"
+    }
+    responses.add(
+        responses.POST,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    counterexample = service.update_counterexample(
+        workspace_id='boguswid',
+        text='What are you wearing%3F',
+        new_text='What are you wearing%3F')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert counterexample == response
+
+
+#########################
+# examples
+#########################
+
+
+@responses.activate
+def test_create_example():
+    endpoint = '/v1/workspaces/{0}/intents/{1}/examples'.format(
+        'boguswid', 'pizza_order')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "text": "Gimme a pizza with pepperoni",
+        "created": "2016-07-11T16:39:01.774Z",
+        "updated": "2015-12-07T18:53:59.153Z"
+    }
+    responses.add(
+        responses.POST,
+        url,
+        body=json.dumps(response),
+        status=201,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    example = service.create_example(
+        workspace_id='boguswid',
+        intent='pizza_order',
+        text='Gimme a pizza with pepperoni')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert example == response
+
+
+@responses.activate
+def test_delete_example():
+    endpoint = '/v1/workspaces/{0}/intents/{1}/examples/{2}'.format(
+        'boguswid', 'pizza_order', 'Gimme%20a%20pizza%20with%20pepperoni')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {}
+    responses.add(
+        responses.DELETE,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    example = service.delete_example(
+        workspace_id='boguswid',
+        intent='pizza_order',
+        text='Gimme a pizza with pepperoni')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert example == response
+
+
+@responses.activate
+def test_get_example():
+    endpoint = '/v1/workspaces/{0}/intents/{1}/examples/{2}'.format(
+        'boguswid', 'pizza_order', 'Gimme%20a%20pizza%20with%20pepperoni')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "text": "Gimme a pizza with pepperoni",
+        "created": "2016-07-11T23:53:59.153Z",
+        "updated": "2016-12-07T18:53:59.153Z"
+    }
+    responses.add(
+        responses.GET,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    example = service.get_example(
+        workspace_id='boguswid',
+        intent='pizza_order',
+        text='Gimme a pizza with pepperoni')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert example == response
+
+
+@responses.activate
+def test_list_examples():
+    endpoint = '/v1/workspaces/{0}/intents/{1}/examples'.format(
+        'boguswid', 'pizza_order')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "examples": [{
+            "text": "Can I order a pizza?",
+            "created": "2016-07-11T16:39:01.774Z",
+            "updated": "2015-12-07T18:53:59.153Z"
+        }, {
+            "text": "Gimme a pizza with pepperoni",
+            "created": "2016-07-11T16:39:01.774Z",
+            "updated": "2015-12-07T18:53:59.153Z"
+        }],
+        "pagination": {
+            "refresh_url":
+            "/v1/workspaces/pizza_app-e0f3/intents/order/examples?version=2017-12-18&page_limit=2",
+            "next_url":
+            "/v1/workspaces/pizza_app-e0f3/intents/order/examples?cursor=base64=&version=2017-12-18&page_limit=2"
+        }
+    }
+    responses.add(
+        responses.GET,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    examples = service.list_examples(
+        workspace_id='boguswid', intent='pizza_order')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert examples == response
+
+
+@responses.activate
+def test_update_example():
+    endpoint = '/v1/workspaces/{0}/intents/{1}/examples/{2}'.format(
+        'boguswid', 'pizza_order', 'Gimme%20a%20pizza%20with%20pepperoni')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "text": "Gimme a pizza with pepperoni",
+        "created": "2016-07-11T23:53:59.153Z",
+        "updated": "2015-12-07T18:53:59.153Z"
+    }
+    responses.add(
+        responses.POST,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    example = service.update_example(
+        workspace_id='boguswid',
+        intent='pizza_order',
+        text='Gimme a pizza with pepperoni',
+        new_text='Gimme a pizza with pepperoni')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert example == response
+
+
+#########################
+# intents
+#########################
+
+
+@responses.activate
+def test_create_intent():
+    endpoint = '/v1/workspaces/{0}/intents'.format('boguswid')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "intent": "pizza_order",
+        "created": "2015-12-06T23:53:59.153Z",
+        "updated": "2015-12-07T18:53:59.153Z",
+        "description": "User wants to start a new pizza order"
+    }
+    responses.add(
+        responses.POST,
+        url,
+        body=json.dumps(response),
+        status=201,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    intent = service.create_intent(
+        workspace_id='boguswid',
+        intent='pizza_order',
+        description='User wants to start a new pizza order')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert intent == response
+
+
+@responses.activate
+def test_delete_intent():
+    endpoint = '/v1/workspaces/{0}/intents/{1}'.format('boguswid',
+                                                       'pizza_order')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {}
+    responses.add(
+        responses.DELETE,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    intent = service.delete_intent(
+        workspace_id='boguswid', intent='pizza_order')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert intent == response
+
+
+@responses.activate
+def test_get_intent():
+    endpoint = '/v1/workspaces/{0}/intents/{1}'.format('boguswid',
+                                                       'pizza_order')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "intent": "pizza_order",
+        "created": "2015-12-06T23:53:59.153Z",
+        "updated": "2015-12-07T18:53:59.153Z",
+        "description": "User wants to start a new pizza order"
+    }
+    responses.add(
+        responses.GET,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    intent = service.get_intent(
+        workspace_id='boguswid', intent='pizza_order', export=False)
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert intent == response
+
+
+@responses.activate
+def test_list_intents():
+    endpoint = '/v1/workspaces/{0}/intents'.format('boguswid')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "intents": [{
+            "intent": "pizza_order",
+            "created": "2015-12-06T23:53:59.153Z",
+            "updated": "2015-12-07T18:53:59.153Z",
+            "description": "User wants to start a new pizza order"
+        }],
+        "pagination": {
+            "refresh_url":
+            "/v1/workspaces/pizza_app-e0f3/intents?version=2017-12-18&page_limit=1",
+            "next_url":
+            "/v1/workspaces/pizza_app-e0f3/intents?cursor=base64=&version=2017-12-18&page_limit=1"
+        }
+    }
+    responses.add(
+        responses.GET,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    intents = service.list_intents(workspace_id='boguswid', export=False)
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert intents == response
+
+
+@responses.activate
+def test_update_intent():
+    endpoint = '/v1/workspaces/{0}/intents/{1}'.format('boguswid',
+                                                       'pizza_order')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "intent": "pizza_order",
+        "created": "2015-12-06T23:53:59.153Z",
+        "updated": "2015-12-07T18:53:59.153Z",
+        "description": "User wants to start a new pizza order"
+    }
+    responses.add(
+        responses.POST,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    intent = service.update_intent(
+        workspace_id='boguswid',
+        intent='pizza_order',
+        new_intent='pizza_order',
+        new_description='User wants to start a new pizza order')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert intent == response
+
+
+#########################
+# message
+#########################
 
 
 @responses.activate
 def test_message():
 
-    conversation = watson_developer_cloud.ConversationV1(username="username",
-                                                         password="password",
-                                                         version='2016-09-20')
+    conversation = watson_developer_cloud.ConversationV1(
+        username="username", password="password", version='2016-09-20')
 
     workspace_id = 'f8fdbc65-e0bd-4e43-b9f8-2975a366d4ec'
-    message_url = '%s/workspaces/%s/message' % (base_url, workspace_id)
-    url1_str = '%s/workspaces/%s/message?version=2016-09-20'
+    message_url = '%s/v1/workspaces/%s/message' % (base_url, workspace_id)
+    url1_str = '%s/v1/workspaces/%s/message?version=2016-09-20'
     message_url1 = url1_str % (base_url, workspace_id)
-    message_response = {"context": {
-                        "conversation_id":
-                            "1b7b67c0-90ed-45dc-8508-9488bc483d5b",
-                        "system": {"dialog_stack":
-                                   ["root"],
-                                   "dialog_turn_counter": 1,
-                                   "dialog_request_counter": 1}},
-                        "intents": [],
-                        "entities": [],
-                        "input": {}}
-
-    responses.add(responses.POST, message_url,
-                  body=json.dumps(message_response),
-                  status=200,
-                  content_type='application/json')
-
-    message = conversation.message(workspace_id=workspace_id,
-                                   message_input={'text':
-                                                  'Turn on the lights'},
-                                   context=None)
+    message_response = {
+        "context": {
+            "conversation_id": "1b7b67c0-90ed-45dc-8508-9488bc483d5b",
+            "system": {
+                "dialog_stack": ["root"],
+                "dialog_turn_counter": 1,
+                "dialog_request_counter": 1
+            }
+        },
+        "intents": [],
+        "entities": [],
+        "input": {}
+    }
+
+    responses.add(
+        responses.POST,
+        message_url,
+        body=json.dumps(message_response),
+        status=200,
+        content_type='application/json')
+
+    message = conversation.message(
+        workspace_id=workspace_id,
+        message_input={'text': 'Turn on the lights'},
+        context=None)
 
     assert message is not None
     assert responses.calls[0].request.url == message_url1
     assert responses.calls[0].response.text == json.dumps(message_response)
 
+    # test context
+    responses.add(
+        responses.POST,
+        message_url,
+        body=message_response,
+        status=200,
+        content_type='application/json')
 
-# test context
-    responses.add(responses.POST, message_url,
-                  body=message_response, status=200,
-                  content_type='application/json')
-
-    message_ctx = {'context':
-                   {'conversation_id': '1b7b67c0-90ed-45dc-8508-9488bc483d5b',
-                    'system': {
-                        'dialog_stack': ['root'],
-                        'dialog_turn_counter': 2,
-                        'dialog_request_counter': 1}}}
-    message = conversation.message(workspace_id=workspace_id,
-                                   message_input={'text':
-                                                  'Turn on the lights'},
-                                   context=json.dumps(message_ctx))
+    message_ctx = {
+        'context': {
+            'conversation_id': '1b7b67c0-90ed-45dc-8508-9488bc483d5b',
+            'system': {
+                'dialog_stack': ['root'],
+                'dialog_turn_counter': 2,
+                'dialog_request_counter': 1
+            }
+        }
+    }
+    message = conversation.message(
+        workspace_id=workspace_id,
+        message_input={'text': 'Turn on the lights'},
+        context=json.dumps(message_ctx))
 
     assert message is not None
     assert responses.calls[1].request.url == message_url1
     assert responses.calls[1].response.text == json.dumps(message_response)
 
     assert len(responses.calls) == 2
+
+
+#########################
+# workspaces
+#########################
+
+
+@responses.activate
+def test_create_workspace():
+    endpoint = '/v1/workspaces'
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "name": "Pizza app",
+        "created": "2015-12-06T23:53:59.153Z",
+        "language": "en",
+        "metadata": {},
+        "updated": "2015-12-06T23:53:59.153Z",
+        "description": "Pizza app",
+        "workspace_id": "pizza_app-e0f3"
+    }
+    responses.add(
+        responses.POST,
+        url,
+        body=json.dumps(response),
+        status=201,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    workspace = service.create_workspace(
+        name='Pizza app', description='Pizza app', language='en', metadata={})
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert workspace == response
+
+
+@responses.activate
+def test_delete_workspace():
+    endpoint = '/v1/workspaces/{0}'.format('boguswid')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {}
+    responses.add(
+        responses.DELETE,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    workspace = service.delete_workspace(workspace_id='boguswid')
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert workspace == response
+
+
+@responses.activate
+def test_get_workspace():
+    endpoint = '/v1/workspaces/{0}'.format('boguswid')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "name": "Pizza app",
+        "created": "2015-12-06T23:53:59.153Z",
+        "language": "en",
+        "metadata": {},
+        "updated": "2015-12-06T23:53:59.153Z",
+        "description": "Pizza app",
+        "status": "Available",
+        "workspace_id": "pizza_app-e0f3"
+    }
+    responses.add(
+        responses.GET,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    workspace = service.get_workspace(workspace_id='boguswid', export=False)
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert workspace == response
+
+
+@responses.activate
+def test_list_workspaces():
+    endpoint = '/v1/workspaces'
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "workspaces": [{
+            "name": "Pizza app",
+            "created": "2015-12-06T23:53:59.153Z",
+            "language": "en",
+            "metadata": {},
+            "updated": "2015-12-06T23:53:59.153Z",
+            "description": "Pizza app",
+            "workspace_id": "pizza_app-e0f3"
+        }],
+        "pagination": {
+            "refresh_url":
+            "/v1/workspaces?version=2016-01-24&page_limit=1",
+            "next_url":
+            "/v1/workspaces?cursor=base64=&version=2016-01-24&page_limit=1"
+        }
+    }
+    responses.add(
+        responses.GET,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    workspaces = service.list_workspaces()
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert workspaces == response
+
+
+@responses.activate
+def test_update_workspace():
+    endpoint = '/v1/workspaces/{0}'.format('pizza_app-e0f3')
+    url = '{0}{1}'.format(base_url, endpoint)
+    response = {
+        "name": "Pizza app",
+        "created": "2015-12-06T23:53:59.153Z",
+        "language": "en",
+        "metadata": {},
+        "updated": "2015-12-06T23:53:59.153Z",
+        "description": "Pizza app",
+        "workspace_id": "pizza_app-e0f3"
+    }
+    responses.add(
+        responses.POST,
+        url,
+        body=json.dumps(response),
+        status=200,
+        content_type='application/json')
+    service = watson_developer_cloud.ConversationV1(
+        username='username', password='password', version='2017-02-03')
+    workspace = service.update_workspace(
+        workspace_id='pizza_app-e0f3',
+        name='Pizza app',
+        description='Pizza app',
+        language='en',
+        metadata={})
+    assert len(responses.calls) == 1
+    assert responses.calls[0].request.url.startswith(url)
+    assert workspace == response