diff --git a/src/app/degree-planner/actions/plan.actions.ts b/src/app/degree-planner/actions/plan.actions.ts
index be3559d9e5ab023295ef540f6a5661d6bbd1508b..70182eb46bdcbb963c2058c79449404b3e6f5144 100644
--- a/src/app/degree-planner/actions/plan.actions.ts
+++ b/src/app/degree-planner/actions/plan.actions.ts
@@ -1,13 +1,20 @@
 import { Action } from '@ngrx/store';
 import { PlannedTerm } from '@app/core/models/planned-term';
 import { DegreePlannerState } from '@app/degree-planner/state';
+import { Course} from '../../core/models/course';
 
 export enum PlanActionTypes {
 	InitialPlanLoadResponse = '[Plan] Initial Load Response',
 	ChangeVisiblePlanRequest = '[Plan] Change Visible Request',
 	ChangeVisiblePlanResponse = '[Plan] Change Visible Response',
+	AddCourseRequest = '[Plan] Add Course Request',
+	AddCourseResponse = '[Plan] Add Course Response',
+	RemoveCourseRequest = '[Plan] Remove Course Request',
+	RemoveCourseResponse = '[Plan] Remove Course Response',
 	ChangeCourseTermRequest = '[Plan] Change Course Term Request',
-	ChangeCourseTermResponse = '[Plan] Change Course Term Response'
+	ChangeCourseTermResponse = '[Plan] Change Course Term Response',
+	MoveFromSavedToTermRequest = '[Plan] Move Course From Saved to Term Request',
+	MoveFromSavedToTermResponse= '[Plan] Move Course From Saved to Term Response'
 }
 
 export class InitialPlanLoadResponse implements Action {
@@ -40,3 +47,31 @@ export class ChangeCourseTermResponse implements Action {
 		public payload: {to: string, from: string, id: number}
 	) {}
 }
+
+export class AddCourseRequest implements Action {
+	public readonly type = PlanActionTypes.AddCourseRequest;
+	constructor(
+		public payload: {subjectCode: string, courseId: string, termCode: string}
+	) {}
+}
+
+export class AddCourseResponse implements Action {
+	public readonly type = PlanActionTypes.AddCourseResponse;
+	constructor(
+		public payload: {course: Course}
+	) {}
+}
+
+export class RemoveCourseRequest implements Action {
+	public readonly type = PlanActionTypes.RemoveCourseRequest;
+	constructor(
+		public payload: {id: number}
+	) {}
+}
+
+export class RemoveCourseResponse implements Action {
+	public readonly type = PlanActionTypes.RemoveCourseResponse;
+	constructor(
+		public payload: {id: number}
+	) {}
+}
diff --git a/src/app/degree-planner/effects/plan.effects.ts b/src/app/degree-planner/effects/plan.effects.ts
index a17defa55fadfb4c43b74aed63a9fa601c608034..b85d9a85bb73e3351264356a545e8919ea457812 100644
--- a/src/app/degree-planner/effects/plan.effects.ts
+++ b/src/app/degree-planner/effects/plan.effects.ts
@@ -8,7 +8,7 @@ import { Store } from '@ngrx/store';
 
 // Services
 import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
-import { getDegreePlannerState } from '@app/degree-planner/selectors';
+import { getDegreePlannerState, getVisibleRoadmapId } from '@app/degree-planner/selectors';
 
 // Actions
 import {
@@ -16,7 +16,9 @@ import {
 	ChangeVisiblePlanRequest,
 	ChangeVisiblePlanResponse,
 	PlanActionTypes,
-	ChangeCourseTermResponse
+	ChangeCourseTermResponse,
+	AddCourseResponse,
+	RemoveCourseResponse
 } from '@app/degree-planner/actions/plan.actions';
 
 // Models
@@ -111,6 +113,81 @@ export class DegreePlanEffects {
 		})
 	);
 
