diff --git a/src/JsonApiDotNetCore/Builders/ContextGraphBuilder.cs b/src/JsonApiDotNetCore/Builders/ContextGraphBuilder.cs
index ca6caad1f8..923ca074e5 100644
--- a/src/JsonApiDotNetCore/Builders/ContextGraphBuilder.cs
+++ b/src/JsonApiDotNetCore/Builders/ContextGraphBuilder.cs
@@ -139,6 +139,18 @@ protected virtual List<AttrAttribute> GetAttributes(Type entityType)
 
             foreach (var prop in properties)
             {
+                if (prop.Name == nameof(Identifiable.Id))
+                {
+                    var idAttr = new AttrAttribute()
+                    {
+                        PublicAttributeName = JsonApiOptions.ResourceNameFormatter.FormatPropertyName(prop),
+                        PropertyInfo = prop,
+                        InternalAttributeName = prop.Name
+                    };
+                    attributes.Add(idAttr);
+                    continue;
+                }
+
                 var attribute = (AttrAttribute)prop.GetCustomAttribute(typeof(AttrAttribute));
                 if (attribute == null)
                     continue;
diff --git a/src/JsonApiDotNetCore/Builders/DocumentBuilder.cs b/src/JsonApiDotNetCore/Builders/DocumentBuilder.cs
index 82c3d2ec75..5261140e5d 100644
--- a/src/JsonApiDotNetCore/Builders/DocumentBuilder.cs
+++ b/src/JsonApiDotNetCore/Builders/DocumentBuilder.cs
@@ -141,6 +141,7 @@ public ResourceObject GetData(ContextEntity contextEntity, IIdentifiable entity,
         private bool ShouldIncludeAttribute(AttrAttribute attr, object attributeValue)
         {
             return OmitNullValuedAttribute(attr, attributeValue) == false
+                    && attr.InternalAttributeName != nameof(Identifiable.Id)
                    && ((_jsonApiContext.QuerySet == null
                        || _jsonApiContext.QuerySet.Fields.Count == 0)
                        || _jsonApiContext.QuerySet.Fields.Contains(attr.InternalAttributeName));
@@ -280,10 +281,13 @@ private ResourceObject GetIncludedEntity(IIdentifiable entity)
 
             data.Attributes = new Dictionary<string, object>();
 
-            contextEntity.Attributes.ForEach(attr =>
+            foreach(var attr in contextEntity.Attributes)
             {
+                if (attr.InternalAttributeName == nameof(Identifiable.Id))
+                    continue;
+
                 data.Attributes.Add(attr.PublicAttributeName, attr.GetValue(entity));
-            });
+            }
 
             return data;
         }
diff --git a/test/JsonApiDotNetCoreExampleTests/Acceptance/TodoItemsControllerTests.cs b/test/JsonApiDotNetCoreExampleTests/Acceptance/TodoItemsControllerTests.cs
index 618db7dd10..69bcccb2a2 100644
--- a/test/JsonApiDotNetCoreExampleTests/Acceptance/TodoItemsControllerTests.cs
+++ b/test/JsonApiDotNetCoreExampleTests/Acceptance/TodoItemsControllerTests.cs
@@ -69,6 +69,54 @@ public async Task Can_Get_TodoItems()
             Assert.True(deserializedBody.Count <= expectedEntitiesPerPage);
         }
 
+        [Fact]
+        public async Task Can_Filter_By_Resource_Id()
+        {
+            // Arrange
+            var todoItem = _todoItemFaker.Generate();
+            _context.TodoItems.Add(todoItem);
+            _context.SaveChanges();
+
+            var httpMethod = new HttpMethod("GET");
+            var route = $"/api/v1/todo-items?filter[id]={todoItem.Id}";
+            var request = new HttpRequestMessage(httpMethod, route);
+
+            // Act
+            var response = await _fixture.Client.SendAsync(request);
+            var body = await response.Content.ReadAsStringAsync();
+            var deserializedBody = _fixture.GetService<IJsonApiDeSerializer>().DeserializeList<TodoItem>(body);
+
+            // Assert
+            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+            Assert.NotEmpty(deserializedBody);
+            Assert.Contains(deserializedBody, (i) => i.Id == todoItem.Id);
+        }
+
+        [Fact]
+        public async Task Can_Filter_By_Relationship_Id()
+        {
+            // Arrange
+            var person = new Person();           
+            var todoItem = _todoItemFaker.Generate();
+            todoItem.Owner = person;
+            _context.TodoItems.Add(todoItem);
+            _context.SaveChanges();
+
+            var httpMethod = new HttpMethod("GET");
+            var route = $"/api/v1/todo-items?filter[owner.id]={person.Id}";
+            var request = new HttpRequestMessage(httpMethod, route);
+
+            // Act
+            var response = await _fixture.Client.SendAsync(request);
+            var body = await response.Content.ReadAsStringAsync();
+            var deserializedBody = _fixture.GetService<IJsonApiDeSerializer>().DeserializeList<TodoItem>(body);
+
+            // Assert
+            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+            Assert.NotEmpty(deserializedBody);
+            Assert.Contains(deserializedBody, (i) => i.OwnerId == person.Id);
+        }
+
         [Fact]
         public async Task Can_Filter_TodoItems()
         {
diff --git a/test/UnitTests/Builders/ContextGraphBuilder_Tests.cs b/test/UnitTests/Builders/ContextGraphBuilder_Tests.cs
index eab003309f..a88ecceb67 100644
--- a/test/UnitTests/Builders/ContextGraphBuilder_Tests.cs
+++ b/test/UnitTests/Builders/ContextGraphBuilder_Tests.cs
@@ -94,7 +94,7 @@ public void Attrs_Without_Names_Specified_Will_Use_Default_Formatter()
 
             // assert
             var resource = graph.GetContextEntity(typeof(TestResource));
-            Assert.Equal("compound-attribute", resource.Attributes.Single().PublicAttributeName);
+            Assert.Contains(resource.Attributes, (i) => i.PublicAttributeName == "compound-attribute");
         }
 
         [Fact]
@@ -110,7 +110,7 @@ public void Attrs_Without_Names_Specified_Will_Use_Configured_Formatter()
 
             // assert
             var resource = graph.GetContextEntity(typeof(TestResource));
-            Assert.Equal("compoundAttribute", resource.Attributes.Single().PublicAttributeName);
+            Assert.Contains(resource.Attributes, (i) => i.PublicAttributeName == "compoundAttribute");
         }
 
         [Fact]