diff --git a/django/website/hid/templates/hid/categories_column.html b/django/website/hid/templates/hid/categories_column.html
index 709ce07df606e695170a18c3da945e6e1ecfad27..5a224cdbc741390bbecf5a403d3e44a79aadbce8 100644
--- a/django/website/hid/templates/hid/categories_column.html
+++ b/django/website/hid/templates/hid/categories_column.html
@@ -4,7 +4,7 @@
             <option value="" selected="selected">---------</option>
         {% endif %}
         {% for cat in categories %}
-        <option value="{{ cat.0 }}"{% if category == cat.0 %} selected="selected"{% endif %}>{{ cat.0 }}</option>
+        <option value="{{ cat.0 }}"{% if category == cat.0 %} selected="selected"{% endif %}>{{ cat.1 }}</option>
         {% endfor %}
     </select>
 {% endif %}
diff --git a/django/website/hid/tests/views_tests.py b/django/website/hid/tests/views_tests.py
index 9ce9cd1399d6e3f3db448ad387049d98572b856e..a283b1e03284d138912b4f62fb9f752266067ed4 100644
--- a/django/website/hid/tests/views_tests.py
+++ b/django/website/hid/tests/views_tests.py
@@ -128,11 +128,11 @@ def test_get_category_options_uses_terms():
     )
 
     view = ViewItems()
-    options = view.get_category_options(ebola_questions.id)
+    options = view.get_category_options(ebola_questions.slug)
 
-    assert (type_1.name, type_1.long_name) in options
-    assert (type_2.name, type_2.long_name) in options
-    assert (type_3.name, type_3.long_name) in options
+    assert (type_1.name, type_1.name) in options
+    assert (type_2.name, type_2.name) in options
+    assert (type_3.name, type_3.name) in options
     assert (other_term.name, other_term.long_name) not in options
 
 
@@ -154,14 +154,14 @@ def test_get_category_options_with_no_taxonomy_returns_all():
     view = ViewItems()
     options = view.get_category_options()
 
-    assert (type_1.name, type_1.long_name) in options
-    assert (other_term.name, other_term.long_name) in options
+    assert (type_1.name, type_1.name) in options
+    assert (other_term.name, other_term.name) in options
 
 
 @pytest.mark.django_db
 def test_get_category_options_orders_by_lowercase_name():
     # TODO: Rewrite tests to use transport layer
-    ebola_questions = TaxonomyFactory(name="Ebola Questions")
+    taxonomy = TaxonomyFactory(name="order_by_lowercase_name_test")
     test_term_values = [
         ('test a1', '1'), ('test b1', '2'),
         ('test A2', '3'), ('test B2', '4')
@@ -170,16 +170,15 @@ def test_get_category_options_orders_by_lowercase_name():
         TermFactory(
             name=test_value[0],
             long_name=test_value[1],
-            taxonomy=ebola_questions
+            taxonomy=taxonomy
         )
 
     view = ViewItems()
-    options = view.get_category_options(ebola_questions.id)
-    # Make sure we are only comparing with out test values!
-    options = [o for o in options if o in test_term_values]
+    options = view.get_category_options(taxonomy.slug)
 
     # Expected is the list ordered by lowercase short name.
-    expected = sorted(test_term_values, key=lambda e: e[0].lower())
+    expected = [(short, short) for short, long_name in test_term_values]
+    expected = tuple(sorted(expected, key=lambda e: e[0].lower()))
 
     assert options == expected
 
diff --git a/django/website/hid/views.py b/django/website/hid/views.py
index 1c1ea9575f57b50505be9692716fed36aa0e7584..f8821f405aa00fb8e25b00c43ecc82ae519d6618 100644
--- a/django/website/hid/views.py
+++ b/django/website/hid/views.py
@@ -14,7 +14,6 @@ from django.views.generic.base import TemplateView
 from django_tables2 import SingleTableView
 
 from chn_spreadsheet.importer import Importer, SheetImportException
-from data_layer.models import Term
 import transport
 from transport.exceptions import TransportException
 from .assets import require_assets
@@ -90,26 +89,18 @@ class ViewItems(SingleTableView):
     def get_queryset(self):
         return transport.items.list()
 
-    def get_category_options(self, categories_id=None):
-        # TODO: Use data layer
-        terms = self.get_matching_terms(categories_id)
-        return tuple((t.name, t.long_name) for t in terms)
-
-    def get_matching_terms(self, categories_id):
-        if categories_id is None:
-            return (Term.objects
-                    .extra(select={'name_lower': 'lower(name)'})
-                    .order_by('name_lower')
-                    .all())
-
-        return (Term.objects
-                .extra(select={'name_lower': 'lower(name)'})
-                .order_by('name_lower')
-                .filter(taxonomy__id=categories_id))
+    def get_category_options(self, taxonomy_slug=None):
+        if taxonomy_slug is not None:
+            terms = transport.terms.list(taxonomy=taxonomy_slug)
+        else:
+            terms = transport.terms.list()
+        terms.sort(key=lambda e: e['name'].lower())
+        return tuple((t['name'], t['name']) for t in terms)
 
     def get_table(self, **kwargs):
-        # TODO: Filter on taxonomy
-        kwargs['categories'] = self.get_category_options()
+        kwargs['categories'] = self.get_category_options(
+            QUESTION_TYPE_TAXONOMY
+        )
         return super(ViewItems, self).get_table(**kwargs)
 
     def get_context_data(self, **kwargs):
@@ -126,9 +117,7 @@ class ViewItems(SingleTableView):
             ),
             self._build_action_dropdown_group(
                 label=_('Set question type'),
-                items=[(short_name, short_name)
-                       for short_name, long_name
-                       in self.get_category_options()],
+                items=self.get_category_options(QUESTION_TYPE_TAXONOMY),
                 prefix=ADD_CATEGORY_PREFIX
             )
         ]
