Guide for developers on retrieving user information through the Freddy API.
All user data endpoints require Bearer token authentication:
Authorization: Bearer $FREDDY_API_KEYRetrieve 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 profileGET /v1/user/profile- Same as aboveGET /v1/user/current- Basic user info
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_atGet 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)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()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)
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, usernamerole_id- Filter by rolestatus_id- Filter by statussort_field-full_name,email,role,status,created_at,last_modified_atsort_direction-ascordescinclude_deleted- Include soft-deleted members
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 statusAccepts:
- User ID (
usr_...) - OrganizationUser ID (
orgusr_...)
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", ...]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 Falsedef 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"]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_membersHandle 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()- 100 requests per minute per user
- 1000 requests per hour per organization
Implement exponential backoff on 429 responses.