Skip to content
Last updated

Guide for developers on retrieving user information through the Freddy API.

Authentication Required

All user data endpoints require Bearer token authentication:

Authorization: Bearer $FREDDY_API_KEY

Getting Your Own Profile

Current User Profile

Retrieve your complete profile with GET /v1/user/me:

import requests
import os

response = requests.get(
    "https://api.aitronos.com/v1/user/me",
    headers={"Authorization": f"Bearer {os.environ['FREDDY_API_KEY']}"}
)

profile = response.json()
# Returns: id, email, username, full_name, timezone, profile_image, etc.

Alternative endpoints:

  • GET /v1/user/me - Full profile
  • GET /v1/user/profile - Same as above
  • GET /v1/user/current - Basic user info

Your Active Devices

Get all device sessions with GET /v1/user/devices:

response = requests.get(
    "https://api.aitronos.com/v1/user/devices",
    headers={"X-API-Key": api_key}
)

devices = response.json()
# Returns: device_id, device_name, platform, location, last_used_at

Welcome Details

Get organization context for onboarding with GET /v1/user/welcomedetails:

response = requests.get(
    "https://api.aitronos.com/v1/user/welcomedetails",
    headers={"X-API-Key": api_key}
)

welcome = response.json()
# Returns: name, logo, email (organization details)

Getting Other Users

Retrieve User by Email

Use GET /v1/user/email/{email}:

response = requests.get(
    "https://api.aitronos.com/v1/user/email/user@example.com",
    headers={"X-API-Key": api_key}
)

user = response.json()

List All Users

Paginated list with GET /v1/user:

response = requests.get(
    "https://api.aitronos.com/v1/user",
    params={
        "skip": 0,
        "limit": 100,
        "active_only": True
    },
    headers={"X-API-Key": api_key}
)

users = response.json()

Query parameters:

  • skip - Pagination offset (default: 0)
  • limit - Max results (default: 100)
  • active_only - Filter active users only (default: false)

Organization Members

List Organization Members

Requires Admin or Owner role. Use POST /v1/organizations/{org_id}/users:

response = requests.post(
    f"https://api.aitronos.com/v1/organizations/{org_id}/users",
    headers={
        "X-API-Key": api_key,
        "Content-Type": "application/json"
    },
    json={
        "skip": 0,
        "take": 10,
        "search_term": "john",
        "role_id": "role_admin",
        "status_id": "status_active",
        "sort_field": "created_at",
        "sort_direction": "desc",
        "include_deleted": False
    }
)

result = response.json()
members = result["users"]
total = result["total_users_count"]

Request body options:

  • skip / take - Pagination (max take: 100)
  • search_term - Search name, email, username
  • role_id - Filter by role
  • status_id - Filter by status
  • sort_field - full_name, email, role, status, created_at, last_modified_at
  • sort_direction - asc or desc
  • include_deleted - Include soft-deleted members

Get Specific Member

Retrieve detailed member info with GET /v1/organizations/{org_id}/users/{user_id}:

response = requests.get(
    f"https://api.aitronos.com/v1/organizations/{org_id}/users/{user_id}",
    headers={"X-API-Key": api_key}
)

member = response.json()
# Returns: full member details with role and status

Accepts:

  • User ID (usr_...)
  • OrganizationUser ID (orgusr_...)

Get All Member IDs

Quick list of user IDs with POST /v1/organizations/{org_id}/users/ids:

response = requests.post(
    f"https://api.aitronos.com/v1/organizations/{org_id}/users/ids",
    headers={"X-API-Key": api_key}
)

user_ids = response.json()
# Returns: ["usr_abc123", "usr_def456", ...]

Common Patterns

Check if User Exists

def user_exists(email):
    try:
        response = requests.get(
            f"https://api.aitronos.com/v1/user/email/{email}",
            headers={"X-API-Key": api_key}
        )
        return response.status_code == 200
    except:
        return False

Search Organization Members

def search_members(org_id, search_term):
    response = requests.post(
        f"https://api.aitronos.com/v1/organizations/{org_id}/users",
        headers={
            "X-API-Key": api_key,
            "Content-Type": "application/json"
        },
        json={
            "search_term": search_term,
            "take": 50
        }
    )
    return response.json()["users"]

Paginate Through All Members

def get_all_members(org_id):
    all_members = []
    skip = 0
    take = 100
    
    while True:
        response = requests.post(
            f"https://api.aitronos.com/v1/organizations/{org_id}/users",
            headers={
                "X-API-Key": api_key,
                "Content-Type": "application/json"
            },
            json={"skip": skip, "take": take}
        )
        
        result = response.json()
        members = result["users"]
        all_members.extend(members)
        
        if len(members) < take:
            break
            
        skip += take
    
    return all_members

Error Handling

Handle common errors:

response = requests.get(url, headers=headers)

if response.status_code == 401:
    # Authentication required or invalid token
    print("Invalid or missing API key")
elif response.status_code == 403:
    # Insufficient permissions (organization endpoints)
    print("Admin or Owner role required")
elif response.status_code == 404:
    # User not found
    print("User does not exist")
else:
    user = response.json()

Rate Limits

  • 100 requests per minute per user
  • 1000 requests per hour per organization

Implement exponential backoff on 429 responses.