diff --git a/django/website/rest_api/views.py b/django/website/rest_api/views.py
index 1b4e59d49a52ae8098495358ac141536e9343773..2ea8627f98554e13976f1145a0e8cd31d087a12f 100644
--- a/django/website/rest_api/views.py
+++ b/django/website/rest_api/views.py
@@ -92,4 +92,32 @@ class TaxonomyViewSet(viewsets.ModelViewSet):
 class TermViewSet(viewsets.ModelViewSet):
     serializer_class = TermSerializer
 
-    queryset = Term.objects.all()  # Will need to filter by taxonomy eventually
+    queryset = Term.objects.all()
+
+    def get_queryset(self):
+        """ Return the query set to fetch terms.
+
+        The request may contain the following
+        exact match filters:
+            name: Name of the term
+            long_name: Long name of the term
+            taxonomy: Slug of the term's taxonomy
+
+        Returns:
+            QuerySet: A query set
+        """
+        items = Term.objects.all()
+
+        name = self.request.query_params.get('name', None)
+        if name is not None:
+            items = items.filter(name=name)
+
+        long_name = self.request.query_params.get('long_name', None)
+        if long_name is not None:
+            items = items.filter(long_name=long_name)
+
+        taxonomy_slug = self.request.query_params.get('taxonomy', None)
+        if taxonomy_slug is not None:
+            items = items.filter(taxonomy__slug=taxonomy_slug)
+
+        return items
diff --git a/django/website/taxonomies/tests/factories.py b/django/website/taxonomies/tests/factories.py
index 8192276617cdf8dfe8b88f59e3c18d0f130ec28f..1dd486070687b8bb301471efa0fce16fbbfdc358 100644
--- a/django/website/taxonomies/tests/factories.py
+++ b/django/website/taxonomies/tests/factories.py
@@ -19,7 +19,7 @@ class TermFactory(DjangoModelFactory):
 
     class Meta:
         model = Term
-        django_get_or_create = ('name',)
+        django_get_or_create = ('name', 'taxonomy')
 
     name = fuzzy.FuzzyText()
 
diff --git a/django/website/transport/__init__.py b/django/website/transport/__init__.py
index fd7d6a560c116a78e82af74b6ddba919af09a81d..d267d406c3a752471ee52c073a2ae139b75372b8 100644
--- a/django/website/transport/__init__.py
+++ b/django/website/transport/__init__.py
@@ -1,4 +1,5 @@
 import items
 import taxonomies
+import terms
 
