diff --git a/paper-api/src/main/java/org/bukkit/Registry.java b/paper-api/src/main/java/org/bukkit/Registry.java
index 44b8c9111d..f79f4f20ee 100644
--- a/paper-api/src/main/java/org/bukkit/Registry.java
+++ b/paper-api/src/main/java/org/bukkit/Registry.java
@@ -24,6 +24,7 @@ import org.bukkit.generator.structure.StructureType;
 import org.bukkit.inventory.meta.trim.TrimMaterial;
 import org.bukkit.inventory.meta.trim.TrimPattern;
 import org.bukkit.loot.LootTables;
+import org.bukkit.potion.PotionType;
 import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -155,6 +156,12 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
      * @see Material
      */
     Registry<Material> MATERIAL = new SimpleRegistry<>(Material.class, (mat) -> !mat.isLegacy());
+    /**
+     * Server potions.
+     *
+     * @see PotionType
+     */
+    Registry<PotionType> POTION = new SimpleRegistry<>(PotionType.class);
     /**
      * Server statistics.
      *
diff --git a/paper-api/src/main/java/org/bukkit/UnsafeValues.java b/paper-api/src/main/java/org/bukkit/UnsafeValues.java
index 68194147e9..4a9a82540e 100644
--- a/paper-api/src/main/java/org/bukkit/UnsafeValues.java
+++ b/paper-api/src/main/java/org/bukkit/UnsafeValues.java
@@ -12,6 +12,7 @@ import org.bukkit.inventory.ItemStack;
 import org.bukkit.material.MaterialData;
 import org.bukkit.plugin.InvalidPluginException;
 import org.bukkit.plugin.PluginDescriptionFile;
+import org.bukkit.potion.PotionType;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -91,4 +92,12 @@ public interface UnsafeValues {
 
     @Nullable
     FeatureFlag getFeatureFlag(@NotNull NamespacedKey key);
+
+    /**
+     * Do not use, method will get removed, and the plugin won't run
+     *
+     * @param key of the potion type
+     * @return an internal potion data
+     */
+    PotionType.InternalPotionData getInternalPotionData(NamespacedKey key);
 }
diff --git a/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java b/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java
index c2096b5344..8d6caae8ba 100644
--- a/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java
+++ b/paper-api/src/main/java/org/bukkit/entity/AreaEffectCloud.java
@@ -6,6 +6,7 @@ import org.bukkit.Particle;
 import org.bukkit.potion.PotionData;
 import org.bukkit.potion.PotionEffect;
 import org.bukkit.potion.PotionEffectType;
