diff --git a/appengine/endpoints/app.yaml b/appengine/endpoints/app.yaml
new file mode 100644
index 000000000000..31030b73367e
--- /dev/null
+++ b/appengine/endpoints/app.yaml
@@ -0,0 +1,16 @@
+runtime: python27
+threadsafe: true
+api_version: 1
+
+handlers:
+# The endpoints handler must be mapped to /_ah/spi.
+# Apps send requests to /_ah/api, but the endpoints service handles mapping
+# those requests to /_ah/spi.
+- url: /_ah/spi/.*
+  script: main.api
+
+libraries:
+- name: pycrypto
+  version: 2.6
+- name: endpoints
+  version: 1.0
diff --git a/appengine/endpoints/main.py b/appengine/endpoints/main.py
new file mode 100644
index 000000000000..fc4049b1309a
--- /dev/null
+++ b/appengine/endpoints/main.py
@@ -0,0 +1,149 @@
+# Copyright 2016 Google Inc. 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.
+
+"""This is a sample Hello World API implemented using Google Cloud
+Endpoints."""
+
+# [START imports]
+import endpoints
+from protorpc import message_types
+from protorpc import messages
+from protorpc import remote
+# [END imports]
+
+
+# [START messages]
+class Greeting(messages.Message):
+    """Greeting that stores a message."""
+    message = messages.StringField(1)
+
+
+class GreetingCollection(messages.Message):
+    """Collection of Greetings."""
+    items = messages.MessageField(Greeting, 1, repeated=True)
+
+
+STORED_GREETINGS = GreetingCollection(items=[
+    Greeting(message='hello world!'),
+    Greeting(message='goodbye world!'),
+])
+# [END messages]
+
+
+# [START greeting_api]
+@endpoints.api(name='greeting', version='v1')
+class GreetingApi(remote.Service):
+
+    @endpoints.method(
+        # This method does not take a request message.
+        message_types.VoidMessage,
+        # This method returns a GreetingCollection message.
+        GreetingCollection,
+        path='greetings',
+        http_method='GET',
+        name='greetings.list')
+    def list_greetings(self, unused_request):
+        return STORED_GREETINGS
+
+    # ResourceContainers are used to encapsuate a request body and url
+    # parameters. This one is used to represent the Greeting ID for the
+    # greeting_get method.
+    GET_RESOURCE = endpoints.ResourceContainer(
+        # The request body should be empty.
+        message_types.VoidMessage,
+        # Accept one url parameter: and integer named 'id'
+        id=messages.IntegerField(1, variant=messages.Variant.INT32))
+
+    @endpoints.method(
+        # Use the ResourceContainer defined above to accept an empty body
+        # but an ID in the query string.
+        GET_RESOURCE,
+        # This method returns a Greeting message.
+        Greeting,
+        # The path defines the source of the URL parameter 'id'. If not
+        # specified here, it would need to be in the query string.
+        path='greetings/{id}',
+        http_method='GET',
+        name='greetings.get')
+    def get_greeting(self, request):
+        try:
+            # request.id is used to access the URL parameter.
+            return STORED_GREETINGS.items[request.id]
+        except (IndexError, TypeError):
+            raise endpoints.NotFoundException(
+                'Greeting {} not found'.format(request.id))
+    # [END greeting_api]
+
+    # [START multiply]
+    # This ResourceContainer is similar to the one used for get_greeting, but
+    # this one also contains a request body in the form of a Greeting message.
+    MULTIPLY_RESOURCE = endpoints.ResourceContainer(
+        Greeting,
+        times=messages.IntegerField(2, variant=messages.Variant.INT32,
+                                    required=True))
+
+    @endpoints.method(
+        # This method accepts a request body containing a Greeting message
+        # and a URL parameter specifying how many times to multiply the
+        # message.
+        MULTIPLY_RESOURCE,
+        # This method returns a Greeting message.
+        Greeting,
+        path='greetings/multiply/{times}',
+        http_method='POST',
+        name='greetings.multiply')
+    def multiply_greeting(self, request):
+        return Greeting(message=request.message * request.times)
+    # [END multiply]
+
+
+# [START auth_config]
+WEB_CLIENT_ID = 'replace this with your web client application ID'
+ANDROID_CLIENT_ID = 'replace this with your Android client ID'
+IOS_CLIENT_ID = 'replace this with your iOS client ID'
+ANDROID_AUDIENCE = WEB_CLIENT_ID
+ALLOWED_CLIENT_IDS = [
+    WEB_CLIENT_ID, ANDROID_CLIENT_ID, IOS_CLIENT_ID,
+    endpoints.API_EXPLORER_CLIENT_ID]
+# [END auth_config]
+
+
+# [START authed_greeting_api]
+@endpoints.api(
+    name='authed_greeting',
+    version='v1',
+    # Only allowed configured Client IDs to access this API.
+    allowed_client_ids=ALLOWED_CLIENT_IDS,
+    # Only allow auth tokens with the given audience to access this API.
+    audiences=[ANDROID_AUDIENCE],
+    # Require auth tokens to have the following scopes to access this API.
+    scopes=[endpoints.EMAIL_SCOPE])
+class AuthedGreetingApi(remote.Service):
+
+    @endpoints.method(
+        message_types.VoidMessage,
+        Greeting,
+        path='greet',
+        http_method='POST',
+        name='greet')
+    def greet(self, request):
+        user = endpoints.get_current_user()
+        user_name = user.email() if user else 'Anonymous'
+        return Greeting(message='Hello, {}'.format(user_name))
+# [END authed_greeting_api]
+
+
+# [START api_server]
+api = endpoints.api_server([GreetingApi, AuthedGreetingApi])
+# [END api_server]
diff --git a/appengine/endpoints/main_test.py b/appengine/endpoints/main_test.py
new file mode 100644
index 000000000000..56fefa2ead66
--- /dev/null
+++ b/appengine/endpoints/main_test.py
@@ -0,0 +1,53 @@
+# Copyright 2016 Google Inc. 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 main
+import mock
+from protorpc import message_types
+
+
+def test_list_greetings(testbed):
+    api = main.GreetingApi()
+    response = api.list_greetings(message_types.VoidMessage())
+    assert len(response.items) == 2
+
+
+def test_get_greeting(testbed):
+    api = main.GreetingApi()
+    request = main.GreetingApi.get_greeting.remote.request_type(id=1)
+    response = api.get_greeting(request)
+    assert response.message == 'goodbye world!'
+
+
+def test_multiply_greeting(testbed):
+    api = main.GreetingApi()
+    request = main.GreetingApi.multiply_greeting.remote.request_type(
+        times=4,
+        message='help I\'m trapped in a test case.')
+    response = api.multiply_greeting(request)
+    assert response.message == 'help I\'m trapped in a test case.' * 4
+
+
+def test_authed_greet(testbed):
+    api = main.AuthedGreetingApi()
+
+    with mock.patch('main.endpoints.get_current_user') as user_mock:
+        user_mock.return_value = None
+        response = api.greet(message_types.VoidMessage())
+        assert response.message == 'Hello, Anonymous'
+
+        user_mock.return_value = mock.Mock()
+        user_mock.return_value.email.return_value = 'user@example.com'
+        response = api.greet(message_types.VoidMessage())
+        assert response.message == 'Hello, user@example.com'