diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04069795..3dd15afa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,12 @@
 v2.5.0 - [unreleased]
 * Add new pagination classes based on JSON:API query parameter *recommendations*:
-  * JsonApiPageNumberPagination and JsonApiLimitOffsetPagination. See [usage docs](docs/usage.md#pagination).
-  * Deprecates PageNumberPagination and LimitOffsetPagination.
-* Add ReadOnlyModelViewSet extension with prefetch mixins.
+  * `JsonApiPageNumberPagination` and `JsonApiLimitOffsetPagination`. See [usage docs](docs/usage.md#pagination).
+  * Deprecates `PageNumberPagination` and `LimitOffsetPagination`.
+* Add `ReadOnlyModelViewSet` extension with prefetch mixins.
 * Add support for Django REST Framework 3.8.x
+* Introduce `JSON_API_FORMAT_FIELD_NAMES` option replacing `JSON_API_FORMAT_KEYS` but in comparision preserving
+  values from being formatted as attributes can contain any [json value](http://jsonapi.org/format/#document-resource-object-attributes).
+   * `JSON_API_FORMAT_KEYS` still works as before (formating all json value keys also nested) but is marked as deprecated.
 
 v2.4.0 - Released January 25, 2018
 
diff --git a/docs/usage.md b/docs/usage.md
index 990638f9..c8727f1b 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -149,13 +149,13 @@ multiple endpoints. Setting the `resource_name` on views may result in a differe
 
 ### Inflecting object and relation keys
 
-This package includes the ability (off by default) to automatically convert json
-requests and responses from the python/rest_framework's preferred underscore to
+This package includes the ability (off by default) to automatically convert [json
+api field names](http://jsonapi.org/format/#document-resource-object-fields) of requests and responses from the python/rest_framework's preferred underscore to
 a format of your choice. To hook this up include the following setting in your
 project settings:
 
 ``` python
-JSON_API_FORMAT_KEYS = 'dasherize'
+JSON_API_FORMAT_FIELD_NAMES = 'dasherize'
 ```
 
 Possible values:
diff --git a/example/api/resources/identity.py b/example/api/resources/identity.py
index 470bd79c..a00def74 100644
--- a/example/api/resources/identity.py
+++ b/example/api/resources/identity.py
@@ -37,7 +37,7 @@ def posts(self, request):
             encoding.force_text('identities'): IdentitySerializer(identities, many=True).data,
             encoding.force_text('posts'): PostSerializer(posts, many=True).data,
         }
-        return Response(utils.format_keys(data, format_type='camelize'))
+        return Response(utils.format_field_names(data, format_type='camelize'))
 
     @detail_route()
     def manual_resource_name(self, request, *args, **kwargs):
diff --git a/example/settings/dev.py b/example/settings/dev.py
index 61dfa443..01e2fef1 100644
--- a/example/settings/dev.py
+++ b/example/settings/dev.py
@@ -65,7 +65,7 @@
 
 INTERNAL_IPS = ('127.0.0.1', )
 
-JSON_API_FORMAT_KEYS = 'camelize'
+JSON_API_FORMAT_FIELD_NAMES = 'camelize'
 JSON_API_FORMAT_TYPES = 'camelize'
 REST_FRAMEWORK = {
     'PAGE_SIZE': 5,
diff --git a/example/settings/test.py b/example/settings/test.py
index 1f0e959d..bbf6e400 100644
--- a/example/settings/test.py
+++ b/example/settings/test.py
@@ -9,7 +9,7 @@
 
 ROOT_URLCONF = 'example.urls_test'
 
-JSON_API_FORMAT_KEYS = 'camelize'
+JSON_API_FIELD_NAMES = 'camelize'
 JSON_API_FORMAT_TYPES = 'camelize'
 JSON_API_PLURALIZE_TYPES = True
 REST_FRAMEWORK.update({
diff --git a/example/tests/test_generic_viewset.py b/example/tests/test_generic_viewset.py
index bfde51ea..15d9bd1e 100644
--- a/example/tests/test_generic_viewset.py
+++ b/example/tests/test_generic_viewset.py
@@ -4,7 +4,7 @@
 from example.tests import TestBase
 
 
-@override_settings(JSON_API_FORMAT_KEYS='dasherize')
+@override_settings(JSON_API_FORMAT_FIELD_NAMES='dasherize')
 class GenericViewSet(TestBase):
     """
     Test expected responses coming from a Generic ViewSet
diff --git a/example/tests/test_model_viewsets.py b/example/tests/test_model_viewsets.py
index 21c6d41a..ee3e4ba0 100644
--- a/example/tests/test_model_viewsets.py
+++ b/example/tests/test_model_viewsets.py
@@ -7,7 +7,7 @@
 from example.tests import TestBase
 
 
-@override_settings(JSON_API_FORMAT_KEYS='dasherize')
+@override_settings(JSON_API_FORMAT_FIELD_NAMES='dasherize')
 class ModelViewSetTests(TestBase):
     """
     Test usage with ModelViewSets, also tests pluralization, camelization,
diff --git a/example/tests/test_parsers.py b/example/tests/test_parsers.py
index 3c7a102c..aec80a12 100644
--- a/example/tests/test_parsers.py
+++ b/example/tests/test_parsers.py
@@ -1,7 +1,7 @@
 import json
 from io import BytesIO
 
-from django.test import TestCase
+from django.test import TestCase, override_settings
 from rest_framework.exceptions import ParseError
 
 from rest_framework_json_api.parsers import JSONParser
@@ -22,7 +22,10 @@ def __init__(self):
         data = {
             'data': {
                 'id': 123,
-                'type': 'Blog'
+                'type': 'Blog',
+                'attributes': {
+                    'json-value': {'JsonKey': 'JsonValue'}
+                },
             },
             'meta': {
                 'random_key': 'random_value'
@@ -31,13 +34,25 @@ def __init__(self):
 
         self.string = json.dumps(data)
 
-    def test_parse_include_metadata(self):
+    @override_settings(JSON_API_FORMAT_KEYS='camelize')
+    def test_parse_include_metadata_format_keys(self):
         parser = JSONParser()
 
         stream = BytesIO(self.string.encode('utf-8'))
         data = parser.parse(stream, None, self.parser_context)
 
         self.assertEqual(data['_meta'], {'random_key': 'random_value'})
+        self.assertEqual(data['json_value'], {'json_key': 'JsonValue'})
+
+    @override_settings(JSON_API_FORMAT_FIELD_NAMES='dasherize')
+    def test_parse_include_metadata_format_field_names(self):
+        parser = JSONParser()
+
+        stream = BytesIO(self.string.encode('utf-8'))
+        data = parser.parse(stream, None, self.parser_context)
+
+        self.assertEqual(data['_meta'], {'random_key': 'random_value'})
+        self.assertEqual(data['json_value'], {'JsonKey': 'JsonValue'})
 
     def test_parse_invalid_data(self):
         parser = JSONParser()
diff --git a/example/tests/unit/test_renderers.py b/example/tests/unit/test_renderers.py
index de40afac..42a45a94 100644
--- a/example/tests/unit/test_renderers.py
+++ b/example/tests/unit/test_renderers.py
@@ -1,3 +1,5 @@
+import json
+
 from rest_framework_json_api import serializers, views
 from rest_framework_json_api.renderers import JSONRenderer
 
@@ -19,9 +21,14 @@ class DummyTestSerializer(serializers.ModelSerializer):
     related_models = RelatedModelSerializer(
         source='comments', many=True, read_only=True)
 
+    json_field = serializers.SerializerMethodField()
+
+    def get_json_field(self, entry):
+        return {'JsonKey': 'JsonValue'}
+
     class Meta:
         model = Entry
-        fields = ('related_models',)
+        fields = ('related_models', 'json_field')
 
     class JSONAPIMeta:
         included_resources = ('related_models',)
@@ -61,3 +68,22 @@ def test_simple_reverse_relation_included_read_only_viewset():
         ReadOnlyDummyTestViewSet)
 
     assert rendered
+
+
+def test_render_format_field_names(settings):
+    """Test that json field is kept untouched."""
+    settings.JSON_API_FORMAT_FIELD_NAMES = 'dasherize'
+    rendered = render_dummy_test_serialized_view(DummyTestViewSet)
+
+    result = json.loads(rendered.decode())
+    assert result['data']['attributes']['json-field'] == {'JsonKey': 'JsonValue'}
+
+
+def test_render_format_keys(settings):
+    """Test that json field value keys are formated."""
+    delattr(settings, 'JSON_API_FORMAT_FILED_NAMES')
+    settings.JSON_API_FORMAT_KEYS = 'dasherize'
+    rendered = render_dummy_test_serialized_view(DummyTestViewSet)
+
+    result = json.loads(rendered.decode())
+    assert result['data']['attributes']['json-field'] == {'json-key': 'JsonValue'}
diff --git a/example/tests/unit/test_settings.py b/example/tests/unit/test_settings.py
index 516e76ec..e6b82a24 100644
--- a/example/tests/unit/test_settings.py
+++ b/example/tests/unit/test_settings.py
@@ -13,5 +13,5 @@ def test_settings_default():
 
 
 def test_settings_override(settings):
-    settings.JSON_API_FORMAT_KEYS = 'dasherize'
-    assert json_api_settings.FORMAT_KEYS == 'dasherize'
+    settings.JSON_API_FORMAT_FIELD_NAMES = 'dasherize'
+    assert json_api_settings.FORMAT_FIELD_NAMES == 'dasherize'
diff --git a/example/tests/unit/test_utils.py b/example/tests/unit/test_utils.py
index 46315772..a1414050 100644
--- a/example/tests/unit/test_utils.py
+++ b/example/tests/unit/test_utils.py
@@ -69,7 +69,8 @@ def test_format_keys():
     }
 
     output = {'firstName': 'a', 'lastName': 'b'}
-    assert utils.format_keys(underscored, 'camelize') == output
+    result = pytest.deprecated_call(utils.format_keys, underscored, 'camelize')
+    assert result == output
 
     output = {'FirstName': 'a', 'LastName': 'b'}
     assert utils.format_keys(underscored, 'capitalize') == output
@@ -84,6 +85,19 @@ def test_format_keys():
     assert utils.format_keys([underscored], 'dasherize') == output
 
 
+@pytest.mark.parametrize("format_type,output", [
+    ('camelize', {'fullName': {'last-name': 'a', 'first-name': 'b'}}),
+    ('capitalize', {'FullName': {'last-name': 'a', 'first-name': 'b'}}),
+    ('dasherize', {'full-name': {'last-name': 'a', 'first-name': 'b'}}),
+    ('underscore', {'full_name': {'last-name': 'a', 'first-name': 'b'}}),
+])
+def test_format_field_names(settings, format_type, output):
+    settings.JSON_API_FORMAT_FIELD_NAMES = format_type
+
+    value = {'full_name': {'last-name': 'a', 'first-name': 'b'}}
+    assert utils.format_field_names(value, format_type) == output
+
+
 def test_format_value():
     assert utils.format_value('first_name', 'camelize') == 'firstName'
     assert utils.format_value('first_name', 'capitalize') == 'FirstName'
diff --git a/rest_framework_json_api/parsers.py b/rest_framework_json_api/parsers.py
index 98873d2e..8459f3ba 100644
--- a/rest_framework_json_api/parsers.py
+++ b/rest_framework_json_api/parsers.py
@@ -32,26 +32,26 @@ class JSONParser(parsers.JSONParser):
     @staticmethod
     def parse_attributes(data):
         attributes = data.get('attributes')
-        uses_format_translation = json_api_settings.FORMAT_KEYS
+        uses_format_translation = json_api_settings.format_type
 
         if not attributes:
             return dict()
         elif uses_format_translation:
             # convert back to python/rest_framework's preferred underscore format
-            return utils.format_keys(attributes, 'underscore')
+            return utils._format_object(attributes, 'underscore')
         else:
             return attributes
 
     @staticmethod
     def parse_relationships(data):
-        uses_format_translation = json_api_settings.FORMAT_KEYS
+        uses_format_translation = json_api_settings.format_type
         relationships = data.get('relationships')
 
         if not relationships:
             relationships = dict()
         elif uses_format_translation:
             # convert back to python/rest_framework's preferred underscore format
-            relationships = utils.format_keys(relationships, 'underscore')
+            relationships = utils._format_object(relationships, 'underscore')
 
         # Parse the relationships
         parsed_relationships = dict()
diff --git a/rest_framework_json_api/renderers.py b/rest_framework_json_api/renderers.py
index 6059d2a2..ba6424ee 100644
--- a/rest_framework_json_api/renderers.py
+++ b/rest_framework_json_api/renderers.py
@@ -68,7 +68,7 @@ def extract_attributes(cls, fields, resource):
                 field_name: resource.get(field_name)
             })
 
-        return utils.format_keys(data)
+        return utils._format_object(data)
 
     @classmethod
     def extract_relationships(cls, fields, resource, resource_instance):
@@ -281,7 +281,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
                 })
                 continue
 
-        return utils.format_keys(data)
+        return utils._format_object(data)
 
     @classmethod
     def extract_relation_instance(cls, field_name, field, resource_instance, serializer):
@@ -405,7 +405,7 @@ def extract_included(cls, fields, resource, resource_instance, included_resource
                             getattr(serializer, '_poly_force_type_resolution', False)
                         )
                         included_cache[new_item['type']][new_item['id']] = \
-                            utils.format_keys(new_item)
+                            utils._format_object(new_item)
                         cls.extract_included(
                             serializer_fields,
                             serializer_resource,
@@ -427,7 +427,9 @@ def extract_included(cls, fields, resource, resource_instance, included_resource
                         relation_type,
                         getattr(field, '_poly_force_type_resolution', False)
                     )
-                    included_cache[new_item['type']][new_item['id']] = utils.format_keys(new_item)
+                    included_cache[new_item['type']][new_item['id']] = utils._format_object(
+                        new_item
+                    )
                     cls.extract_included(
                         serializer_fields,
                         serializer_data,
@@ -577,7 +579,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
                     )
                     meta = self.extract_meta(serializer, resource)
                     if meta:
-                        json_resource_obj.update({'meta': utils.format_keys(meta)})
+                        json_resource_obj.update({'meta': utils._format_object(meta)})
                     json_api_data.append(json_resource_obj)
 
                     self.extract_included(
@@ -594,7 +596,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
 
                 meta = self.extract_meta(serializer, serializer_data)
                 if meta:
-                    json_api_data.update({'meta': utils.format_keys(meta)})
+                    json_api_data.update({'meta': utils._format_object(meta)})
 
                 self.extract_included(
                     fields, serializer_data, resource_instance, included_resources, included_cache
@@ -620,7 +622,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
                     render_data['included'].append(included_cache[included_type][included_id])
 
         if json_api_meta:
-            render_data['meta'] = utils.format_keys(json_api_meta)
+            render_data['meta'] = utils._format_object(json_api_meta)
 
         return super(JSONRenderer, self).render(
             render_data, accepted_media_type, renderer_context
diff --git a/rest_framework_json_api/settings.py b/rest_framework_json_api/settings.py
index 40c5a96b..6c7eeffe 100644
--- a/rest_framework_json_api/settings.py
+++ b/rest_framework_json_api/settings.py
@@ -10,12 +10,15 @@
 JSON_API_SETTINGS_PREFIX = 'JSON_API_'
 
 DEFAULTS = {
-    'FORMAT_KEYS': False,
-    'FORMAT_RELATION_KEYS': None,
+    'FORMAT_FIELD_NAMES': False,
     'FORMAT_TYPES': False,
-    'PLURALIZE_RELATION_TYPE': None,
     'PLURALIZE_TYPES': False,
     'UNIFORM_EXCEPTIONS': False,
+
+    # deprecated settings to be removed in the future
+    'FORMAT_KEYS': None,
+    'FORMAT_RELATION_KEYS': None,
+    'PLURALIZE_RELATION_TYPE': None,
 }
 
 
@@ -39,6 +42,13 @@ def __getattr__(self, attr):
         setattr(self, attr, value)
         return value
 
+    @property
+    def format_type(self):
+        if self.FORMAT_KEYS is not None:
+            return self.FORMAT_KEYS
+
+        return self.FORMAT_FIELD_NAMES
+
 
 json_api_settings = JSONAPISettings()
 
diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py
index a7220084..39000216 100644
--- a/rest_framework_json_api/utils.py
+++ b/rest_framework_json_api/utils.py
@@ -98,13 +98,50 @@ def get_serializer_fields(serializer):
         return fields
 
 
+def format_field_names(obj, format_type=None):
+    """
+    Takes a dict and returns it with formatted keys as set in `format_type`
+    or `JSON_API_FORMAT_FIELD_NAMES`
+
+    :format_type: Either 'dasherize', 'camelize', 'capitalize' or 'underscore'
+    """
+    if format_type is None:
+        format_type = json_api_settings.FORMAT_FIELD_NAMES
+
+    if isinstance(obj, dict):
+        formatted = OrderedDict()
+        for key, value in obj.items():
+            key = format_value(key, format_type)
+            formatted[key] = value
+        return formatted
+
+    return obj
+
+
+def _format_object(obj, format_type=None):
+    """Depending on settings calls either `format_keys` or `format_field_names`"""
+
+    if json_api_settings.FORMAT_KEYS is not None:
+        return format_keys(obj, format_type)
+
+    return format_field_names(obj, format_type)
+
+
 def format_keys(obj, format_type=None):
     """
     Takes either a dict or list and returns it with camelized keys only if
     JSON_API_FORMAT_KEYS is set.
 
-    :format_type: Either 'dasherize', 'camelize' or 'underscore'
+    :format_type: Either 'dasherize', 'camelize', 'capitalize' or 'underscore'
     """
+    warnings.warn(
+        "`format_keys` function and `JSON_API_FORMAT_KEYS` setting are deprecated and will be "
+        "removed in the future. "
+        "Use `format_field_names` and `JSON_API_FIELD_NAMES` instead. Be aware that "
+        "`format_field_names` only formats keys and preserves value.",
+        DeprecationWarning
+    )
+
     if format_type is None:
         format_type = json_api_settings.FORMAT_KEYS
 
@@ -138,7 +175,7 @@ def format_keys(obj, format_type=None):
 
 def format_value(value, format_type=None):
     if format_type is None:
-        format_type = json_api_settings.FORMAT_KEYS
+        format_type = json_api_settings.format_type
     if format_type == 'dasherize':
         # inflection can't dasherize camelCase
         value = inflection.underscore(value)
@@ -155,7 +192,9 @@ def format_value(value, format_type=None):
 def format_relation_name(value, format_type=None):
     warnings.warn(
         "The 'format_relation_name' function has been renamed 'format_resource_type' and the "
-        "settings are now 'JSON_API_FORMAT_TYPES' and 'JSON_API_PLURALIZE_TYPES'"
+        "settings are now 'JSON_API_FORMAT_TYPES' and 'JSON_API_PLURALIZE_TYPES' instead of "
+        "'JSON_API_FORMAT_RELATION_KEYS' and 'JSON_API_PLURALIZE_RELATION_TYPE'",
+        DeprecationWarning
     )
     if format_type is None:
         format_type = json_api_settings.FORMAT_RELATION_KEYS