+import org.bukkit.potion.PotionType;
 import org.bukkit.projectiles.ProjectileSource;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -149,17 +150,36 @@ public interface AreaEffectCloud extends Entity {
      * Sets the underlying potion data
      *
      * @param data PotionData to set the base potion state to
+     * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead.
      */
+    @Deprecated
     void setBasePotionData(@NotNull PotionData data);
 
     /**
      * Returns the potion data about the base potion
      *
      * @return a PotionData object
+     * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead.
      */
     @NotNull
+    @Deprecated
     PotionData getBasePotionData();
 
+    /**
+     * Sets the underlying potion type
+     *
+     * @param type PotionType to set the base potion state to
+     */
+    void setBasePotionType(@NotNull PotionType type);
+
+    /**
+     * Returns the potion type about the base potion
+     *
+     * @return a PotionType object
+     */
+    @NotNull
+    PotionType getBasePotionType();
+
     /**
      * Checks for the presence of custom potion effects.
      *
diff --git a/paper-api/src/main/java/org/bukkit/entity/Arrow.java b/paper-api/src/main/java/org/bukkit/entity/Arrow.java
index 8814519df1..8eb0cf31b1 100644
--- a/paper-api/src/main/java/org/bukkit/entity/Arrow.java
+++ b/paper-api/src/main/java/org/bukkit/entity/Arrow.java
@@ -5,6 +5,7 @@ import org.bukkit.Color;
 import org.bukkit.potion.PotionData;
 import org.bukkit.potion.PotionEffect;
 import org.bukkit.potion.PotionEffectType;
+import org.bukkit.potion.PotionType;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -14,17 +15,36 @@ public interface Arrow extends AbstractArrow {
      * Sets the underlying potion data
      *
      * @param data PotionData to set the base potion state to
+     * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead.
      */
+    @Deprecated
     void setBasePotionData(@NotNull PotionData data);
 
     /**
      * Returns the potion data about the base potion
      *
      * @return a PotionData object
+     * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead.
      */
     @NotNull
+    @Deprecated
     PotionData getBasePotionData();
 
+    /**
+     * Sets the underlying potion type
+     *
+     * @param type PotionType to set the base potion state to
+     */
+    void setBasePotionType(@NotNull PotionType type);
+
+    /**
+     * Returns the potion type about the base potion
+     *
+     * @return a PotionType object
+     */
+    @NotNull
+    PotionType getBasePotionType();
+
     /**
      * Gets the color of this arrow.
      *
diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java b/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java
index 8e2f474a44..1113c40fb3 100644
--- a/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java
+++ b/paper-api/src/main/java/org/bukkit/inventory/meta/PotionMeta.java
@@ -5,6 +5,7 @@ import org.bukkit.Color;
 import org.bukkit.potion.PotionData;
 import org.bukkit.potion.PotionEffect;
 import org.bukkit.potion.PotionEffectType;
+import org.bukkit.potion.PotionType;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -17,17 +18,36 @@ public interface PotionMeta extends ItemMeta {
      * Sets the underlying potion data
      *
      * @param data PotionData to set the base potion state to
+     * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #setBasePotionType} instead.
      */
+    @Deprecated
     void setBasePotionData(@NotNull PotionData data);
 
     /**
      * Returns the potion data about the base potion
      *
      * @return a PotionData object
+     * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link #getBasePotionType()} instead.
      */
     @NotNull
+    @Deprecated
     PotionData getBasePotionData();
 
+    /**
+     * Sets the underlying potion type
+     *
+     * @param type PotionType to set the base potion state to
+     */
+    void setBasePotionType(@NotNull PotionType type);
+
+    /**
+     * Returns the potion type about the base potion
+     *
+     * @return a PotionType object
+     */
+    @NotNull
+    PotionType getBasePotionType();
+
     /**
      * Checks for the presence of custom potion effects.
      *
diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionBrewer.java b/paper-api/src/main/java/org/bukkit/potion/PotionBrewer.java
index d21f407cc1..2072f048e1 100644
--- a/paper-api/src/main/java/org/bukkit/potion/PotionBrewer.java
+++ b/paper-api/src/main/java/org/bukkit/potion/PotionBrewer.java
@@ -40,7 +40,9 @@ public interface PotionBrewer {
      * @param upgraded Whether the potion is upgraded
      * @param extended Whether the potion is extended
      * @return The list of effects
+     * @deprecated Upgraded / extended potions are now their own {@link PotionType} use {@link PotionType#getPotionEffects()} instead
      */
     @NotNull
+    @Deprecated
     public Collection<PotionEffect> getEffects(@NotNull PotionType type, boolean upgraded, boolean extended);
 }
diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionData.java b/paper-api/src/main/java/org/bukkit/potion/PotionData.java
index ef5fe586a7..3852a092fa 100644
--- a/paper-api/src/main/java/org/bukkit/potion/PotionData.java
+++ b/paper-api/src/main/java/org/bukkit/potion/PotionData.java
@@ -3,6 +3,10 @@ package org.bukkit.potion;
 import com.google.common.base.Preconditions;
 import org.jetbrains.annotations.NotNull;
 
