diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7df4b27..e04e046 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,7 +11,7 @@ jobs:
     strategy:
       matrix:
         operating-system: [ubuntu-latest]
-        php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
+        php-versions: ['7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
 
     runs-on: ${{ matrix.operating-system }}
 
diff --git a/README.md b/README.md
index 863dc52..3e6f1dc 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ HTTP Status Codes and Exceptions
 
 ## Requirements
 
-- **php**: ^7.2 | ^8.0
+- **php**: ^7.3 | ^8.0
 
 ## Installing
 
@@ -67,6 +67,14 @@ function getHttpStatusCode() : int
 function getHttpStatusCode() : int
 ```
 
+### Class: Corpus\Http\Exceptions\ClientError\TooManyRequestsException
+
+#### Method: TooManyRequestsException->getHttpStatusCode
+
+```php
+function getHttpStatusCode() : int
+```
+
 ### Class: Corpus\Http\Exceptions\ClientError\UnauthorizedException
 
 #### Method: UnauthorizedException->getHttpStatusCode
diff --git a/composer.json b/composer.json
index 74e2430..90c9337 100644
--- a/composer.json
+++ b/composer.json
@@ -10,7 +10,7 @@
 		}
 	],
 	"require": {
-		"php": "^7.2 | ^8.0"
+		"php": "^7.3 | ^8.0"
 	},
 	"autoload": {
 		"psr-4": {
@@ -18,11 +18,11 @@
 		}
 	},
 	"require-dev": {
-		"phpunit/phpunit": "~7.5 | ~9.0",
-		"squizlabs/php_codesniffer": "^3.5",
 		"corpus/coding-standard": "^0.6.0",
-		"friendsofphp/php-cs-fixer": "^2.17",
-		"phpstan/phpstan": "^1.12"
+		"friendsofphp/php-cs-fixer": "^3.4",
+		"phpstan/phpstan": "^1.12",
+		"phpunit/phpunit": "^9.6",
+		"squizlabs/php_codesniffer": "^3.5"
 	},
 	"config": {
 		"allow-plugins": {
diff --git a/phpstan.neon b/phpstan.neon
index d66b4c1..3b01fc9 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -2,4 +2,4 @@ parameters:
 	level: 9
 	paths:
 		- src
-	phpVersion: 70200
+	phpVersion: 70300
diff --git a/src/Exceptions/ClientError/TooManyRequestsException.php b/src/Exceptions/ClientError/TooManyRequestsException.php
new file mode 100644
index 0000000..bfb4034
--- /dev/null
+++ b/src/Exceptions/ClientError/TooManyRequestsException.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Corpus\Http\Exceptions\ClientError;
+
+use Corpus\Http\Status;
+
+class TooManyRequestsException extends AbstractClientErrorException {
+
+	/** @inheritdoc */
+	public function getHttpStatusCode() : int {
+		return Status::TooManyRequests;
+	}
+
+}
diff --git a/test/ExceptionNamingTest.php b/test/ExceptionNamingTest.php
new file mode 100644
index 0000000..c4511a7
--- /dev/null
+++ b/test/ExceptionNamingTest.php
@@ -0,0 +1,45 @@
+<?php
+
+
+use Corpus\Http\Exceptions\AbstractHttpException;
+use Corpus\Http\Status;
+use PHPUnit\Framework\TestCase;
+
+class ExceptionNamingTest extends TestCase {
+
+	public function testNaming() : void {
+		$dir   = new \RecursiveDirectoryIterator(__DIR__ . '/../src/Exceptions');
+		$ite   = new \RecursiveIteratorIterator($dir);
+		$files = new \RegexIterator($ite, "/Exception\\.php$/");
+		foreach( $files as $file ) {
+			require_once $file;
+		}
+
+		$classes = array_filter(get_declared_classes(), function ($class) {
+			return is_subclass_of($class, AbstractHttpException::class);
+		});
+
+		foreach($classes as $className) {
+			$reflect = new \ReflectionClass($className);
+			if($reflect->isAbstract()) {
+				continue;
+			}
+
+			$inst = $this->getMockBuilder($className)
+				->onlyMethods([])
+				->disableOriginalConstructor()
+				->getMock();
+
+			assert($inst instanceof AbstractHttpException);
+
+			$shortName = $reflect->getShortName();
+			$constName = preg_replace('/Exception$/', '', $shortName);
+
+			$this->assertSame(
+				constant(Status::class . '::' . $constName),
+				$inst->getHttpStatusCode()
+			);
+		}
+	}
+
+}