diff --git a/integration-tests/http/__tests__/price-preference/admin/price-preference.spec.ts b/integration-tests/http/__tests__/price-preference/admin/price-preference.spec.ts
new file mode 100644
index 0000000000000..fd5c979e57fbd
--- /dev/null
+++ b/integration-tests/http/__tests__/price-preference/admin/price-preference.spec.ts
@@ -0,0 +1,221 @@
+import { medusaIntegrationTestRunner } from "medusa-test-utils"
+import {
+  createAdminUser,
+  adminHeaders,
+} from "../../../../helpers/create-admin-user"
+
+jest.setTimeout(30000)
+
+medusaIntegrationTestRunner({
+  env: {},
+  testSuite: ({ dbConnection, getContainer, api }) => {
+    let pricePreference1
+    let pricePreference2
+
+    beforeEach(async () => {
+      const container = getContainer()
+      await createAdminUser(dbConnection, adminHeaders, container)
+
+      pricePreference1 = (
+        await api.post(
+          "/admin/price-preferences",
+          {
+            attribute: "region_id",
+            value: "region-1",
+            is_tax_inclusive: true,
+          },
+          adminHeaders
+        )
+      ).data.price_preference
+
+      pricePreference2 = (
+        await api.post(
+          "/admin/price-preferences",
+          {
+            attribute: "currency_code",
+            value: "EUR",
+            is_tax_inclusive: true,
+          },
+          adminHeaders
+        )
+      ).data.price_preference
+    })
+
+    describe("/admin/price-preferences", () => {
+      describe("POST /admin/price-preferences", () => {
+        it("creates a price preference", async () => {
+          const newPricePreference = (
+            await api.post(
+              "/admin/price-preferences",
+              {
+                attribute: "region_id",
+                value: "region-2",
+                is_tax_inclusive: true,
+              },
+              adminHeaders
+            )
+          ).data.price_preference
+
+          expect(newPricePreference).toEqual(
+            expect.objectContaining({
+              attribute: "region_id",
+              value: "region-2",
+              is_tax_inclusive: true,
+            })
+          )
+        })
+
+        it("creates a price preference with false tax inclusivity by default", async () => {
+          const newPricePreference = (
+            await api.post(
+              "/admin/price-preferences",
+              {
+                attribute: "region_id",
+                value: "region-2",
+              },
+              adminHeaders
+            )
+          ).data.price_preference
+
+          expect(newPricePreference).toEqual(
+            expect.objectContaining({
+              attribute: "region_id",
+              value: "region-2",
+              is_tax_inclusive: false,
+            })
+          )
+        })
+      })
+
+      describe("GET /admin/price-preferences", () => {
+        it("returns a list of price preferences", async () => {
+          const response = (
+            await api.get("/admin/price-preferences", adminHeaders)
+          ).data.price_preferences
+
+          expect(response).toEqual(
+            expect.arrayContaining([
+              expect.objectContaining({
+                attribute: "region_id",
+                value: "region-1",
+                is_tax_inclusive: true,
+              }),
+              expect.objectContaining({
+                attribute: "currency_code",
+                value: "EUR",
+                is_tax_inclusive: true,
+              }),
+            ])
+          )
+        })
+        it("filters price preferences by attribute", async () => {
+          const response = (
+            await api.get(
+              "/admin/price-preferences?attribute=region_id",
+              adminHeaders
+            )
+          ).data.price_preferences
+
+          expect(response).toEqual([
+            expect.objectContaining({
+              attribute: "region_id",
+              value: "region-1",
+              is_tax_inclusive: true,
+            }),
+          ])
+        })
+      })
+
+      describe("GET /admin/price-preferences/:id", () => {
+        it("returns a price preference by :id", async () => {
+          const response = (
+            await api.get(
+              `/admin/price-preferences/${pricePreference1.id}`,
+              adminHeaders
+            )
+          ).data.price_preference
+
+          expect(response).toEqual(
+            expect.objectContaining({
+              attribute: "region_id",
+              value: "region-1",
+              is_tax_inclusive: true,
+            })
+          )
+        })
+      })
+
+      describe("POST /admin/price-preferences/:id", () => {
+        it("updates a price preference", async () => {
+          const response = (
+            await api.post(
+              `/admin/price-preferences/${pricePreference1.id}`,
+              {
+                attribute: "region_id",
+                value: "region-2",
+                is_tax_inclusive: false,
+              },
+              adminHeaders
+            )
+          ).data.price_preference
+
+          expect(response).toEqual(
+            expect.objectContaining({
+              attribute: "region_id",
+              value: "region-2",
+              is_tax_inclusive: false,
+            })
+          )
+        })
+        it("updates the tax inclusivity in the price preference", async () => {
+          const response = (
+            await api.post(
+              `/admin/price-preferences/${pricePreference1.id}`,
+              {
+                is_tax_inclusive: false,
+              },
+              adminHeaders
+            )
+          ).data.price_preference
+
+          expect(response).toEqual(
+            expect.objectContaining({
+              attribute: "region_id",
+              value: "region-1",
+              is_tax_inclusive: false,
+            })
+          )
+        })
+      })
+
+      describe("DELETE /admin/price-preferences/:id", () => {
+        it("Deletes a price preference", async () => {
+          const deleteResponse = await api.delete(
+            `/admin/price-preferences/${pricePreference1.id}`,
+            adminHeaders
+          )
+
+          const remainingPricePreferences = (
+            await api.get("/admin/price-preferences", adminHeaders)
+          ).data.price_preferences
+
+          expect(deleteResponse.data).toEqual(
+            expect.objectContaining({
+              id: pricePreference1.id,
+              object: "price_preference",
+              deleted: true,
+            })
+          )
+
+          expect(remainingPricePreferences).toEqual([
+            expect.objectContaining({
+              attribute: "currency_code",
+              value: "EUR",
+              is_tax_inclusive: true,
+            }),
+          ])
+        })
+      })
+    })
+  },
+})
diff --git a/packages/core/core-flows/src/order/workflows/get-orders-list.ts b/packages/core/core-flows/src/order/workflows/get-orders-list.ts
index b967d8997d469..c6875c86154b7 100644
--- a/packages/core/core-flows/src/order/workflows/get-orders-list.ts
+++ b/packages/core/core-flows/src/order/workflows/get-orders-list.ts
@@ -18,9 +18,9 @@ type OrderOutput =
       metadata: any
     }
 