+/**
+ * @deprecated Upgraded / extended potions are now their own {@link PotionType} use them instead.
+ */
+@Deprecated
 public final class PotionData {
 
     private final PotionType type;
@@ -24,6 +28,8 @@ public final class PotionData {
         Preconditions.checkArgument(!upgraded || type.isUpgradeable(), "Potion Type is not upgradable");
         Preconditions.checkArgument(!extended || type.isExtendable(), "Potion Type is not extendable");
         Preconditions.checkArgument(!upgraded || !extended, "Potion cannot be both extended and upgraded");
+        Preconditions.checkArgument(!type.getKey().getKey().startsWith("strong_"), "Strong potion type cannot be used directly, got %s", type.getKey());
+        Preconditions.checkArgument(!type.getKey().getKey().startsWith("long_"), "Extended potion type cannot be used directly, got %s", type.getKey());
         this.type = type;
         this.extended = extended;
         this.upgraded = upgraded;
diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionType.java b/paper-api/src/main/java/org/bukkit/potion/PotionType.java
index af7dea669c..70456f0866 100644
--- a/paper-api/src/main/java/org/bukkit/potion/PotionType.java
+++ b/paper-api/src/main/java/org/bukkit/potion/PotionType.java
@@ -1,52 +1,99 @@
 package org.bukkit.potion;
 
+import com.google.common.base.Suppliers;
+import java.util.List;
+import java.util.function.Supplier;
+import org.bukkit.Bukkit;
+import org.bukkit.Keyed;
+import org.bukkit.NamespacedKey;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
  * This enum reflects and matches each potion state that can be obtained from
  * the Creative mode inventory
  */
-public enum PotionType {
-    UNCRAFTABLE(null, false, false),
-    WATER(null, false, false),
-    MUNDANE(null, false, false),
-    THICK(null, false, false),
-    AWKWARD(null, false, false),
-    NIGHT_VISION(PotionEffectType.NIGHT_VISION, false, true),
-    INVISIBILITY(PotionEffectType.INVISIBILITY, false, true),
-    JUMP(PotionEffectType.JUMP, true, true),
-    FIRE_RESISTANCE(PotionEffectType.FIRE_RESISTANCE, false, true),
-    SPEED(PotionEffectType.SPEED, true, true),
-    SLOWNESS(PotionEffectType.SLOW, true, true),
-    WATER_BREATHING(PotionEffectType.WATER_BREATHING, false, true),
-    INSTANT_HEAL(PotionEffectType.HEAL, true, false),
-    INSTANT_DAMAGE(PotionEffectType.HARM, true, false),
-    POISON(PotionEffectType.POISON, true, true),
-    REGEN(PotionEffectType.REGENERATION, true, true),
-    STRENGTH(PotionEffectType.INCREASE_DAMAGE, true, true),
-    WEAKNESS(PotionEffectType.WEAKNESS, false, true),
-    LUCK(PotionEffectType.LUCK, false, false),
-    TURTLE_MASTER(PotionEffectType.SLOW, true, true), // TODO: multiple effects
-    SLOW_FALLING(PotionEffectType.SLOW_FALLING, false, true),
+public enum PotionType implements Keyed {
+    UNCRAFTABLE("empty"),
+    WATER("water"),
+    MUNDANE("mundane"),
+    THICK("thick"),
+    AWKWARD("awkward"),
+    NIGHT_VISION("night_vision"),
+    LONG_NIGHT_VISION("long_night_vision"),
+    INVISIBILITY("invisibility"),
+    LONG_INVISIBILITY("long_invisibility"),
+    JUMP("leaping"),
+    LONG_LEAPING("long_leaping"),
+    STRONG_LEAPING("strong_leaping"),
+    FIRE_RESISTANCE("fire_resistance"),
+    LONG_FIRE_RESISTANCE("long_fire_resistance"),
+    SPEED("swiftness"),
+    LONG_SWIFTNESS("long_swiftness"),
+    STRONG_SWIFTNESS("strong_swiftness"),
+    SLOWNESS("slowness"),
+    LONG_SLOWNESS("long_slowness"),
+    STRONG_SLOWNESS("strong_slowness"),
+    WATER_BREATHING("water_breathing"),
+    LONG_WATER_BREATHING("long_water_breathing"),
+    INSTANT_HEAL("healing"),
+    STRONG_HEALING("strong_healing"),
+    INSTANT_DAMAGE("harming"),
+    STRONG_HARMING("strong_harming"),
+    POISON("poison"),
+    LONG_POISON("long_poison"),
+    STRONG_POISON("strong_poison"),
+    REGEN("regeneration"),
+    LONG_REGENERATION("long_regeneration"),
+    STRONG_REGENERATION("strong_regeneration"),
+    STRENGTH("strength"),
+    LONG_STRENGTH("long_strength"),
+    STRONG_STRENGTH("strong_strength"),
+    WEAKNESS("weakness"),
+    LONG_WEAKNESS("long_weakness"),
+    LUCK("luck"),
+    TURTLE_MASTER("turtle_master"),
+    LONG_TURTLE_MASTER("long_turtle_master"),
+    STRONG_TURTLE_MASTER("strong_turtle_master"),
+    SLOW_FALLING("slow_falling"),
+    LONG_SLOW_FALLING("long_slow_falling"),
     ;
 
-    private final PotionEffectType effect;
-    private final boolean upgradeable;
-    private final boolean extendable;
+    private final NamespacedKey key;
+    private final Supplier<InternalPotionData> internalPotionDataSupplier;
 
-    PotionType(/*@Nullable*/ PotionEffectType effect, boolean upgradeable, boolean extendable) {
-        this.effect = effect;
-        this.upgradeable = upgradeable;
-        this.extendable = extendable;
+    PotionType(String key) {
+        this.key = NamespacedKey.minecraft(key);
+        this.internalPotionDataSupplier = Suppliers.memoize(() -> Bukkit.getUnsafe().getInternalPotionData(this.key));
     }
 
+    /**
+     * @return the potion effect type of this potion type
+     * @deprecated Potions can have multiple effects use {@link #getPotionEffects()}
+     */
     @Nullable
+    @Deprecated
     public PotionEffectType getEffectType() {
-        return effect;
+        return internalPotionDataSupplier.get().getEffectType();
     }
 
+    /**
+     * @return a list of all effects this potion type has
+     */
+    @NotNull
+    public List<PotionEffect> getPotionEffects() {
+        return internalPotionDataSupplier.get().getPotionEffects();
+    }
+
+    /**
+     * @return if this potion type is instant
+     * @deprecated PotionType can have multiple effects, some of which can be instant and others not.
+     * Use {@link PotionEffectType#isInstant()} in combination with {@link #getPotionEffects()} and {@link PotionEffect#getType()}
+     */
+    @Deprecated
     public boolean isInstant() {
-        return effect != null && effect.isInstant();
+        return internalPotionDataSupplier.get().isInstant();
     }
 
     /**
@@ -57,7 +104,7 @@ public enum PotionType {
      * @return true if the potion type can be upgraded;
      */
     public boolean isUpgradeable() {
-        return upgradeable;
+        return internalPotionDataSupplier.get().isUpgradeable();
     }
 
     /**
@@ -67,11 +114,11 @@ public enum PotionType {
      * @return true if the potion type can be extended
      */
     public boolean isExtendable() {
-        return extendable;
+        return internalPotionDataSupplier.get().isExtendable();
     }
 
     public int getMaxLevel() {
-        return upgradeable ? 2 : 1;
+        return internalPotionDataSupplier.get().getMaxLevel();
     }
 
     /**
@@ -85,9 +132,35 @@ public enum PotionType {
         if (effectType == null)
             return WATER;
         for (PotionType type : PotionType.values()) {
-            if (effectType.equals(type.effect))
+            if (effectType.equals(type.getEffectType()))
                 return type;
         }
         return null;
     }
+
+    @NotNull
+    @Override
+    public NamespacedKey getKey() {
+        return key;
+    }
+
+    /**
+     * @deprecated Do not use, interface will get removed, and the plugin won't run
+     */
+    @Deprecated
+    @ApiStatus.Internal
+    public interface InternalPotionData {
+
+        PotionEffectType getEffectType();
+
+        List<PotionEffect> getPotionEffects();
+
+        boolean isInstant();
+
+        boolean isUpgradeable();
+
+        boolean isExtendable();
+
+        int getMaxLevel();
+    }
 }