-__all__ = ['items', 'taxonomies', ]
+__all__ = ['items', 'taxonomies', 'terms']
diff --git a/django/website/transport/terms.py b/django/website/transport/terms.py
new file mode 100644
index 0000000000000000000000000000000000000000..2d99757e562b924a52d1d1c3c8d42855c4372ad3
--- /dev/null
+++ b/django/website/transport/terms.py
@@ -0,0 +1,58 @@
+from django.core.urlresolvers import reverse
+
+from rest_api.views import TermViewSet
+from rest_framework.test import APIRequestFactory
+from rest_framework import status
+
+from .exceptions import TransportException
+
+
+request_factory = APIRequestFactory()
+
+
+def list_url():
+    """ Returns the url to obtain the list of terms
+
+    Returns:
+        str: List of term URL
+    """
+    return reverse('term-list')
+
+
+def get_view(actions):
+    """ Return the view to perform the given action.
+
+    Args:
+        actions (dict): Dictionary of actions, eg.
+            {'get': 'list'}
+    Returns:
+        View: A view object
+    """
+    return TermViewSet.as_view(actions)
+
+
+def list(**kwargs):
+    """ Return a list of Terms
+
+    If keyword arguments are given, they are used
+    to filter the terms. This can be used to list
+    the terms in a given taxonomy.
+
+    Args:
+        **kwargs: Filters
+    Returns:
+        list: List of terms
+    Raises:
+        TransportException: On transport failure.
+            'status_code' is set to the response
+            status code.
+    """
+    view = get_view(actions={'get': 'list'})
+    request = request_factory.get(list_url(), kwargs)
+    response = view(request)
+
+    if not status.is_success(response.status_code):
+        response.data['status_code'] = response.status_code
+        raise TransportException(response.data)
+
+    return response.data
diff --git a/django/website/transport/tests/term_list_tests.py b/django/website/transport/tests/term_list_tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..d9d13c59fe75ecd6d0c1fb9cebda29bda7ee8dae
--- /dev/null
+++ b/django/website/transport/tests/term_list_tests.py
@@ -0,0 +1,79 @@
+from __future__ import unicode_literals, absolute_import
+import pytest
+
+from taxonomies.tests.factories import TaxonomyFactory, TermFactory
+import transport
+
+
+@pytest.mark.django_db
+def test_list_terms_returns_terms():
+    taxonomy = TaxonomyFactory(name='A test taxonomy')
+    term = TermFactory(name="A test term", taxonomy=taxonomy)
+
+    terms = transport.terms.list()
+    terms_as_items = [t.items() for t in terms]
+
+    expected = {
+        'taxonomy': taxonomy.slug,
+        'name': term.name,
+        'long_name': term.long_name
+    }.items()
+
+    assert expected in terms_as_items
+
+
+@pytest.mark.django_db
+def test_list_terms_applies_taxonomy_filter():
+    taxonomy = TaxonomyFactory(name='A test taxonomy')
+    term = TermFactory(name="A test term", taxonomy=taxonomy)
+    term_2 = TermFactory(name="A second test term", taxonomy=taxonomy)
+    taxonomy_2 = TaxonomyFactory(name='Another test taxonomy')
+    TermFactory(name="A third test term", taxonomy=taxonomy_2)
+
+    terms = transport.terms.list(taxonomy=taxonomy.slug)
+    terms_as_items = [t.items() for t in terms]
+
+    expected = [t.items() for t in [
+        {
+            'taxonomy': taxonomy.slug,
+            'name': term.name,
+            'long_name': term.long_name
+        },
+        {
+            'taxonomy': taxonomy.slug,
+            'name': term_2.name,
+            'long_name': term_2.long_name
+        }
+
+    ]]
+
+    assert len(terms) == 2
+    assert sorted(terms_as_items) == sorted(expected)
+
+
+@pytest.mark.django_db
+def test_list_terms_applies_name_filter_accross_taxonomies():
+    taxonomy = TaxonomyFactory(name='A test taxonomy')
+    term = TermFactory(name="A test term", taxonomy=taxonomy)
+    TermFactory(name="Another test term", taxonomy=taxonomy)
+    taxonomy_2 = TaxonomyFactory(name='Another test taxonomy')
+    term_2 = TermFactory(name="A test term", taxonomy=taxonomy_2)
+
+    terms = transport.terms.list(name="A test term")
+    terms_as_items = [t.items() for t in terms]
+
+    expected = [t.items() for t in [
+        {
+            'taxonomy': taxonomy.slug,
+            'name': term.name,
+            'long_name': term.long_name
+        },
+        {
+            'taxonomy': taxonomy_2.slug,
+            'name': term_2.name,
+            'long_name': term_2.long_name
+        }
+    ]]
+
+    assert len(terms) == 2
+    assert sorted(terms_as_items) == sorted(expected)