diff --git a/docs/dns-usage.rst b/docs/dns-usage.rst
index 78ec078c4c1e..4a674ce08d30 100644
--- a/docs/dns-usage.rst
+++ b/docs/dns-usage.rst
@@ -104,23 +104,23 @@ Each managed zone exposes a read-only set of resource records:
      >>> from gcloud import dns
      >>> client = dns.Client(project='PROJECT_ID')
      >>> zone = client.zone('acme-co')
-     >>> records, page_token = zone.list_resources()  # API request
+     >>> records, page_token = zone.list_resource_record_sets()  # API request
      >>> [(record.name, record.type, record.ttl, record.rrdatas) for record in records]
      [('example.com.', 'SOA', 21600, ['ns-cloud1.googlecomains.com dns-admin.google.com 1 21600 3600 1209600 300'])]
 
 .. note::
 
-   The ``page_token`` returned from ``zone.list_resources()`` will be
-   an opaque string if there are more resources than can be returned in a
+   The ``page_token`` returned from ``zone.list_resource_record_sets()`` will
+   be an opaque string if there are more resources than can be returned in a
    single request.  To enumerate them all, repeat calling
-   ``zone.list_resources()``, passing the ``page_token``, until the token
-   is ``None``.  E.g.
+   ``zone.list_resource_record_sets()``, passing the ``page_token``, until
+   the token is ``None``.  E.g.
 
    .. doctest::
 
-      >>> records, page_token = zone.list_resources()  # API request
+      >>> records, page_token = zone.list_resource_record_sets()  # API request
       >>> while page_token is not None:
