diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp
index fc045f6..58ab1c9 100644
--- a/redfish-core/include/utils/telemetry_utils.hpp
+++ b/redfish-core/include/utils/telemetry_utils.hpp
@@ -34,6 +34,25 @@
     return {triggersPath / id};
 }
 
+inline std::optional<std::string>
+    getTriggerIdFromDbusPath(const std::string& dbusPath)
+{
+    sdbusplus::message::object_path converted(dbusPath);
+
+    if (converted.parent_path() !=
+        "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService")
+    {
+        return std::nullopt;
+    }
+
+    const std::string& id = converted.filename();
+    if (id.empty())
+    {
+        return std::nullopt;
+    }
+    return id;
+}
+
 struct IncorrectMetricUri
 {
     std::string uri;
diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp
index 6a03b7f..fdd86d4 100644
--- a/redfish-core/lib/metric_report_definition.hpp
+++ b/redfish-core/lib/metric_report_definition.hpp
@@ -743,6 +743,44 @@
 };
 } // namespace telemetry
 
+inline void handleMetricReportDelete(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
+
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+
+    const std::string reportPath = telemetry::getDbusReportPath(id);
+
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, id](const boost::system::error_code& ec) {
+        /*
+         * boost::system::errc and std::errc are missing value
+         * for EBADR error that is defined in Linux.
+         */
+        if (ec.value() == EBADR)
+        {
+            messages::resourceNotFound(asyncResp->res, "MetricReportDefinition",
+                                       id);
+            return;
+        }
+
+        if (ec)
+        {
+            BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
+            messages::internalError(asyncResp->res);
+            return;
+        }
+
+        asyncResp->res.result(boost::beast::http::status::no_content);
+        },
+        telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete",
+        "Delete");
+}
+
 inline void requestRoutesMetricReportDefinitionCollection(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
@@ -859,42 +897,6 @@
                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
         .privileges(redfish::privileges::deleteMetricReportDefinitionCollection)
         .methods(boost::beast::http::verb::delete_)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& id)
-
-            {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-
-        const std::string reportPath = telemetry::getDbusReportPath(id);
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, id](const boost::system::error_code& ec) {
-            /*
-             * boost::system::errc and std::errc are missing value
-             * for EBADR error that is defined in Linux.
-             */
-            if (ec.value() == EBADR)
-            {
-                messages::resourceNotFound(asyncResp->res,
-                                           "MetricReportDefinition", id);
-                return;
-            }
-
-            if (ec)
-            {
-                BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            asyncResp->res.result(boost::beast::http::status::no_content);
-            },
-            telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete",
-            "Delete");
-        });
+            std::bind_front(handleMetricReportDelete, std::ref(app)));
 }
 } // namespace redfish
diff --git a/redfish-core/lib/trigger.hpp b/redfish-core/lib/trigger.hpp
index 68d6dd2..33e3bde 100644
--- a/redfish-core/lib/trigger.hpp
+++ b/redfish-core/lib/trigger.hpp
@@ -1,8 +1,12 @@
 #pragma once
 
 #include "app.hpp"
+#include "generated/enums/resource.hpp"
+#include "generated/enums/triggers.hpp"
 #include "query.hpp"
 #include "registries/privilege_registry.hpp"
+#include "sensors.hpp"
+#include "utility.hpp"
 #include "utils/collection.hpp"
 #include "utils/dbus_utils.hpp"
 #include "utils/telemetry_utils.hpp"
@@ -31,6 +35,10 @@
 using DiscreteThresholdParams =
     std::tuple<std::string, std::string, uint64_t, std::string>;
 
+using TriggerThresholdParams =
+    std::variant<std::vector<NumericThresholdParams>,
+                 std::vector<DiscreteThresholdParams>>;
+
 using TriggerThresholdParamsExt =
     std::variant<std::monostate, std::vector<NumericThresholdParams>,
                  std::vector<DiscreteThresholdParams>>;
@@ -43,48 +51,676 @@
                  TriggerSensorsParams, std::vector<std::string>,
                  std::vector<sdbusplus::message::object_path>>;
 
