diff --git a/EXILED/Exiled.API/Features/Waves/TimedWave.cs b/EXILED/Exiled.API/Features/Waves/TimedWave.cs
new file mode 100644
index 0000000000..e8e91583bd
--- /dev/null
+++ b/EXILED/Exiled.API/Features/Waves/TimedWave.cs
@@ -0,0 +1,188 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.API.Features.Waves
+{
+ using System.Collections.Generic;
+
+ using System.Linq;
+
+ using PlayerRoles;
+
+ using Respawning;
+
+ using Respawning.Waves;
+
+ ///
+ /// Represents a timed wave.
+ ///
+ public class TimedWave
+ {
+ private readonly TimeBasedWave timedWave;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The that this class should be based off of.
+ ///
+ public TimedWave(TimeBasedWave wave)
+ {
+ timedWave = wave;
+ }
+
+ ///
+ /// Gets the name of the wave timer.
+ ///
+ public string Name => timedWave.GetType().Name;
+
+ ///
+ /// Gets a value indicating whether the wave is a mini wave.
+ ///
+ public bool IsMiniWave => timedWave is IMiniWave;
+
+ ///
+ /// Gets the wave timer instance.
+ ///
+ public WaveTimer Timer => new(timedWave.Timer);
+
+ ///
+ /// Gets the faction of this wave.
+ ///
+ public Faction Faction => timedWave.TargetFaction;
+
+ ///
+ /// Gets the team of this wave.
+ ///
+ public SpawnableTeamType Team => timedWave.TargetFaction.GetSpawnableTeam();
+
+ ///
+ /// Gets the maximum amount of people that can spawn in this wave.
+ ///
+ public int MaxAmount => timedWave.MaxWaveSize;
+
+ ///
+ /// Get the timed waves for the specified faction.
+ ///
+ ///
+ /// The faction to get the waves for.
+ ///
+ ///
+ /// The waves if found.
+ ///
+ ///
+ /// A value indicating whether the wave were found.
+ ///
+ public static bool TryGetTimedWaves(Faction faction, out List waves)
+ {
+ List spawnableWaveBases = WaveManager.Waves.Where(w => w is TimeBasedWave wave && wave.TargetFaction == faction).ToList();
+ if(!spawnableWaveBases.Any())
+ {
+ waves = null;
+ return false;
+ }
+
+ waves = spawnableWaveBases.Select(w => new TimedWave((TimeBasedWave)w)).ToList();
+ return true;
+ }
+
+ ///
+ /// Get the timed wave for the specified team.
+ ///
+ ///
+ /// The team to get the wave for.
+ ///
+ ///
+ /// The waves if found.
+ ///
+ ///
+ /// A value indicating whether the wave were found.
+ ///
+ public static bool TryGetTimedWaves(SpawnableTeamType team, out List waves)
+ {
+ if (team == SpawnableTeamType.None)
+ {
+ waves = null;
+ return false;
+ }
+
+ Faction faction = team == SpawnableTeamType.NineTailedFox ? Faction.FoundationStaff : Faction.FoundationEnemy;
+
+ return TryGetTimedWaves(faction, out waves);
+ }
+
+ ///
+ /// Get the timed wave for the specified type.
+ ///
+ ///
+ /// The wave type to get.
+ ///
+ ///
+ /// The type of wave to get. Must be a . I.e. or .
+ ///
+ ///
+ /// A value indicating whether the wave was found.
+ ///
+ public static bool TryGetTimedWave(out TimedWave wave)
+ where T : TimeBasedWave
+ {
+ foreach (SpawnableWaveBase waveBase in WaveManager.Waves)
+ {
+ if (waveBase is not TimeBasedWave timeWave || timeWave.GetType() != typeof(T))
+ continue;
+
+ wave = new(timeWave);
+ return true;
+ }
+
+ wave = null;
+ return false;
+ }
+
+ ///
+ /// Get all timed waves.
+ ///
+ ///
+ /// A list of all timed waves.
+ ///
+ public static List GetTimedWaves()
+ {
+ List waves = new();
+ foreach (SpawnableWaveBase wave in WaveManager.Waves)
+ {
+ if (wave is TimeBasedWave timeBasedWave)
+ {
+ waves.Add(new (timeBasedWave));
+ }
+ }
+
+ return waves;
+ }
+
+ ///
+ /// Destroys this wave.
+ ///
+ public void Destroy()
+ {
+ timedWave.Destroy();
+ }
+
+ ///
+ /// Populates this wave with the specified amount of roles.
+ ///
+ ///
+ /// The queue to populate.
+ ///
+ ///
+ /// The amount of people to populate.
+ ///
+ public void PopulateQueue(Queue queue, int amount)
+ {
+ timedWave.PopulateQueue(queue, amount);
+ }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.API/Features/Waves/WaveTimer.cs b/EXILED/Exiled.API/Features/Waves/WaveTimer.cs
new file mode 100644
index 0000000000..203f4a1cd2
--- /dev/null
+++ b/EXILED/Exiled.API/Features/Waves/WaveTimer.cs
@@ -0,0 +1,217 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.API.Features.Waves
+{
+ using System;
+
+ using System.Collections.Generic;
+
+ using System.Linq;
+
+ using PlayerRoles;
+
+ using Respawning;
+
+ using Respawning.Waves;
+
+ ///
+ /// Represents a wave timer.
+ ///
+ public class WaveTimer
+ {
+ ///
+ /// Get the native .
+ ///
+ private readonly Respawning.Waves.WaveTimer waveTimer;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The that this class should be based off of.
+ public WaveTimer(Respawning.Waves.WaveTimer wave)
+ {
+ waveTimer = wave;
+ }
+
+ ///
+ /// Gets the name of the wave timer.
+ ///
+ public string Name => waveTimer._wave.GetType().Name;
+
+ ///
+ /// Gets a value indicating whether the wave is a mini wave.
+ ///
+ public bool IsMiniWave => waveTimer._wave is IMiniWave;
+
+ ///
+ /// Gets the amount of time left before the wave spawns.
+ ///
+ public TimeSpan TimeLeft => TimeSpan.FromSeconds(waveTimer.TimeLeft);
+
+ ///
+ /// Gets the amount of time passed since the last wave spawned.
+ ///
+ public TimeSpan TimePassed => TimeSpan.FromSeconds(waveTimer.TimePassed);
+
+ ///
+ /// Gets the amount of time left before this wave unpause.
+ ///
+ public TimeSpan PauseTimeLeft => TimeSpan.FromSeconds(waveTimer.PauseTimeLeft);
+
+ ///
+ /// Gets the amount of time this wave has been paused for.
+ ///
+ public TimeSpan PausedFor => TimeSpan.FromSeconds(waveTimer._pauseTimer);
+
+ ///
+ /// Gets a value indicating whether this wave is paused.
+ ///
+ public bool IsPaused => waveTimer.IsPaused;
+
+ ///
+ /// Gets a value indicating whether this wave is ready to spawn.
+ ///
+ public bool IsReady => waveTimer.IsReadyToSpawn;
+
+ ///
+ /// Gets a value indicating whether this wave is out of respawns.
+ ///
+ public bool IsRespawnable => !waveTimer.IsOutOfRespawns;
+
+ ///
+ /// Gets the default amount of time between a respawn of this wave.
+ ///
+ public float DefaultSpawnInterval => waveTimer.DefaultSpawnInterval;
+
+ ///
+ /// Gets the actual amount of time between a respawn of this wave.
+ ///
+ public float SpawnInterval => waveTimer.SpawnIntervalSeconds;
+
+ ///
+ /// Get the wave timers for the specified faction.
+ ///
+ /// The faction.
+ /// The waves, if any.
+ /// A bool indicating if waves were found.
+ public static bool TryGetWaveTimers(Faction faction, out List waves)
+ {
+ if (!TimedWave.TryGetTimedWaves(faction, out List timedWaves))
+ {
+ waves = null;
+ return false;
+ }
+
+ waves = timedWaves.Select(wave => wave.Timer).ToList();
+ return true;
+ }
+
+ ///
+ /// Gets the wave timers for the specified team.
+ ///
+ /// The team.
+ /// The waves, if any.
+ /// A bool indicating if waves were found.
+ public static bool TryGetWaveTimers(SpawnableTeamType team, out List waves)
+ {
+ if (!TimedWave.TryGetTimedWaves(team, out List timedWaves))
+ {
+ waves = null;
+ return false;
+ }
+
+ waves = timedWaves.Select(wave => wave.Timer).ToList();
+ return true;
+ }
+
+ ///
+ /// Gets all wave timers.
+ ///
+ /// A list of all wave timers.
+ public static List GetWaveTimers()
+ {
+ return TimedWave.GetTimedWaves().Select(l => l.Timer).ToList();
+ }
+
+ ///
+ /// Destroys this wave timer.
+ ///
+ public void Destroy()
+ {
+ waveTimer.Destroy();
+ }
+
+ ///
+ /// Pauses this wave timer.
+ ///
+ ///
+ /// The amount of time to pause this wave timer for.
+ ///
+ public void Pause(float seconds)
+ {
+ waveTimer.Pause(seconds);
+ }
+
+ ///
+ /// Unpauses this wave timer.
+ ///
+ public void Unpause()
+ {
+ waveTimer.Pause(0);
+ }
+
+ ///
+ /// Resets this wave timer.
+ ///
+ ///
+ /// A value indicating whether the should be reset.
+ ///
+ public void Reset(bool resetInterval = true)
+ {
+ waveTimer.Reset(resetInterval);
+ }
+
+ ///
+ /// Update the timer.
+ ///
+ public void Update()
+ {
+ waveTimer.Update();
+ }
+
+ ///
+ /// Add time to the wave timer.
+ ///
+ ///
+ /// The amount of time to add in seconds.
+ ///
+ public void AddTime(float seconds)
+ {
+ waveTimer.AddTime(seconds);
+ }
+
+ ///
+ /// Set the amount of time before the wave spawns.
+ ///
+ ///
+ /// The amount of time before the wave spawns.
+ ///
+ public void SetTime(TimeSpan time) => SetTime((float)time.TotalSeconds);
+
+ ///
+ /// Set the amount of time before the wave spawns.
+ ///
+ ///
+ /// The amount of time before the wave spawns, in seconds.
+ ///
+ public void SetTime(float seconds)
+ {
+ waveTimer.SetTime(seconds);
+ }
+ }
+}
\ No newline at end of file