+	@Effect()
+	AddCourse$ = this.actions$.pipe(
+		ofType<any>(PlanActionTypes.AddCourseRequest),
+
+		withLatestFrom(this.store$.select(getDegreePlannerState)),
+		filter(([_, state]) => typeof state.visibleRoadmapId === 'number'),
+
+		// Get the roadmap ID from the action.
+		tap(([action, state]) => {
+			console.log(action);
+			console.log(state);
+		}),
+
+		// Get term data for the degree plan specified by the roadmap ID.
+		flatMap(([action, state]) => {
+			// TODO error handle the API calls
+			const roadmapId = state.visibleRoadmapId;
+			const {subjectCode, termCode, courseId} = action.payload;
+			return this.api.addCourse(roadmapId as number, subjectCode, courseId, termCode).pipe(
+				map(response => {
+					return {
+						response,
+						action
+					};
+				})
+			);
+		}),
+
+		// Wrap data in an Action for dispatch
+		map(({ response, action }) => {
+			// TODO add error handleing
+			console.log('------');
+			console.log(action);
+			console.log(response);
+			console.log('------');
+			return new AddCourseResponse({ course: response});
+		})
+	);
+
+	@Effect()
+	RemoveCourse$ = this.actions$.pipe(
+		ofType<any>(PlanActionTypes.RemoveCourseRequest),
+
+		withLatestFrom(this.store$.select(getDegreePlannerState)),
+		filter(([_, state]) => typeof state.visibleRoadmapId === 'number'),
+
+		// Get the roadmap ID from the action.
+		tap(([action, state]) => {
+			console.log(action);
+			console.log(state);
+		}),
+
+		// Get term data for the degree plan specified by the roadmap ID.
+		flatMap(([action, state]) => {
+			// TODO error handle the API calls
+			return this.api.removeCourse(state.visibleRoadmapId as number, action.payload.id).pipe(
+				map(response => {
+					return {
+						response,
+						action
+					};
+				})
+			);
+		}),
+
+		// Wrap data in an Action for dispatch
+		map(({ response, action }) => {
+			if (response === null) {
+				const { id } = action.payload;
+				return new RemoveCourseResponse({ id });
+			}
+			return;
+		})
+	);
+
 	private loadTermsForPlan<T extends { visibleRoadmapId: number }>(stdin: T) {
 		return forkJoin(
 			this.api.getAllNotes(stdin.visibleRoadmapId),
diff --git a/src/app/degree-planner/reducer.ts b/src/app/degree-planner/reducer.ts
index c2c277a917f7f890f8010f0ac5021b6367dfeb87..aaacf1d6436df270826282fdbae98e487c120193 100644
--- a/src/app/degree-planner/reducer.ts
+++ b/src/app/degree-planner/reducer.ts
@@ -6,8 +6,9 @@ import {
 	PlanActionTypes,
 	InitialPlanLoadResponse,
 	ChangeVisiblePlanResponse,
-	ChangeCourseTermRequest,
-	ChangeCourseTermResponse
+	RemoveCourseResponse,
+	ChangeCourseTermResponse,
+	AddCourseResponse
 } from '@app/degree-planner/actions/plan.actions';
 import {
 	NoteActionTypes,
@@ -20,7 +21,9 @@ type SupportedActions =
 	| ChangeVisiblePlanResponse
 	| WriteNoteResponse
 	| DeleteNoteResponse
-	| ChangeCourseTermResponse;
+	| ChangeCourseTermResponse
+	| RemoveCourseResponse
+	| AddCourseResponse;
 
 export function degreePlannerReducer(
 	state = INITIAL_DEGREE_PLANNER_STATE,
@@ -146,6 +149,36 @@ export function degreePlannerReducer(
 			return state;
 		}
 
+		case PlanActionTypes.AddCourseResponse: {
+			const { course } = action.payload;
+
+			const newVisibleTerms = state.visibleTerms.map(term => {
+				if (term.termCode === course.termCode) {
+					term.courses.push(course);
+				}
+				return term;
+			});
+
+			return {...state, visibleTerms: newVisibleTerms};
+
+			// return {...state, visibleTerms: newVisibleTerms};
+			// return state;
+		}
+
+		case PlanActionTypes.RemoveCourseResponse: {
+			const { id } = action.payload;
+
+			// Create new visibleTerms array
+			const newVisibleTerms = state.visibleTerms.map(term => {
+				term.courses = term.courses.filter(course => {
+					return course.id !== id;
+				});
+				return term;
+			});
+
+			return {...state, visibleTerms: newVisibleTerms};
+		}
+
 		/**
 		 * It's okay if the action didn't match any of the cases above. If that's
 		 * the case, just return the existing state object.
diff --git a/src/app/degree-planner/services/api.service.ts b/src/app/degree-planner/services/api.service.ts
index 287120260b70089447067bda044e86d053002377..734bdb89faa1540be0f0db1b8f63bd4e5ebc7698 100644
--- a/src/app/degree-planner/services/api.service.ts
+++ b/src/app/degree-planner/services/api.service.ts
@@ -58,6 +58,15 @@ export class DegreePlannerApiService {
 		roadmapId + '/courses/' + recordId + '?termCode=' + termCode, HTTP_OPTIONS);
 	}
 
+	public addCourse(planId: number, subjectCode: string, courseId: string, termCode: string) {
+		return this.http.post<Course>(
+			this.config.apiPlannerUrl + '/degreePlan/' + planId + '/courses', {subjectCode, courseId, termCode }, HTTP_OPTIONS);
+	}
+
+	public removeCourse(planId: number, recordId: string) {
+		return this.http.delete(this.config.apiPlannerUrl + '/degreePlan/' + planId + '/courses/' + recordId, HTTP_OPTIONS);
+	}
+
 	public createNote(
 		planId: number,
 		termCode: string,