The Hub Visits API allows you to track when Recursers visit physical RC spaces. You can create, read, update, and delete hub visit records.
HubVisit Struct
The HubVisit struct represents a visit to an RC hub:
#[derive( Debug , Clone , Serialize , Deserialize )]
pub struct HubVisit {
pub person : PersonInfo ,
pub date : String ,
#[serde(default)]
pub app_data : serde_json :: Value ,
#[serde(default)]
pub notes : String ,
pub created_at : String ,
pub updated_at : String ,
#[serde(default)]
pub created_by_app : Option < String >,
#[serde(default)]
pub updated_by_app : Option < String >,
}
Information about a hub visit. Information about the person who visited
Date of the visit (YYYY-MM-DD format)
Custom application data (JSON)
Timestamp when the record was created
Timestamp when the record was last updated
Name of the app that created the record
Name of the app that last updated the record
PersonInfo
#[derive( Debug , Clone , Serialize , Deserialize )]
pub struct PersonInfo {
pub id : u32 ,
pub name : String ,
}
Get Hub Visits
Query hub visits with flexible filtering options.
/// Get hub visits
pub fn get_hub_visits ( & self , params : HubVisitQueryParams ) -> Result < Vec < HubVisit >> {
let url = self . build_url ( "/hub_visits" );
let mut query_params = Vec :: new ();
if let Some ( date ) = params . date {
query_params . push (( "date" , date . to_string ()));
}
if let Some ( start_date ) = params . start_date {
query_params . push (( "start_date" , start_date . to_string ()));
}
if let Some ( end_date ) = params . end_date {
query_params . push (( "end_date" , end_date . to_string ()));
}
if let Some ( person_id ) = params . person_id {
query_params . push (( "person_id" , person_id . to_string ()));
}
if let Some ( page ) = params . page {
query_params . push (( "page" , page . to_string ()));
}
if let Some ( per_page ) = params . per_page {
query_params . push (( "per_page" , per_page . to_string ()));
}
let response = self
. client
. get ( & url )
. headers ( self . auth_headers ())
. query ( & query_params )
. send () ? ;
Self :: handle_response ( response )
}
HubVisitQueryParams
#[derive( Debug , Default , Clone )]
pub struct HubVisitQueryParams {
pub date : Option < NaiveDate >,
pub start_date : Option < NaiveDate >,
pub end_date : Option < NaiveDate >,
pub person_id : Option < u32 >,
pub page : Option < u32 >,
pub per_page : Option < u32 >,
}
get_hub_visits
fn(&self, HubVisitQueryParams) -> Result<Vec<HubVisit>>
Query hub visits with flexible filters. Parameters: Get visits on a specific date
Get visits from this date onwards (inclusive)
Get visits up to this date (inclusive)
Page number for pagination
Number of results per page
Returns: Result<Vec<HubVisit>>API Endpoint: GET /api/v1/hub_visits
Examples
Get All Visits
Get Visits for Specific Date
Get Visits in Date Range
Get Visits by Person
use rc_api :: { RcApiClient , HubVisitQueryParams };
let client = RcApiClient :: new ( token ) ? ;
let visits = client . get_hub_visits ( HubVisitQueryParams {
per_page : Some ( 100 ),
.. Default :: default ()
}) ? ;
println! ( "Total visits: {}" , visits . len ());
Get Specific Hub Visit
Retrieve a specific hub visit by person ID and date.
/// Get a specific hub visit
pub fn get_hub_visit ( & self , person_id : u32 , date : NaiveDate ) -> Result < HubVisit > {
let url = self . build_url ( & format! ( "/hub_visits/{}/{}" , person_id , date ));
let response = self . client . get ( & url ) . headers ( self . auth_headers ()) . send () ? ;
Self :: handle_response ( response )
}
get_hub_visit
fn(&self, u32, NaiveDate) -> Result<HubVisit>
Get a specific hub visit. Parameters:
person_id (u32): The person’s ID
date (NaiveDate): The visit date
Returns: Result<HubVisit>API Endpoint: GET /api/v1/hub_visits/{person_id}/{date}Errors: Returns RcApiError::NotFound if visit doesn’t exist
Example
use chrono :: NaiveDate ;
let person_id = 12345 ;
let date = NaiveDate :: from_ymd_opt ( 2024 , 3 , 15 ) . unwrap ();
let visit = client . get_hub_visit ( person_id , date ) ? ;
println! ( "{} visited on {}" , visit . person . name, visit . date);
println! ( "Notes: {}" , visit . notes);
Update Hub Visit
Update or create a hub visit record.
/// Update or create a hub visit
pub fn update_hub_visit (
& self ,
person_id : u32 ,
date : NaiveDate ,
update : HubVisitUpdate ,
) -> Result < HubVisit > {
let url = self . build_url ( & format! ( "/hub_visits/{}/{}" , person_id , date ));
let mut form = HashMap :: new ();
if let Some ( notes ) = update . notes {
form . insert ( "notes" , notes );
}
if let Some ( app_data ) = update . app_data {
form . insert ( "app_data" , app_data . to_string ());
}
let response = self
. client
. patch ( & url )
. headers ( self . auth_headers ())
. form ( & form )
. send () ? ;
Self :: handle_response ( response )
}
HubVisitUpdate
#[derive( Debug , Default , Clone )]
pub struct HubVisitUpdate {
pub notes : Option < String >,
pub app_data : Option < serde_json :: Value >,
}
update_hub_visit
fn(&self, u32, NaiveDate, HubVisitUpdate) -> Result<HubVisit>
Update or create a hub visit. If the visit doesn’t exist, it will be created. Parameters:
person_id (u32): The person’s ID
date (NaiveDate): The visit date
update (HubVisitUpdate): The fields to update
app_data
Option<serde_json::Value>
Custom application data (JSON)
Returns: Result<HubVisit>API Endpoint: PATCH /api/v1/hub_visits/{person_id}/{date}
Examples
Update Notes
Update App Data
Update Both Fields
use chrono :: NaiveDate ;
use rc_api :: HubVisitUpdate ;
let person_id = 12345 ;
let date = NaiveDate :: from_ymd_opt ( 2024 , 3 , 15 ) . unwrap ();
let visit = client . update_hub_visit (
person_id ,
date ,
HubVisitUpdate {
notes : Some ( "Great discussion about Rust!" . to_string ()),
app_data : None ,
},
) ? ;
println! ( "Updated visit: {:?}" , visit );
Replace Hub Visit Notes
Replace the notes on a hub visit (specialized endpoint).
/// Replace notes on a hub visit
pub fn replace_hub_visit_notes (
& self ,
person_id : u32 ,
date : NaiveDate ,
notes : & str ,
) -> Result < HubVisit > {
let url = self . build_url ( & format! ( "/hub_visits/{}/{}/notes" , person_id , date ));
let params = [( "notes" , notes )];
let response = self
. client
. patch ( & url )
. headers ( self . auth_headers ())
. form ( & params )
. send () ? ;
Self :: handle_response ( response )
}
replace_hub_visit_notes
fn(&self, u32, NaiveDate, &str) -> Result<HubVisit>
Replace the notes on a hub visit. Parameters:
person_id (u32): The person’s ID
date (NaiveDate): The visit date
notes (&str): The new notes (replaces existing notes)
Returns: Result<HubVisit>API Endpoint: PATCH /api/v1/hub_visits/{person_id}/{date}/notes
Example
let visit = client . replace_hub_visit_notes (
12345 ,
NaiveDate :: from_ymd_opt ( 2024 , 3 , 15 ) . unwrap (),
"Updated notes - worked on database optimization" ,
) ? ;
This method replaces the entire notes field. Use update_hub_visit() if you want to preserve app_data.
Delete Hub Visit
Delete a hub visit record.
/// Delete a hub visit
pub fn delete_hub_visit ( & self , person_id : u32 , date : NaiveDate ) -> Result <()> {
let url = self . build_url ( & format! ( "/hub_visits/{}/{}" , person_id , date ));
let response = self
. client
. delete ( & url )
. headers ( self . auth_headers ())
. send () ? ;
if response . status () . is_success () {
Ok (())
} else {
Err ( Self :: error_from_status ( response . status ()))
}
}
delete_hub_visit
fn(&self, u32, NaiveDate) -> Result<()>
Delete a hub visit record. Parameters:
person_id (u32): The person’s ID
date (NaiveDate): The visit date
Returns: Result<()> (no content on success)API Endpoint: DELETE /api/v1/hub_visits/{person_id}/{date}Errors: Returns RcApiError::NotFound if visit doesn’t exist
Example
use chrono :: NaiveDate ;
let person_id = 12345 ;
let date = NaiveDate :: from_ymd_opt ( 2024 , 3 , 15 ) . unwrap ();
match client . delete_hub_visit ( person_id , date ) {
Ok (()) => println! ( "Visit deleted successfully" ),
Err ( e ) => eprintln! ( "Failed to delete visit: {}" , e ),
}
Common Workflows
Track Daily Hub Visits
use chrono :: Utc ;
use serde_json :: json;
let today = Utc :: now () . date_naive ();
let person_id = 12345 ;
// Record a visit
let visit = client . update_hub_visit (
person_id ,
today ,
HubVisitUpdate {
notes : Some ( "Working on final project" . to_string ()),
app_data : Some ( json! ({
"check_in" : Utc :: now () . to_rfc3339 (),
})),
},
) ? ;
println! ( "Recorded visit for {}" , visit . person . name);
Generate Visit Report
use chrono :: NaiveDate ;
let start = NaiveDate :: from_ymd_opt ( 2024 , 3 , 1 ) . unwrap ();
let end = NaiveDate :: from_ymd_opt ( 2024 , 3 , 31 ) . unwrap ();
let visits = client . get_hub_visits ( HubVisitQueryParams {
start_date : Some ( start ),
end_date : Some ( end ),
per_page : Some ( 1000 ),
.. Default :: default ()
}) ? ;
let mut visitor_counts = std :: collections :: HashMap :: new ();
for visit in visits {
* visitor_counts . entry ( visit . person . id) . or_insert ( 0 ) += 1 ;
}
println! ( "Top visitors in March 2024:" );
let mut counts : Vec < _ > = visitor_counts . into_iter () . collect ();
counts . sort_by_key ( | ( _ , count ) | std :: cmp :: Reverse ( * count ));
for ( person_id , count ) in counts . iter () . take ( 10 ) {
println! ( " Person {}: {} visits" , person_id , count );
}
Check if Person Visited Today
use chrono :: Utc ;
fn visited_today ( client : & RcApiClient , person_id : u32 ) -> Result < bool > {
let today = Utc :: now () . date_naive ();
match client . get_hub_visit ( person_id , today ) {
Ok ( _ ) => Ok ( true ),
Err ( RcApiError :: NotFound ) => Ok ( false ),
Err ( e ) => Err ( e ),
}
}
if visited_today ( & client , 12345 ) ? {
println! ( "Person is at the hub today!" );
} else {
println! ( "Person hasn't visited today" );
}
Next Steps
Profiles Get person information for hub visits
Error Handling Handle hub visit errors