diff --git a/api/event.go b/api/event.go
new file mode 100644
index 0000000000000000000000000000000000000000..4e5c59d91d3ef39189b148cf0172402d88b53c38
--- /dev/null
+++ b/api/event.go
@@ -0,0 +1,132 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package api
+
+import (
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/stoppable"
+	"sync"
+	"github.com/pkg/errors"
+	"fmt"
+)
+
+// EventCallbackFunction defines the callback functions for client event reports
+type EventCallbackFunction func(priority int, category, evtType, details string)
+
+// ReportableEvent is used to surface events to client users.
+type reportableEvent struct {
+	Priority int
+	Category string
+	EventType string
+	Details string
+}
+// Holds state for the event reporting system
+type eventManager struct {
+	eventCh chan reportableEvent
+	eventCbs []EventCallbackFunction
+	eventLck sync.Mutex
+}
+func newEventManager() eventManager {
+	return eventManager {
+		eventCh: make(chan reportableEvent, 1000),
+		eventCbs: make([]EventCallbackFunction, 0),
+	}
+}
+
+// ReportEvent reports an event from the client to api users, providing a
+// priority, category, eventType, and details
+func (e eventManager) ReportEvent(priority int, category, evtType,
+	details string) {
+	re := reportableEvent{
+		Priority: priority,
+		Category: category,
+		EventType: evtType,
+		Details: details,
+	}
+	select {
+	case e.eventCh <- re:
+		jww.TRACE.Printf("Event reported: %s", re)
+	default:
+		jww.ERROR.Printf("Event Queue full, unable to report: %s", re)
+	}
+}
+
+// RegisterEventCallback records the given function to receive
+// ReportableEvent objects. It returns the internal index
+// of the callback so that it can be deleted later.
+func (e eventManager) RegisterEventCallback(myFunc EventCallbackFunction) int {
+	e.eventLck.Lock()
+	defer e.eventLck.Unlock()
+	e.eventCbs = append(e.eventCbs, myFunc)
+	return len(e.eventCbs) - 1
+}
+
+// UnregisterEventCallback deletes the callback identified by the
+// index. It returns an error if it fails.
+func (e eventManager) UnregisterEventCallback(index int) error {
+	e.eventLck.Lock()
+	defer e.eventLck.Unlock()
+	if index > 0 && index < len(e.eventCbs) {
+		e.eventCbs = append(e.eventCbs[:index], e.eventCbs[index+1:]...)
+	} else {
+		return errors.Errorf("Index %d out of bounds: %d -> %d",
+			index, 0, len(e.eventCbs))
+	}
+	return nil
+}
+
+func (e eventManager) eventService() (stoppable.Stoppable, error) {
+	stop := stoppable.NewSingle("EventReporting")
+	go e.reportEventsHandler(stop)
+	return stop, nil
+}
+
+// reportEventsHandler reports events to every registered event callback
+func (e eventManager) reportEventsHandler(stop *stoppable.Single) {
+	jww.DEBUG.Print("reportEventsHandler routine started")
+	for {
+		select {
+		case <-stop.Quit():
+			jww.DEBUG.Printf("Stopping reportEventsHandler")
+			stop.ToStopped()
+			return
+		case evt := <-e.eventCh:
+			jww.DEBUG.Printf("Received event: %s", evt)
+			// NOTE: We could call each in a routine but decided
+			// against it. It's the users responsibility not to let
+			// the event queue explode. The API will report errors
+			// in the logging any time the event queue gets full.
+			for i := 0; i < len(e.eventCbs); i++ {
+				e.eventCbs[i](evt.Priority, evt.Category,
+					evt.EventType, evt.Details)
+			}
+		}
+	}
+}
+
+// ReportEvent reports an event from the client to api users, providing a
+// priority, category, eventType, and details
+func (c *Client) ReportEvent(priority int, category, evtType, details string) {
+	c.events.ReportEvent(priority, category, evtType, details)
+}
+// RegisterEventCallback records the given function to receive
+// ReportableEvent objects. It returns the internal index
+// of the callback so that it can be deleted later.
+func (c *Client) RegisterEventCallback(myFunc EventCallbackFunction) int {
+	return c.events.RegisterEventCallback(myFunc)
+}
+// UnregisterEventCallback deletes the callback identified by the
+// index. It returns an error if it fails.
+func (c *Client) UnregisterEventCallback(index int) error {
+	return c.events.UnregisterEventCallback(index)
+}
+
+func (e reportableEvent) String() string {
+	return fmt.Sprintf("Event(%d, %s, %s, %s)", e.Priority, e.Category,
+		e.EventType, e.Details)
+}