diff --git a/account/tests/test_api.py b/account/tests/test_api.py
index 028b5cf..b063537 100644
--- a/account/tests/test_api.py
+++ b/account/tests/test_api.py
@@ -32,7 +32,6 @@ def test_token_expiration(api_client_authenticated, users, profiles):
 
 @pytest.mark.django_db
 def test_unauthenticated_cannot_do_anything(api_client, users):
-    # TODO, add start-poll url after recaptcha integration
     urls = [
         reverse("account:profiles-detail", args=[users.get(username="test1").id]),
     ]
diff --git a/config_dev.env.example b/config_dev.env.example
index e3851c7..1a48887 100644
--- a/config_dev.env.example
+++ b/config_dev.env.example
@@ -53,3 +53,6 @@ STATIC_URL=/static/
 
 # Location of memcached
 CACHE_LOCATION=127.0.0.1:11211
+
+# Must be 16 char long
+TOKEN_SECRET=
\ No newline at end of file
diff --git a/mpbackend/settings.py b/mpbackend/settings.py
index bfa5e8e..0addfeb 100644
--- a/mpbackend/settings.py
+++ b/mpbackend/settings.py
@@ -23,6 +23,7 @@
     STATIC_URL=(str, "/static/"),
     CORS_ORIGIN_WHITELIST=(list, []),
     CACHE_LOCATION=(str, "127.0.0.1:11211"),
+    TOKEN_SECRET=(str, None),
 )
 # WARN about env file not being preset. Here we pre-empt it.
 env_file_path = os.path.join(BASE_DIR, CONFIG_FILE_NAME)
@@ -98,7 +99,7 @@
 CSRF_TRUSTED_ORIGINS = ["http://localhost:8080"]
 
 SECURE_CROSS_ORIGIN_OPENER_POLICY = None
-
+TOKEN_SECRET = env("TOKEN_SECRET")
 REST_FRAMEWORK = {
     "DEFAULT_PERMISSION_CLASSES": [
         "rest_framework.permissions.IsAuthenticatedOrReadOnly"
diff --git a/profiles/api/utils.py b/profiles/api/utils.py
index 690a876..94a47b5 100644
--- a/profiles/api/utils.py
+++ b/profiles/api/utils.py
@@ -1,9 +1,19 @@
+import base64
+
 import django_filters
+from Crypto.Cipher import AES
+from Crypto.Util.Padding import pad
 from rest_framework.exceptions import ValidationError
 
 from profiles.models import PostalCodeResult
 
 
+def decrypt_text(text, key):
+    text = pad(text.encode(), 16)
+    cipher = AES.new(key.encode("utf-8"), AES.MODE_ECB)
+    return base64.b64encode(cipher.encrypt(text))
+
+
 class CustomValidationError(ValidationError):
     # The detail field is shown also when DEBUG=False
     # Ensures the error message is displayed to the user
diff --git a/profiles/api/views.py b/profiles/api/views.py
index fc83597..1c1f922 100644
--- a/profiles/api/views.py
+++ b/profiles/api/views.py
@@ -56,7 +56,7 @@
 )
 from profiles.utils import generate_password, get_user_result
 
-from .utils import PostalCodeResultFilter
+from .utils import decrypt_text, PostalCodeResultFilter
 
 logger = logging.getLogger(__name__)
 
@@ -187,7 +187,6 @@ def list(self, request, *args, **kwargs):
         permission_classes=[AllowAny],
     )
     def start_poll(self, request):
-        # TODO check recaptha
         uuid4 = uuid.uuid4()
         username = f"anonymous_{str(uuid4)}"
         user = User.objects.create(pk=uuid4, username=username, is_generated=True)
@@ -196,7 +195,8 @@ def start_poll(self, request):
         user.profile = Profile.objects.create(user=user)
         user.save()
         token, _ = Token.objects.get_or_create(user=user)
