code: func (h *Handler) siteSessionEventsGet(w http.ResponseWriter, r *http.Request, p httprouter.Params, ctx *SessionContext, site reversetunnel.RemoteSite) (interface{}, error) {
  	logger := log.WithFields(log.Fields{
  		trace.Component: teleport.ComponentWeb,
  	})
  
  	sessionID, err := session.ParseID(p.ByName("sid"))
  	if err != nil {
  		return nil, trace.BadParameter("invalid session ID %q", p.ByName("sid"))
  	}
  
  	clt, err := ctx.GetUserClient(site)
  	if err != nil {
  		return nil, trace.Wrap(err)
  	}
  	afterN, err := strconv.Atoi(r.URL.Query().Get("after"))
  	if err != nil {
  		afterN = 0
  	}
  	namespace := p.ByName("namespace")
  	if !services.IsValidNamespace(namespace) {
  		return nil, trace.BadParameter("invalid namespace %q", namespace)
  	}
  	e, err := clt.GetSessionEvents(namespace, *sessionID, afterN, true)
  	if err != nil {
  		logger.Debugf("Unable to find events for session %v: %v.", sessionID, err)
  		if trace.IsNotFound(err) {
  			return nil, trace.NotFound("Unable to find events for session %q", sessionID)
  		}
  
  		return nil, trace.Wrap(err)
  	}
  	return eventsListGetResponse{Events: e}, nil
  }
docs: // siteSessionEventsGet gets the site session by id
  //
  // GET /v1/webapi/sites/:site/namespaces/:namespace/sessions/:sid/events?after=N
  //
  // Query:
  //    "after" : cursor value of an event to return "newer than" events
  //              good for repeated polling
  //
  // Response body (each event is an arbitrary JSON structure)
  //
  // {"events": [{...}, {...}, ...}
  //