-inline std::optional<std::string>
-    getRedfishFromDbusAction(const std::string& dbusAction)
+inline triggers::TriggerActionEnum
+    toRedfishTriggerAction(std::string_view dbusValue)
 {
-    std::optional<std::string> redfishAction = std::nullopt;
-    if (dbusAction == "UpdateReport")
+    if (dbusValue ==
+        "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
     {
-        redfishAction = "RedfishMetricReport";
+        return triggers::TriggerActionEnum::RedfishMetricReport;
     }
-    if (dbusAction == "LogToRedfishEventLog")
+    if (dbusValue ==
+        "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
     {
-        redfishAction = "RedfishEvent";
+        return triggers::TriggerActionEnum::RedfishEvent;
     }
-    if (dbusAction == "LogToJournal")
+    if (dbusValue ==
+        "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
     {
-        redfishAction = "LogToLogService";
+        return triggers::TriggerActionEnum::LogToLogService;
     }
-    return redfishAction;
+    return triggers::TriggerActionEnum::Invalid;
 }
 
-inline std::optional<std::vector<std::string>>
+inline std::string toDbusTriggerAction(std::string_view redfishValue)
+{
+    if (redfishValue == "RedfishMetricReport")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
+    }
+    if (redfishValue == "RedfishEvent")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
+    }
+    if (redfishValue == "LogToLogService")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
+    }
+    return "";
+}
+
+inline std::string toDbusSeverity(std::string_view redfishValue)
+{
+    if (redfishValue == "OK")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
+    }
+    if (redfishValue == "Warning")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
+    }
+    if (redfishValue == "Critical")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
+    }
+    return "";
+}
+
+inline resource::Health toRedfishSeverity(std::string_view dbusValue)
+{
+    if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
+    {
+        return resource::Health::OK;
+    }
+    if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
+    {
+        return resource::Health::Warning;
+    }
+    if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
+    {
+        return resource::Health::Critical;
+    }
+    return resource::Health::Invalid;
+}
+
+inline std::string toDbusThresholdName(std::string_view redfishValue)
+{
+    if (redfishValue == "UpperCritical")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical";
+    }
+
+    if (redfishValue == "LowerCritical")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical";
+    }
+
+    if (redfishValue == "UpperWarning")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning";
+    }
+
+    if (redfishValue == "LowerWarning")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning";
+    }
+
+    return "";
+}
+
+inline std::string toRedfishThresholdName(std::string_view dbusValue)
+{
+    if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
+    {
+        return "UpperCritical";
+    }
+
+    if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
+    {
+        return "LowerCritical";
+    }
+
+    if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
+    {
+        return "UpperWarning";
+    }
+
+    if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
+    {
+        return "LowerWarning";
+    }
+
+    return "";
+}
+
+inline std::string toDbusActivation(std::string_view redfishValue)
+{
+    if (redfishValue == "Either")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
+    }
+
+    if (redfishValue == "Decreasing")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
+    }
+
+    if (redfishValue == "Increasing")
+    {
+        return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
+    }
+
+    return "";
+}
+
+inline triggers::ThresholdActivation
+    toRedfishActivation(std::string_view dbusValue)
+{
+    if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
+    {
+        return triggers::ThresholdActivation::Either;
+    }
+
+    if (dbusValue ==
+        "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
+    {
+        return triggers::ThresholdActivation::Decreasing;
+    }
+
+    if (dbusValue ==
+        "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
+    {
+        return triggers::ThresholdActivation::Increasing;
+    }
+
+    return triggers::ThresholdActivation::Invalid;
+}
+
+enum class MetricType
+{
+    Discrete,
+    Numeric
+};
+
+enum class DiscreteCondition
+{
+    Specified,
+    Changed
+};
+
+struct Context
+{
+    std::string id;
+    std::string name;
+    std::vector<std::string> actions;
+    std::vector<std::pair<sdbusplus::message::object_path, std::string>>
+        sensors;
+    std::vector<sdbusplus::message::object_path> reports;
+    TriggerThresholdParams thresholds;
+
+    std::optional<DiscreteCondition> discreteCondition;
+    std::optional<MetricType> metricType;
+    std::optional<std::vector<std::string>> metricProperties;
+};
+
+inline std::optional<sdbusplus::message::object_path>
+    getReportPathFromReportDefinitionUri(const std::string& uri)
+{
+    boost::urls::result<boost::urls::url_view> parsed =
+        boost::urls::parse_relative_ref(uri);
+
+    if (!parsed)
+    {
+        return std::nullopt;
+    }
+
+    std::string id;
+    if (!crow::utility::readUrlSegments(
+            *parsed, "redfish", "v1", "TelemetryService",
+            "MetricReportDefinitions", std::ref(id)))
+    {
+        return std::nullopt;
+    }
+
+    return sdbusplus::message::object_path(
+               "/xyz/openbmc_project/Telemetry/Reports") /
+           "TelemetryService" / id;
+}
+
+inline std::optional<MetricType> getMetricType(const std::string& metricType)
+{
+    if (metricType == "Discrete")
+    {
+        return MetricType::Discrete;
+    }
+    if (metricType == "Numeric")
+    {
+        return MetricType::Numeric;
+    }
+    return std::nullopt;
+}
+
+inline std::optional<DiscreteCondition>
+    getDiscreteCondition(const std::string& discreteTriggerCondition)
+{
+    if (discreteTriggerCondition == "Specified")
+    {
+        return DiscreteCondition::Specified;
+    }
+    if (discreteTriggerCondition == "Changed")
+    {
+        return DiscreteCondition::Changed;
+    }
+    return std::nullopt;
+}
+
+inline bool parseNumericThresholds(crow::Response& res,
+                                   nlohmann::json& numericThresholds,
+                                   Context& ctx)
+{
+    nlohmann::json::object_t* obj =
+        numericThresholds.get_ptr<nlohmann::json::object_t*>();
+    if (obj == nullptr)
+    {
+        messages::propertyValueTypeError(res, numericThresholds.dump(),
+                                         "NumericThresholds");
+        return false;
+    }
+
+    std::vector<NumericThresholdParams> parsedParams;
+    parsedParams.reserve(numericThresholds.size());
+
+    for (auto& key : *obj)
+    {
+        std::string dbusThresholdName = toDbusThresholdName(key.first);
+        if (dbusThresholdName.empty())
+        {
+            messages::propertyUnknown(res, key.first);
+            return false;
+        }
+
+        double reading = 0.0;
+        std::string activation;
+        std::string dwellTimeStr;
+
+        if (!json_util::readJson(key.second, res, "Reading", reading,
+                                 "Activation", activation, "DwellTime",
+                                 dwellTimeStr))
+        {
+            return false;
+        }
+
+        std::string dbusActivation = toDbusActivation(activation);
+
+        if (dbusActivation.empty())
+        {
+            messages::propertyValueIncorrect(res, "Activation", activation);
+            return false;
+        }
+
+        std::optional<std::chrono::milliseconds> dwellTime =
+            time_utils::fromDurationString(dwellTimeStr);
+        if (!dwellTime)
+        {
+            messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
+            return false;
+        }
+
+        parsedParams.emplace_back(dbusThresholdName,
+                                  static_cast<uint64_t>(dwellTime->count()),
+                                  dbusActivation, reading);
+    }
+
+    ctx.thresholds = std::move(parsedParams);
+    return true;
+}
+
+inline bool parseDiscreteTriggers(
+    crow::Response& res,
+    std::optional<std::vector<nlohmann::json>>& discreteTriggers, Context& ctx)
+{
+    std::vector<DiscreteThresholdParams> parsedParams;
+    if (!discreteTriggers)
+    {
+        ctx.thresholds = std::move(parsedParams);
+        return true;
+    }
+
+    parsedParams.reserve(discreteTriggers->size());
+    for (nlohmann::json& thresholdInfo : *discreteTriggers)
+    {
+        std::optional<std::string> name = "";
+        std::string value;
+        std::string dwellTimeStr;
+        std::string severity;
+
+        if (!json_util::readJson(thresholdInfo, res, "Name", name, "Value",
+                                 value, "DwellTime", dwellTimeStr, "Severity",
+                                 severity))
+        {
+            return false;
+        }
+
+        std::optional<std::chrono::milliseconds> dwellTime =
+            time_utils::fromDurationString(dwellTimeStr);
+        if (!dwellTime)
+        {
+            messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
+            return false;
+        }
+
+        std::string dbusSeverity = toDbusSeverity(severity);
+        if (dbusSeverity.empty())
+        {
+            messages::propertyValueIncorrect(res, "Severity", severity);
+            return false;
+        }
+
+        parsedParams.emplace_back(*name, dbusSeverity,
+                                  static_cast<uint64_t>(dwellTime->count()),
+                                  value);
+    }
+
+    ctx.thresholds = std::move(parsedParams);
+    return true;
+}
+
+inline bool parseTriggerThresholds(
+    crow::Response& res,
+    std::optional<std::vector<nlohmann::json>>& discreteTriggers,
+    std::optional<nlohmann::json>& numericThresholds, Context& ctx)
+{
+    if (discreteTriggers && numericThresholds)
+    {
+        messages::propertyValueConflict(res, "DiscreteTriggers",
+                                        "NumericThresholds");
+        messages::propertyValueConflict(res, "NumericThresholds",
+                                        "DiscreteTriggers");
+        return false;
+    }
+
+    if (ctx.discreteCondition)
+    {
+        if (numericThresholds)
+        {
+            messages::propertyValueConflict(res, "DiscreteTriggerCondition",
+                                            "NumericThresholds");
+            messages::propertyValueConflict(res, "NumericThresholds",
+                                            "DiscreteTriggerCondition");
+            return false;
+        }
+    }
+
+    if (ctx.metricType)
+    {
+        if (*ctx.metricType == MetricType::Discrete && numericThresholds)
+        {
+            messages::propertyValueConflict(res, "NumericThresholds",
+                                            "MetricType");
+            return false;
+        }
+        if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
+        {
+            messages::propertyValueConflict(res, "DiscreteTriggers",
+                                            "MetricType");
+            return false;
+        }
+        if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
+        {
+            messages::propertyValueConflict(res, "DiscreteTriggers",
+                                            "DiscreteTriggerCondition");
+            return false;
+        }
+    }
+
+    if (discreteTriggers || ctx.discreteCondition ||
+        (ctx.metricType && *ctx.metricType == MetricType::Discrete))
+    {
+        if (ctx.discreteCondition)
+        {
+            if (*ctx.discreteCondition == DiscreteCondition::Specified &&
+                !discreteTriggers)
+            {
+                messages::createFailedMissingReqProperties(res,
+                                                           "DiscreteTriggers");
+                return false;
+            }
+            if (discreteTriggers &&
+                ((*ctx.discreteCondition == DiscreteCondition::Specified &&
+                  discreteTriggers->empty()) ||
+                 (*ctx.discreteCondition == DiscreteCondition::Changed &&
+                  !discreteTriggers->empty())))
+            {
+                messages::propertyValueConflict(res, "DiscreteTriggers",
+                                                "DiscreteTriggerCondition");
+                return false;
+            }
+        }
+        if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
+        {
+            return false;
+        }
+    }
+    else if (numericThresholds)
+    {
+        if (!parseNumericThresholds(res, *numericThresholds, ctx))
+        {
+            return false;
+        }
+    }
+    else
+    {
+        messages::createFailedMissingReqProperties(
+            res, "'DiscreteTriggers', 'NumericThresholds', "
+                 "'DiscreteTriggerCondition' or 'MetricType'");
+        return false;
+    }
+    return true;
+}
+
+inline bool parseLinks(crow::Response& res, nlohmann::json& links, Context& ctx)
+{
+    if (links.empty())
+    {
+        return true;
+    }
+
+    std::optional<std::vector<std::string>> metricReportDefinitions;
+    if (!json_util::readJson(links, res, "MetricReportDefinitions",
+                             metricReportDefinitions))
+    {
+        return false;
+    }
+
+    if (metricReportDefinitions)
+    {
+        ctx.reports.reserve(metricReportDefinitions->size());
+        for (std::string& reportDefinionUri : *metricReportDefinitions)
+        {
+            std::optional<sdbusplus::message::object_path> reportPath =
+                getReportPathFromReportDefinitionUri(reportDefinionUri);
+            if (!reportPath)
+            {
+                messages::propertyValueIncorrect(res, "MetricReportDefinitions",
+                                                 reportDefinionUri);
+                return false;
+            }
+            ctx.reports.emplace_back(*reportPath);
+        }
+    }
+    return true;
+}
+
+inline bool parseMetricProperties(crow::Response& res, Context& ctx)
+{
+    if (!ctx.metricProperties)
+    {
+        return true;
+    }
+
+    ctx.sensors.reserve(ctx.metricProperties->size());
+
+    size_t uriIdx = 0;
+    for (const std::string& uriStr : *ctx.metricProperties)
+    {
+        boost::urls::result<boost::urls::url_view> uri =
+            boost::urls::parse_relative_ref(uriStr);
+        if (!uri)
+        {
+            messages::propertyValueIncorrect(
+                res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
+            return false;
+        }
+        std::string chassisName;
+        std::string sensorName;
+        if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
+                                            std::ref(chassisName), "Sensors",
+                                            std::ref(sensorName)))
+        {
+            messages::propertyValueIncorrect(
+                res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
+            return false;
+        }
+
+        std::pair<std::string, std::string> split =
+            splitSensorNameAndType(sensorName);
+        if (split.first.empty() || split.second.empty())
+        {
+            messages::propertyValueIncorrect(
+                res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
+            return false;
+        }
+
+        std::string sensorPath = "/xyz/openbmc_project/sensors/" + split.first +
+                                 '/' + split.second;
+
+        ctx.sensors.emplace_back(sensorPath, uriStr);
+        uriIdx++;
+    }
+    return true;
+}
+
+inline bool parsePostTriggerParams(crow::Response& res,
+                                   const crow::Request& req, Context& ctx)
+{
+    std::optional<std::string> id = "";
+    std::optional<std::string> name = "";
+    std::optional<std::string> metricType;
+    std::optional<std::vector<std::string>> triggerActions;
+    std::optional<std::string> discreteTriggerCondition;
+    std::optional<std::vector<nlohmann::json>> discreteTriggers;
+    std::optional<nlohmann::json> numericThresholds;
+    std::optional<nlohmann::json> links;
+    if (!json_util::readJsonPatch(
+            req, res, "Id", id, "Name", name, "MetricType", metricType,
+            "TriggerActions", triggerActions, "DiscreteTriggerCondition",
+            discreteTriggerCondition, "DiscreteTriggers", discreteTriggers,
+            "NumericThresholds", numericThresholds, "MetricProperties",
+            ctx.metricProperties, "Links", links))
+    {
+        return false;
+    }
+
+    ctx.id = *id;
+    ctx.name = *name;
+
+    if (metricType)
+    {
+        if (!(ctx.metricType = getMetricType(*metricType)))
+        {
+            messages::propertyValueIncorrect(res, "MetricType", *metricType);
+            return false;
+        }
+    }
+
+    if (discreteTriggerCondition)
+    {
+        if (!(ctx.discreteCondition =
+                  getDiscreteCondition(*discreteTriggerCondition)))
+        {
+            messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
+                                             *discreteTriggerCondition);
+            return false;
+        }
+    }
+
+    if (triggerActions)
+    {
+        ctx.actions.reserve(triggerActions->size());
+        for (const std::string& action : *triggerActions)
+        {
+            std::string dbusAction = toDbusTriggerAction(action);
+
+            if (dbusAction.empty())
+            {
+                messages::propertyValueNotInList(res, action, "TriggerActions");
+                return false;
+            }
+
+            ctx.actions.emplace_back(dbusAction);
+        }
+    }
+    if (!parseMetricProperties(res, ctx))
+    {
+        return false;
+    }
+
+    if (!parseTriggerThresholds(res, discreteTriggers, numericThresholds, ctx))
+    {
+        return false;
+    }
+
+    if (links)
+    {
+        if (!parseLinks(res, *links, ctx))
+        {
+            return false;
+        }
+    }
+    return true;
+}
+
+inline void afterCreateTrigger(
+    const boost::system::error_code& ec, const std::string& dbusPath,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
+{
+    if (ec == boost::system::errc::file_exists)
+    {
+        messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
+        return;
+    }
+    if (ec == boost::system::errc::too_many_files_open)
+    {
+        messages::createLimitReachedForResource(asyncResp->res);
+        return;
+    }
+    if (ec)
+    {
+        messages::internalError(asyncResp->res);
+        BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
+        return;
+    }
+
+    const std::optional<std::string>& triggerId =
+        getTriggerIdFromDbusPath(dbusPath);
+    if (!triggerId)
+    {
+        messages::internalError(asyncResp->res);
+        BMCWEB_LOG_ERROR << "Unknown data returned by "
+                            "AddTrigger DBus method";
+        return;
+    }
+
+    messages::created(asyncResp->res);
+    boost::urls::url locationUrl = boost::urls::format(
+        "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
+    asyncResp->res.addHeader("Location", locationUrl.buffer());
+}
+
+inline std::optional<nlohmann::json::array_t>
     getTriggerActions(const std::vector<std::string>& dbusActions)
 {
-    std::vector<std::string> triggerActions;
+    nlohmann::json::array_t triggerActions;
     for (const std::string& dbusAction : dbusActions)
     {
-        std::optional<std::string> redfishAction =
-            getRedfishFromDbusAction(dbusAction);
+        triggers::TriggerActionEnum redfishAction =
+            toRedfishTriggerAction(dbusAction);
 
-        if (!redfishAction)
+        if (redfishAction == triggers::TriggerActionEnum::Invalid)
         {
             return std::nullopt;
         }
 
-        triggerActions.push_back(*redfishAction);
+        triggerActions.emplace_back(redfishAction);
     }
 
-    return {std::move(triggerActions)};
+    return triggerActions;
 }
 
 inline std::optional<nlohmann::json::array_t>
     getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams)
 {
+    nlohmann::json::array_t triggers;
     const std::vector<DiscreteThresholdParams>* discreteParams =
         std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams);
 
@@ -93,7 +729,6 @@
         return std::nullopt;
     }
 
-    nlohmann::json::array_t triggers;
     for (const auto& [name, severity, dwellTime, value] : *discreteParams)
     {
         std::optional<std::string> duration =
@@ -105,18 +740,19 @@
         }
         nlohmann::json::object_t trigger;
         trigger["Name"] = name;
-        trigger["Severity"] = severity;
+        trigger["Severity"] = toRedfishSeverity(severity);
         trigger["DwellTime"] = *duration;
         trigger["Value"] = value;
         triggers.emplace_back(std::move(trigger));
     }
 
-    return {std::move(triggers)};
+    return triggers;
 }
 
 inline std::optional<nlohmann::json>
     getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams)
 {
+    nlohmann::json::object_t thresholds;
     const std::vector<NumericThresholdParams>* numericParams =
         std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams);
 
