diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/RundeckApi.java b/rd-api-client/src/main/java/org/rundeck/client/api/RundeckApi.java
index 8f28cce1..5657deab 100644
--- a/rd-api-client/src/main/java/org/rundeck/client/api/RundeckApi.java
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/RundeckApi.java
@@ -22,6 +22,9 @@
 import org.rundeck.client.api.model.*;
 import org.rundeck.client.api.model.repository.ArtifactActionMessage;
 import org.rundeck.client.api.model.repository.RepositoryArtifacts;
+import org.rundeck.client.api.model.scheduler.ScheduledJobItem;
+import org.rundeck.client.api.model.scheduler.SchedulerTakeover;
+import org.rundeck.client.api.model.scheduler.SchedulerTakeoverResult;
 import org.rundeck.client.util.Json;
 import org.rundeck.client.util.Xml;
 import retrofit2.Call;
@@ -445,6 +448,13 @@ Call<BulkExecutionDeleteResponse> deleteExecutions(
             @Body BulkExecutionDelete delete
     );
 
+    /**
+     * Delete all executions for a job.
+     */
+    @Headers("Accept: application/json")
+    @DELETE("job/{id}/executions")
+    Call<BulkExecutionDeleteResponse> deleteAllJobExecutions(@Path("id") String id);
+
     @Headers("Accept: application/json")
     @GET("execution/{id}/abort")
     Call<AbortResult> abortExecution(@Path("id") String id);
