diff --git a/src/_zkapauthorizer/controller.py b/src/_zkapauthorizer/controller.py
index decee7ab125285ba3ce3aca8d10e88eb02c19e3e..cb1c82af80ac9da21ff7210b1c7a79ed88fedeea 100644
--- a/src/_zkapauthorizer/controller.py
+++ b/src/_zkapauthorizer/controller.py
@@ -218,6 +218,7 @@ class RistrettoRedeemer(object):
                     in blinded_tokens
                 ),
             }),
+            headers={b"content-type": b"application/json"},
         )
         try:
             result = yield json_content(response)
diff --git a/src/_zkapauthorizer/tests/test_controller.py b/src/_zkapauthorizer/tests/test_controller.py
index 3ff2d7bd6cc0a58ef63bd7ce0964b6ff0fbf6ee5..4e3f264ce22a05d32535c87888d19d2af93d0147 100644
--- a/src/_zkapauthorizer/tests/test_controller.py
+++ b/src/_zkapauthorizer/tests/test_controller.py
@@ -65,8 +65,12 @@ from twisted.web.iweb import (
     IAgent,
 )
 from twisted.web.resource import (
+    ErrorPage,
     Resource,
 )
+from twisted.web.http import (
+    UNSUPPORTED_MEDIA_TYPE,
+)
 from treq.testing import (
     StubTreq,
 )
@@ -338,27 +342,6 @@ def treq_for_loopback_ristretto(local_issuer):
     return StubTreq(root)
 
 
-class SuccessfulRedemption(Resource):
-    def __init__(self, public_key, signatures, proof):
-        Resource.__init__(self)
-        self.public_key = public_key
-        self.signatures = signatures
-        self.proof = proof
-        self.redemptions = []
-
-    def render_POST(self, request):
-        request_body = loads(request.content.read())
-        voucher = request_body[u"redeemVoucher"]
-        tokens = request_body[u"redeemTokens"]
-        self.redemptions.append((voucher, tokens))
-        return dumps({
-            u"success": True,
-            u"public-key": self.public_key,
-            u"signatures": self.signatures,
-            u"proof": self.proof,
-        })
-
-
 @implementer(IAgent)
 class _StubAgent(object):
     def request(self, method, uri, headers=None, bodyProducer=None):
@@ -376,6 +359,9 @@ class RistrettoRedemption(Resource):
         self.public_key = PublicKey.from_signing_key(signing_key)
 
     def render_POST(self, request):
+        if request.requestHeaders.getRawHeaders(b"content-type") != ["application/json"]:
+            return bad_content_type(request)
+
         request_body = loads(request.content.read())
         marshaled_blinded_tokens = request_body[u"redeemTokens"]
         servers_blinded_tokens = list(
@@ -409,3 +395,11 @@ class RistrettoRedemption(Resource):
             u"signatures": marshaled_signed_tokens,
             u"proof": marshaled_proof,
         })
+
+
+def bad_content_type(request):
+    return ErrorPage(
+        UNSUPPORTED_MEDIA_TYPE,
+        b"Unsupported media type",
+        b"Unsupported media type",
+    ).render(request)