diff --git a/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php b/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php
index 0c36340..e350a9a 100644
--- a/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php
+++ b/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php
@@ -83,9 +83,14 @@ class JsonApiDocumentTopLevelNormalizer extends NormalizerBase implements Denorm
       'on_relationship' => $this->currentContext->isOnRelationship(),
     ];
     $normalized = [];
+
+    // Validate a few common errors in document formatting.
+    $this->validateDocument($data);
+
     if (!empty($data['data']['attributes'])) {
       $normalized = $data['data']['attributes'];
     }
+
     if (!empty($data['data']['relationships'])) {
       // Turn all single object relationship data fields into an array of objects.
       $relationships = array_map(function ($relationship) {
@@ -273,4 +278,18 @@ class JsonApiDocumentTopLevelNormalizer extends NormalizerBase implements Denorm
     return $context;
   }
 
+  /**
+   * Performs mimimal validation of the document.
+   */
+  public function validateDocument($document) {
+    // Ensure that the relationships key was not placed in the top level.
+    if (isset($document['relationships']) && !empty($document['relationships'])) {
+      throw new BadRequestHttpException("Found \"relationships\" within the document's top level. The \"relationships\" key must be within resource object.");
+    }
+    // Ensure that the resource object contains the "type" key.
+    if (!isset($document['data']['type'])) {
+      throw new BadRequestHttpException("Resource object must include a \"type\".");
+    }
+  }
+
 }
diff --git a/tests/src/Functional/JsonApiFunctionalTest.php b/tests/src/Functional/JsonApiFunctionalTest.php
index f6441c7..093cdb7 100644
--- a/tests/src/Functional/JsonApiFunctionalTest.php
+++ b/tests/src/Functional/JsonApiFunctionalTest.php
@@ -242,7 +242,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
         $this->userCanViewProfiles->pass_raw,
       ],
     ]);
-    $single_output = Json::decode($response->getBody()->__toString());
+    $single_output = Json::decode((string) $response->getBody());
     $this->assertEquals(200, $response->getStatusCode());
     $this->assertEquals('user--user', $single_output['data']['type']);
     $this->assertEquals($this->user->get('name')->value, $single_output['data']['attributes']['name']);
@@ -506,7 +506,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $created_response = Json::decode($response->getBody()->__toString());
+    $created_response = Json::decode((string) $response->getBody());
     $this->assertEquals(201, $response->getStatusCode());
     $this->assertArrayHasKey('uuid', $created_response['data']['attributes']);
     $uuid = $created_response['data']['attributes']['uuid'];
@@ -518,7 +518,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'body' => Json::encode($body),
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $created_response = Json::decode($response->getBody()->__toString());
+    $created_response = Json::decode((string) $response->getBody());
     $this->assertEquals(403, $response->getStatusCode());
     $this->assertNotEmpty($created_response['errors']);
     $this->assertEquals('Forbidden', $created_response['errors'][0]['title']);
@@ -529,7 +529,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->userCanViewProfiles->getUsername(), $this->userCanViewProfiles->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $created_response = Json::decode($response->getBody()->__toString());
+    $created_response = Json::decode((string) $response->getBody());
     $this->assertEquals(403, $response->getStatusCode());
     $this->assertNotEmpty($created_response['errors']);
     $this->assertEquals('Forbidden', $created_response['errors'][0]['title']);
@@ -540,7 +540,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Accept' => 'application/vnd.api+json'],
     ]);
-    $created_response = Json::decode($response->getBody()->__toString());
+    $created_response = Json::decode((string) $response->getBody());
     $this->assertEquals(422, $response->getStatusCode());
     $this->assertNotEmpty($created_response['errors']);
     $this->assertEquals('Unprocessable Entity', $created_response['errors'][0]['title']);
@@ -552,7 +552,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $created_response = Json::decode($response->getBody()->__toString());
+    $created_response = Json::decode((string) $response->getBody());
     $this->assertEquals(500, $response->getStatusCode());
     $this->assertNotEmpty($created_response['errors']);
     $this->assertEquals('Internal Server Error', $created_response['errors'][0]['title']);
@@ -565,7 +565,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $created_response = Json::decode($response->getBody()->__toString());
+    $created_response = Json::decode((string) $response->getBody());
     $this->assertEquals(201, $response->getStatusCode());
     $this->assertEquals(0, count($created_response['data']['relationships']['field_tags']['data']));
     // 6. Serialization error.
@@ -577,10 +577,43 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
         'Accept' => 'application/vnd.api+json',
       ],
     ]);
-    $created_response = Json::decode($response->getBody()->__toString());
+    $created_response = Json::decode((string) $response->getBody());
     $this->assertEquals(422, $response->getStatusCode());
     $this->assertNotEmpty($created_response['errors']);
     $this->assertEquals('Unprocessable Entity', $created_response['errors'][0]['title']);