@@ -453,6 +463,9 @@ Call<BulkExecutionDeleteResponse> deleteExecutions(
     @GET("execution/{id}")
     Call<Execution> getExecution(@Path("id") String id);
 
+    @Headers("Accept: application/json")
+    @GET("execution/{id}/state")
+    Call<ExecutionStateResponse> getExecutionState(@Path("id") String id);
 
     @Headers("Accept: application/json")
     @DELETE("execution/{id}")
@@ -739,6 +752,15 @@ Call<Void> deleteSystemAclPolicy(
     @GET("scheduler/server/{uuid}/jobs")
     Call<List<ScheduledJobItem>> listSchedulerJobs(@Path("uuid") String uuid);
 
+    /**
+     * Tell a Rundeck server in cluster mode to claim all scheduled jobs from another cluster server.
+     *
+     * @see <a href="https://rundeck.org/docs/api/#takeover-schedule-in-cluster-mode">API</a>
+     */
+    @Headers("Accept: application/json")
+    @PUT("scheduler/takeover")
+    Call<SchedulerTakeoverResult> takeoverSchedule(@Body SchedulerTakeover schedulerTakeover);
+
 
     /**
      * <a href="http://rundeck.org/docs/api/index.html#get-project-scm-config">
@@ -1085,4 +1107,50 @@ Call<Execution> retryJob(
     @Headers("Accept: application/json")
     @POST("plugins/uninstall/{pluginId}")
     Call<ArtifactActionMessage> uninstallPlugin(@Path("pluginId") String pluginId);
+
+    /* Bulk toggle job execution. */
+
+    /**
+     * @see <a href="https://rundeck.org/docs/api/#bulk-toggle-job-execution">API</a>
+     */
+    @Json
+    @Headers("Accept: application/json")
+    @POST("jobs/execution/enable")
+    Call<BulkToggleJobExecutionResponse> bulkEnableJobs(
+        @Body IdList ids
+    );
+
+    /**
+     * @see <a href="https://rundeck.org/docs/api/#bulk-toggle-job-execution">API</a>
+     */
+    @Json
+    @Headers("Accept: application/json")
+    @POST("jobs/execution/disable")
+    Call<BulkToggleJobExecutionResponse> bulkDisableJobs(
+        @Body IdList ids
+    );
+
+    /* Bulk toggle job schedule. */
+
+    /**
+     * @see <a href="https://rundeck.org/docs/api/#bulk-toggle-job-schedules">API</a>
+     */
+    @Json
+    @Headers("Accept: application/json")
+    @POST("jobs/schedule/enable")
+    Call<BulkToggleJobScheduleResponse> bulkEnableJobSchedule(
+        @Body IdList ids
+    );
+
+    /**
+     * @see <a href="https://rundeck.org/docs/api/#bulk-toggle-job-schedules">API</a>
+     */
+    @Json
+    @Headers("Accept: application/json")
+    @POST("jobs/schedule/disable")
+    Call<BulkToggleJobScheduleResponse> bulkDisableJobSchedule(
+        @Body IdList ids
+    );
+
+
 }
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/BulkToggleJobExecutionResponse.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/BulkToggleJobExecutionResponse.java
new file mode 100644
index 00000000..97b73fde
--- /dev/null
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/BulkToggleJobExecutionResponse.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2017 Rundeck, Inc. (http://rundeck.com)
+ *
+ * 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.
+ */
+
+package org.rundeck.client.api.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class BulkToggleJobExecutionResponse {
+  private int          requestCount;
+  private boolean      enabled;
+  private boolean      allsuccessful;
+  private List<Result> succeeded;
+  private List<Result> failed;
+
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  public static class Result {
+    private String id;
+    private String errorCode;
+    private String message;
+
+    public String getId() {
+      return id;
+    }
+
+    public void setId(String id) {
+      this.id = id;
+    }
+
+    public String getErrorCode() {
+      return errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+      this.errorCode = errorCode;
+    }
+
+    public String getMessage() {
+      return message;
+    }
+
+    public void setMessage(String message) {
+      this.message = message;
+    }
+
+    @Override
+    public String toString() {
+      return String.format("* #%s: '%s'", id, message);
+    }
+  }
+
+  public int getRequestCount() {
+    return requestCount;
+  }
+
+  public void setRequestCount(int requestCount) {
+    this.requestCount = requestCount;
+  }
+
+  public boolean isEnabled() {
+    return enabled;
+  }
+
+  public void setEnabled(boolean enabled) {
+    this.enabled = enabled;
+  }
+
+  public boolean isAllsuccessful() {
+    return allsuccessful;
+  }
+
+  public void setAllsuccessful(boolean allsuccessful) {
+    this.allsuccessful = allsuccessful;
+  }
+
+  public List<Result> getSucceeded() {
+    return succeeded;
+  }
+
+  public void setSucceeded(List<Result> succeeded) {
+    this.succeeded = succeeded;
+  }
+
+  public List<Result> getFailed() {
+    return failed;
+  }
+
+  public void setFailed(List<Result> failed) {
+    this.failed = failed;
+  }
+
+  @Override
+  public String toString() {
+    return "BulkToggleJobExecutionResponse{" +
+        "requestCount=" + requestCount +
+        ", enabled=" + enabled +
+        ", allsuccessful=" + allsuccessful +
+        ", succeeded=" + succeeded +
+        ", failed=" + failed +
+        '}';
+  }
+}
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/BulkToggleJobScheduleResponse.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/BulkToggleJobScheduleResponse.java
new file mode 100644
index 00000000..5743a700
--- /dev/null
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/BulkToggleJobScheduleResponse.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2017 Rundeck, Inc. (http://rundeck.com)
+ *
+ * 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.
+ */
+
+package org.rundeck.client.api.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class BulkToggleJobScheduleResponse {
+  private int          requestCount;
+  private boolean      enabled;
+  private boolean      allsuccessful;
+  private List<Result> succeeded;
+  private List<Result> failed;
+
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  public static class Result {
+    private String id;
+    private String errorCode;
+    private String message;
+
+    public String getId() {
+      return id;
+    }
+
+    public void setId(String id) {
+      this.id = id;
+    }
+
+    public String getErrorCode() {
+      return errorCode;
+    }
+
+    public void setErrorCode(String errorCode) {
+      this.errorCode = errorCode;
+    }
+
+    public String getMessage() {
+      return message;
+    }
+
+    public void setMessage(String message) {
+      this.message = message;
+    }
+
+    @Override
+    public String toString() {
+      return String.format("* #%s: '%s'", id, message);
+    }
+  }
+
+  public int getRequestCount() {
+    return requestCount;
+  }
+
+  public void setRequestCount(int requestCount) {
+    this.requestCount = requestCount;
+  }
+
+  public boolean isEnabled() {
+    return enabled;
+  }
+
+  public void setEnabled(boolean enabled) {
+    this.enabled = enabled;
+  }
+
+  public boolean isAllsuccessful() {
+    return allsuccessful;
+  }
+
+  public void setAllsuccessful(boolean allsuccessful) {
+    this.allsuccessful = allsuccessful;
+  }
+
+  public List<Result> getSucceeded() {
+    return succeeded;
+  }
+
+  public void setSucceeded(List<Result> succeeded) {
+    this.succeeded = succeeded;
+  }
+
+  public List<Result> getFailed() {
+    return failed;
+  }
+
+  public void setFailed(List<Result> failed) {
+    this.failed = failed;
+  }
+
+  @Override
+  public String toString() {
+    return "BulkToggleJobScheduleResponse{" +
+        "requestCount=" + requestCount +
+        ", enabled=" + enabled +
+        ", allsuccessful=" + allsuccessful +
+        ", succeeded=" + succeeded +
+        ", failed=" + failed +
+        '}';
+  }
+}
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/ExecutionStateResponse.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/ExecutionStateResponse.java
new file mode 100644
index 00000000..31946f7f
--- /dev/null
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/ExecutionStateResponse.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2017 Rundeck, Inc. (http://rundeck.com)
+ *
+ * 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.
+ */
+
+package org.rundeck.client.api.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.rundeck.client.util.RdClientConfig;
+import org.simpleframework.xml.Element;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ExecutionStateResponse {
+
+  private String   executionId;
+  private String   serverNode;
+  private String   executionState;
+  private Boolean  completed;
+  private Integer  stepCount;
+  private DateInfo updateTime;
+  private DateInfo startTime;
+  private DateInfo endTime;
+
+  private List<String> targetNodes;
+  private List<String> allNodes;
+
+  private Map<String, List<StepState>> nodes;
+
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  public static class StepState {
+    private String stepctx;
+    private String executionState;
+
+    public String getStepctx() {
+      return stepctx;
+    }
+
+    public void setStepctx(String stepctx) {
+      this.stepctx = stepctx;
+    }
+
+    public String getExecutionState() {
+      return executionState;
+    }
+
+    public void setExecutionState(String executionState) {
+      this.executionState = executionState;
+    }
+
+    @Override
+    public String toString() {
+      return "{" +
+          "stepctx='" + stepctx + '\'' +
+          ", executionState='" + executionState + '\'' +
+          '}';
+    }
+  }
+
+  public String execInfoString(RdClientConfig config) {
+    return String.format(
+        "%s %s %s %s %s",
+        executionId,
+        executionState,
+        null != startTime ? startTime.format(config.getDateFormat()) : "-",
+        null != updateTime ? updateTime.format(config.getDateFormat()) : "-",
+        null != endTime ? endTime.format(config.getDateFormat()) : "-"
+    );
+  }
+
+  public String nodeStatusString() {
+    if (nodes == null) {
+      return "No node status.";
+    }
+
+    return nodes.entrySet().stream()
+        .map(nodeEntry -> Optional.ofNullable(nodeEntry.getValue())
+            .map(steps -> steps.stream()
+                .map(step -> String.format("%s:%-10s", step.getStepctx(), step.getExecutionState()))
+                .collect(Collectors.joining(
+                    " ",
+                    String.format("%-15s ",nodeEntry.getKey() + ":"),
+                    ""
+                )))
+            .orElse(nodeEntry.getKey() + ": No Status."))
+        .collect(Collectors.joining(
+            "\n",
+            "Node Step Status: \n",
+            ""
+        ));
+  }
+
+  @Override
+  public String toString() {
+    return "ExecutionStateResponse{" +
+        "executionId='" + executionId + '\'' +
+        ", serverNode='" + serverNode + '\'' +
+        ", executionState='" + executionState + '\'' +
+        ", completed=" + completed +
+        ", stepCount=" + stepCount +
+        ", updateTime=" + updateTime +
+        ", startTime=" + startTime +
+        ", endTime=" + endTime +
+        ", targetNodes=" + targetNodes +
+        ", allNodes=" + allNodes +
+        ", nodes=" + nodes +
+        '}';
+  }
+
+
+  public String getExecutionId() {
+    return executionId;
+  }
+
+  public void setExecutionId(String executionId) {
+    this.executionId = executionId;
+  }
+
+  public String getServerNode() {
+    return serverNode;
+  }
+
+  public void setServerNode(String serverNode) {
+    this.serverNode = serverNode;
+  }
+
+  public String getExecutionState() {
+    return executionState;
+  }
+
+  public void setExecutionState(String executionState) {
+    this.executionState = executionState;
+  }
+
+  public Boolean getCompleted() {
+    return completed;
+  }
+
+  public void setCompleted(Boolean completed) {
+    this.completed = completed;
+  }
+
+  public Integer getStepCount() {
+    return stepCount;
+  }
+
+  public void setStepCount(Integer stepCount) {
+    this.stepCount = stepCount;
+  }
+
+  public DateInfo getUpdateTime() {
+    return updateTime;
+  }
+
+  public void setUpdateTime(DateInfo updateTime) {
+    this.updateTime = updateTime;
+  }
+
+  public DateInfo getStartTime() {
+    return startTime;
+  }
+
+  public void setStartTime(DateInfo startTime) {
+    this.startTime = startTime;
+  }
+
+  public DateInfo getEndTime() {
+    return endTime;
+  }
+
+  public void setEndTime(DateInfo endTime) {
+    this.endTime = endTime;
+  }
+
+  public List<String> getTargetNodes() {
+    return targetNodes;
+  }
+
+  public void setTargetNodes(List<String> targetNodes) {
+    this.targetNodes = targetNodes;
+  }
+
+  public List<String> getAllNodes() {
+    return allNodes;
+  }
+
+  public void setAllNodes(List<String> allNodes) {
+    this.allNodes = allNodes;
+  }
+
+  public Map<String, List<StepState>> getNodes() {
+    return nodes;
+  }
+
+  public void setNodes(Map<String, List<StepState>> nodes) {
+    this.nodes = nodes;
+  }
+}
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/IdList.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/IdList.java
new file mode 100644
index 00000000..b3651511
--- /dev/null
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/IdList.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017 Rundeck, Inc. (http://rundeck.com)
+ *
+ * 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.
+ */
+
+package org.rundeck.client.api.model;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class IdList {
+    private List<String> ids;
+
+    public IdList(final List<String> ids) {
+        this.ids = ids;
+    }
+
+    public List<String> getIds() {
+        return ids;
+    }
+
+    public void setIds(List<String> ids) {
+        this.ids = ids;
+    }
+}
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/ScheduledJobItem.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/ScheduledJobItem.java
similarity index 96%
rename from rd-api-client/src/main/java/org/rundeck/client/api/model/ScheduledJobItem.java
rename to rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/ScheduledJobItem.java
index 01c98719..749bba24 100644
--- a/rd-api-client/src/main/java/org/rundeck/client/api/model/ScheduledJobItem.java
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/ScheduledJobItem.java
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package org.rundeck.client.api.model;
+package org.rundeck.client.api.model.scheduler;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import org.rundeck.client.api.model.JobItem;
 
 import java.util.HashMap;
 import java.util.LinkedHashMap;
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/SchedulerTakeover.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/SchedulerTakeover.java
new file mode 100644
index 00000000..84196136
--- /dev/null
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/SchedulerTakeover.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017 Rundeck, Inc. (http://rundeck.com)
+ *
+ * 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.
+ */
+
+package org.rundeck.client.api.model.scheduler;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SchedulerTakeover {
+
+  private TakeoverServerItem server;
+  private String project;
+  private JobId  job;
+
+
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  @JsonInclude(JsonInclude.Include.NON_NULL)
+  public static class JobId {
+    public String id;
+
+    public String getId() {
+      return id;
+    }
+
+    public JobId setId(String id) {
+      this.id = id;
+      return this;
+    }
+
+    @Override
+    public String toString() {
+      return "{" +
+          "id='" + id + '\'' +
+          '}';
+    }
+  }
+
+  // getters setters
+
+  public TakeoverServerItem getServer() {
+    return server;
+  }
+
+  public SchedulerTakeover setServer(TakeoverServerItem server) {
+    this.server = server;
+    return this;
+  }
+
+  public String getProject() {
+    return project;
+  }
+
+  public SchedulerTakeover setProject(String project) {
+    this.project = project;
+    return this;
+  }
+
+  public JobId getJob() {
+    return job;
+  }
+
+  public SchedulerTakeover setJob(JobId job) {
+    this.job = job;
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    return "SchedulerTakeover{" +
+        "server=" + server +
+        ", project='" + project + '\'' +
+        ", job=" + job +
+        '}';
+  }
+}
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/SchedulerTakeoverResult.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/SchedulerTakeoverResult.java
new file mode 100644
index 00000000..f88cb340
--- /dev/null
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/SchedulerTakeoverResult.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2017 Rundeck, Inc. (http://rundeck.com)
+ *
+ * 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.
+ */
+
+package org.rundeck.client.api.model.scheduler;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+import java.util.List;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SchedulerTakeoverResult {
+
+
+  private String           message;
+  private int              apiversion;
+  private boolean          success;
+  private TakeoverSchedule takeoverSchedule;
+  private TakeoverSelf     self;
+
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  public static class TakeoverSelf {
+    private TakeoverServerItem server;
+
+    public TakeoverServerItem getServer() {
+      return server;
+    }
+
+    public TakeoverSelf setServer(TakeoverServerItem server) {
+      this.server = server;
+      return this;
+    }
+
+    @Override
+    public String toString() {
+      return "{" +
+          "server=" + server +
+          '}';
+    }
+  }
+
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  public static class TakeoverSchedule {
+    private TakeoverServerItem server;
+    private String             project;
+    private JobTakeoverResult  jobs;
+
+    public TakeoverServerItem getServer() {
+      return server;
+    }
+
+    public TakeoverSchedule setServer(TakeoverServerItem server) {
+      this.server = server;
+      return this;
+    }
+
+    public String getProject() {
+      return project;
+    }
+
+    public TakeoverSchedule setProject(String project) {
+      this.project = project;
+      return this;
+    }
+
+    public JobTakeoverResult getJobs() {
+      return jobs;
+    }
+
+    public TakeoverSchedule setJobs(JobTakeoverResult jobs) {
+      this.jobs = jobs;
+      return this;
+    }
+
+    @Override
+    public String toString() {
+      return "{" +
+          "server=" + server +
+          ", project='" + project + '\'' +
+          ", jobs=" + jobs +
+          '}';
+    }
+  }
+
+  @JsonIgnoreProperties(ignoreUnknown = true)
+  public static class JobTakeoverResult {
+    private int                   total;
+    private List<TakeoverJobItem> successful;
+    private List<TakeoverJobItem> failed;
+
+    public int getTotal() {
+      return total;
+    }
+
+    public JobTakeoverResult setTotal(int total) {
+      this.total = total;
+      return this;
+    }
+
+    public List<TakeoverJobItem> getSuccessful() {
+      return successful;
+    }
+
+    public JobTakeoverResult setSuccessful(List<TakeoverJobItem> successful) {
+      this.successful = successful;
+      return this;
+    }
+
+    public List<TakeoverJobItem> getFailed() {
+      return failed;
+    }
+
+    public JobTakeoverResult setFailed(List<TakeoverJobItem> failed) {
+      this.failed = failed;
+      return this;
+    }
+
+    @Override
+    public String toString() {
+      return "{" +
+          "total=" + total +
+          ", successful=" + successful +
+          ", failed=" + failed +
+          '}';
+    }
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public SchedulerTakeoverResult setMessage(String message) {
+    this.message = message;
+    return this;
+  }
+
+  public int getApiversion() {
+    return apiversion;
+  }
+
+  public SchedulerTakeoverResult setApiversion(int apiversion) {
+    this.apiversion = apiversion;
+    return this;
+  }
+
+  public boolean isSuccess() {
+    return success;
+  }
+
+  public SchedulerTakeoverResult setSuccess(boolean success) {
+    this.success = success;
+    return this;
+  }
+
+  public TakeoverSchedule getTakeoverSchedule() {
+    return takeoverSchedule;
+  }
+
+  public SchedulerTakeoverResult setTakeoverSchedule(TakeoverSchedule takeoverSchedule) {
+    this.takeoverSchedule = takeoverSchedule;
+    return this;
+  }
+
+  public TakeoverSelf getSelf() {
+    return self;
+  }
+
+  public SchedulerTakeoverResult setSelf(TakeoverSelf self) {
+    this.self = self;
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    return "SchedulerTakeoverResult{" +
+        "message='" + message + '\'' +
+        ", apiversion=" + apiversion +
+        ", success=" + success +
+        ", takeoverSchedule=" + takeoverSchedule +
+        ", self=" + self +
+        '}';
+  }
+}
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/TakeoverJobItem.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/TakeoverJobItem.java
new file mode 100644
index 00000000..6511eea9
--- /dev/null
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/TakeoverJobItem.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2017 Rundeck, Inc. (http://rundeck.com)
+ *
+ * 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.
+ */
+
+package org.rundeck.client.api.model.scheduler;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.rundeck.client.api.model.JobItem;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TakeoverJobItem extends JobItem {
+    private String previousOwner;
+
+    @JsonProperty("previous-owner")
+    public String getPreviousOwner() {
+        return previousOwner;
+    }
+
+    @JsonProperty("previous-owner")
+    public TakeoverJobItem setPreviousOwner(String previousOwner) {
+        this.previousOwner = previousOwner;
+        return this;
+    }
+
+
+    @Override
+    public String toString() {
+        return super.toBasicString() +
+            " previousOwner='" + previousOwner + '\'';
+    }
+}
diff --git a/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/TakeoverServerItem.java b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/TakeoverServerItem.java
new file mode 100644
index 00000000..3c9a6bd1
--- /dev/null
+++ b/rd-api-client/src/main/java/org/rundeck/client/api/model/scheduler/TakeoverServerItem.java
@@ -0,0 +1,38 @@
+package org.rundeck.client.api.model.scheduler;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class TakeoverServerItem {
+
+  public String  uuid;
+  public Boolean all;
+
+  public String getUuid() {
+    return uuid;
+  }
+
+  public TakeoverServerItem setUuid(String uuid) {
+    this.uuid = uuid;
+    return this;
+  }
+
+  public Boolean getAll() {
+    return all;
+  }
+
+  public TakeoverServerItem setAll(Boolean all) {
+    this.all = all;
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    return "{" +
+        "uuid='" + uuid + '\'' +
+        ", all=" + all +
+        '}';
+  }
+}
diff --git a/src/main/java/org/rundeck/client/tool/Main.java b/src/main/java/org/rundeck/client/tool/Main.java
index 83da415b..5bb4dd0f 100644
--- a/src/main/java/org/rundeck/client/tool/Main.java
+++ b/src/main/java/org/rundeck/client/tool/Main.java
@@ -16,6 +16,7 @@
 
 package org.rundeck.client.tool;
 
+import org.rundeck.client.api.model.scheduler.ScheduledJobItem;
 import org.rundeck.client.tool.commands.repository.Plugins;
 import org.rundeck.toolbelt.*;
 import org.rundeck.toolbelt.format.json.jackson.JsonFormatter;
diff --git a/src/main/java/org/rundeck/client/tool/commands/Executions.java b/src/main/java/org/rundeck/client/tool/commands/Executions.java
index 8a6b75a5..92f6385b 100644
--- a/src/main/java/org/rundeck/client/tool/commands/Executions.java
+++ b/src/main/java/org/rundeck/client/tool/commands/Executions.java
@@ -240,6 +240,24 @@ public void info(Info options, CommandOutput out) throws IOException, InputError
         outputExecutionList(options, out, getAppConfig(), Collections.singletonList(execution).stream());
     }
 
+
+    /*
+    Executions state command
+     */
+    @CommandLineInterface(application = "state") interface State extends ExecutionIdOption {
+    }
+
+    @Command(description = "Get detail about the node and step state of an execution by ID.")
+    public void state(State options, CommandOutput out) throws IOException, InputError {
+        ExecutionStateResponse response = apiCall(api -> api.getExecutionState(options.getId()));
+        out.info(response.execInfoString(getAppConfig()));
+        out.output(response.nodeStatusString());
+    }
+
+
+    /* END state command */
+
+
     @CommandLineInterface(application = "list") interface ListCmd
             extends ExecutionListOptions, ProjectNameOptions, ExecutionResultOptions
     {
@@ -573,6 +591,48 @@ public static void outputExecutionList(
         executions.forEach(e -> out.output(outformat.apply(e)));
     }
 
+
+    // Delete All executions for job command.
+    @CommandLineInterface(application = "deleteall") interface DeleteAllExecCmd {
+        @Option(longName = "confirm", shortName = "y", description = "Force confirmation of delete request.")
+        boolean isConfirm();
+
+        @Option(shortName = "i", longName = "id", description = "Job ID")
+        String getId();
+    }
+
+    @Command(description = "Delete all executions for a job.")
+    public boolean deleteall(DeleteAllExecCmd options, CommandOutput out) throws IOException, InputError {
+
+        if (!options.isConfirm()) {
+            //request confirmation
+            String s = System.console().readLine("Really delete all executions for job %s? (y/N) ", options.getId());
+
+            if (!"y".equals(s)) {
+                out.warning("Not deleting executions.");
+                return false;
+            }
+        }
+
+        BulkExecutionDeleteResponse result = apiCall(api -> api.deleteAllJobExecutions(options.getId()));
+        if (!result.isAllsuccessful()) {
+            out.error(String.format("Failed to delete %d executions:", result.getFailedCount()));
+            out.error(result.getFailures()
+                .stream()
+                .map(BulkExecutionDeleteResponse.DeleteFailure::toString)
+                .collect(Collectors.toList()));
+        }else{
+            out.info(String.format("Deleted %d executions.", result.getSuccessCount()));
+        }
+        return result.isAllsuccessful();
+    }
+
+
+
+
+    // End Delete all executions.
+
+
     @CommandLineInterface(application = "deletebulk") interface BulkDeleteCmd extends QueryCmd {
         @Option(longName = "confirm", shortName = "y", description = "Force confirmation of delete request.")
         boolean isConfirm();
diff --git a/src/main/java/org/rundeck/client/tool/commands/Jobs.java b/src/main/java/org/rundeck/client/tool/commands/Jobs.java
index effbce38..d053d842 100644
--- a/src/main/java/org/rundeck/client/tool/commands/Jobs.java
+++ b/src/main/java/org/rundeck/client/tool/commands/Jobs.java
@@ -18,6 +18,7 @@
 
 import com.lexicalscope.jewel.cli.CommandLineInterface;
 import com.lexicalscope.jewel.cli.Option;
+import org.rundeck.client.api.model.scheduler.ScheduledJobItem;
 import org.rundeck.toolbelt.Command;
 import org.rundeck.toolbelt.CommandOutput;
 import org.rundeck.toolbelt.HasSubCommands;
@@ -189,7 +190,7 @@ interface JobResultOptions extends JobOutputFormatOption, VerboseOption {
 
     }
 
-    @CommandLineInterface(application = "list") interface ListOpts extends JobListOptions, JobResultOptions {
+    @CommandLineInterface(application = "list") interface ListOpts extends JobListOptions, JobFileOptions, JobResultOptions {
     }
 
     @Command(description = "List jobs found in a project, or download Job definitions (-f).")
@@ -375,4 +376,228 @@ public static String[] splitJobNameParts(final String job) {
         return new String[]{group, name};
 
     }
+
+    /* Bulk toggle execution */
+
+    private List<String> getJobList(BulkJobActionOptions options) throws InputError, IOException {
+
+        //if id,idlist specified, use directly
+        //otherwise query for the list and assemble the ids
+
+        List<String> ids = new ArrayList<>();
+        if (options.isIdlist()) {
+            ids = Arrays.asList(options.getIdlist().split("\\s*,\\s*"));
+        }
+        else {
+            if (!options.isJob() && !options.isGroup() && !options.isGroupExact() && !options.isJobExact()) {
+                throw new InputError("must specify -i, or -j/-g/-J/-G to specify jobs to enable.");
+            }
+            String project = projectOrEnv(options);
+            List<JobItem> body = apiCall(api -> api.listJobs(
+                project,
+                options.getJob(),
+                options.getGroup(),
+                options.getJobExact(),
+                options.getGroupExact()
+            ));
+            for (JobItem jobItem : body) {
+                ids.add(jobItem.getId());
+            }
+        }
+
+        return ids;
+    }
+
+
+    @CommandLineInterface(application = "enablebulk")
+    interface EnableBulk extends BulkJobActionOptions, VerboseOption {
+    }
+
+    @Command(description = "Enable execution for a set of jobs. " +
+        "--idlist/-i, or --job/-j or --group/-g or --jobxact/-J or --groupxact/-G Options are " +
+        "required.")
+    public boolean enablebulk(EnableBulk options, CommandOutput output) throws IOException, InputError {
+
+        List<String> ids = getJobList(options);
+
+        if (!options.isConfirm()) {
+            //request confirmation
+            if (null == System.console()) {
+                output.error("No user interaction available. Use --confirm to confirm request without user interaction");
+                output.warning(String.format("Not enabling %d jobs", ids.size()));
+                return false;
+            }
+            String s = System.console().readLine("Really enable %d Jobs? (y/N) ", ids.size());
+
+            if (!"y".equals(s)) {
+                output.warning(String.format("Not enabling %d jobs", ids.size()));
+                return false;
+            }
+        }
+
+        final List<String> finalIds = ids;
+
+        BulkToggleJobExecutionResponse response = apiCall(api -> api.bulkEnableJobs(new IdList(finalIds)));
+
+        if (response.isAllsuccessful()) {
+            output.info(String.format("%d Jobs were enabled%n", response.getRequestCount()));
+            if (options.isVerbose()) {
+                output.output(response.getSucceeded().stream()
+                    .map(BulkToggleJobExecutionResponse.Result::toString)
+                    .collect(Collectors.toList()));
+            }
+            return true;
+        }
+        output.error(String.format("Failed to enable %d Jobs%n", response.getFailed().size()));
+        output.output(response.getFailed().stream()
+            .map(BulkToggleJobExecutionResponse.Result::toString)
+            .collect(Collectors.toList()));
+        return false;
+    }
+
+
+    @CommandLineInterface(application = "disablebulk")
+    interface DisableBulk extends BulkJobActionOptions, VerboseOption {
+    }
+
+    @Command(description = "Disable execution for a set of jobs. " +
+        "--idlist/-i, or --job/-j or --group/-g or --jobxact/-J or --groupxact/-G Options are " +
+        "required.")
+    public boolean disablebulk(DisableBulk options, CommandOutput output) throws IOException, InputError {
+
+        List<String> ids = getJobList(options);
+
+        if (!options.isConfirm()) {
+            //request confirmation
+            if (null == System.console()) {
+                output.error("No user interaction available. Use --confirm to confirm request without user interaction");
+                output.warning(String.format("Not disabling %d jobs", ids.size()));
+                return false;
+            }
+            String s = System.console().readLine("Really disable %d Jobs? (y/N) ", ids.size());
+
+            if (!"y".equals(s)) {
+                output.warning(String.format("Not disabling %d jobs", ids.size()));
+                return false;
+            }
+        }
+
+        final List<String> finalIds = ids;
+
+        BulkToggleJobExecutionResponse response = apiCall(api -> api.bulkDisableJobs(new IdList(finalIds)));
+
+        if (response.isAllsuccessful()) {
+            output.info(String.format("%d Jobs were disabled%n", response.getRequestCount()));
+            if (options.isVerbose()) {
+                output.output(response.getSucceeded().stream()
+                    .map(BulkToggleJobExecutionResponse.Result::toString)
+                    .collect(Collectors.toList()));
+            }
+            return true;
+        }
+        output.error(String.format("Failed to disable %d Jobs%n", response.getFailed().size()));
+        output.output(response.getFailed().stream()
+            .map(BulkToggleJobExecutionResponse.Result::toString)
+            .collect(Collectors.toList()));
+        return false;
+    }
+
+
+    @CommandLineInterface(application = "reschedulebulk")
+    interface RescheduleBulk extends BulkJobActionOptions, VerboseOption {
+    }
+
+
+    @Command(description = "Enable schedule for a set of jobs. " +
+        "--idlist/-i, or --job/-j or --group/-g or --jobxact/-J or --groupxact/-G Options are " +
+        "required.")
+    public boolean reschedulebulk(RescheduleBulk options, CommandOutput output) throws IOException, InputError {
+
+        List<String> ids = getJobList(options);
+
+        if (!options.isConfirm()) {
+            //request confirmation
+            if (null == System.console()) {
+                output.error("No user interaction available. Use --confirm to confirm request without user interaction");
+                output.warning(String.format("Not rescheduling %d jobs", ids.size()));
+                return false;
+            }
+            String s = System.console().readLine("Really reschedule %d Jobs? (y/N) ", ids.size());
+
+            if (!"y".equals(s)) {
+                output.warning(String.format("Not rescheduling %d jobs", ids.size()));
+                return false;
+            }
+        }
+
+        final List<String> finalIds = ids;
+
+        BulkToggleJobScheduleResponse response = apiCall(api -> api.bulkEnableJobSchedule(new IdList(finalIds)));
+
+        if (response.isAllsuccessful()) {
+            output.info(String.format("%d Jobs were rescheduled%n", response.getRequestCount()));
+            if (options.isVerbose()) {
+                output.output(response.getSucceeded().stream()
+                    .map(BulkToggleJobScheduleResponse.Result::toString)
+                    .collect(Collectors.toList()));
+            }
+            return true;
+        }
+        output.error(String.format("Failed to reschedule %d Jobs%n", response.getFailed().size()));
+        output.output(response.getFailed().stream()
+            .map(BulkToggleJobScheduleResponse.Result::toString)
+            .collect(Collectors.toList()));
+        return false;
+    }
+
+
+    @CommandLineInterface(application = "unschedulebulk")
+    interface UnscheduleBulk extends BulkJobActionOptions, VerboseOption {
+    }
+
+
+    @Command(description = "Disable schedule for a set of jobs. " +
+        "--idlist/-i, or --job/-j or --group/-g or --jobxact/-J or --groupxact/-G Options are " +
+        "required.")
+    public boolean unschedulebulk(UnscheduleBulk options, CommandOutput output) throws IOException, InputError {
+
+        List<String> ids = getJobList(options);
+
+        if (!options.isConfirm()) {
+            //request confirmation
+            if (null == System.console()) {
+                output.error("No user interaction available. Use --confirm to confirm request without user interaction");
+                output.warning(String.format("Not unscheduling %d jobs", ids.size()));
+                return false;
+            }
+            String s = System.console().readLine("Really unschedule %d Jobs? (y/N) ", ids.size());
+
+            if (!"y".equals(s)) {
+                output.warning(String.format("Not unscheduling %d jobs", ids.size()));
+                return false;
+            }
+        }
+
+        final List<String> finalIds = ids;
+
+        BulkToggleJobScheduleResponse response = apiCall(api -> api.bulkDisableJobSchedule(new IdList(finalIds)));
+
+        if (response.isAllsuccessful()) {
+            output.info(String.format("%d Jobs were unsheduled%n", response.getRequestCount()));
+            if (options.isVerbose()) {
+                output.output(response.getSucceeded().stream()
+                    .map(BulkToggleJobScheduleResponse.Result::toString)
+                    .collect(Collectors.toList()));
+            }
+            return true;
+        }
+        output.error(String.format("Failed to disable %d Jobs%n", response.getFailed().size()));
+        output.output(response.getFailed().stream()
+            .map(BulkToggleJobScheduleResponse.Result::toString)
+            .collect(Collectors.toList()));
+        return false;
+    }
+
+
+
 }
diff --git a/src/main/java/org/rundeck/client/tool/commands/Scheduler.java b/src/main/java/org/rundeck/client/tool/commands/Scheduler.java
index a3be1cab..bff56683 100644
--- a/src/main/java/org/rundeck/client/tool/commands/Scheduler.java
+++ b/src/main/java/org/rundeck/client/tool/commands/Scheduler.java
@@ -18,10 +18,11 @@
 
 import com.lexicalscope.jewel.cli.CommandLineInterface;
 import com.lexicalscope.jewel.cli.Option;
+import org.rundeck.client.api.model.scheduler.*;
+import org.rundeck.client.tool.options.VerboseOption;
 import org.rundeck.toolbelt.Command;
 import org.rundeck.toolbelt.CommandOutput;
 import org.rundeck.toolbelt.InputError;
-import org.rundeck.client.api.model.ScheduledJobItem;
 import org.rundeck.client.tool.RdApp;
 
 import java.io.IOException;
@@ -33,32 +34,133 @@
  */
 @Command(description = "View scheduler information")
 public class Scheduler extends AppCommand {
-    public Scheduler(final RdApp client) {
-        super(client);
+  public Scheduler(final RdApp client) {
+    super(client);
+  }
+
+
+  @CommandLineInterface(application = "jobs")
+  interface SchedulerJobs {
+
+    @Option(shortName = "u",
+        longName = "uuid",
+        description = "Server UUID to query, or blank to select the target server")
+    String getUuid();
+
+    boolean isUuid();
+  }
+
+  @Command(description = "List jobs for the current target server, or a specified server.")
+  public void jobs(SchedulerJobs options, CommandOutput output) throws IOException, InputError {
+    List<ScheduledJobItem> jobInfo = apiCall(api -> {
+      if (options.isUuid()) {
+        return api.listSchedulerJobs(options.getUuid());
+      }
+      else {
+        return api.listSchedulerJobs();
+      }
+
+    });
+    output.output(jobInfo.stream().map(ScheduledJobItem::toMap).collect(Collectors.toList()));
+  }
+
+
+  @CommandLineInterface(application = "takeover")
+  interface Takeover extends VerboseOption {
+
+    @Option(shortName = "u",
+        longName = "uuid",
+        description = "Server UUID to take over.")
+    String getUuid();
+
+    boolean isUuid();
+
+    @Option(shortName = "a",
+        longName = "all",
+        description = "Take over all jobs regardless of server UUID.")
+    boolean isAllServers();
+
+    @Option(shortName = "p",
+        longName = "project",
+        description = "Take over only jobs matching the given project name, in combination with --all/-a or --uuid/-u.")
+    String projectName();
+
+    boolean isProjectName();
+
+    @Option(shortName = "j",
+        longName = "job",
+        description = "Job UUID to takeover only a single Job’s schedule.")
+    String getJobId();
+
+    boolean isJobId();
+
+  }
+
+  @Command(description = "Tell a Rundeck server in cluster mode to claim all scheduled jobs from another cluster server. " +
+      "Use --job/-j to specify a job uuid, or alternatively use --uuid/-u, --all/-a, --project/-p to " +
+      "specify a server/project combination.")
+  public void takeover(Takeover options, CommandOutput output) throws IOException, InputError {
+
+    SchedulerTakeover takeoverParams = new SchedulerTakeover();
+
+    if (options.isJobId()) {
+      // Takeover by job uuid.
+      takeoverParams.setJob(new SchedulerTakeover.JobId()
+          .setId(options.getJobId())
+      );
     }
 
+    else {
+      // Takeover by server params.
+      if (options.isAllServers()) {
+        takeoverParams.setServer(new TakeoverServerItem()
+            .setAll(true));
+      }
+      else if (options.isUuid()) {
+        takeoverParams.setServer(new TakeoverServerItem()
+            .setUuid(options.getUuid()));
+      }
+      else {
+        throw new InputError("Must specify -u, or -a or -j to specify jobs to takeover.");
+      }
+
+      if (options.isProjectName()) {
+        takeoverParams.setProject(options.projectName());
+      }
+    }
 
-    @CommandLineInterface(application = "jobs") interface SchedulerJobs {
+//    output.info(takeoverParams.toString());
+    SchedulerTakeoverResult response = apiCall(api -> api.takeoverSchedule(takeoverParams));
 
+    // print output.
+    output.info(response.getMessage());
 
-        @Option(shortName = "u",
-                longName = "uuid",
-                description = "Server UUID to query, or blank to select the target server")
-        String getUuid();
+    if(response.getTakeoverSchedule() != null
+        && response.getTakeoverSchedule().getJobs() != null
+        && response.getTakeoverSchedule().getJobs().getFailed() != null
+        && response.getTakeoverSchedule().getJobs().getFailed().size() > 0) {
 
-        boolean isUuid();
+      output.error(String.format("Failed to takeover %d Jobs%n", response.getTakeoverSchedule().getJobs().getFailed().size()));
+      output.output(response.getTakeoverSchedule().getJobs().getFailed().stream()
+          .map(TakeoverJobItem::toString)
+          .collect(Collectors.toList()));
     }
 
-    @Command(description = "List jobs for the current target server, or a specified server.")
-    public void jobs(SchedulerJobs options, CommandOutput output) throws IOException, InputError {
-        List<ScheduledJobItem> jobInfo = apiCall(api -> {
-            if (options.isUuid()) {
-                return api.listSchedulerJobs(options.getUuid());
-            } else {
-                return api.listSchedulerJobs();
-            }
-
-        });
-        output.output(jobInfo.stream().map(ScheduledJobItem::toMap).collect(Collectors.toList()));
+    if (options.isVerbose()) {
+      if(response.getTakeoverSchedule() != null
+          && response.getTakeoverSchedule().getJobs() != null
+          && response.getTakeoverSchedule().getJobs().getSuccessful() != null
+          && response.getTakeoverSchedule().getJobs().getSuccessful().size() > 0) {
+
+        output.info(String.format("Successfully taken over %d Jobs%n", response.getTakeoverSchedule().getJobs().getSuccessful().size()));
+        output.output(response.getTakeoverSchedule().getJobs().getSuccessful().stream()
+            .map(TakeoverJobItem::toString)
+            .collect(Collectors.toList()));
+      }
+      else {
+        output.warning("* No jobs were taken over.");
+      }
     }
+  }
+
 }
diff --git a/src/main/java/org/rundeck/client/tool/options/BulkJobActionOptions.java b/src/main/java/org/rundeck/client/tool/options/BulkJobActionOptions.java
new file mode 100644
index 00000000..0cdcc8df
--- /dev/null
+++ b/src/main/java/org/rundeck/client/tool/options/BulkJobActionOptions.java
@@ -0,0 +1,10 @@
+package org.rundeck.client.tool.options;
+
+import com.lexicalscope.jewel.cli.Option;
+
+public interface BulkJobActionOptions extends JobListOptions {
+
+  @Option(longName = "confirm", shortName = "y", description = "Force confirmation of request.")
+  boolean isConfirm();
+
+}
diff --git a/src/main/java/org/rundeck/client/tool/options/JobBaseOptions.java b/src/main/java/org/rundeck/client/tool/options/JobFileOptions.java
similarity index 95%
rename from src/main/java/org/rundeck/client/tool/options/JobBaseOptions.java
rename to src/main/java/org/rundeck/client/tool/options/JobFileOptions.java
index b4c57b02..37571e59 100644
--- a/src/main/java/org/rundeck/client/tool/options/JobBaseOptions.java
+++ b/src/main/java/org/rundeck/client/tool/options/JobFileOptions.java
@@ -20,7 +20,7 @@
 
 import java.io.File;
 
-public interface JobBaseOptions extends ProjectNameOptions {
+public interface JobFileOptions {
 
     @Option(shortName = "f",
             longName = "file",
diff --git a/src/main/java/org/rundeck/client/tool/options/JobListOptions.java b/src/main/java/org/rundeck/client/tool/options/JobListOptions.java
index 7a975e7c..dad31d58 100644
--- a/src/main/java/org/rundeck/client/tool/options/JobListOptions.java
+++ b/src/main/java/org/rundeck/client/tool/options/JobListOptions.java
@@ -18,7 +18,7 @@
 
 import com.lexicalscope.jewel.cli.Option;
 
-public interface JobListOptions extends JobBaseOptions{
+public interface JobListOptions extends ProjectNameOptions {
 
 
     @Option(shortName = "j", longName = "job", description = "Job name filter")
diff --git a/src/main/java/org/rundeck/client/tool/options/JobLoadOptions.java b/src/main/java/org/rundeck/client/tool/options/JobLoadOptions.java
index 2be2d267..bc72bfab 100644
--- a/src/main/java/org/rundeck/client/tool/options/JobLoadOptions.java
+++ b/src/main/java/org/rundeck/client/tool/options/JobLoadOptions.java
@@ -18,7 +18,7 @@
 
 import com.lexicalscope.jewel.cli.Option;
 
-public interface JobLoadOptions extends JobBaseOptions {
+public interface JobLoadOptions extends JobFileOptions, ProjectNameOptions {
 
     @Option(shortName = "d",
             longName = "duplicate",
diff --git a/src/test/groovy/org/rundeck/client/tool/commands/JobsSpec.groovy b/src/test/groovy/org/rundeck/client/tool/commands/JobsSpec.groovy
index 2e638788..77598c2c 100644
--- a/src/test/groovy/org/rundeck/client/tool/commands/JobsSpec.groovy
+++ b/src/test/groovy/org/rundeck/client/tool/commands/JobsSpec.groovy
@@ -26,7 +26,7 @@ import org.rundeck.client.api.model.DeleteJobsResult
 import org.rundeck.client.api.model.ImportResult
 import org.rundeck.client.api.model.JobItem
 import org.rundeck.client.api.model.JobLoadItem
-import org.rundeck.client.api.model.ScheduledJobItem
+import org.rundeck.client.api.model.scheduler.ScheduledJobItem
 import org.rundeck.client.tool.RdApp
 import org.rundeck.client.util.Client
 import retrofit2.Retrofit
diff --git a/src/test/groovy/org/rundeck/client/tool/commands/SchedulerSpec.groovy b/src/test/groovy/org/rundeck/client/tool/commands/SchedulerSpec.groovy
new file mode 100644
index 00000000..8a98ef39
--- /dev/null
+++ b/src/test/groovy/org/rundeck/client/tool/commands/SchedulerSpec.groovy
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017 Rundeck, Inc. (http://rundeck.com)
+ *
+ * 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.
+ */
+
+package org.rundeck.client.tool.commands
+
+import okhttp3.mockwebserver.MockResponse
+import okhttp3.mockwebserver.MockWebServer
+import okhttp3.mockwebserver.RecordedRequest
+import org.rundeck.client.api.RundeckApi
+import org.rundeck.client.api.model.*
+import org.rundeck.client.api.model.scheduler.SchedulerTakeover
+import org.rundeck.client.tool.RdApp
+import org.rundeck.client.util.Client
+import org.rundeck.client.util.RdClientConfig
+import org.rundeck.toolbelt.CommandOutput
+import retrofit2.Retrofit
+import retrofit2.converter.jackson.JacksonConverterFactory
+import retrofit2.mock.Calls
+import spock.lang.Specification
+
+/**
+ * @author greg
+ * @since 12/5/16
+ */
+class SchedulerSpec extends Specification {
+
+    def "parse takeover"() {
+        given:
+        MockWebServer server = new MockWebServer();
+        server.enqueue(new MockResponse().setBody('''{
+  "takeoverSchedule": {
+    "jobs": {
+      "failed": [
+        {
+          "href": "http://dignan:4440/api/14/job/a1aa53ac-73a6-4ead-bbe4-34afbff8e057",
+          "permalink": "http://dignan:4440/job/show/a1aa53ac-73a6-4ead-bbe4-34afbff8e057",
+          "id": "11111111-73a6-4ead-1111-34afbff8e057",
+          "previous-owner": "8F3D5976-2232-4529-847B-8E45764608E3"
+        },
+        {
+          "href": "http://dignan:4440/api/14/job/116e2025-7895-444a-88f7-d96b4f19fdb3",
+          "permalink": "http://dignan:4440/job/show/116e2025-7895-444a-88f7-d96b4f19fdb3",
+          "id": "116e2025-7895-444a-88f7-d96b4f19fdb3",
+          "previous-owner": "8F3D5976-2232-4529-847B-8E45764608E3"
+        }
+      ],
+      "successful": [
+        {
+          "href": "http://dignan:4440/api/14/job/a1aa53ac-73a6-4ead-bbe4-34afbff8e057",
+          "permalink": "http://dignan:4440/job/show/a1aa53ac-73a6-4ead-bbe4-34afbff8e057",
+          "id": "a1aa53ac-73a6-4ead-bbe4-34afbff8e057",
+          "previous-owner": "8F3D5976-2232-4529-847B-8E45764608E3"
+        },
+        {
+          "href": "http://dignan:4440/api/14/job/116e2025-7895-444a-88f7-d96b4f19fdb3",
+          "permalink": "http://dignan:4440/job/show/116e2025-7895-444a-88f7-d96b4f19fdb3",
+          "id": "116e2025-7895-444a-88f7-d96b4f19fdb3",
+          "previous-owner": "8F3D5976-2232-4529-847B-8E45764608E3"
+        }
+      ],
+      "total": 4
+    },
+    "server": {
+      "uuid": "8F3D5976-2232-4529-847B-8E45764608E3"
+    }
+  },
+  "self": {
+    "server": {
+      "uuid": "C677C663-F902-4B97-B8AC-4AA57B58DDD6"
+    }
+  },
+  "message": "Schedule Takeover successful for 2/2 Jobs.",
+  "apiversion": 14,
+  "success": true
+}'''
+        ).addHeader('content-type', 'application/json')
+        );
+        server.start()
+
+        def retrofit = new Retrofit.Builder().baseUrl(server.url('/api/14/')).
+                addConverterFactory(JacksonConverterFactory.create()).
+                build()
+        def api = retrofit.create(RundeckApi)
+
+        when:
+        def body = api.takeoverSchedule(new SchedulerTakeover()).execute().body()
+
+        then:
+        RecordedRequest request1 = server.takeRequest()
+        request1.path == '/api/14/scheduler/takeover'
+
+
+        body.apiversion == 14
+        body.success == true
+        body.takeoverSchedule != null
+        body.takeoverSchedule.jobs != null
+        body.takeoverSchedule.jobs.total == 4
+        body.takeoverSchedule.jobs.successful.size() == 2
+        body.takeoverSchedule.jobs.failed.size() == 2
+        body.takeoverSchedule.jobs.successful.get(0).id == "a1aa53ac-73a6-4ead-bbe4-34afbff8e057"
+        body.takeoverSchedule.jobs.failed.get(0).id == "11111111-73a6-4ead-1111-34afbff8e057"
+        body.takeoverSchedule.jobs.failed.get(0).previousOwner == "8F3D5976-2232-4529-847B-8E45764608E3"
+        server.shutdown()
+
+    }
+
+}