Skip to main content
The Profiles API allows you to search for and retrieve detailed information about Recursers. It provides methods to search profiles, get profiles by ID or email, and retrieve your own profile.

Profile Struct

The Profile struct contains comprehensive information about a Recurser:
src/rc_api.rs:88-216
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Profile {
    pub id: u32,
    pub first_name: String,
    pub last_name: String,
    pub name: String,
    pub name_hl: String,
    pub email: String,
    pub slug: String,
    pub image_path: String,
    
    // Optional fields
    pub github: Option<String>,
    pub twitter: Option<String>,
    pub linkedin: Option<String>,
    pub pronouns: Option<String>,
    pub phone_number: Option<String>,
    pub employer_role: Option<String>,
    pub zoom_url: Option<String>,
    pub zulip_id: Option<u32>,
    pub personal_site_url: Option<String>,
    pub blog_url: Option<String>,
    pub cluster_username: Option<String>,
    
    // Nested structures
    pub current_location: Option<Location>,
    pub stints: Vec<Stint>,
    pub company: Option<Company>,
    
    // Profile fields with rendered HTML and highlights
    pub bio_rendered: Option<String>,
    pub bio_match: Option<bool>,
    pub bio_hl: Option<String>,
    // ... and many more rendered/highlighted fields
}
Profile
struct
Complete profile information for a Recurser.

Search Profiles

Search for profiles with flexible query parameters.
src/rc_api.rs:429-464
/// Search for profiles
pub fn search_profiles(&self, params: ProfileSearchParams) -> Result<Vec<Profile>> {
    let url = self.build_url("/profiles");
    // ... builds query params and sends request
}

ProfileSearchParams

src/rc_api.rs:318-327
#[derive(Debug, Default, Clone)]
pub struct ProfileSearchParams {
    pub query: Option<String>,
    pub batch_id: Option<u32>,
    pub location_id: Option<u32>,
    pub role: Option<String>,
    pub scope: Option<String>,
    pub limit: Option<u32>,
    pub offset: Option<u32>,
}
search_profiles
fn(&self, ProfileSearchParams) -> Result<Vec<Profile>>
Search for profiles matching the specified criteria.Parameters:Returns: Result<Vec<Profile>>API Endpoint: GET /api/v1/profiles

Examples

use rc_api::{RcApiClient, ProfileSearchParams};

let client = RcApiClient::new(token)?;

let profiles = client.search_profiles(ProfileSearchParams {
    limit: Some(50),
    offset: Some(0),
    ..Default::default()
})?;

println!("Found {} profiles", profiles.len());

Real-World Example

From the RC VCF Generator:
src/main.rs:336-351
let mut offset = 0;
let limit = 50;

loop {
    let response = client.search_profiles(ProfileSearchParams {
        limit: Some(limit),
        offset: Some(offset),
        ..Default::default()
    });
    
    match response {
        Ok(profiles) => {
            if profiles.is_empty() {
                break;
            }
            // Process profiles...
            offset += profiles.len() as u32;
        }
        Err(e) => eprintln!("Error: {}", e),
    }
}

Get Profile by ID

Retrieve a specific profile by person ID.
src/rc_api.rs:466-472
/// Get a profile by person ID
pub fn get_profile_by_id(&self, person_id: u32) -> Result<Profile> {
    let url = self.build_url(&format!("/profiles/{}", person_id));
    let response = self.client.get(&url).headers(self.auth_headers()).send()?;
    Self::handle_response(response)
}
get_profile_by_id
fn(&self, u32) -> Result<Profile>
Get a profile by person ID.Parameters:
  • person_id (u32): The person’s unique ID
Returns: Result<Profile>API Endpoint: GET /api/v1/profiles/{person_id}Errors: Returns RcApiError::NotFound if profile doesn’t exist

Example

let profile = client.get_profile_by_id(12345)?;
println!("Name: {}", profile.name);
println!("Email: {}", profile.email);
println!("GitHub: {:?}", profile.github);

Get Profile by Email

Retrieve a profile by email address.
src/rc_api.rs:474-480
/// Get a profile by email
pub fn get_profile_by_email(&self, email: &str) -> Result<Profile> {
    let url = self.build_url(&format!("/profiles/{}", urlencoding::encode(email)));
    let response = self.client.get(&url).headers(self.auth_headers()).send()?;
    Self::handle_response(response)
}
get_profile_by_email
fn(&self, &str) -> Result<Profile>
Get a profile by email address.Parameters:
  • email (&str): The person’s email address (URL-encoded automatically)
Returns: Result<Profile>API Endpoint: GET /api/v1/profiles/{email} (email is URL-encoded)Errors: Returns RcApiError::NotFound if profile doesn’t exist

Example

let profile = client.get_profile_by_email("[email protected]")?;
println!("Found: {} (ID: {})", profile.name, profile.id);
The email is automatically URL-encoded, so you can pass it as-is.

Get My Profile

Retrieve the profile of the currently authenticated user.
src/rc_api.rs:482-488
/// Get the current user's profile
pub fn get_my_profile(&self) -> Result<Profile> {
    let url = self.build_url("/profiles/me");
    let response = self.client.get(&url).headers(self.auth_headers()).send()?;
    Self::handle_response(response)
}
get_my_profile
fn(&self) -> Result<Profile>
Get the currently authenticated user’s profile.Returns: Result<Profile>API Endpoint: GET /api/v1/profiles/meErrors: Returns RcApiError::AuthenticationFailed if not authenticated

Example

let my_profile = client.get_my_profile()?;
println!("Hello, {}!", my_profile.name);
println!("Your email: {}", my_profile.email);

Working with Profile Data

Accessing Stints

let profile = client.get_profile_by_id(12345)?;

for stint in &profile.stints {
    if let Some(batch) = &stint.batch {
        println!("Batch: {}", batch.name);
        println!("Type: {}", stint.stint_type);
        println!("Start: {}", stint.start_date);
    }
}

Checking for Profile Photo

src/main.rs:370-371
let has_photo = !profile.image_path.is_empty()
    && !profile.image_path.contains("missing");

Building Profile URL

src/main.rs:244-247
let profile_url = format!(
    "https://www.recurse.com/directory/{}",
    profile.slug
);

Profile Search Fields

When using the query parameter, the API searches across multiple fields:
  • Name
  • Bio
  • Before RC
  • During RC
  • Interests
  • Employer info
  • GitHub username
  • Skills and projects
Matches are indicated by the *_match and *_hl (highlighted) fields in the response.

Example: Checking Search Matches

let profiles = client.search_profiles(ProfileSearchParams {
    query: Some("machine learning".to_string()),
    ..Default::default()
})?;

for profile in profiles {
    if profile.bio_match == Some(true) {
        println!("Match in bio: {:?}", profile.bio_hl);
    }
    if profile.interests_match == Some(true) {
        println!("Match in interests: {:?}", profile.interests_hl);
    }
}

Next Steps

Batches

Work with batch data

Locations

Search for locations

Error Handling

Handle API errors

Build docs developers (and LLMs) love