-        response_data = {"token": token.key, "id": user.id}
+        data = decrypt_text(token.key, settings.TOKEN_SECRET)
+        response_data = {"data": data, "id": user.id}
         return Response(response_data, status=status.HTTP_200_OK)
 
     @extend_schema(
diff --git a/profiles/tests/api/test_postal_code_result.py b/profiles/tests/api/test_postal_code_result.py
index 358b378..572ee3c 100644
--- a/profiles/tests/api/test_postal_code_result.py
+++ b/profiles/tests/api/test_postal_code_result.py
@@ -147,7 +147,6 @@ def test_postal_code_result(
 ):
     num_users = 5
     num_answers = 0
-    start_poll_url = reverse("profiles:question-start-poll")
     postal_codes = [None, "20100", "20200", "20100", None]
     q1 = questions_test_result.get(number="1")
     q1_option_pos = options_test_result.get(question=q1, value=POS)
@@ -155,22 +154,19 @@ def test_postal_code_result(
 
     # post positive
     for i in range(num_users):
-        response = api_client.post(start_poll_url)
-        token = response.json()["token"]
-        assert response.status_code == 200
-        token = response.json()["token"]
-        user_id = response.json()["id"]
+        user = User.objects.create(username=f"user_{i}")
+        Profile.objects.create(user=user)
+        token = Token.objects.create(user=user)
+        api_client.credentials(HTTP_AUTHORIZATION="Token " + token.key)
         assert User.objects.all().count() == 1 + i
-        user = User.objects.get(id=user_id)
         user.profile.postal_code = postal_codes[i]
         user.profile.optional_postal_code = postal_codes[i]
         user.profile.save()
-        api_client.credentials(HTTP_AUTHORIZATION=f"Token {token}")
         api_client.post(ANSWER_URL, {"option": q1_option_pos.id, "question": q1.id})
         num_answers += 1
         assert Answer.objects.count() == num_answers
-        response = api_client.post(reverse("profiles:question-end-poll"))
-        api_client.credentials()
+        api_client.post(reverse("profiles:question-end-poll"))
+
     assert PostalCodeResult.objects.count() == 6
     assert PostalCode.objects.count() == 3
     assert PostalCodeType.objects.count() == 2
@@ -213,13 +209,12 @@ def test_postal_code_result(
 
     # post negative, but only to user Home postal code
     for i in range(num_users):
-        response = api_client.post(start_poll_url)
-        token = response.json()["token"]
-        assert response.status_code == 200
-        token = response.json()["token"]
-        user_id = response.json()["id"]
+        user = User.objects.create(username=f"neg_user_{i}")
+        Profile.objects.create(user=user)
+        token = Token.objects.create(user=user)
+        api_client.credentials(HTTP_AUTHORIZATION="Token " + token.key)
+
         assert User.objects.all().count() == num_users + 1 + i
-        user = User.objects.get(id=user_id)
         user.profile.postal_code = postal_codes[i]
         user.profile.optional_postal_code = None
         user.profile.save()
@@ -227,8 +222,8 @@ def test_postal_code_result(
         api_client.post(ANSWER_URL, {"option": q1_option_neg.id, "question": q1.id})
         num_answers += 1
         assert Answer.objects.count() == num_answers
-        response = api_client.post(reverse("profiles:question-end-poll"))
-        api_client.credentials()
+        api_client.post(reverse("profiles:question-end-poll"))
+
     neg_result = results_test_result.get(topic=NEG)
     pos_result = results_test_result.get(topic=POS)
 
diff --git a/requirements.in b/requirements.in
index 146d860..4ef714f 100644
--- a/requirements.in
+++ b/requirements.in
@@ -17,3 +17,4 @@ django-cors-headers
 freezegun
 django-filter
 pymemcache
+pycryptodome
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index abe665e..0f91efd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,9 +17,7 @@ click==8.1.3
     #   black
     #   pip-tools
 coverage[toml]==7.2.3
-    # via
-    #   coverage
-    #   pytest-cov
+    # via pytest-cov
 django==4.2.10
     # via
     #   -r requirements.in
@@ -88,6 +86,8 @@ psycopg2-binary==2.9.6
     # via -r requirements.in
 pycodestyle==2.10.0
     # via flake8
+pycryptodome==3.20.0
+    # via -r requirements.in
 pyflakes==3.0.1
     # via flake8
 pymemcache==4.0.0
@@ -123,7 +123,6 @@ tomli==2.0.1
     #   black
     #   build
     #   coverage
-    #   pyproject-hooks
     #   pytest
 typing-extensions==4.5.0
     # via django-modeltranslation