-      ...     next_batch, page_token = zone.list_resources(
+      ...     next_batch, page_token = zone.list_resource_record_sets(
       ...         page_token=page_token)  # API request
       ...     records.extend(next_batch)
 
diff --git a/gcloud/dns/resource_record_set.py b/gcloud/dns/resource_record_set.py
new file mode 100644
index 000000000000..b53fe8ceebea
--- /dev/null
+++ b/gcloud/dns/resource_record_set.py
@@ -0,0 +1,66 @@
+# Copyright 2015 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.
+
+"""Define API ResourceRecordSets."""
+
+
+class ResourceRecordSet(object):
+    """ResourceRecordSets are DNS resource records.
+
+    RRS are contained wihin a :class:`gcloud.dns.zone.ManagedZone` instance.
+
+    See:
+    https://cloud.google.com/dns/api/v1/resourceRecordSets
+
+    :type name: string
+    :param name: the name of the record set
+
+    :type record_type: string
+    :param record_type: the RR type of the zone
+
+    :type ttl: integer
+    :param ttl: TTL (in seconds) for caching the record sets
+
+    :type rrdatas: list of string
+    :param rrdatas: one or more lines containing the resource data
+
+    :type zone: :class:`gcloud.dns.zone.ManagedZone`
+    :param zone: A zone which holds one or more record sets.
+    """
+
+    def __init__(self, name, record_type, ttl, rrdatas, zone):
+        self.name = name
+        self.record_type = record_type
+        self.ttl = ttl
+        self.rrdatas = rrdatas
+        self.zone = zone
+
+    @classmethod
+    def from_api_repr(cls, resource, zone):
+        """Factory:  construct a record set given its API representation
+
+        :type resource: dict
+        :param resource: record sets representation returned from the API
+
+        :type zone: :class:`gcloud.dns.zone.ManagedZone`
+        :param zone: A zone which holds one or more record sets.
+
+        :rtype: :class:`gcloud.dns.zone.ResourceRecordSet`
+        :returns: RRS parsed from ``resource``.
+        """
+        name = resource['name']
+        record_type = resource['type']
+        ttl = int(resource['ttl'])
+        rrdatas = resource['rrdatas']
+        return cls(name, record_type, ttl, rrdatas, zone=zone)
diff --git a/gcloud/dns/test_resource_record_set.py b/gcloud/dns/test_resource_record_set.py
new file mode 100644
index 000000000000..8f4bc98bd61b
--- /dev/null
+++ b/gcloud/dns/test_resource_record_set.py
@@ -0,0 +1,94 @@
+# Copyright 2015 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 unittest2
+
+
+class TestResourceRecordSet(unittest2.TestCase):
+
+    def _getTargetClass(self):
+        from gcloud.dns.resource_record_set import ResourceRecordSet
+        return ResourceRecordSet
+
+    def _makeOne(self, *args, **kw):
+        return self._getTargetClass()(*args, **kw)
+
+    def test_ctor(self):
+        zone = _Zone()
+
+        rrs = self._makeOne('test.example.com', 'CNAME', 3600,
+                            ['www.example.com'], zone)
+
+        self.assertEqual(rrs.name, 'test.example.com')
+        self.assertEqual(rrs.record_type, 'CNAME')
+        self.assertEqual(rrs.ttl, 3600)
+        self.assertEqual(rrs.rrdatas, ['www.example.com'])
+        self.assertTrue(rrs.zone is zone)
+
+    def test_from_api_repr_missing_rrdatas(self):
+        zone = _Zone()
+        klass = self._getTargetClass()
+
+        with self.assertRaises(KeyError):
+            klass.from_api_repr({'name': 'test.example.com',
+                                 'type': 'CNAME',
+                                 'ttl': 3600}, zone=zone)
+
+    def test_from_api_repr_missing_ttl(self):
+        zone = _Zone()
+        klass = self._getTargetClass()
+
+        with self.assertRaises(KeyError):
+            klass.from_api_repr({'name': 'test.example.com',
+                                 'type': 'CNAME',
+                                 'rrdatas': ['www.example.com']}, zone=zone)
+
+    def test_from_api_repr_missing_type(self):
+        zone = _Zone()
+        klass = self._getTargetClass()
+
+        with self.assertRaises(KeyError):
+            klass.from_api_repr({'name': 'test.example.com',
+                                 'ttl': 3600,
+                                 'rrdatas': ['www.example.com']}, zone=zone)
+
+    def test_from_api_repr_missing_name(self):
+        zone = _Zone()
+        klass = self._getTargetClass()
+
+        with self.assertRaises(KeyError):
+            klass.from_api_repr({'type': 'CNAME',
+                                 'ttl': 3600,
+                                 'rrdatas': ['www.example.com']}, zone=zone)
+
+    def test_from_api_repr_bare(self):
+        zone = _Zone()
+        RESOURCE = {
+            'kind': 'dns#resourceRecordSet',
+            'name': 'test.example.com',
+            'type': 'CNAME',
+            'ttl': '3600',
+            'rrdatas': ['www.example.com'],
+        }
+        klass = self._getTargetClass()
+        rrs = klass.from_api_repr(RESOURCE, zone=zone)
+        self.assertEqual(rrs.name, 'test.example.com')
+        self.assertEqual(rrs.record_type, 'CNAME')
+        self.assertEqual(rrs.ttl, 3600)
+        self.assertEqual(rrs.rrdatas, ['www.example.com'])
+        self.assertTrue(rrs.zone is zone)
+
+
+class _Zone(object):
+    pass
diff --git a/gcloud/dns/test_zone.py b/gcloud/dns/test_zone.py
index a96daa868ef7..760bc372b3df 100644
--- a/gcloud/dns/test_zone.py
+++ b/gcloud/dns/test_zone.py
@@ -314,6 +314,107 @@ def test_delete_w_alternate_client(self):
         self.assertEqual(req['method'], 'DELETE')
         self.assertEqual(req['path'], '/%s' % PATH)
 
+    def test_list_resource_record_sets_defaults(self):
+        from gcloud.dns.resource_record_set import ResourceRecordSet
+        PATH = 'projects/%s/managedZones/%s/rrsets' % (
+            self.PROJECT, self.ZONE_NAME)
+        TOKEN = 'TOKEN'
+        NAME_1 = 'www.example.com'
+        TYPE_1 = 'A'
+        TTL_1 = '86400'
+        RRDATAS_1 = ['123.45.67.89']
+        NAME_2 = 'alias.example.com'
+        TYPE_2 = 'CNAME'
+        TTL_2 = '3600'
+        RRDATAS_2 = ['www.example.com']
+        DATA = {
+            'nextPageToken': TOKEN,
+            'rrsets': [
+                {'kind': 'dns#resourceRecordSet',
+                 'name': NAME_1,
+                 'type': TYPE_1,
+                 'ttl': TTL_1,
+                 'rrdatas': RRDATAS_1},
+                {'kind': 'dns#resourceRecordSet',
+                 'name': NAME_2,
+                 'type': TYPE_2,
+                 'ttl': TTL_2,
+                 'rrdatas': RRDATAS_2},
+            ]
+        }
+        conn = _Connection(DATA)
+        client = _Client(project=self.PROJECT, connection=conn)
+        zone = self._makeOne(self.ZONE_NAME, self.DNS_NAME, client)
+
+        rrsets, token = zone.list_resource_record_sets()
+
+        self.assertEqual(len(rrsets), len(DATA['rrsets']))
+        for found, expected in zip(rrsets, DATA['rrsets']):
+            self.assertTrue(isinstance(found, ResourceRecordSet))
+            self.assertEqual(found.name, expected['name'])
+            self.assertEqual(found.record_type, expected['type'])
+            self.assertEqual(found.ttl, int(expected['ttl']))
+            self.assertEqual(found.rrdatas, expected['rrdatas'])
+        self.assertEqual(token, TOKEN)
+
+        self.assertEqual(len(conn._requested), 1)
+        req = conn._requested[0]
+        self.assertEqual(req['method'], 'GET')
+        self.assertEqual(req['path'], '/%s' % PATH)
+
+    def test_list_resource_record_sets_explicit(self):
+        from gcloud.dns.resource_record_set import ResourceRecordSet
+        PATH = 'projects/%s/managedZones/%s/rrsets' % (
+            self.PROJECT, self.ZONE_NAME)
+        TOKEN = 'TOKEN'
+        NAME_1 = 'www.example.com'
+        TYPE_1 = 'A'
+        TTL_1 = '86400'
+        RRDATAS_1 = ['123.45.67.89']
+        NAME_2 = 'alias.example.com'
+        TYPE_2 = 'CNAME'
+        TTL_2 = '3600'
+        RRDATAS_2 = ['www.example.com']
+        DATA = {
+            'rrsets': [
+                {'kind': 'dns#resourceRecordSet',
+                 'name': NAME_1,
+                 'type': TYPE_1,
+                 'ttl': TTL_1,
+                 'rrdatas': RRDATAS_1},
+                {'kind': 'dns#resourceRecordSet',
+                 'name': NAME_2,
+                 'type': TYPE_2,
+                 'ttl': TTL_2,
+                 'rrdatas': RRDATAS_2},
+            ]
+        }
+        conn1 = _Connection()
+        client1 = _Client(project=self.PROJECT, connection=conn1)
+        conn2 = _Connection(DATA)
+        client2 = _Client(project=self.PROJECT, connection=conn2)
+        zone = self._makeOne(self.ZONE_NAME, self.DNS_NAME, client1)
+
+        rrsets, token = zone.list_resource_record_sets(
+            max_results=3, page_token=TOKEN, client=client2)
+
+        self.assertEqual(len(rrsets), len(DATA['rrsets']))
+        for found, expected in zip(rrsets, DATA['rrsets']):
+            self.assertTrue(isinstance(found, ResourceRecordSet))
+            self.assertEqual(found.name, expected['name'])
+            self.assertEqual(found.record_type, expected['type'])
+            self.assertEqual(found.ttl, int(expected['ttl']))
+            self.assertEqual(found.rrdatas, expected['rrdatas'])
+        self.assertEqual(token, None)
+
+        self.assertEqual(len(conn1._requested), 0)
+        self.assertEqual(len(conn2._requested), 1)
+        req = conn2._requested[0]
+        self.assertEqual(req['method'], 'GET')
+        self.assertEqual(req['path'], '/%s' % PATH)
+        self.assertEqual(req['query_params'],
+                         {'maxResults': 3, 'pageToken': TOKEN})
+
 
 class _Client(object):
 
diff --git a/gcloud/dns/zone.py b/gcloud/dns/zone.py
index 8a56fb13348a..4ed9eea65ac2 100644
--- a/gcloud/dns/zone.py
+++ b/gcloud/dns/zone.py
@@ -17,6 +17,7 @@
 
 from gcloud._helpers import _datetime_from_microseconds
 from gcloud.exceptions import NotFound
+from gcloud.dns.resource_record_set import ResourceRecordSet
 
 
 class ManagedZone(object):
@@ -267,3 +268,47 @@ def delete(self, client=None):
         """
         client = self._require_client(client)
         client.connection.api_request(method='DELETE', path=self.path)
+
+    def list_resource_record_sets(self, max_results=None, page_token=None,
+                                  client=None):
+        """List resource record sets for this zone.
+
+        See:
+        https://cloud.google.com/dns/api/v1/resourceRecordSets/list
+
+        :type max_results: int
+        :param max_results: maximum number of zones to return, If not
+                            passed, defaults to a value set by the API.
+
+        :type page_token: string
+        :param page_token: opaque marker for the next "page" of zones. If
+                           not passed, the API will return the first page of
+                           zones.
+
+        :type client: :class:`gcloud.dns.client.Client` or ``NoneType``
+        :param client: the client to use.  If not passed, falls back to the
+                       ``client`` stored on the current zone.
+
+        :rtype: tuple, (list, str)
+        :returns: list of
+                  :class:`gcloud.dns.resource_record_set.ResourceRecordSet`,
+                  plus a "next page token" string:  if the token is not None,
+                  indicates that more zones can be retrieved with another
+                  call (pass that value as ``page_token``).
+        """
+        params = {}
+
+        if max_results is not None:
+            params['maxResults'] = max_results
+
+        if page_token is not None:
+            params['pageToken'] = page_token
+
+        path = '/projects/%s/managedZones/%s/rrsets' % (
+            self.project, self.name)
+        client = self._require_client(client)
+        conn = client.connection
+        resp = conn.api_request(method='GET', path=path, query_params=params)
+        zones = [ResourceRecordSet.from_api_repr(resource, self)
+                 for resource in resp['rrsets']]
+        return zones, resp.get('nextPageToken')