diff --git a/src/metabase/models/params.clj b/src/metabase/models/params.clj
index a23c504852c1b4e2a77d7d4f8024070db3c8ee01..f109cac99b6e24bedf34ac59e302170f4bfcd997 100644
--- a/src/metabase/models/params.clj
+++ b/src/metabase/models/params.clj
@@ -21,14 +21,14 @@
   "Receive a Paremeterized Object and check if its parameters is valid."
   [{:keys [parameters]}]
   (when (s/check (s/maybe [su/Parameter]) parameters)
-    (throw (ex-info (tru ":parameters must be a sequence of maps with String :id key")
+    (throw (ex-info (tru ":parameters must be a sequence of maps with :id and :type keys")
                     {:parameters parameters}))))
 
 (defn assert-valid-parameter-mappings
   "Receive a Paremeterized Object and check if its parameters is valid."
   [{:keys [parameter_mappings]}]
   (when (s/check (s/maybe [su/ParameterMapping]) parameter_mappings)
-    (throw (ex-info (tru ":parameter_mappings must be a sequence of maps with String :parameter_id key")
+    (throw (ex-info (tru ":parameter_mappings must be a sequence of maps with :parameter_id and :type keys")
                     {:parameter_mappings parameter_mappings}))))
 
 (s/defn unwrap-field-clause :- mbql.s/field
diff --git a/src/metabase/models/user.clj b/src/metabase/models/user.clj
index 5b73789dbefb47e964698e8b454d65042450a353..ee8e8ed2419390572834d76f190cb9b0dc8d9b7a 100644
--- a/src/metabase/models/user.clj
+++ b/src/metabase/models/user.clj
@@ -348,4 +348,4 @@
        ;; do things like automatically set the `is_superuser` flag for a User
        (doseq [group-id to-add]
          (db/insert! PermissionsGroupMembership {:user_id user-id, :group_id group-id}))))
-      true))
+    true))
diff --git a/src/metabase/util/schema.clj b/src/metabase/util/schema.clj
index 1a3dee65ac93ee903c4c99b45090729763e5fca5..afa7b0f4bf39b10f4a560d40506d70d58bd04ed9 100644
--- a/src/metabase/util/schema.clj
+++ b/src/metabase/util/schema.clj
@@ -329,16 +329,26 @@
     (deferred-tru "value must be a valid JSON string.")))
 
 (def Parameter
-  "Schema for a valid Parameter."
-  (with-api-error-message {:id       NonBlankString
-                           s/Keyword s/Any}
-    (deferred-tru "parameter must be a map with String :id key")))
+  "Schema for a valid Parameter.
+  We're not using [metabase.mbql.schema/Parameter] here because this Parameter is meant to be used for
+  Parameters we store on dashboard/card, and it has some difference with Parameter in MBQL."
+  (with-api-error-message {:id                         NonBlankString
+                           :type                       NonBlankString
+                           ;; Allow blank name and slug #15279
+                           (s/optional-key :name)      s/Str
+                           (s/optional-key :slug)      s/Str
+                           (s/optional-key :default)   s/Any
+                           (s/optional-key :sectionId) NonBlankString
+                           s/Keyword                   s/Any}
+    (deferred-tru "parameter must be a map with :id and :type keys")))
 
 (def ParameterMapping
   "Schema for a valid Parameter Mapping"
-  (with-api-error-message {:parameter_id       NonBlankString
-                           s/Keyword s/Any}
-    (deferred-tru "parameter mapping must be a String :parameter_id key")))
+  (with-api-error-message {:parameter_id             NonBlankString
+                           :target                   s/Any
+                           (s/optional-key :card_id) IntGreaterThanZero
+                           s/Keyword                 s/Any}
+    (deferred-tru "parameter_mapping must be a map with :parameter_id and :target keys")))
 
 (def EmbeddingParams
   "Schema for a valid map of embedding params."
diff --git a/test/metabase/api/card_test.clj b/test/metabase/api/card_test.clj
index 07c373c05345c2fe8ed20995b863f054e98d1aef..8657fc1fbe9c8728e67f0b322140d138ee70d409 100644
--- a/test/metabase/api/card_test.clj
+++ b/test/metabase/api/card_test.clj
@@ -314,7 +314,7 @@
                                                         (mbql-count-query (mt/id) (mt/id :venues)))
                               :collection_id      (u/the-id collection)
                               :parameters         [{:id "abc123", :name "test", :type "date"}]
