diff --git a/paper-api/src/main/java/org/bukkit/Raid.java b/paper-api/src/main/java/org/bukkit/Raid.java
new file mode 100644
index 0000000000..983a8c20a0
--- /dev/null
+++ b/paper-api/src/main/java/org/bukkit/Raid.java
@@ -0,0 +1,134 @@
+package org.bukkit;
+
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import org.bukkit.entity.Raider;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents a raid event.
+ */
+public interface Raid {
+
+ /**
+ * Get whether this raid started.
+ *
+ * @return whether raid is started
+ */
+ boolean isStarted();
+
+ /**
+ * Gets the amount of ticks this raid has existed.
+ *
+ * @return active ticks
+ */
+ long getActiveTicks();
+
+ /**
+ * Gets the Bad Omen level of this raid.
+ *
+ * @return Bad Omen level (between 0 and 5)
+ */
+ int getBadOmenLevel();
+
+ /**
+ * Sets the Bad Omen level.
+ *
+ * If the level is higher than 1, there will be an additional wave that as
+ * strong as the final wave.
+ *
+ * @param badOmenLevel new Bad Omen level (from 0-5)
+ * @throws IllegalArgumentException if invalid Bad Omen level
+ */
+ void setBadOmenLevel(int badOmenLevel);
+
+ /**
+ * Gets the center location where the raid occurs.
+ *
+ * @return location
+ */
+ @NotNull
+ Location getLocation();
+
+ /**
+ * Gets the current status of the raid.
+ *
+ * Do not use this method to check if the raid has been started, call
+ * {@link #isStarted()} instead.
+ *
+ * @return Raids status
+ */
+ @NotNull
+ RaidStatus getStatus();
+
+ /**
+ * Gets the number of raider groups which have spawned.
+ *
+ * @return total spawned groups
+ */
+ int getSpawnedGroups();
+
+ /**
+ * Gets the number of raider groups which would spawn.
+ *
+ * This also includes the group which spawns in the additional wave (if
+ * present).
+ *
+ * @return total groups
+ */
+ int getTotalGroups();
+
+ /**
+ * Gets the number of waves in this raid (exclude the additional wave).
+ *
+ * @return number of waves
+ */
+ int getTotalWaves();
+
+ /**
+ * Gets the sum of all raider's health.
+ *
+ * @return total raiders health
+ */
+ float getTotalHealth();
+
+ /**
+ * Get the UUID of all heroes in this raid.
+ *
+ * @return a set of unique ids
+ */
+ @NotNull
+ Set getHeroes();
+
+ /**
+ * Gets all remaining {@link Raider} in the present wave.
+ *
+ * @return a list of current raiders
+ */
+ @NotNull
+ List getRaiders();
+
+ /**
+ * Represents the status of a {@link Raid}.
+ */
+ public enum RaidStatus {
+
+ /**
+ * The raid is in progress.
+ */
+ ONGOING,
+ /**
+ * The raid was beaten by heroes.
+ */
+ VICTORY,
+ /**
+ * The village has fallen (i.e. all villagers died).
+ */
+ LOSS,
+ /**
+ * The raid was terminated.
+ */
+ STOPPED;
+ }
+}
diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java
index 5de5774fbf..0f93b251a7 100644
--- a/paper-api/src/main/java/org/bukkit/World.java
+++ b/paper-api/src/main/java/org/bukkit/World.java
@@ -1961,6 +1961,24 @@ public interface World extends PluginMessageRecipient, Metadatable {
@Nullable
public Location locateNearestStructure(@NotNull Location origin, @NotNull StructureType structureType, int radius, boolean findUnexplored);
+ /**
+ * Finds the nearest raid close to the given location.
+ *
+ * @param location the origin location
+ * @param radius the radius
+ * @return the closest {@link Raid}, or null if no raids were found
+ */
+ @Nullable
+ public Raid locateNearestRaid(@NotNull Location location, int radius);
+
+ /**
+ * Gets all raids that are going on over this world.
+ *
+ * @return the list of all active raids
+ */
+ @NotNull
+ public List getRaids();
+
/**
* Represents various map environment types that a world may be
*/
diff --git a/paper-api/src/main/java/org/bukkit/event/raid/RaidEvent.java b/paper-api/src/main/java/org/bukkit/event/raid/RaidEvent.java
new file mode 100644
index 0000000000..b2ff4bc331
--- /dev/null
+++ b/paper-api/src/main/java/org/bukkit/event/raid/RaidEvent.java
@@ -0,0 +1,29 @@
+package org.bukkit.event.raid;
+
+import org.bukkit.Raid;
+import org.bukkit.World;
+import org.bukkit.event.world.WorldEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents events related to raids.
+ */
+public abstract class RaidEvent extends WorldEvent {
+
+ private final Raid raid;
+
+ protected RaidEvent(@NotNull Raid raid, @NotNull World world) {
+ super(world);
+ this.raid = raid;
+ }
+
+ /**
+ * Returns the raid involved with this event.
+ *
+ * @return Raid
+ */
+ @NotNull
+ public Raid getRaid() {
+ return raid;
+ }
+}
diff --git a/paper-api/src/main/java/org/bukkit/event/raid/RaidFinishEvent.java b/paper-api/src/main/java/org/bukkit/event/raid/RaidFinishEvent.java
new file mode 100644
index 0000000000..f0d280b8c1
--- /dev/null
+++ b/paper-api/src/main/java/org/bukkit/event/raid/RaidFinishEvent.java
@@ -0,0 +1,48 @@
+package org.bukkit.event.raid;
+
+import java.util.Collections;
+import java.util.List;
+import org.bukkit.Raid;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * This event is called when a {@link Raid} was complete with a clear result.
+ */
+public class RaidFinishEvent extends RaidEvent {
+
+ private static final HandlerList handlers = new HandlerList();
+ //
+ private final List winners;
+
+ public RaidFinishEvent(@NotNull Raid raid, @NotNull World world, @NotNull List winners) {
+ super(raid, world);
+ this.winners = winners;
+ }
+
+ /**
+ * Returns an immutable list contains all winners.
+ *
+ * Note: Players who are considered as heroes but were not online at the
+ * end would not be included in this list.
+ *
+ * @return winners
+ */
+ @NotNull
+ public List getWinners() {
+ return Collections.unmodifiableList(winners);
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/paper-api/src/main/java/org/bukkit/event/raid/RaidSpawnWaveEvent.java b/paper-api/src/main/java/org/bukkit/event/raid/RaidSpawnWaveEvent.java
new file mode 100644
index 0000000000..cd58dd7de7
--- /dev/null
+++ b/paper-api/src/main/java/org/bukkit/event/raid/RaidSpawnWaveEvent.java
@@ -0,0 +1,58 @@
+package org.bukkit.event.raid;
+
+import java.util.Collections;
+import java.util.List;
+import org.bukkit.Raid;
+import org.bukkit.World;
+import org.bukkit.entity.Raider;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Called when a raid wave spawns.
+ */
+public class RaidSpawnWaveEvent extends RaidEvent {
+
+ private static final HandlerList handlers = new HandlerList();
+ //
+ private final List raiders;
+ private final Raider leader;
+
+ public RaidSpawnWaveEvent(@NotNull Raid raid, @NotNull World world, @Nullable Raider leader, @NotNull List raiders) {
+ super(raid, world);
+ this.raiders = raiders;
+ this.leader = leader;
+ }
+
+ /**
+ * Returns the patrol leader.
+ *
+ * @return {@link Raider}
+ */
+ @Nullable
+ public Raider getPatrolLeader() {
+ return leader;
+ }
+
+ /**
+ * Returns all {@link Raider} that spawned in this wave.
+ *
+ * @return an immutable list of raiders
+ */
+ @NotNull
+ public List getRaiders() {
+ return Collections.unmodifiableList(raiders);
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/paper-api/src/main/java/org/bukkit/event/raid/RaidStopEvent.java b/paper-api/src/main/java/org/bukkit/event/raid/RaidStopEvent.java
new file mode 100644
index 0000000000..9e852ac973
--- /dev/null
+++ b/paper-api/src/main/java/org/bukkit/event/raid/RaidStopEvent.java
@@ -0,0 +1,66 @@
+package org.bukkit.event.raid;
+
+import org.bukkit.Raid;
+import org.bukkit.World;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Called when a {@link Raid} is stopped.
+ */
+public class RaidStopEvent extends RaidEvent {
+
+ private static final HandlerList handlers = new HandlerList();
+ //
+ private final Reason reason;
+
+ public RaidStopEvent(@NotNull Raid raid, @NotNull World world, @NotNull Reason reason) {
+ super(raid, world);
+ this.reason = reason;
+ }
+
+ /**
+ * Returns the stop reason.
+ *
+ * @return Reason
+ */
+ @NotNull
+ public Reason getReason() {
+ return reason;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+ public enum Reason {
+
+ /**
+ * Because the difficulty has been changed to peaceful.
+ */
+ PEACE,
+ /**
+ * The raid took a long time without a final result.
+ */
+ TIMEOUT,
+ /**
+ * Finished the raid.
+ */
+ FINISHED,
+ /**
+ * Couldn't find a suitable place to spawn raiders.
+ */
+ UNSPAWNABLE,
+ /**
+ * The place where the raid occurs no longer be a village.
+ */
+ NOT_IN_VILLAGE
+ }
+}
diff --git a/paper-api/src/main/java/org/bukkit/event/raid/RaidTriggerEvent.java b/paper-api/src/main/java/org/bukkit/event/raid/RaidTriggerEvent.java
new file mode 100644
index 0000000000..128e43cf12
--- /dev/null
+++ b/paper-api/src/main/java/org/bukkit/event/raid/RaidTriggerEvent.java
@@ -0,0 +1,56 @@
+package org.bukkit.event.raid;
+
+import org.bukkit.Raid;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Called when a {@link Raid} is triggered (e.g: a player with Bad Omen effect
+ * enters a village).
+ */
+public class RaidTriggerEvent extends RaidEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+ //
+ private final Player player;
+ private boolean cancel;
+
+ public RaidTriggerEvent(@NotNull Raid raid, @NotNull World world, @NotNull Player player) {
+ super(raid, world);
+ this.player = player;
+ }
+
+ /**
+ * Returns the player who triggered the raid.
+ *
+ * @return triggering player
+ */
+ @NotNull
+ public Player getPlayer() {
+ return player;
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancel;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancel = cancel;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}