diff --git a/resources/migrations/037_add_card_parameters_column.yaml b/resources/migrations/037_add_card_parameters_column.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e3632403b213150bdb1f637e71c934fd43b39d66
--- /dev/null
+++ b/resources/migrations/037_add_card_parameters_column.yaml
@@ -0,0 +1,20 @@
+databaseChangeLog:
+  - changeSet:
+      id: 37
+      author: agilliland
+      changes:
+        - addColumn:
+            tableName: report_card
+            columns:
+              - column:
+                  name: parameters
+                  type: text
+                  constraints:
+                    nullable: true
+                    deferrable: false
+                    initiallyDeferred: false
+        - addNotNullConstraint:
+            columnDataType: text
+            columnName: parameters
+            defaultNullValue: '[]'
+            tableName: report_card
diff --git a/resources/migrations/liquibase.json b/resources/migrations/liquibase.json
index 2ed788d166dacfcefb7a2a2a9861001a7d9c709e..83948e5af39e64296694e525a20cb5a9a35744f8 100644
--- a/resources/migrations/liquibase.json
+++ b/resources/migrations/liquibase.json
@@ -34,6 +34,7 @@
       {"include": {"file": "migrations/033_add_physical_schema_tables.yaml"}},
       {"include": {"file": "migrations/034_add_pulse_channel_enabled_field.yaml"}},
       {"include": {"file": "migrations/035_modify_setting_value_length.yaml"}},
-      {"include": {"file": "migrations/036_add_dashboard_filters_columns.yaml"}}
+      {"include": {"file": "migrations/036_add_dashboard_filters_columns.yaml"}},
+      {"include": {"file": "migrations/037_add_card_parameters_column.yaml"}}
   ]
 }