+    // 6.1 Relationships are not included in "data".
+    $malformed_body = $body;
+    unset($malformed_body['data']['relationships']);
+    $malformed_body['relationships'] = $body['data']['relationships'];
+    $response = $this->request('POST', $collection_url, [
+      'body' => Json::encode($malformed_body),
+      'auth' => [$this->user->getUsername(), $this->user->pass_raw],
+      'headers' => [
+        'Accept' => 'application/vnd.api+json',
+        'Content-Type' => 'application/vnd.api+json',
+      ],
+    ]);
+    $created_response = Json::decode((string) $response->getBody());
+    $this->assertEquals(400, $response->getStatusCode());
+    $this->assertNotEmpty($created_response['errors']);
+    $this->assertEquals("Bad Request", $created_response['errors'][0]['title']);
+    $this->assertEquals("Found \"relationships\" within the document's top level. The \"relationships\" key must be within resource object.", $created_response['errors'][0]['detail']);
+    // 6.2 "type" not included in "data"
+    $missing_type = $body;
+    unset($missing_type['data']['type']);
+    $response = $this->request('POST', $collection_url, [
+      'body' => Json::encode($missing_type),
+      'auth' => [$this->user->getUsername(), $this->user->pass_raw],
+      'headers' => [
+        'Accept' => 'application/vnd.api+json',
+        'Content-Type' => 'application/vnd.api+json',
+      ],
+    ]);
+    $created_response = Json::decode((string) $response->getBody());
+    $this->assertEquals(400, $response->getStatusCode());
+    $this->assertNotEmpty($created_response['errors']);
+    $this->assertEquals("Bad Request", $created_response['errors'][0]['title']);
+    $this->assertEquals("Resource object must include a \"type\".", $created_response['errors'][0]['detail']);
     // 7. Successful PATCH.
     $body = [
       'data' => [
@@ -597,7 +630,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $updated_response = Json::decode($response->getBody()->__toString());
+    $updated_response = Json::decode((string) $response->getBody());
     $this->assertEquals(200, $response->getStatusCode());
     $this->assertEquals('My updated title', $updated_response['data']['attributes']['title']);
 
@@ -635,7 +668,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $updated_response = Json::decode($response->getBody()->__toString());
+    $updated_response = Json::decode((string) $response->getBody());
     $this->assertEquals(403, $response->getStatusCode());
     $this->assertEquals("The current user is not allowed to PATCH the selected field (status). The 'administer nodes' permission is required.",
       $updated_response['errors'][0]['detail']);
@@ -660,7 +693,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $updated_response = Json::decode($response->getBody()->__toString());
+    $updated_response = Json::decode((string) $response->getBody());
     $this->assertEquals(201, $response->getStatusCode());
     $this->assertEquals(3, count($updated_response['data']));
     $this->assertEquals('taxonomy_term--tags', $updated_response['data'][2]['type']);
@@ -679,7 +712,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $updated_response = Json::decode($response->getBody()->__toString());
+    $updated_response = Json::decode((string) $response->getBody());
     $this->assertEquals(200, $response->getStatusCode());
     $this->assertCount(1, $updated_response['data']);
     $this->assertEquals('taxonomy_term--tags', $updated_response['data'][0]['type']);
@@ -694,7 +727,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
         'Accept' => 'application/vnd.api+json',
       ],
     ]);
-    $updated_response = Json::decode($response->getBody()->__toString());
+    $updated_response = Json::decode((string) $response->getBody());
     $this->assertEquals(
       'You need to provide a body for DELETE operations on a relationship (field_tags).',
       $updated_response['errors'][0]['detail']
@@ -712,7 +745,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
       'auth' => [$this->user->getUsername(), $this->user->pass_raw],
       'headers' => ['Content-Type' => 'application/vnd.api+json'],
     ]);
-    $updated_response = Json::decode($response->getBody()->__toString());
+    $updated_response = Json::decode((string) $response->getBody());
     $this->assertEquals(201, $response->getStatusCode());
     $this->assertCount(0, $updated_response['data']);
     // 12. PATCH with invalid title and body format.
@@ -738,7 +771,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
         'Accept' => 'application/vnd.api+json',
       ],
     ]);
-    $updated_response = Json::decode($response->getBody()->__toString());
+    $updated_response = Json::decode((string) $response->getBody());
     $this->assertEquals(422, $response->getStatusCode());
     $this->assertCount(2, $updated_response['errors']);
     for ($i = 0; $i < 2; $i++) {
@@ -768,7 +801,7 @@ class JsonApiFunctionalTest extends JsonApiFunctionalTestBase {
         'Accept' => 'application/vnd.api+json',
       ],
     ]);
-    $updated_response = Json::decode($response->getBody()->__toString());
+    $updated_response = Json::decode((string) $response->getBody());
     $this->assertEquals(400, $response->getStatusCode());
     $this->assertEquals("The provided field (field_that_doesnt_exist) does not exist in the entity with ID $uuid.",
       $updated_response['errors']['0']['detail']);
diff --git a/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php b/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
index 6d1afc9..77e3b45 100644
--- a/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
+++ b/tests/src/Kernel/Normalizer/JsonApiDocumentTopLevelNormalizerTest.php
@@ -444,7 +444,7 @@ class JsonApiDocumentTopLevelNormalizerTest extends JsonapiKernelTestBase {
    * @covers ::denormalize
    */
   public function testDenormalize() {
-    $payload = '{"type":"article", "data":{"attributes":{"title":"Testing article"}}}';
+    $payload = '{"data":{"type":"article","attributes":{"title":"Testing article"}}}';
 
     list($request, $resource_type) = $this->generateProphecies('node', 'article', 'id');
     $node = $this
@@ -554,8 +554,8 @@ class JsonApiDocumentTopLevelNormalizerTest extends JsonapiKernelTestBase {
    */
   public function testDenormalizeInvalidTypeAndNoType() {
     $payload_data = [
-      'type' => 'node--article',
       'data' => [
+        'type' => 'node--article',
         'attributes' => [
           'title' => 'Testing article',
           'id' => '33095485-70D2-4E51-A309-535CC5BC0115',
@@ -631,8 +631,8 @@ class JsonApiDocumentTopLevelNormalizerTest extends JsonapiKernelTestBase {
 
     $node = [
       [
-        'type' => 'node--article',
         'data' => [
+          'type' => 'node--article',
           'attributes' => [
             'title' => 'Testing article',
             'id' => '33095485-70D2-4E51-A309-535CC5BC0115',