@@ -125,7 +761,6 @@
         return std::nullopt;
     }
 
-    nlohmann::json::object_t thresholds;
     for (const auto& [type, dwellTime, activation, reading] : *numericParams)
     {
         std::optional<std::string> duration =
@@ -135,13 +770,13 @@
         {
             return std::nullopt;
         }
-        nlohmann::json& threshold = thresholds[type];
+        nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
         threshold["Reading"] = reading;
-        threshold["Activation"] = activation;
+        threshold["Activation"] = toRedfishActivation(activation);
         threshold["DwellTime"] = *duration;
     }
 
-    return {std::move(thresholds)};
+    return thresholds;
 }
 
 inline std::optional<nlohmann::json> getMetricReportDefinitions(
@@ -208,7 +843,7 @@
 
     if (triggerActions != nullptr)
     {
-        std::optional<std::vector<std::string>> redfishTriggerActions =
+        std::optional<nlohmann::json::array_t> redfishTriggerActions =
             getTriggerActions(*triggerActions);
         if (!redfishTriggerActions)
         {
@@ -216,7 +851,7 @@
                 << "Property TriggerActions is invalid in Trigger: " << id;
             return false;
         }
-        json["TriggerActions"] = *triggerActions;
+        json["TriggerActions"] = *redfishTriggerActions;
     }
 
     if (reports != nullptr)
@@ -290,6 +925,32 @@
     return true;
 }
 
+inline void handleTriggerCollectionPost(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+
+    telemetry::Context ctx;
+    if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
+    {
+        return;
+    }
+
+    crow::connections::systemBus->async_method_call(
+        [asyncResp, id = ctx.id](const boost::system::error_code& ec,
+                                 const std::string& dbusPath) {
+        afterCreateTrigger(ec, dbusPath, asyncResp, id);
+        },
+        service, "/xyz/openbmc_project/Telemetry/Triggers",
+        "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
+        "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
+        ctx.reports, ctx.thresholds);
+}
+
 } // namespace telemetry
 
 inline void requestRoutesTriggerCollection(App& app)
@@ -316,6 +977,11 @@
             interfaces,
             "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
         });
+
+    BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
+        .privileges(redfish::privileges::postTriggersCollection)
+        .methods(boost::beast::http::verb::post)(std::bind_front(
+            telemetry::handleTriggerCollectionPost, std::ref(app)));
 }
 
 inline void requestRoutesTrigger(App& app)
