diff --git a/src/applications/herald/controller/HeraldWebhookTestController.php b/src/applications/herald/controller/HeraldWebhookTestController.php
--- a/src/applications/herald/controller/HeraldWebhookTestController.php
+++ b/src/applications/herald/controller/HeraldWebhookTestController.php
@@ -52,6 +52,7 @@
 
         $request = HeraldWebhookRequest::initializeNewWebhookRequest($hook)
           ->setObjectPHID($object->getPHID())
+          ->setTriggerPHIDs(array($viewer->getPHID()))
           ->setIsTestAction(true)
           ->setTransactionPHIDs(mpull($xactions, 'getPHID'))
           ->save();
diff --git a/src/applications/herald/editor/HeraldWebhookEditor.php b/src/applications/herald/editor/HeraldWebhookEditor.php
--- a/src/applications/herald/editor/HeraldWebhookEditor.php
+++ b/src/applications/herald/editor/HeraldWebhookEditor.php
@@ -19,4 +19,13 @@
     return pht('%s created %s.', $author, $object);
   }
 
+  public function getTransactionTypes() {
+    $types = parent::getTransactionTypes();
+
+    $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
+    $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
+
+    return $types;
+  }
+
 }
diff --git a/src/applications/herald/management/HeraldWebhookCallManagementWorkflow.php b/src/applications/herald/management/HeraldWebhookCallManagementWorkflow.php
--- a/src/applications/herald/management/HeraldWebhookCallManagementWorkflow.php
+++ b/src/applications/herald/management/HeraldWebhookCallManagementWorkflow.php
@@ -78,11 +78,14 @@
       ->setLimit(10)
       ->execute();
 
+    $application_phid = id(new PhabricatorHeraldApplication())->getPHID();
+
     $request = HeraldWebhookRequest::initializeNewWebhookRequest($hook)
       ->setObjectPHID($object->getPHID())
       ->setIsTestAction(true)
       ->setIsSilentAction((bool)$args->getArg('silent'))
       ->setIsSecureAction((bool)$args->getArg('secure'))
+      ->setTriggerPHIDs(array($application_phid))
       ->setTransactionPHIDs(mpull($xactions, 'getPHID'))
       ->save();
 
diff --git a/src/applications/herald/phid/HeraldWebhookRequestPHIDType.php b/src/applications/herald/phid/HeraldWebhookRequestPHIDType.php
--- a/src/applications/herald/phid/HeraldWebhookRequestPHIDType.php
+++ b/src/applications/herald/phid/HeraldWebhookRequestPHIDType.php
@@ -31,8 +31,7 @@
 
     foreach ($handles as $phid => $handle) {
       $request = $objects[$phid];
-
-      // TODO: Fill this in.
+      $handle->setName(pht('Webhook Request %d', $request->getID()));
     }
   }
 
diff --git a/src/applications/herald/storage/HeraldWebhookRequest.php b/src/applications/herald/storage/HeraldWebhookRequest.php
--- a/src/applications/herald/storage/HeraldWebhookRequest.php
+++ b/src/applications/herald/storage/HeraldWebhookRequest.php
@@ -116,6 +116,14 @@
     return $this->getProperty('transactionPHIDs', array());
   }
 
+  public function setTriggerPHIDs(array $phids) {
+    return $this->setProperty('triggerPHIDs', $phids);
+  }
+
+  public function getTriggerPHIDs() {
+    return $this->getProperty('triggerPHIDs', array());
+  }
+
   public function setIsSilentAction($bool) {
     return $this->setProperty('silent', $bool);
   }
diff --git a/src/applications/herald/worker/HeraldWebhookWorker.php b/src/applications/herald/worker/HeraldWebhookWorker.php
--- a/src/applications/herald/worker/HeraldWebhookWorker.php
+++ b/src/applications/herald/worker/HeraldWebhookWorker.php
@@ -138,11 +138,19 @@
       );
     }
 
+    $trigger_data = array();
+    foreach ($request->getTriggerPHIDs() as $trigger_phid) {
+      $trigger_data[] = array(
+        'phid' => $trigger_phid,
+      );
+    }
+
     $payload = array(
-      'triggers' => array(),
       'object' => array(
+        'type' => phid_get_type($object->getPHID()),
         'phid' => $object->getPHID(),
       ),
+      'triggers' => $trigger_data,
       'action' => array(
         'test' => $request->getIsTestAction(),
         'silent' => $request->getIsSilentAction(),
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -79,6 +79,7 @@
   private $mailRemovedPHIDs = array();
   private $mailUnexpandablePHIDs = array();
   private $mailMutedPHIDs = array();
+  private $webhookMap = array();
 
   private $transactionQueue = array();
 
@@ -1307,6 +1308,8 @@
       $mail->save();
     }
 
+    $this->queueWebhooks($object, $xactions);
+
     return $xactions;
   }
 
@@ -3660,6 +3663,8 @@
       'mailStamps',
       'mailUnexpandablePHIDs',
       'mailMutedPHIDs',
+      'webhookMap',
+      'silent',
     );
   }
 
@@ -4240,4 +4245,56 @@
     return $this;
   }
 
+  private function queueWebhooks($object, array $xactions) {
+    $hook_viewer = PhabricatorUser::getOmnipotentUser();
+
+    $webhook_map = $this->webhookMap;
+    if (!is_array($webhook_map)) {
+      $webhook_map = array();
+    }
+
+    // Add any "Firehose" hooks to the list of hooks we're going to call.
+    $firehose_hooks = id(new HeraldWebhookQuery())
+      ->setViewer($hook_viewer)
+      ->withStatuses(
+        array(
+          HeraldWebhook::HOOKSTATUS_FIREHOSE,
+        ))
+      ->execute();
+    foreach ($firehose_hooks as $firehose_hook) {
+      // This is "the hook itself is the reason this hook is being called",
+      // since we're including it because it's configured as a firehose
+      // hook.
+      $hook_phid = $firehose_hook->getPHID();
+      $webhook_map[$hook_phid][] = $hook_phid;
+    }
+
+    if (!$webhook_map) {
+      return;
+    }
+
+    // NOTE: We're going to queue calls to disabled webhooks, they'll just
+    // immediately fail in the worker queue. This makes the behavior more
+    // visible.
+
+    $call_hooks = id(new HeraldWebhookQuery())
+      ->setViewer($hook_viewer)
+      ->withPHIDs(array_keys($webhook_map))
+      ->execute();
+
+    foreach ($call_hooks as $call_hook) {
+      $trigger_phids = idx($webhook_map, $call_hook->getPHID());
+
+      $request = HeraldWebhookRequest::initializeNewWebhookRequest($call_hook)
+        ->setObjectPHID($object->getPHID())
+        ->setTransactionPHIDs(mpull($xactions, 'getPHID'))
+        ->setTriggerPHIDs($trigger_phids)
+        ->setIsSilentAction((bool)$this->getIsSilent())
+        ->setIsSecureAction((bool)$this->getMustEncrypt())
+        ->save();
+
+      $request->queueCall();
+    }
+  }
+
 }