diff --git a/ui/src/chronograf/reducers/queryConfigs.js b/ui/src/chronograf/reducers/queryConfigs.js
index 52bd40bb7c..82fe56c7c1 100644
--- a/ui/src/chronograf/reducers/queryConfigs.js
+++ b/ui/src/chronograf/reducers/queryConfigs.js
@@ -37,9 +37,9 @@ export default function queryConfigs(state = {}, action) {
     }
 
     case 'LOAD_KAPACITOR_QUERY': {
-      const {queryID, query} = action.payload;
+      const {query} = action.payload;
       const nextState = Object.assign({}, state, {
-        [queryID]: query,
+        [query.id]: query,
       });
 
       return nextState;
diff --git a/ui/src/index.js b/ui/src/index.js
index fd1ba732fa..12dd3359ab 100644
--- a/ui/src/index.js
+++ b/ui/src/index.js
@@ -119,6 +119,7 @@ const Root = React.createClass({
               <Route path="alerts" component={AlertsApp} />
               <Route path="alert-rules" component={KapacitorRulesPage} />
               <Route path="alert-rules/:ruleID" component={KapacitorRulePage} />
+              <Route path="alert-rules/new" component={KapacitorRulePage} />
             </Route>
             <Route path="tasks" component={TasksPage} />
             <Route path="*" component={NotFound} />
diff --git a/ui/src/kapacitor/actions/view/index.js b/ui/src/kapacitor/actions/view/index.js
index fc62d4652d..df3135d344 100644
--- a/ui/src/kapacitor/actions/view/index.js
+++ b/ui/src/kapacitor/actions/view/index.js
@@ -1,14 +1,38 @@
 import uuid from 'node-uuid';
+import {getRules, getRule} from 'src/kapacitor/apis';
+import {getKapacitor} from 'src/shared/apis';
 
-export function fetchRule() { // ruleID
+export function fetchRule(source, ruleID) {
+  return (dispatch) => {
+    getKapacitor(source).then((kapacitor) => {
+      getRule(kapacitor, ruleID).then(({data: rule}) => {
+        dispatch({
+          type: 'LOAD_RULE',
+          payload: {
+            rule: Object.assign(rule, {queryID: rule.query.id}),
+          },
+        });
+
+        dispatch({
+          type: 'LOAD_KAPACITOR_QUERY',
+          payload: {
+            query: rule.query,
+          },
+        });
+      });
+    });
+  };
+}
+
+export function loadDefaultRule() {
   return (dispatch) => {
-    // do some ajax to get the rule. put it in the payload
     const queryID = uuid.v4();
     dispatch({
-      type: 'LOAD_RULE',
-      payload: {},
+      type: 'LOAD_DEFAULT_RULE',
+      payload: {
+        queryID,
+      },
     });
-
     dispatch({
       type: 'ADD_KAPACITOR_QUERY',
       payload: {
@@ -18,22 +42,17 @@ export function fetchRule() { // ruleID
   };
 }
 
-export function loadDefaultRule() {
+export function fetchRules(source) {
   return (dispatch) => {
-    const queryID = uuid.v4();
-    const ruleID = uuid.v4();
-    dispatch({
-      type: 'LOAD_DEFAULT_RULE',
-      payload: {
-        queryID,
-        ruleID,
-      },
-    });
-    dispatch({
-      type: 'ADD_KAPACITOR_QUERY',
-      payload: {
-        queryId: queryID,
-      },
+    getKapacitor(source).then((kapacitor) => {
+      getRules(kapacitor).then(({data: {rules}}) => {
+        dispatch({
+          type: 'LOAD_RULES',
+          payload: {
+            rules,
+          },
+        });
+      });
     });
   };
 }
diff --git a/ui/src/kapacitor/apis/index.js b/ui/src/kapacitor/apis/index.js
index 3b68e95c35..5a9c7ebd23 100644
--- a/ui/src/kapacitor/apis/index.js
+++ b/ui/src/kapacitor/apis/index.js
@@ -14,3 +14,18 @@ export function getRules(kapacitor) {
     url: kapacitor.links.rules,
   });
 }
+
+export function getRule(kapacitor, ruleID) {
+  return AJAX({
+    method: 'GET',
+    url: `${kapacitor.links.rules}/${ruleID}`,
+  });
+}
+
+export function editRule(rule) {
+  return AJAX({
+    method: 'PUT',
+    url: rule.links.self,
+    data: rule,
+  });
+}
diff --git a/ui/src/kapacitor/constants/index.js b/ui/src/kapacitor/constants/index.js
index b32ec9b34f..f93d7483db 100644
--- a/ui/src/kapacitor/constants/index.js
+++ b/ui/src/kapacitor/constants/index.js
@@ -24,3 +24,5 @@ export const PERIODS = ['1m', '5m', '10m', '30m', '1h', '2h', '1d'];
 export const CHANGES = ['change', '% change'];
 export const SHIFTS = ['1m', '5m', '10m', '30m', '1h', '2h', '1d'];
 export const ALERTS = ['hipchat', 'opsgenie', 'pagerduty', 'sensu', 'slack', 'smtp', 'talk', 'telegram', 'victorops'];
+
+export const DEFAULT_RULE_ID = 'DEFAULT_RULE_ID';
diff --git a/ui/src/kapacitor/containers/KapacitorRulePage.js b/ui/src/kapacitor/containers/KapacitorRulePage.js
index 07ca5d9495..d15fd480cd 100644
--- a/ui/src/kapacitor/containers/KapacitorRulePage.js
+++ b/ui/src/kapacitor/containers/KapacitorRulePage.js
@@ -1,4 +1,5 @@
 import React, {PropTypes} from 'react';
+import {withRouter} from 'react-router';
 import {connect} from 'react-redux';
 import _ from 'lodash';
 import DataSection from '../components/DataSection';
@@ -12,8 +13,8 @@ import LineGraph from 'shared/components/LineGraph';
 const RefreshingLineGraph = AutoRefresh(LineGraph);
 import {getKapacitor, getKapacitorConfig} from 'shared/apis/index';
 import Dropdown from 'shared/components/Dropdown';
-import {ALERTS} from 'src/kapacitor/constants';
-import {createRule} from 'src/kapacitor/apis';
+import {ALERTS, DEFAULT_RULE_ID} from 'src/kapacitor/constants';
+import {createRule, editRule} from 'src/kapacitor/apis';
 
 export const KapacitorRulePage = React.createClass({
   propTypes: {
@@ -49,10 +50,15 @@ export const KapacitorRulePage = React.createClass({
     };
   },
 
+  isEditing() {
+    const {params} = this.props;
+    return params.ruleID && params.ruleID !== 'new';
+  },
+
   componentDidMount() {
-    const {ruleID} = false; // this.props.params;
-    if (ruleID) {
-      this.props.kapacitorActions.fetchRule(ruleID);
+    const {ruleID} = this.props.params;
+    if (this.isEditing()) {
+      this.props.kapacitorActions.fetchRule(this.props.source, ruleID);
     } else {
       this.props.kapacitorActions.loadDefaultRule();
     }
@@ -64,25 +70,34 @@ export const KapacitorRulePage = React.createClass({
         });
         this.setState({kapacitor, enabledAlerts});
       }).catch(() => {
-        this.props.addFlashMessage({type: 'failure', message: `There was a problem communicating with Kapacitor`});
+        this.props.addFlashMessage({type: 'failure', text: `There was a problem communicating with Kapacitor`});
       }).catch(() => {
-        this.props.addFlashMessage({type: 'failure', message: `We couldn't find a configured Kapacitor for this source`});
+        this.props.addFlashMessage({type: 'failure', text: `We couldn't find a configured Kapacitor for this source`});
       });
     });
   },
 
   handleSave() {
-    const {queryConfigs, rules} = this.props;
-    const rule = rules[Object.keys(rules)[0]]; // this.props.params.taskID
-    const newRule = Object.assign({}, rule, {
-      query: queryConfigs[rule.queryID],
-    });
-    delete newRule.queryID;
-    createRule(this.state.kapacitor, newRule).then(() => {
-      // maybe update the default rule in redux state.. and update the URL
-    }).catch(() => {
-      this.props.addFlashMessage({type: 'failure', message: `There was a problem creating the rule`});
-    });
+    const {queryConfigs, rules, params, source} = this.props;
+    if (this.isEditing()) { // If we are editing updated rule if not, create a new one
+      editRule(rules[params.ruleID]).then(() => {
+        this.props.addFlashMessage({type: 'success', text: `Rule successfully updated!`});
+      }).catch(() => {
+        this.props.addFlashMessage({type: 'failure', text: `There was a problem updating the rule`});
+      });
+    } else {
+      const rule = rules[DEFAULT_RULE_ID];
+      const newRule = Object.assign({}, rule, {
+        query: queryConfigs[rule.queryID],
+      });
+      delete newRule.queryID;
+      createRule(this.state.kapacitor, newRule).then(() => {
+        this.props.router.push(`sources/${source.id}/alert-rules`);
+        this.props.addFlashMessage({type: 'success', text: `Rule successfully created`});
+      }).catch(() => {
+        this.props.addFlashMessage({type: 'failure', text: `There was a problem creating the rule`});
+      });
+    }
   },
 
   handleChooseAlert(item) {
@@ -132,13 +147,13 @@ export const KapacitorRulePage = React.createClass({
   },
 
   render() {
-    const {rules, queryConfigs, source} = this.props;
-    const rule = rules[Object.keys(rules)[0]]; // this.props.params.ruleID
+    const {rules, queryConfigs, source, params} = this.props;
+    const rule = this.isEditing() ? rules[params.ruleID] : rules[DEFAULT_RULE_ID];
     const query = rule && queryConfigs[rule.queryID];
     const autoRefreshMs = 30000;
 
-    if (!query) { // or somethin like that
-      return null; // or a spinner or somethin
+    if (!query) {
+      return <div className="page-spinner"></div>;
     }
 
     const queryText = selectStatement({lower: 'now() - 15m'}, query);
@@ -218,7 +233,7 @@ export const KapacitorRulePage = React.createClass({
     return (
       <div className="kapacitor-rule-section">
         <h3>Message</h3>
-        <textarea ref={(r) => this.message = r} onChange={() => this.handleMessageChange(rule)} />
+        <textarea ref={(r) => this.message = r} value={rule.message} onChange={() => this.handleMessageChange(rule)} />
       </div>
     );
   },
@@ -256,4 +271,4 @@ function mapDispatchToProps(dispatch) {
   };
 }
 
-export default connect(mapStateToProps, mapDispatchToProps)(KapacitorRulePage);
+export default connect(mapStateToProps, mapDispatchToProps)(withRouter(KapacitorRulePage));
diff --git a/ui/src/kapacitor/containers/KapacitorRulesPage.js b/ui/src/kapacitor/containers/KapacitorRulesPage.js
index ebe6a11c2c..c42b69b203 100644
--- a/ui/src/kapacitor/containers/KapacitorRulesPage.js
+++ b/ui/src/kapacitor/containers/KapacitorRulesPage.js
@@ -1,39 +1,36 @@
 import React, {PropTypes} from 'react';
+import {connect} from 'react-redux';
+import {bindActionCreators} from 'redux';
 import {Link} from 'react-router';
-import {getRules} from 'src/kapacitor/apis';
-import {getKapacitor} from 'src/shared/apis';
+import * as kapacitorActionCreators from 'src/kapacitor/actions/view';
 
 export const KapacitorRulesPage = React.createClass({
   propTypes: {
     source: PropTypes.shape({
-      id: PropTypes.string.isRequired,
-      name: PropTypes.string.isRequired,
-      type: PropTypes.string.isRequired, // 'influx-enterprise'
-      username: PropTypes.string.isRequired,
       links: PropTypes.shape({
+        proxy: PropTypes.string.isRequired,
+        self: PropTypes.string.isRequired,
         kapacitors: PropTypes.string.isRequired,
-      }).isRequired,
+      }),
+    }),
+    rules: PropTypes.arrayOf(PropTypes.shape({
+      name: PropTypes.string.isRequired,
+      trigger: PropTypes.string.isRequired,
+      message: PropTypes.string.isRequired,
+      alerts: PropTypes.arrayOf(PropTypes.string.isRequired).isRequired,
+    })).isRequired,
+    actions: PropTypes.shape({
+      fetchRules: PropTypes.func.isRequired,
     }).isRequired,
     addFlashMessage: PropTypes.func,
   },
 
-  getInitialState() {
-    return {
-      rules: [],
-    };
-  },
-
   componentDidMount() {
-    getKapacitor(this.props.source).then((kapacitor) => {
-      getRules(kapacitor).then(({data: {rules}}) => {
-        this.setState({rules});
-      });
-    });
+    this.props.actions.fetchRules(this.props.source);
   },
 
   render() {
-    const {rules} = this.state;
-    const {source} = this.props;
+    const {source, rules} = this.props;
 
     return (
       <div className="kapacitor-rules-page">
@@ -48,6 +45,7 @@ export const KapacitorRulesPage = React.createClass({
           <div className="panel panel-minimal">
             <div className="panel-heading u-flex u-ai-center u-jc-space-between">
               <h2 className="panel-title">Alert Rules</h2>
+              <Link to={`/sources/${source.id}/alert-rules/new`} className="btn btn-sm btn-primary">Add New Rule</Link>
             </div>
             <div className="panel-body">
               <table className="table v-center">
@@ -82,4 +80,16 @@ export const KapacitorRulesPage = React.createClass({
   },
 });
 
-export default KapacitorRulesPage;
+function mapStateToProps(state) {
+  return {
+    rules: Object.values(state.rules),
+  };
+}
+
+function mapDispatchToProps(dispatch) {
+  return {
+    actions: bindActionCreators(kapacitorActionCreators, dispatch),
+  };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(KapacitorRulesPage);
diff --git a/ui/src/kapacitor/reducers/rules.js b/ui/src/kapacitor/reducers/rules.js
index f153cc2a51..ff759192d7 100644
--- a/ui/src/kapacitor/reducers/rules.js
+++ b/ui/src/kapacitor/reducers/rules.js
@@ -1,12 +1,13 @@
-import {defaultRuleConfigs} from 'src/kapacitor/constants';
+import {defaultRuleConfigs, DEFAULT_RULE_ID} from 'src/kapacitor/constants';
+import _ from 'lodash';
 
 export default function rules(state = {}, action) {
   switch (action.type) {
     case 'LOAD_DEFAULT_RULE': {
-      const {queryID, ruleID} = action.payload;
+      const {queryID} = action.payload;
       return Object.assign({}, state, {
-        [ruleID]: {
-          id: ruleID,
+        [DEFAULT_RULE_ID]: {
+          id: DEFAULT_RULE_ID,
           queryID,
           trigger: 'threshold',
           values: defaultRuleConfigs.threshold,
@@ -18,10 +19,16 @@ export default function rules(state = {}, action) {
       });
     }
 
+    case 'LOAD_RULES': {
+      const theRules = action.payload.rules;
+      const ruleIDs = theRules.map(r => r.id);
+      return _.zipObject(ruleIDs, theRules);
+    }
+
     case 'LOAD_RULE': {
-      const {ruleID, rule} = action.payload;
+      const {rule} = action.payload;
       return Object.assign({}, state, {
-        [ruleID]: rule,
+        [rule.id]: rule,
       });
     }
 
diff --git a/ui/src/sources/containers/ManageSources.js b/ui/src/sources/containers/ManageSources.js
index b4180db6df..9def5396a2 100644
--- a/ui/src/sources/containers/ManageSources.js
+++ b/ui/src/sources/containers/ManageSources.js
@@ -8,6 +8,13 @@ export const ManageSources = React.createClass({
     location: PropTypes.shape({
       pathname: PropTypes.string.isRequired,
     }).isRequired,
+    source: PropTypes.shape({
+      id: PropTypes.string.isRequired,
+      links: PropTypes.shape({
+        proxy: PropTypes.string.isRequired,
+        self: PropTypes.string.isRequired,
+      }),
+    }),
   },
   getInitialState() {
     return {
@@ -59,7 +66,7 @@ export const ManageSources = React.createClass({
               <div className="panel panel-minimal">
                 <div className="panel-heading u-flex u-ai-center u-jc-space-between">
                   <h2 className="panel-title">{sourcesTitle}</h2>
-                  <Link to={`/sources/1/manage-sources/new`} className="btn btn-sm btn-primary">Add New Source</Link>
+                  <Link to={`/sources/${this.props.source.id}/manage-sources/new`} className="btn btn-sm btn-primary">Add New Source</Link>
                 </div>
                 <div className="panel-body">
                   <div className="table-responsive margin-bottom-zero">