diff --git a/src/infrastructure/daemon/irc/bot/PhabricatorIRCBot.php b/src/infrastructure/daemon/irc/bot/PhabricatorIRCBot.php
index 9bffa665dd..1bd9f6e1b8 100644
--- a/src/infrastructure/daemon/irc/bot/PhabricatorIRCBot.php
+++ b/src/infrastructure/daemon/irc/bot/PhabricatorIRCBot.php
@@ -1,259 +1,265 @@
 <?php
 
 /*
  * Copyright 2012 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 /**
  * Simple IRC bot which runs as a Phabricator daemon. Although this bot is
  * somewhat useful, it is also intended to serve as a demo of how to write
  * "system agents" which communicate with Phabricator over Conduit, so you can
  * script system interactions and integrate with other systems.
  *
  * NOTE: This is super janky and experimental right now.
  *
  * @group irc
  */
 final class PhabricatorIRCBot extends PhabricatorDaemon {
 
   private $socket;
   private $handlers;
 
   private $writeBuffer;
   private $readBuffer;
 
   private $conduit;
   private $config;
 
   public function run() {
 
     $argv = $this->getArgv();
     if (count($argv) !== 1) {
       throw new Exception("usage: PhabricatorIRCBot <json_config_file>");
     }
 
     $json_raw = Filesystem::readFile($argv[0]);
     $config = json_decode($json_raw, true);
     if (!is_array($config)) {
       throw new Exception("File '{$argv[0]}' is not valid JSON!");
     }
 
     $server   = idx($config, 'server');
     $port     = idx($config, 'port', 6667);
     $handlers = idx($config, 'handlers', array());
     $pass     = idx($config, 'pass');
     $nick     = idx($config, 'nick', 'phabot');
     $user     = idx($config, 'user', $nick);
     $ssl      = idx($config, 'ssl', false);
     $nickpass = idx($config, 'nickpass');
 
     $this->config = $config;
 
     if (!preg_match('/^[A-Za-z0-9_`[{}^|\]\\-]+$/', $nick)) {
       throw new Exception(
         "Nickname '{$nick}' is invalid!");
     }
 
     foreach ($handlers as $handler) {
       $obj = newv($handler, array($this));
       $this->handlers[] = $obj;
     }
 
     $conduit_uri = idx($config, 'conduit.uri');
     if ($conduit_uri) {
       $conduit_user = idx($config, 'conduit.user');
       $conduit_cert = idx($config, 'conduit.cert');
 
+      // Normalize the path component of the URI so users can enter the
+      // domain without the "/api/" part.
+      $conduit_uri = new PhutilURI($conduit_uri);
+      $conduit_uri->setPath('/api/');
+      $conduit_uri = (string)$conduit_uri;
+
       $conduit = new ConduitClient($conduit_uri);
       $response = $conduit->callMethodSynchronous(
         'conduit.connect',
         array(
           'client'            => 'PhabricatorIRCBot',
           'clientVersion'     => '1.0',
           'clientDescription' => php_uname('n').':'.$nick,
           'user'              => $conduit_user,
           'certificate'       => $conduit_cert,
         ));
 
       $this->conduit = $conduit;
     }
 
     $errno = null;
     $error = null;
     if (!$ssl) {
       $socket = fsockopen($server, $port, $errno, $error);
     } else {
       $socket = fsockopen('ssl://'.$server, $port, $errno, $error);
     }
     if (!$socket) {
       throw new Exception("Failed to connect, #{$errno}: {$error}");
     }
     $ok = stream_set_blocking($socket, false);
     if (!$ok) {
       throw new Exception("Failed to set stream nonblocking.");
     }
 
     $this->socket = $socket;
     $this->writeCommand('USER', "{$user} 0 * :{$user}");
     if ($pass) {
       $this->writeCommand('PASS', "{$pass}");
     }
 
     if ($nickpass) {
       $this->writeCommand("NickServ IDENTIFY ", "{$nickpass}");
     }
 
     $this->writeCommand('NICK', "{$nick}");
     $this->runSelectLoop();
   }
 
   public function getConfig($key, $default = null) {
     return idx($this->config, $key, $default);
   }
 
   private function runSelectLoop() {
     do {
       $this->stillWorking();
 
       $read = array($this->socket);
       if (strlen($this->writeBuffer)) {
         $write = array($this->socket);
       } else {
         $write = array();
       }
       $except = array();
 
       $ok = @stream_select($read, $write, $except, $timeout_sec = 1);
       if ($ok === false) {
         throw new Exception(
           "socket_select() failed: ".socket_strerror(socket_last_error()));
       }
 
       if ($read) {
         // Test for connection termination; in PHP, fread() off a nonblocking,
         // closed socket is empty string.
         if (feof($this->socket)) {
           // This indicates the connection was terminated on the other side,
           // just exit via exception and let the overseer restart us after a
           // delay so we can reconnect.
           throw new Exception("Remote host closed connection.");
         }
         do {
           $data = fread($this->socket, 4096);
           if ($data === false) {
             throw new Exception("fread() failed!");
           } else {
             $this->debugLog(true, $data);
             $this->readBuffer .= $data;
           }
         } while (strlen($data));
       }
 
       if ($write) {
         do {
           $len = fwrite($this->socket, $this->writeBuffer);
           if ($len === false) {
             throw new Exception("fwrite() failed!");
           } else {
             $this->debugLog(false, substr($this->writeBuffer, 0, $len));
             $this->writeBuffer = substr($this->writeBuffer, $len);
           }
         } while (strlen($this->writeBuffer));
       }
 
       do {
         $routed_message = $this->processReadBuffer();
       } while ($routed_message);
 
       foreach ($this->handlers as $handler) {
         $handler->runBackgroundTasks();
       }
 
     } while (true);
   }
 
   private function write($message) {
     $this->writeBuffer .= $message;
     return $this;
   }
 
   public function writeCommand($command, $message) {
     return $this->write($command.' '.$message."\r\n");
   }
 
   private function processReadBuffer() {
     $until = strpos($this->readBuffer, "\r\n");
     if ($until === false) {
       return false;
     }
 
     $message = substr($this->readBuffer, 0, $until);
     $this->readBuffer = substr($this->readBuffer, $until + 2);
 
     $pattern =
       '/^'.
       '(?:(?P<sender>:(\S+)) )?'. // This may not be present.
       '(?P<command>[A-Z0-9]+) '.
       '(?P<data>.*)'.
       '$/';
 
     $matches = null;
     if (!preg_match($pattern, $message, $matches)) {
       throw new Exception("Unexpected message from server: {$message}");
     }
 
     $irc_message = new PhabricatorIRCMessage(
       idx($matches, 'sender'),
       $matches['command'],
       $matches['data']);
 
     $this->routeMessage($irc_message);
 
     return true;
   }
 
   private function routeMessage(PhabricatorIRCMessage $message) {
     foreach ($this->handlers as $handler) {
       try {
         $handler->receiveMessage($message);
       } catch (Exception $ex) {
         phlog($ex);
       }
     }
   }
 
   public function __destroy() {
     $this->write("QUIT Goodbye.\r\n");
     fclose($this->socket);
   }
 
   private function debugLog($is_read, $message) {
     if ($this->getTraceMode()) {
       echo $is_read ? '<<< ' : '>>> ';
       echo addcslashes($message, "\0..\37\177..\377");
       echo "\n";
     }
   }
 
   public function getConduit() {
     if (empty($this->conduit)) {
       throw new Exception(
         "This bot is not configured with a Conduit uplink. Set 'conduit.uri', ".
         "'conduit.user' and 'conduit.cert' in the configuration to connect.");
     }
     return $this->conduit;
   }
 
 }
diff --git a/src/infrastructure/daemon/irc/bot/__init__.php b/src/infrastructure/daemon/irc/bot/__init__.php
index 33c26ab4d6..d160b058c3 100644
--- a/src/infrastructure/daemon/irc/bot/__init__.php
+++ b/src/infrastructure/daemon/irc/bot/__init__.php
@@ -1,18 +1,19 @@
 <?php
 /**
  * This file is automatically generated. Lint this module to rebuild it.
  * @generated
  */
 
 
 
 phutil_require_module('phabricator', 'infrastructure/daemon/base');
 phutil_require_module('phabricator', 'infrastructure/daemon/irc/message');
 
 phutil_require_module('phutil', 'conduit/client');
 phutil_require_module('phutil', 'error');
 phutil_require_module('phutil', 'filesystem');
+phutil_require_module('phutil', 'parser/uri');
 phutil_require_module('phutil', 'utils');
 
 
 phutil_require_source('PhabricatorIRCBot.php');