diff --git a/src/metabase/api/card.clj b/src/metabase/api/card.clj
index e2ea51fceb4948e5621fd09697ab6bed2ecc8c24..d13fda5c564bcbe92e38e25b834ed1f68d6db6b7 100644
--- a/src/metabase/api/card.clj
+++ b/src/metabase/api/card.clj
@@ -144,19 +144,14 @@
 
 (defendpoint POST "/"
   "Create a new `Card`."
-  [:as {{:keys [dataset_query description display name public_perms visualization_settings]} :body}]
-  {name         [Required NonEmptyString]
-   public_perms [Required PublicPerms]
-   display      [Required NonEmptyString]}
-  (->> (db/insert! Card
-         :creator_id             *current-user-id*
-         :dataset_query          dataset_query
-         :description            description
-         :display                display
-         :name                   name
-         :public_perms           public_perms
-         :visualization_settings visualization_settings)
-       (events/publish-event :card-create)))
+  [:as {{:keys [dataset_query display name parameters public_perms visualization_settings], :as body} :body}]
+  {dataset_query          [Required Dict]
+   display                [Required NonEmptyString]
+   name                   [Required NonEmptyString]
+   parameters             [Required ArrayOfMaps]
+   public_perms           [Required PublicPerms]
+   visualization_settings [Required Dict]}
+  (card/create-card body *current-user-id*))
 
 (defendpoint GET "/:id"
   "Get `Card` with ID."
@@ -170,32 +165,25 @@
 
 (defendpoint PUT "/:id"
   "Update a `Card`."
-  [id :as {{:keys [dataset_query description display name public_perms visualization_settings archived], :as body} :body}]
-  {name                   NonEmptyString
-   public_perms           PublicPerms
-   display                NonEmptyString
-   visualization_settings Dict
-   archived               Boolean}
+  [id :as {{:keys [archived dataset_query display name parameters public_perms visualization_settings], :as body} :body}]
+  {archived               [Boolean]
+   dataset_query          [Required Dict]
+   display                [Required NonEmptyString]
+   name                   [Required NonEmptyString]
+   parameters             [Required ArrayOfMaps]
+   public_perms           [Required PublicPerms]
+   visualization_settings [Required Dict]}
   (let-404 [card (Card id)]
     (write-check card)
-    (db/update-non-nil-keys! Card id
-      :dataset_query          dataset_query
-      :description            description
-      :display                display
-      :name                   name
-      :public_perms           public_perms
-      :visualization_settings visualization_settings
-      :archived               archived)
-    (let [event (cond
-                  ;; card was archived
-                  (and archived
-                       (not (:archived card))) :card-archive
-                  ;; card was unarchived
-                  (and (not (nil? archived))
-                       (not archived)
-                       (:archived card))       :card-unarchive
-                  :else                        :card-update)]
-      (events/publish-event event (assoc (Card id) :actor_id *current-user-id*)))))
+    (cond
+      ;; card is being archived
+      (and archived
+           (not (:archived card))) (card/archive-card id *current-user-id*)
+      ;; card is being unarchived
+      (and (not (nil? archived))
+           (not archived)
+           (:archived card))       (card/unarchive-card id *current-user-id*)
+      :else                        (card/update-card body *current-user-id*))))
 
 (defendpoint DELETE "/:id"
   "Delete a `Card`."
diff --git a/src/metabase/models/card.clj b/src/metabase/models/card.clj
index 987c036823cdef47d970ca484d7711135f476b72..a3b66f8e546c943612e7f800d866342f9d2aece6 100644
--- a/src/metabase/models/card.clj
+++ b/src/metabase/models/card.clj
@@ -1,6 +1,7 @@
 (ns metabase.models.card
   (:require [medley.core :as m]
             [metabase.db :as db]
+            [metabase.events :as events]
             (metabase.models [card-label :refer [CardLabel]]
                              [dependency :as dependency]
                              [interface :as i]
@@ -45,6 +46,62 @@
   (db/cascade-delete! 'CardLabel :card_id id))
 
 
+;;; ## ---------------------------------------- PERSISTENCE FUNCTIONS ----------------------------------------
+
+
+(defn create-card
+  "Create a `Card`"
+  [{:keys [dataset_query description display name parameters public_perms visualization_settings], :as card} user-id]
+  {:pre [(map? card)
+         (u/nil-or-sequence-of-maps? parameters)
+         (integer? user-id)]}
+  (->> (db/insert! Card
+         :creator_id             user-id
+         :dataset_query          dataset_query
+         :description            description
+         :display                display
+         :name                   name
+         :public_perms           public_perms
+         :visualization_settings visualization_settings)
+       (events/publish-event :card-create)))
+
+(defn update-card
+  "Update a `Card`"
+  [{:keys [dataset_query description display id name parameters public_perms visualization_settings], :as card} user-id]
+  {:pre [(map? card)
+         (integer? id)
+         (u/nil-or-sequence-of-maps? parameters)
+         (integer? user-id)]}
+  (db/update-non-nil-keys! Card id
+    :dataset_query          dataset_query
+    :description            description
+    :display                display
+    :name                   name
+    :parameters             parameters
+    :public_perms           public_perms
+    :visualization_settings visualization_settings)
+  (u/prog1 (Card id)
+    (events/publish-event :card-update (assoc <> :actor_id user-id))))
+
+(defn archive-card
+  "Archive a `Card`"
+  [card-id user-id]
+  {:pre [(integer? card-id)
+         (integer? user-id)]}
+  (db/update! Card card-id :archived true)
+  (u/prog1 (Card card-id)
+    (events/publish-event :card-archive (assoc <> :actor_id user-id))))
+
+(defn unarchive-card
+  "Unarchive a `Card`"
+  [card-id user-id]
+  {:pre [(integer? card-id)
+         (integer? user-id)]}
+  (db/update! Card card-id :archived false)
+  (u/prog1 (Card card-id)
+    (events/publish-event :card-unarchive (assoc <> :actor_id user-id))))
+
+
 ;;; ## ---------------------------------------- REVISIONS ----------------------------------------
 
 
@@ -71,7 +128,12 @@
   i/IEntity
   (merge i/IEntityDefaults
          {:hydration-keys     (constantly [:card])
-          :types              (constantly {:display :keyword, :query_type :keyword, :dataset_query :json, :visualization_settings :json, :description :clob})
+          :types              (constantly {:description            :clob
+                                           :display                :keyword
+                                           :dataset_query          :json
+                                           :parameters             :json
+                                           :query_type             :keyword
+                                           :visualization_settings :json})
           :timestamped?       (constantly true)
           :can-read?          i/publicly-readable?
           :can-write?         i/publicly-writeable?