-                              :parameter_mappings [{:parameter_id "abc123", :card_id "10",
+                              :parameter_mappings [{:parameter_id "abc123", :card_id 10,
                                                     :target [:dimension [:template-tags "category"]]}])]
               (is (= (merge
                       card-defaults
@@ -323,7 +323,7 @@
                        :collection             true
                        :creator_id             (mt/user->id :rasta)
                        :parameters             [{:id "abc123", :name "test", :type "date"}]
-                       :parameter_mappings     [{:parameter_id "abc123", :card_id "10",
+                       :parameter_mappings     [{:parameter_id "abc123", :card_id 10,
                                                  :target ["dimension" ["template-tags" "category"]]}]
                        :dataset_query          true
                        :query_type             "query"
@@ -364,7 +364,7 @@
           (mt/user-http-request :crowberto :post 400 "card" {:visualization_settings "ABC"})))
 
    (is (= {:errors {:parameters (str "value may be nil, or if non-nil, value must be an array. "
-                                     "Each parameter must be a map with String :id key")}}
+                                     "Each parameter must be a map with :id and :type keys")}}
           (mt/user-http-request :crowberto :post 400 "card" {:visualization_settings {:global {:title nil}}
                                                              :parameters             "abc"})))))
 
@@ -804,16 +804,16 @@
   (testing "PUT /api/card/:id"
     (mt/with-temp Card [card]
       (testing "successfully update with valid parameter_mappings"
-        (is (partial= {:parameter_mappings [{:parameter_id "abc123", :card_id "10",
+        (is (partial= {:parameter_mappings [{:parameter_id "abc123", :card_id 10,
                                              :target ["dimension" ["template-tags" "category"]]}]}
                       (mt/user-http-request :rasta :put 202 (str "card/" (u/the-id card))
-                                            {:parameter_mappings [{:parameter_id "abc123", :card_id "10",
+                                            {:parameter_mappings [{:parameter_id "abc123", :card_id 10,
                                                                    :target ["dimension" ["template-tags" "category"]]}]})))))
 
-    (mt/with-temp Card [card {:parameter_mappings [{:parameter_id "abc123", :card_id "10",
+    (mt/with-temp Card [card {:parameter_mappings [{:parameter_id "abc123", :card_id 10,
                                                     :target ["dimension" ["template-tags" "category"]]}]}]
       (testing "nil parameters will no-op"
-        (is (partial= {:parameter_mappings [{:parameter_id "abc123", :card_id "10",
+        (is (partial= {:parameter_mappings [{:parameter_id "abc123", :card_id 10,
                                              :target ["dimension" ["template-tags" "category"]]}]}
                       (mt/user-http-request :rasta :put 202 (str "card/" (u/the-id card))
                                             {:parameters nil}))))
diff --git a/test/metabase/api/dashboard_test.clj b/test/metabase/api/dashboard_test.clj
index c3d24acc593d16edfb94540bc599afab229a4d3a..d7c1ab7b0ef5563b6595e2a4fad991dadaff5c44 100644
--- a/test/metabase/api/dashboard_test.clj
+++ b/test/metabase/api/dashboard_test.clj
@@ -114,7 +114,7 @@
            (mt/user-http-request :rasta :post 400 "dashboard" {})))
 
     (is (= {:errors {:parameters (str "value may be nil, or if non-nil, value must be an array. "
-                                      "Each parameter must be a map with String :id key")}}
+                                      "Each parameter must be a map with :id and :type keys")}}
            (mt/user-http-request :crowberto :post 400 "dashboard" {:name       "Test"
                                                                    :parameters "abc"})))))
 
diff --git a/test/metabase/api/embed_test.clj b/test/metabase/api/embed_test.clj
index a20143580c1511bdab318daa9761e74677c39d7e..702cbdcd22aa26aa9729ead1e2f7426cb5dfee4f 100644
--- a/test/metabase/api/embed_test.clj
+++ b/test/metabase/api/embed_test.clj
@@ -1126,7 +1126,7 @@
                                                                           :parameters       [{:name      "Name"
                                                                                               :slug      "name"
                                                                                               :id        "_name_"
-                                                                                              :type      :string/=
+                                                                                              :type      "string/="
                                                                                               :sectionId "string"}]}]
 
                             DashboardCard [{dashcard-id :id, :as dashcard} {:card_id            card-id
diff --git a/test/metabase/api/preview_embed_test.clj b/test/metabase/api/preview_embed_test.clj
index 473e48fbd75a15966822a154428d53eeb32a03d6..b15b8805aaf0e33b4fea661759ce0a7f61e9941e 100644
--- a/test/metabase/api/preview_embed_test.clj
+++ b/test/metabase/api/preview_embed_test.clj
@@ -307,10 +307,12 @@
       (embed-test/with-temp-dashcard [dashcard {:dash {:enable_embedding true
                                                        :parameters       [{:id   "_SECOND_DATE_SEEN_"
                                                                            :slug "2nd_date_seen"
-                                                                           :name "Second Date Seen"}
+                                                                           :name "Second Date Seen"
+                                                                           :type "date"}
                                                                           {:id   "_NUM_BIRDS_"
                                                                            :slug "num_birds"
-                                                                           :name "Number of Birds"}]}}]
+                                                                           :name "Number of Birds"
+                                                                           :type "number"}]}}]
         (is (schema= {:status   (s/eq "completed")
                       s/Keyword s/Any}
                      (mt/user-http-request :crowberto :get 202 (str (dashcard-url dashcard
@@ -470,13 +472,14 @@
                                                                           :parameters       [{:name      "Name"
                                                                                               :slug      "name"
                                                                                               :id        "_name_"
-                                                                                              :type      :string/=
+                                                                                              :type      "string/="
                                                                                               :sectionId "string"}]}]
 
                             DashboardCard [{dashcard-id :id, :as dashcard} {:card_id            card-id
                                                                             :dashboard_id       dashboard-id
                                                                             :parameter_mappings [{:parameter_id "_name_"
                                                                                                   :card_id      card-id
+                                                                                                  :type         "string/="
                                                                                                   :target       [:dimension [:template-tag "NAME"]]}]}]]
               (let [url (dashcard-url dashcard {:_embedding_params {:name "enabled"}})]
                 (is (= [[1]]
diff --git a/test/metabase/api/pulse_test.clj b/test/metabase/api/pulse_test.clj
index 43f15331f5645e3daac98b0364e698cb8aad6824..8a97e676095bd0e4b956bd2348a2fae678cd4e8f 100644
--- a/test/metabase/api/pulse_test.clj
+++ b/test/metabase/api/pulse_test.clj
@@ -892,7 +892,7 @@
                     Dashboard [{dashboard-id :id} {:parameters [{:name    "X"
                                                                  :slug    "x"
                                                                  :id      "__X__"
-                                                                 :type    :category
+                                                                 :type    "category"
                                                                  :default 3}]}]
                     DashboardCard [_ {:card_id            card-id
                                       :dashboard_id       dashboard-id
diff --git a/test/metabase/dashboard_subscription_test.clj b/test/metabase/dashboard_subscription_test.clj
index 291a82f50286989caffc4889da73352bc9c1d6cd..59d33ce1e01eabba264f9e67ebc9fd979b45f5bf 100644
--- a/test/metabase/dashboard_subscription_test.clj
+++ b/test/metabase/dashboard_subscription_test.clj
@@ -375,12 +375,12 @@
                                                                   :parameters [{:name    "Category"
                                                                                 :slug    "category"
                                                                                 :id      "_MBQL_CATEGORY_"
-                                                                                :type    :category
+                                                                                :type    "category"
                                                                                 :default ["Doohickey"]}
                                                                                {:name    "SQL Category"
                                                                                 :slug    "sql_category"
                                                                                 :id      "_SQL_CATEGORY_"
-                                                                                :type    :category
+                                                                                :type    "category"
                                                                                 :default ["Gizmo"]}]}]
         (testing "MBQL query"
           (mt/with-temp* [Card [{mbql-card-id :id} {:name          "Orders"
diff --git a/test/metabase/models/card_test.clj b/test/metabase/models/card_test.clj
index f5a61e90351b815f481acf2cff329196c5211a62..40d980f128fd27dcd9003e7657a32375ceeb7c7b 100644
--- a/test/metabase/models/card_test.clj
+++ b/test/metabase/models/card_test.clj
@@ -300,56 +300,55 @@
     (testing "creating"
       (is (thrown-with-msg?
            clojure.lang.ExceptionInfo
-           #":parameters must be a sequence of maps with String :id key"
+           #":parameters must be a sequence of maps with :id and :type keys"
            (mt/with-temp Card [_ {:parameters {:a :b}}])))
 
-     (mt/with-temp Card [card {:parameters [{:id "valid-id"}]}]
+     (mt/with-temp Card [card {:parameters [{:id   "valid-id"
+                                             :type "id"}]}]
        (is (some? card))))
 
     (testing "updating"
-      (mt/with-temp Card [{:keys [id]} {:parameters []}]
+      (mt/with-temp Card [{:keys [id] :as card} {:parameters []}]
         (is (thrown-with-msg?
              clojure.lang.ExceptionInfo
-             #":parameters must be a sequence of maps with String :id key"
+             #":parameters must be a sequence of maps with :id and :type keys"
              (db/update! Card id :parameters [{:id 100}])))
-        (is (some? (db/update! Card id :parameters [{:id "new-valid-id"}])))))))
+        (is (some? (db/update! Card id :parameters [{:id   "new-valid-id"
+                                                     :type "id"}])))))))
 
 (deftest normalize-parameters-test
   (testing ":parameters should get normalized when coming out of the DB"
     (doseq [[target expected] {[:dimension [:field-id 1000]] [:dimension [:field 1000 nil]]
                                [:field-id 1000]              [:field 1000 nil]}]
       (testing (format "target = %s" (pr-str target))
-        (mt/with-temp Card [{card-id :id} {:parameters [{:name   "Category Name"
-                                                         :slug   "category_name"
-                                                         :id     "_CATEGORY_NAME_"
-                                                         :type   "category"
-                                                         :target target}]}]
-          (is (= [{:name   "Category Name"
-                   :slug   "category_name"
-                   :id     "_CATEGORY_NAME_"
-                   :type   :category
+        (mt/with-temp Card [{card-id :id} {:parameter_mappings [{:parameter_id     "_CATEGORY_NAME_"
+                                                                 :target target}]}]
+
+          (is (= [{:parameter_id     "_CATEGORY_NAME_"
                    :target expected}]
-                 (db/select-one-field :parameters Card :id card-id))))))))
+                 (db/select-one-field :parameter_mappings Card :id card-id))))))))
 
 (deftest validate-parameter-mappings-test
   (testing "Should validate Card :parameter_mappings when"
     (testing "creating"
       (is (thrown-with-msg?
            clojure.lang.ExceptionInfo
-           #":parameter_mappings must be a sequence of maps with String :parameter_id key"
+           #":parameter_mappings must be a sequence of maps with :parameter_id and :type keys"
            (mt/with-temp Card [_ {:parameter_mappings {:a :b}}])))
 
-     (mt/with-temp Card [card {:parameter_mappings [{:parameter_id "valid-id"}]}]
+     (mt/with-temp Card [card {:parameter_mappings [{:parameter_id "valid-id"
+                                                     :target       [:field-id 1000]}]}]
        (is (some? card))))
 
     (testing "updating"
       (mt/with-temp Card [{:keys [id]} {:parameter_mappings []}]
         (is (thrown-with-msg?
              clojure.lang.ExceptionInfo
-             #":parameter_mappings must be a sequence of maps with String :parameter_id key"
+             #":parameter_mappings must be a sequence of maps with :parameter_id and :type keys"
              (db/update! Card id :parameter_mappings [{:parameter_id 100}])))
 
-        (is (some? (db/update! Card id :parameter_mappings [{:parameter_id "new-valid-id"}])))))))
+        (is (some? (db/update! Card id :parameter_mappings [{:parameter_id "new-valid-id"
+                                                             :target       [:field-id 1000]}])))))))
 
 (deftest normalize-parameter-mappings-test
   (testing ":parameter_mappings should get normalized when coming out of the DB"
diff --git a/test/metabase/models/dashboard_test.clj b/test/metabase/models/dashboard_test.clj
index 4a473f1894f1829113a48e413a0b367d1fab15ad..4da09a3ad1ba7a9ced2cb70e7ddc84639e14d5b5 100644
--- a/test/metabase/models/dashboard_test.clj
+++ b/test/metabase/models/dashboard_test.clj
@@ -283,13 +283,13 @@
     (testing "creating"
       (is (thrown-with-msg?
            clojure.lang.ExceptionInfo
-           #":parameters must be a sequence of maps with String :id key"
+           #":parameters must be a sequence of maps with :id and :type keys"
            (mt/with-temp Dashboard [_ {:parameters {:a :b}}]))))
     (testing "updating"
       (mt/with-temp Dashboard [{:keys [id]} {:parameters []}]
         (is (thrown-with-msg?
              clojure.lang.ExceptionInfo
-             #":parameters must be a sequence of maps with String :id key"
+             #":parameters must be a sequence of maps with :id and :type keys"
              (db/update! Dashboard id :parameters [{:id 100}])))))))
 
 (deftest normalize-parameters-test
diff --git a/test/metabase/query_processor/card_test.clj b/test/metabase/query_processor/card_test.clj
index 0df68c1a2d6817f42fa81e07b9f5b0ae1b37937b..0de72127d9f8613191d5d3e02ec04b3947ca650c 100644
--- a/test/metabase/query_processor/card_test.clj
+++ b/test/metabase/query_processor/card_test.clj
@@ -171,7 +171,7 @@
 (deftest validate-card-parameters-test
   (mt/with-temp Card [{card-id :id} {:dataset_query (mt/mbql-query checkins {:aggregation [[:count]]})
                                      :parameters [{:id   "_DATE_"
-                                                   :type :date/single
+                                                   :type "date/single"
                                                    :name "Date"
                                                    :slug "DATE"}]}]
     (testing "API request should fail if request parameter does not contain ID"
@@ -181,7 +181,7 @@
                     s/Keyword           s/Any}
                    (mt/user-http-request :rasta :post (format "card/%d/query" card-id)
                                          {:parameters [{:name  "date"
-                                                        :type  :date/single
+                                                        :type  "date/single"
                                                         :value "2016-01-01"}]}))))
 
     (testing "API request should fail if request parameter ID does not exist on the card"
@@ -192,12 +192,12 @@
                    (mt/user-http-request :rasta :post (format "card/%d/query" card-id)
                                          {:parameters [{:id    "_FAKE_"
                                                         :name  "date"
-                                                        :type  :date/single
+                                                        :type  "date/single"
                                                         :value "2016-01-01"}]}))))
 
     (testing "Happy path -- API request should succeed if request parameter correlates to a card parameter by ID"
       (is (= [1000]
              (mt/first-row (mt/user-http-request :rasta :post (format "card/%d/query" card-id)
                                                  {:parameters [{:id    "_DATE_"
-                                                                :type  :date/single
+                                                                :type  "date/single"
                                                                 :value "2016-01-01"}]})))))))
diff --git a/test/metabase/query_processor/dashboard_test.clj b/test/metabase/query_processor/dashboard_test.clj
index c1efbe9b432bf45b30a0bd6a3d71b42bc041e7ca..85d1ea23fabbf70b3277df10e40c2500715fdc64 100644
--- a/test/metabase/query_processor/dashboard_test.clj
+++ b/test/metabase/query_processor/dashboard_test.clj
@@ -68,7 +68,7 @@
                       Dashboard [{dashboard-id :id} {:parameters [{:name    "category"
                                                                    :slug    "category"
                                                                    :id      "abc123"
-                                                                   :type    :string/=
+                                                                   :type    "string/="
                                                                    :default ["Widget"]}]}]
                       DashboardCard [{dashcard-id :id} {:dashboard_id       dashboard-id
                                                         :card_id            card-id
@@ -99,13 +99,13 @@
                                                                        {:id           "f0774ef5-a14a-e181-f557-2d4bb1fc94ae"
                                                                         :name         "filter"
                                                                         :display-name "Filter"
-                                                                        :type         :text
+                                                                        :type         "text"
                                                                         :required     true
                                                                         :default      "Foo"}}}}}]
                       Dashboard [{dashboard-id :id} {:parameters [{:name    "Text"
                                                                    :slug    "text"
                                                                    :id      "5791ff38"
-                                                                   :type    :string/=
+                                                                   :type    "string/="
                                                                    :default "Bar"}]}]
                       DashboardCard [{dashcard-id :id} {:dashboard_id       dashboard-id
                                                         :card_id            card-id
@@ -133,11 +133,11 @@
                       Dashboard [{dashboard-id :id} {:parameters [{:name "Category (DashCard 1)"
                                                                    :slug "category_1"
                                                                    :id   "CATEGORY_1"
-                                                                   :type :string/=}
+                                                                   :type "string/="}
                                                                   {:name    "Category (DashCard 2)"
                                                                    :slug    "category_2"
                                                                    :id      "CATEGORY_2"
-                                                                   :type    :string/=}]}]
+                                                                   :type    "string/="}]}]
                       DashboardCard [{dashcard-1-id :id} {:card_id            card-id
                                                           :dashboard_id       dashboard-id
                                                           :parameter_mappings [{:parameter_id "CATEGORY_1"
@@ -187,7 +187,7 @@
                         Dashboard     [{dashboard-id :id} {:parameters [{:name      "Text"
                                                                          :slug      "text"
                                                                          :id        "_text_"
-                                                                         :type      :string/=
+                                                                         :type      "string/="
                                                                          :sectionId "string"
                                                                          :default   ["Doohickey"]}]}]
                         DashboardCard [{dashcard-id :id} {:parameter_mappings     [{:parameter_id "_text_"
@@ -211,7 +211,7 @@
                                                      :parameters [{:name    "Category"
                                                                    :slug    "category"
                                                                    :id      "_CATEGORY_"
-                                                                   :type    :category
+                                                                   :type    "category"
                                                                    :default ["Doohickey"]}]}]
                       DashboardCard [{dashcard-id :id} {:parameter_mappings [{:parameter_id "_CATEGORY_"
                                                                               :card_id      card-id
@@ -232,5 +232,5 @@
                                           :parameters [{:name    "Category"
                                                         :slug    "category"
                                                         :id      "_CATEGORY_"
-                                                        :type    :category
+                                                        :type    "category"
                                                         :default ["Gizmo"]}])))))))))