diff --git a/request.go b/request.go
index a7bb0b1..037de88 100644
--- a/request.go
+++ b/request.go
@@ -393,6 +393,11 @@ func unmarshalAttribute(
 		return
 	}
 
+	// Handle field of type json.RawMessage
+	if fieldValue.Type() == reflect.TypeOf(json.RawMessage{}) {
+		value, err = handleJSONRawMessage(attribute)
+	}
+
 	// Handle field of type time.Time
 	if fieldValue.Type() == reflect.TypeOf(time.Time{}) ||
 		fieldValue.Type() == reflect.TypeOf(new(time.Time)) {
@@ -444,6 +449,14 @@ func handleStringSlice(attribute interface{}) (reflect.Value, error) {
 	return reflect.ValueOf(values), nil
 }
 
+func handleJSONRawMessage(attribute interface{}) (reflect.Value, error) {
+	tmp, err := json.Marshal(attribute)
+	if err != nil {
+		return reflect.Value{}, err
+	}
+	return reflect.ValueOf(json.RawMessage(tmp)), nil
+}
+
 func handleTime(attribute interface{}, args []string, fieldValue reflect.Value) (reflect.Value, error) {
 	var isIso8601 bool
 	v := reflect.ValueOf(attribute)
@@ -591,7 +604,19 @@ func handlePointer(
 func handleStruct(
 	attribute interface{},
 	fieldValue reflect.Value) (reflect.Value, error) {
-
+	if fieldValue.CanAddr() {
+		interf := fieldValue.Addr().Interface()
+		if _, ok := interf.(json.Unmarshaler); ok {
+			var tmp []byte
+			tmp, err := json.Marshal(attribute)
+			if err == nil {
+				err = json.Unmarshal(tmp, interf)
+				if err == nil {
+					return reflect.ValueOf(interf), nil
+				}
+			}
+		}
+	}
 	data, err := json.Marshal(attribute)
 	if err != nil {
 		return reflect.Value{}, err
diff --git a/request_test.go b/request_test.go
index 3326598..cdd096c 100644
--- a/request_test.go
+++ b/request_test.go
@@ -1306,3 +1306,75 @@ func TestUnmarshalNestedStructSlice(t *testing.T) {
 			out.Teams[0].Members[0].Firstname)
 	}
 }
+
+type MyCustomAttribute struct {
+	Field string
+}
+
+func (mca MyCustomAttribute) MarshalJSON() ([]byte, error) {
+	return json.Marshal(mca.Field)
+}
+func (mca *MyCustomAttribute) UnmarshalJSON(bts []byte) error {
+	return json.Unmarshal(bts, &mca.Field)
+}
+
+type StructForTest struct {
+	ID     string            `jsonapi:"primary,tests"`
+	Custom MyCustomAttribute `jsonapi:"attr,custom,omitempty"`
+	Raw    json.RawMessage   `jsonapi:"attr,raw,omitempty"`
+}
+
+func TestUnmarshalWithCustomType(t *testing.T) {
+	sft := &StructForTest{
+		ID: "my-id",
+		Custom: MyCustomAttribute{
+			Field: "a-string",
+		},
+	}
+	buf := new(bytes.Buffer)
+	err := MarshalPayload(buf, sft)
+	if err != nil {
+		t.Fatal(err)
+	}
+	newSft := &StructForTest{}
+	err = UnmarshalPayload(buf, newSft)
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if sft.Custom.Field != newSft.Custom.Field {
+		t.Fatalf("Custom type wasn't properly unmarshalled: Expected to have `%s` but got `%s`",
+			sft.Custom.Field, newSft.Custom.Field)
+	}
+}
+
+func TestUnmarshalWithJSONRawMessage(t *testing.T) {
+	tests := [][]byte{
+		[]byte(`{"really":{"deep":true},"test":"toast"}`),
+		[]byte(`"just a string"`),
+		[]byte(`123`),
+	}
+	for _, v := range tests {
+		sft := &StructForTest{
+			ID:  "my-id",
+			Raw: v,
+		}
+		buf := new(bytes.Buffer)
+		err := MarshalPayload(buf, sft)
+		if err != nil {
+			t.Fatal(err)
+		}
+		newSft := &StructForTest{}
+		err = UnmarshalPayload(buf, newSft)
+
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		if bytes.Compare(sft.Raw, newSft.Raw) != 0 {
+			t.Fatalf("json.RawMessage wasn't properly unmarshalled: Expected to have `%s` but got `%s`",
+				string(sft.Raw), string(newSft.Raw))
+		}
+	}
+}