-export const getOrdersListlWorkflowId = "get-orders-list"
-export const getOrdersListlWorkflow = createWorkflow(
-  getOrdersListlWorkflowId,
+export const getOrdersListWorkflowId = "get-orders-list"
+export const getOrdersListWorkflow = createWorkflow(
+  getOrdersListWorkflowId,
   (
     input: WorkflowData<{
       fields: string[]
diff --git a/packages/core/core-flows/src/pricing/index.ts b/packages/core/core-flows/src/pricing/index.ts
index c1f49c23fa343..68de82c9f92da 100644
--- a/packages/core/core-flows/src/pricing/index.ts
+++ b/packages/core/core-flows/src/pricing/index.ts
@@ -1 +1,2 @@
 export * from "./steps"
+export * from "./workflows"
diff --git a/packages/core/core-flows/src/pricing/steps/create-price-preferences.ts b/packages/core/core-flows/src/pricing/steps/create-price-preferences.ts
new file mode 100644
index 0000000000000..4c3ed46082f68
--- /dev/null
+++ b/packages/core/core-flows/src/pricing/steps/create-price-preferences.ts
@@ -0,0 +1,34 @@
+import { IPricingModuleService } from "@medusajs/types"
+import { PricingWorkflow } from "@medusajs/types/dist/workflow"
+import { ModuleRegistrationName } from "@medusajs/utils"
+import { StepResponse, createStep } from "@medusajs/workflows-sdk"
+
+type StepInput = PricingWorkflow.CreatePricePreferencesWorkflowInput[]
+
+export const createPricePreferencesStepId = "create-price-preferences"
+export const createPricePreferencesStep = createStep(
+  createPricePreferencesStepId,
+  async (data: StepInput, { container }) => {
+    const pricingModule = container.resolve<IPricingModuleService>(
+      ModuleRegistrationName.PRICING
+    )
+
+    const pricePreferences = await pricingModule.createPricePreferences(data)
+
+    return new StepResponse(
+      pricePreferences,
+      pricePreferences.map((pricePreference) => pricePreference.id)
+    )
+  },
+  async (pricePreferences, { container }) => {
+    if (!pricePreferences?.length) {
+      return
+    }
+
+    const pricingModule = container.resolve<IPricingModuleService>(
+      ModuleRegistrationName.PRICING
+    )
+
+    await pricingModule.deletePricePreferences(pricePreferences)
+  }
+)
diff --git a/packages/core/core-flows/src/pricing/steps/delete-price-preferences.ts b/packages/core/core-flows/src/pricing/steps/delete-price-preferences.ts
new file mode 100644
index 0000000000000..b625ea95f25af
--- /dev/null
+++ b/packages/core/core-flows/src/pricing/steps/delete-price-preferences.ts
@@ -0,0 +1,28 @@
+import { IPricingModuleService } from "@medusajs/types"
+import { ModuleRegistrationName } from "@medusajs/utils"
+import { StepResponse, createStep } from "@medusajs/workflows-sdk"
+
+export const deletePricePreferencesStepId = "delete-price-preferences"
+export const deletePricePreferencesStep = createStep(
+  deletePricePreferencesStepId,
+  async (ids: string[], { container }) => {
+    const service = container.resolve<IPricingModuleService>(
+      ModuleRegistrationName.PRICING
+    )
+
+    await service.softDeletePricePreferences(ids)
+
+    return new StepResponse(void 0, ids)
+  },
+  async (prevIds, { container }) => {
+    if (!prevIds?.length) {
+      return
+    }
+
+    const service = container.resolve<IPricingModuleService>(
+      ModuleRegistrationName.PRICING
+    )
+
+    await service.restorePricePreferences(prevIds)
+  }
+)
diff --git a/packages/core/core-flows/src/pricing/steps/index.ts b/packages/core/core-flows/src/pricing/steps/index.ts
index 04bc6d7d03944..5d4820f2e0da1 100644
--- a/packages/core/core-flows/src/pricing/steps/index.ts
+++ b/packages/core/core-flows/src/pricing/steps/index.ts
@@ -1,2 +1,5 @@
 export * from "./create-price-sets"
 export * from "./update-price-sets"
+export * from "./create-price-preferences"
+export * from "./update-price-preferences"
+export * from "./delete-price-preferences"
diff --git a/packages/core/core-flows/src/pricing/steps/update-price-preferences.ts b/packages/core/core-flows/src/pricing/steps/update-price-preferences.ts
new file mode 100644
index 0000000000000..f7427d81eb681
--- /dev/null
+++ b/packages/core/core-flows/src/pricing/steps/update-price-preferences.ts
@@ -0,0 +1,45 @@
+import { PricingWorkflow, IPricingModuleService } from "@medusajs/types"
+import {
+  ModuleRegistrationName,
+  getSelectsAndRelationsFromObjectArray,
+} from "@medusajs/utils"
+import { StepResponse, createStep } from "@medusajs/workflows-sdk"
+
+type StepInput = PricingWorkflow.UpdatePricePreferencesWorkflowInput
+
+export const updatePricePreferencesStepId = "update-price-preferences"
+export const updatePricePreferencesStep = createStep(
+  updatePricePreferencesStepId,
+  async (input: StepInput, { container }) => {
+    const service = container.resolve<IPricingModuleService>(
+      ModuleRegistrationName.PRICING
+    )
+
+    const { selects, relations } = getSelectsAndRelationsFromObjectArray([
+      input.update,
+    ])
+
+    const prevData = await service.listPricePreferences(input.selector, {
+      select: selects,
+      relations,
+    })
+
+    const updatedPricePreferences = await service.updatePricePreferences(
+      input.selector,
+      input.update
+    )
+
+    return new StepResponse(updatedPricePreferences, prevData)
+  },
+  async (prevData, { container }) => {
+    if (!prevData?.length) {
+      return
+    }
+
+    const service = container.resolve<IPricingModuleService>(
+      ModuleRegistrationName.PRICING
+    )
+
+    await service.upsertPricePreferences(prevData)
+  }
+)
diff --git a/packages/core/core-flows/src/pricing/workflows/create-price-preferences.ts b/packages/core/core-flows/src/pricing/workflows/create-price-preferences.ts
new file mode 100644
index 0000000000000..b3998e980dd18
--- /dev/null
+++ b/packages/core/core-flows/src/pricing/workflows/create-price-preferences.ts
@@ -0,0 +1,13 @@
+import { PricingWorkflow } from "@medusajs/types"
+import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
+import { createPricePreferencesStep } from "../steps"
+
+type WorkflowInputData = PricingWorkflow.CreatePricePreferencesWorkflowInput[]
+
+export const createPricePreferencesWorkflowId = "create-price-preferences"
+export const createPricePreferencesWorkflow = createWorkflow(
+  createPricePreferencesWorkflowId,
+  (input: WorkflowData<WorkflowInputData>) => {
+    return createPricePreferencesStep(input)
+  }
+)
diff --git a/packages/core/core-flows/src/pricing/workflows/delete-price-preferences.ts b/packages/core/core-flows/src/pricing/workflows/delete-price-preferences.ts
new file mode 100644
index 0000000000000..fcdb54661a212
--- /dev/null
+++ b/packages/core/core-flows/src/pricing/workflows/delete-price-preferences.ts
@@ -0,0 +1,10 @@
+import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
+import { deletePricePreferencesStep } from "../steps"
+
+export const deletePricePreferencesWorkflowId = "delete-price-preferences"
+export const deletePricePreferencesWorkflow = createWorkflow(
+  deletePricePreferencesWorkflowId,
+  (input: WorkflowData<string[]>) => {
+    return deletePricePreferencesStep(input)
+  }
+)
diff --git a/packages/core/core-flows/src/pricing/workflows/index.ts b/packages/core/core-flows/src/pricing/workflows/index.ts
new file mode 100644
index 0000000000000..f2c30d229ece9
--- /dev/null
+++ b/packages/core/core-flows/src/pricing/workflows/index.ts
@@ -0,0 +1,3 @@
+export * from "./create-price-preferences"
+export * from "./update-price-preferences"
+export * from "./delete-price-preferences"
diff --git a/packages/core/core-flows/src/pricing/workflows/update-price-preferences.ts b/packages/core/core-flows/src/pricing/workflows/update-price-preferences.ts
new file mode 100644
index 0000000000000..f090954f4e635
--- /dev/null
+++ b/packages/core/core-flows/src/pricing/workflows/update-price-preferences.ts
@@ -0,0 +1,13 @@
+import { PricingWorkflow } from "@medusajs/types"
+import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
+import { updatePricePreferencesStep } from "../steps"
+
+type WorkflowInputData = PricingWorkflow.UpdatePricePreferencesWorkflowInput
+
+export const updatePricePreferencesWorkflowId = "update-price-preferences"
+export const updatePricePreferencesWorkflow = createWorkflow(
+  updatePricePreferencesWorkflowId,
+  (input: WorkflowData<WorkflowInputData>) => {
+    return updatePricePreferencesStep(input)
+  }
+)
diff --git a/packages/core/types/src/http/pricing/admin/entities.ts b/packages/core/types/src/http/pricing/admin/entities.ts
index 5e5a368dc06e3..85dc5d6ef34cf 100644
--- a/packages/core/types/src/http/pricing/admin/entities.ts
+++ b/packages/core/types/src/http/pricing/admin/entities.ts
@@ -29,3 +29,13 @@ export interface AdminPrice {
   updated_at: string
   deleted_at: string | null
 }
+
+export interface AdminPricePreference {
+  id: string
+  attribute: string | null
+  value: string | null
+  is_tax_inclusive: boolean
+  created_at: string
+  updated_at: string
+  deleted_at: null | string
+}
diff --git a/packages/core/types/src/http/pricing/admin/index.ts b/packages/core/types/src/http/pricing/admin/index.ts
index 8270e0b265e19..1f82a2ead53e3 100644
--- a/packages/core/types/src/http/pricing/admin/index.ts
+++ b/packages/core/types/src/http/pricing/admin/index.ts
@@ -1 +1,4 @@
 export * from "./entities"
+export * from "./payloads"
+export * from "./queries"
+export * from "./responses"
diff --git a/packages/core/types/src/http/pricing/admin/payloads.ts b/packages/core/types/src/http/pricing/admin/payloads.ts
new file mode 100644
index 0000000000000..f4f14983fa1f9
--- /dev/null
+++ b/packages/core/types/src/http/pricing/admin/payloads.ts
@@ -0,0 +1,11 @@
+export interface AdminCreatePricePreference {
+  attribute?: string
+  value?: string
+  is_tax_inclusive?: boolean
+}
+
+export interface AdminUpdatePricePreference {
+  attribute?: string | null
+  value?: string | null
+  is_tax_inclusive?: boolean
+}
diff --git a/packages/core/types/src/http/pricing/admin/queries.ts b/packages/core/types/src/http/pricing/admin/queries.ts
new file mode 100644
index 0000000000000..57ad288e2f31e
--- /dev/null
+++ b/packages/core/types/src/http/pricing/admin/queries.ts
@@ -0,0 +1,12 @@
+import { BaseFilterable } from "../../../dal"
+import { FindParams, SelectParams } from "../../common"
+
+export interface AdminPricePreferenceListParams
+  extends FindParams,
+    BaseFilterable<AdminPricePreferenceListParams> {
+  id?: string | string[]
+  attribute?: string | string[]
+  value?: string | string[]
+}
+
+export interface AdminPricePreferenceParams extends SelectParams {}
diff --git a/packages/core/types/src/http/pricing/admin/responses.ts b/packages/core/types/src/http/pricing/admin/responses.ts
new file mode 100644
index 0000000000000..23d1186d00090
--- /dev/null
+++ b/packages/core/types/src/http/pricing/admin/responses.ts
@@ -0,0 +1,14 @@
+import { DeleteResponse, PaginatedResponse } from "../../common"
+import { AdminPricePreference } from "./entities"
+
+export interface AdminPricePreferenceResponse {
+  price_preference: AdminPricePreference
+}
+
+export interface AdminPricePreferenceListResponse
+  extends PaginatedResponse<{
+    price_preferences: AdminPricePreference[]
+  }> {}
+
+export interface AdminPricePreferenceDeleteResponse
+  extends DeleteResponse<"price_preference"> {}
diff --git a/packages/core/types/src/workflow/index.ts b/packages/core/types/src/workflow/index.ts
index 9b592a109351b..3f8a1f35e1ff0 100644
--- a/packages/core/types/src/workflow/index.ts
+++ b/packages/core/types/src/workflow/index.ts
@@ -10,3 +10,4 @@ export * as RegionWorkflow from "./region"
 export * as ReservationWorkflow from "./reservation"
 export * as UserWorkflow from "./user"
 export * as OrderWorkflow from "./order"
+export * as PricingWorkflow from "./pricing"
diff --git a/packages/core/types/src/workflow/pricing/index.ts b/packages/core/types/src/workflow/pricing/index.ts
new file mode 100644
index 0000000000000..eddbb83f27fca
--- /dev/null
+++ b/packages/core/types/src/workflow/pricing/index.ts
@@ -0,0 +1,18 @@
+import { FilterablePricePreferenceProps } from "../../pricing"
+
+export interface CreatePricePreferencesWorkflowInput {
+  attribute?: string
+  value?: string
+  is_tax_inclusive?: boolean
+}
+
+interface UpdatePricePreferences {
+  attribute?: string | null
+  value?: string | null
+  is_tax_inclusive?: boolean
+}
+
+export interface UpdatePricePreferencesWorkflowInput {
+  selector: FilterablePricePreferenceProps
+  update: UpdatePricePreferences
+}
diff --git a/packages/medusa/src/api/admin/orders/route.ts b/packages/medusa/src/api/admin/orders/route.ts
index 3afcfacebcf32..230d9558e58ba 100644
--- a/packages/medusa/src/api/admin/orders/route.ts
+++ b/packages/medusa/src/api/admin/orders/route.ts
@@ -1,4 +1,4 @@
-import { getOrdersListlWorkflow } from "@medusajs/core-flows"
+import { getOrdersListWorkflow } from "@medusajs/core-flows"
 import { OrderDTO } from "@medusajs/types"
 import {
   AuthenticatedMedusaRequest,
@@ -17,7 +17,7 @@ export const GET = async (
     ...req.remoteQueryConfig.pagination,
   }
 
-  const workflow = getOrdersListlWorkflow(req.scope)
+  const workflow = getOrdersListWorkflow(req.scope)
   const { result } = await workflow.run({
     input: {
       fields: req.remoteQueryConfig.fields,
diff --git a/packages/medusa/src/api/admin/price-preferences/[id]/route.ts b/packages/medusa/src/api/admin/price-preferences/[id]/route.ts
new file mode 100644
index 0000000000000..9693c68d43c7e
--- /dev/null
+++ b/packages/medusa/src/api/admin/price-preferences/[id]/route.ts
@@ -0,0 +1,64 @@
+import {
+  deletePricePreferencesWorkflow,
+  updatePricePreferencesWorkflow,
+} from "@medusajs/core-flows"
+
+import { HttpTypes } from "@medusajs/types"
+import {
+  AuthenticatedMedusaRequest,
+  MedusaResponse,
+} from "../../../../types/routing"
+import { refetchEntity } from "../../../utils/refetch-entity"
+
+export const GET = async (
+  req: AuthenticatedMedusaRequest,
+  res: MedusaResponse
+) => {
+  const price_preference = await refetchEntity(
+    "price_preference",
+    req.params.id,
+    req.scope,
+    req.remoteQueryConfig.fields
+  )
+
+  res.status(200).json({ price_preference })
+}
+
+export const POST = async (
+  req: AuthenticatedMedusaRequest<HttpTypes.AdminUpdatePricePreference>,
+  res: MedusaResponse
+) => {
+  const id = req.params.id
+  const workflow = updatePricePreferencesWorkflow(req.scope)
+
+  await workflow.run({
+    input: { selector: { id: [id] }, update: req.body },
+  })
+
+  const price_preference = await refetchEntity(
+    "price_preference",
+    id,
+    req.scope,
+    req.remoteQueryConfig.fields
+  )
+
+  res.status(200).json({ price_preference })
+}
+
+export const DELETE = async (
+  req: AuthenticatedMedusaRequest,
+  res: MedusaResponse
+) => {
+  const id = req.params.id
+  const workflow = deletePricePreferencesWorkflow(req.scope)
+
+  await workflow.run({
+    input: [id],
+  })
+
+  res.status(200).json({
+    id,
+    object: "price_preference",
+    deleted: true,
+  })
+}
diff --git a/packages/medusa/src/api/admin/price-preferences/middlewares.ts b/packages/medusa/src/api/admin/price-preferences/middlewares.ts
new file mode 100644
index 0000000000000..3f3d5b2112e0b
--- /dev/null
+++ b/packages/medusa/src/api/admin/price-preferences/middlewares.ts
@@ -0,0 +1,55 @@
+import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
+import { validateAndTransformBody } from "../../utils/validate-body"
+import { validateAndTransformQuery } from "../../utils/validate-query"
+import * as QueryConfig from "./query-config"
+import {
+  AdminCreatePricePreference,
+  AdminGetPricePreferenceParams,
+  AdminGetPricePreferencesParams,
+  AdminUpdatePricePreference,
+} from "./validators"
+
+export const adminPricePreferencesRoutesMiddlewares: MiddlewareRoute[] = [
+  {
+    method: ["GET"],
+    matcher: "/admin/price-preferences",
+    middlewares: [
+      validateAndTransformQuery(
+        AdminGetPricePreferencesParams,
+        QueryConfig.listPricePreferenceQueryConfig
+      ),
+    ],
+  },
+  {
+    method: ["GET"],
+    matcher: "/admin/price-preferences/:id",
+    middlewares: [
+      validateAndTransformQuery(
+        AdminGetPricePreferenceParams,
+        QueryConfig.retrivePricePreferenceQueryConfig
+      ),
+    ],
+  },
+  {
+    method: ["POST"],
+    matcher: "/admin/price-preferences",
+    middlewares: [
+      validateAndTransformBody(AdminCreatePricePreference),
+      validateAndTransformQuery(
+        AdminGetPricePreferenceParams,
+        QueryConfig.retrivePricePreferenceQueryConfig
+      ),
+    ],
+  },
+  {
+    method: ["POST"],
+    matcher: "/admin/price-preferences/:id",
+    middlewares: [
+      validateAndTransformBody(AdminUpdatePricePreference),
+      validateAndTransformQuery(
+        AdminGetPricePreferenceParams,
+        QueryConfig.retrivePricePreferenceQueryConfig
+      ),
+    ],
+  },
+]
diff --git a/packages/medusa/src/api/admin/price-preferences/query-config.ts b/packages/medusa/src/api/admin/price-preferences/query-config.ts
new file mode 100644
index 0000000000000..d3e2f3490e572
--- /dev/null
+++ b/packages/medusa/src/api/admin/price-preferences/query-config.ts
@@ -0,0 +1,19 @@
+export const adminPricePreferenceRemoteQueryFields = [
+  "id",
+  "attribute",
+  "value",
+  "is_tax_inclusive",
+  "created_at",
+  "deleted_at",
+  "updated_at",
+]
+
+export const retrivePricePreferenceQueryConfig = {
+  defaults: adminPricePreferenceRemoteQueryFields,
+  isList: false,
+}
+
+export const listPricePreferenceQueryConfig = {
+  ...retrivePricePreferenceQueryConfig,
+  isList: true,
+}
diff --git a/packages/medusa/src/api/admin/price-preferences/route.ts b/packages/medusa/src/api/admin/price-preferences/route.ts
new file mode 100644
index 0000000000000..2621ee661fdf9
--- /dev/null
+++ b/packages/medusa/src/api/admin/price-preferences/route.ts
@@ -0,0 +1,45 @@
+import { HttpTypes } from "@medusajs/types"
+import {
+  AuthenticatedMedusaRequest,
+  MedusaResponse,
+} from "../../../types/routing"
+import { refetchEntities, refetchEntity } from "../../utils/refetch-entity"
+import { createPricePreferencesWorkflow } from "@medusajs/core-flows"
+
+export const GET = async (
+  req: AuthenticatedMedusaRequest,
+  res: MedusaResponse
+) => {
+  const { rows: price_preferences, metadata } = await refetchEntities(
+    "price_preference",
+    req.filterableFields,
+    req.scope,
+    req.remoteQueryConfig.fields,
+    req.remoteQueryConfig.pagination
+  )
+  res.json({
+    price_preferences: price_preferences,
+    count: metadata.count,
+    offset: metadata.skip,
+    limit: metadata.take,
+  })
+}
+
+export const POST = async (
+  req: AuthenticatedMedusaRequest<HttpTypes.AdminCreatePricePreference>,
+  res: MedusaResponse
+) => {
+  const workflow = createPricePreferencesWorkflow(req.scope)
+  const { result } = await workflow.run({
+    input: [req.validatedBody],
+  })
+
+  const price_preference = await refetchEntity(
+    "price_preference",
+    result[0].id,
+    req.scope,
+    req.remoteQueryConfig.fields
+  )
+
+  res.status(200).json({ price_preference })
+}
diff --git a/packages/medusa/src/api/admin/price-preferences/validators.ts b/packages/medusa/src/api/admin/price-preferences/validators.ts
new file mode 100644
index 0000000000000..166fdcdc84aad
--- /dev/null
+++ b/packages/medusa/src/api/admin/price-preferences/validators.ts
@@ -0,0 +1,37 @@
+import { z } from "zod"
+import { createFindParams, createSelectParams } from "../../utils/validators"
+
+export const AdminGetPricePreferenceParams = createSelectParams()
+export const AdminGetPricePreferencesParams = createFindParams({
+  offset: 0,
+  limit: 50,
+}).merge(
+  z.object({
+    q: z.string().optional(),
+    id: z.union([z.string(), z.array(z.string())]).optional(),
+    attribute: z.union([z.string(), z.array(z.string())]).optional(),
+    value: z.union([z.string(), z.array(z.string())]).optional(),
+    $and: z.lazy(() => AdminGetPricePreferencesParams.array()).optional(),
+    $or: z.lazy(() => AdminGetPricePreferencesParams.array()).optional(),
+  })
+)
+
+export const AdminCreatePricePreference = z.object({
+  attribute: z.string(),
+  value: z.string(),
+  is_tax_inclusive: z.boolean().optional(),
+})
+
+export type AdminCreatePricePreferencePriceType = z.infer<
+  typeof AdminCreatePricePreference
+>
+
+export const AdminUpdatePricePreference = z.object({
+  attribute: z.string().optional(),
+  value: z.string().optional(),
+  is_tax_inclusive: z.boolean().optional(),
+})
+
+export type AdminUpdatePricePreferenceType = z.infer<
+  typeof AdminUpdatePricePreference
+>
diff --git a/packages/medusa/src/api/middlewares.ts b/packages/medusa/src/api/middlewares.ts
index 98773b386e980..c4aef9349c62a 100644
--- a/packages/medusa/src/api/middlewares.ts
+++ b/packages/medusa/src/api/middlewares.ts
@@ -14,6 +14,7 @@ import { adminInviteRoutesMiddlewares } from "./admin/invites/middlewares"
 import { adminOrderRoutesMiddlewares } from "./admin/orders/middlewares"
 import { adminPaymentRoutesMiddlewares } from "./admin/payments/middlewares"
 import { adminPriceListsRoutesMiddlewares } from "./admin/price-lists/middlewares"
+import { adminPricePreferencesRoutesMiddlewares } from "./admin/price-preferences/middlewares"
 import { adminProductCategoryRoutesMiddlewares } from "./admin/product-categories/middlewares"
 import { adminProductTypeRoutesMiddlewares } from "./admin/product-types/middlewares"
 import { adminProductTagRoutesMiddlewares } from "./admin/product-tags/middlewares"
@@ -78,6 +79,7 @@ export const config: MiddlewaresConfig = {
     ...adminProductRoutesMiddlewares,
     ...adminPaymentRoutesMiddlewares,
     ...adminPriceListsRoutesMiddlewares,
+    ...adminPricePreferencesRoutesMiddlewares,
     ...adminInventoryRoutesMiddlewares,
     ...adminCollectionRoutesMiddlewares,
     ...adminShippingOptionRoutesMiddlewares,
diff --git a/packages/modules/pricing/src/joiner-config.ts b/packages/modules/pricing/src/joiner-config.ts
index 4df8d395756ca..09a538569c845 100644
--- a/packages/modules/pricing/src/joiner-config.ts
+++ b/packages/modules/pricing/src/joiner-config.ts
@@ -2,7 +2,7 @@ import { defineJoinerConfig, Modules } from "@medusajs/utils"
 import { Price, PriceList, PricePreference, PriceSet } from "@models"
 
 export const joinerConfig = defineJoinerConfig(Modules.PRICING, {
-  models: [PriceSet, PriceList, Price],
+  models: [PriceSet, PriceList, Price, PricePreference],
   linkableKeys: {
     price_set_id: PriceSet.name,
     price_list_id: PriceList.name,
diff --git a/packages/modules/pricing/src/services/pricing-module.ts b/packages/modules/pricing/src/services/pricing-module.ts
index 6c96c3943495a..89ae2ea8cb5e0 100644
--- a/packages/modules/pricing/src/services/pricing-module.ts
+++ b/packages/modules/pricing/src/services/pricing-module.ts
@@ -734,7 +734,10 @@ export default class PricingModuleService
       sharedContext
     )
 
-    return await this.baseRepository_.serialize<any[]>(preferences)
+    const serialized = await this.baseRepository_.serialize<
+      PricePreferenceDTO[]
+    >(preferences)
+    return Array.isArray(data) ? serialized : serialized[0]
   }
 
   async upsertPricePreferences(
@@ -800,11 +803,38 @@ export default class PricingModuleService
     data: PricingTypes.UpdatePricePreferenceDTO,
     @MedusaContext() sharedContext: Context = {}
   ): Promise<PricePreferenceDTO | PricePreferenceDTO[]> {
-    const preferences = await this.pricePreferenceService_.update(
-      data,
+    let normalizedInput: ServiceTypes.UpdatePricePreferenceInput[] = []
+    if (isString(idOrSelector)) {
+      // Check if the ID exists, it will throw if not.
+      await this.pricePreferenceService_.retrieve(
+        idOrSelector,
+        {},
+        sharedContext
+      )
+      normalizedInput = [{ id: idOrSelector, ...data }]
+    } else {
+      const pricePreferences = await this.pricePreferenceService_.list(
+        idOrSelector,
+        {},
+        sharedContext
+      )
+
+      normalizedInput = pricePreferences.map((pricePreference) => ({
+        id: pricePreference.id,
+        ...data,
+      }))
+    }
+
+    const updateResult = await this.pricePreferenceService_.update(
+      normalizedInput,
       sharedContext
     )
-    return await this.baseRepository_.serialize<any[]>(preferences)
+
+    const pricePreferences = await this.baseRepository_.serialize<
+      PricePreferenceDTO[] | PricePreferenceDTO
+    >(updateResult)
+
+    return isString(idOrSelector) ? pricePreferences[0] : pricePreferences
   }
 
   @InjectTransactionManager("baseRepository_")