diff --git a/public_html/webhook.php b/public_html/webhook.php
new file mode 100644
index 0000000..12492be
--- /dev/null
+++ b/public_html/webhook.php
@@ -0,0 +1,58 @@
+ 'Invalid signature']);
+ exit;
+}
+
+$data = json_decode($payload, true);
+$repo = $data['repository']['name'] ?? '';
+$ref = $data['ref'] ?? '';
+$pusher = $data['pusher']['name'] ?? 'unknown';
+
+// Only deploy on pushes to main
+if ($ref !== 'refs/heads/main') {
+ echo json_encode(['ok' => true, 'skipped' => "ref $ref is not main"]);
+ exit;
+}
+
+$repoMap = [
+ 'jarvis' => '/home/jarvis.orbishosting.com',
+ 'tomsjavajive' => '/home/tomsjavajive.com/public_html',
+ 'epictravelexpeditions' => '/home/epictravelexpeditions.com/public_html',
+ 'parkerslingshotrentals' => '/home/parkerslingshotrentals.com/public_html',
+ 'orbishosting' => '/home/orbishosting.com/public_html',
+ 'orbis-hosting-portal' => '/home/orbis.orbishosting.com/public_html',
+ 'tomtomgames' => '/home/tomtomgames.com/public_html',
+ 'infra' => '/tmp/infra-current',
+];
+
+if (!isset($repoMap[$repo])) {
+ http_response_code(404);
+ echo json_encode(['error' => "Unknown repo: $repo"]);
+ exit;
+}
+
+$path = $repoMap[$repo];
+file_put_contents(DEPLOY_QUEUE, $path . "\n", FILE_APPEND | LOCK_EX);
+
+$msg = "[" . date('Y-m-d H:i:s') . "] Queued deploy: $repo by $pusher -> $path";
+file_put_contents(DEPLOY_LOG, $msg . "\n", FILE_APPEND | LOCK_EX);
+
+echo json_encode(['ok' => true, 'queued' => $repo, 'path' => $path]);