๐ Authentication
โผ
POST
/auth/register
PUBLIC
Register / Login user (phone-based)
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| name | string | Required |
| phone | string | Required |
| role | enum | Required |
| fcm_token | string | Optional |
| circles | array | Optional |
Role values: parent, family_caregiver, partner, friend, other
circles: [{name: "Family"}, {name: "Friends"}]
๐ฅ Response (201)
{
"success": true,
"message": "User registered successfully",
"data": {
"user": { "id": 1, "name": "...", "phone": "...", "role": "parent" },
"token": "1|abc...",
"circles": [{ "id": 1, "name": "Family", "invite_code": "ABC-DEF" }]
}
}
GET
/auth/me
๐
Get current user profile + token info
โผ
๐ค Request
No body required. Send Bearer token in header.
๐ฅ Response (200)
{
"success": true,
"data": {
"user": { "id": 1, "name": "...", "role": "parent", "latest_location": null },
"token_info": { "token_id": 1, "token_name": "auth_token", "last_used_at": "..." }
}
}
PUT
/auth/profile
๐
Update user profile (name, avatar)
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| name | string | Optional |
| avatar_url | string (url) | Optional |
๐ฅ Response (200)
{
"success": true,
"message": "Profile updated successfully",
"data": { "id": 1, "name": "New Name", "avatar_url": null }
}
PUT
/auth/fcm-token
๐
Update FCM push notification token
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| fcm_token | string | Required |
๐ฅ Response (200)
{
"success": true,
"message": "FCM token updated successfully"
}
POST
/auth/logout
๐
Logout โ delete current token
โผ
๐ค Request
No body required. Token will be deleted from server.
๐ฅ Response (200)
{
"success": true,
"message": "Logged out successfully"
}
โญ Circles โ CRUD
โผ
GET
/circles
๐
List all my circles
โผ
๐ฅ Response (200)
{
"success": true,
"data": [
{
"id": 1, "name": "Family", "user_id": 1,
"invite_code": "ABC-DEF",
"owner": { "id": 1, "name": "...", "phone": "..." },
"members": [{ "id": 1, "name": "...", "pivot": { "role": "admin" } }]
}
]
}
POST
/circles
๐
Create a new circle
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| name | string | Required |
๐ฅ Response (201)
{
"success": true,
"message": "Circle created successfully",
"data": {
"circle": { "id": 1, "name": "Family", "invite_code": "ABC-DEF" },
"invite_link": "http://localhost/join?code=ABC-DEF"
}
}
GET
/circles/{id}
๐
Get circle details with members & places
โผ
๐ฅ Response (200)
{
"success": true,
"data": {
"id": 1, "name": "Family",
"owner": { ... },
"members": [ ... ],
"places": [ ... ]
}
}
PUT
/circles/{id}
๐
Update circle name (owner only)
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| name | string | Required |
๐ฅ Response (200)
{
"success": true,
"message": "Circle updated successfully",
"data": { "id": 1, "name": "Updated Name" }
}
DELETE
/circles/{id}
๐
Delete circle (owner only)
โผ
๐ฅ Response (200)
{
"success": true,
"message": "Circle deleted successfully"
}
โก Circle Actions
โผ
POST
/circles/join
๐
Join circle with invite code
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| invite_code | string | Required |
Format: ABC-DEF (expires in 24 hours)
๐ฅ Response (200)
{
"success": true,
"message": "Successfully joined the circle",
"data": { "id": 1, "name": "Family", "members": [...] }
}
POST
/circles/{id}/leave
๐
Leave a circle (non-owner)
โผ
๐ฅ Response (200)
{
"success": true,
"message": "You have left the circle"
}
POST
/circles/{id}/remove-member
๐
Remove a member (owner only)
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| user_id | integer | Required |
๐ฅ Response (200)
{
"success": true,
"message": "Member removed successfully"
}
POST
/circles/{id}/regenerate-code
๐
Regenerate invite code (owner only)
โผ
๐ฅ Response (200)
{
"success": true,
"message": "Invite code regenerated successfully",
"data": {
"invite_code": "XYZ-ABC",
"invite_code_expires_at": "2026-03-30T16:00:00Z",
"invite_link": "http://localhost/join?code=XYZ-ABC"
}
}
GET
/circles/{id}/members-locations
๐
Get all members' latest locations
โผ
๐ฅ Response (200)
{
"success": true,
"data": [
{
"id": 1, "name": "User",
"latest_location": {
"latitude": "24.860", "longitude": "67.001",
"battery_level": 85, "is_moving": false
}
}
]
}
๐ Locations
โผ
POST
/locations
๐
Save single location (also emits via Socket.IO)
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| latitude | number (-90 to 90) | Required |
| longitude | number (-180 to 180) | Required |
| battery_level | integer (0-100) | Optional |
| activity_type | enum | Optional |
| is_moving | boolean | Optional |
| recorded_at | datetime | Optional |
activity_type: still, walking, running, driving, cycling, unknown
๐ฅ Response (201)
{
"success": true,
"message": "Location saved successfully",
"data": {
"id": 1, "latitude": "24.860",
"longitude": "67.001", "battery_level": 85
}
}
POST
/locations/batch
๐
Save multiple locations (offline sync)
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| locations | array (max 500) | Required |
| locations.*.latitude | number | Required |
| locations.*.longitude | number | Required |
| locations.*.recorded_at | datetime | Required |
| locations.*.battery_level | integer | Optional |
๐ฅ Response (201)
{
"success": true,
"message": "3 locations saved successfully",
"data": { "saved_count": 3 }
}
GET
/locations/history
๐
Get location history (with date filter)
โผ
๐ค Query Parameters
| Field | Type | Required |
|---|---|---|
| from | date (YYYY-MM-DD) | Optional |
| to | date (YYYY-MM-DD) | Optional |
| limit | integer (1-1000) | Optional (default: 100) |
๐ฅ Response (200)
{
"success": true,
"data": [
{ "id": 1, "latitude": "24.860", "longitude": "67.001",
"recorded_at": "2026-03-29T16:12:55Z" }
]
}
๐ Places / Geofences
โผ
GET
/circles/{circleId}/places
๐
List all places in a circle
โผ
๐ฅ Response (200)
{
"success": true,
"data": [
{ "id": 1, "name": "Home", "latitude": "24.860",
"longitude": "67.001", "radius": 100,
"address": "Clifton, Karachi",
"creator": { "id": 1, "name": "User" } }
]
}
POST
/circles/{circleId}/places
๐
Create a new place/geofence
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| name | string | Required |
| latitude | number | Required |
| longitude | number | Required |
| radius | integer (meters) | Required |
| address | string | Optional |
๐ฅ Response (201)
{
"success": true,
"message": "Place created successfully",
"data": { "id": 1, "name": "Home", "radius": 100 }
}
PUT
/circles/{circleId}/places/{placeId}
๐
Update a place
โผ
๐ค Request Body
| Field | Type | Required |
|---|---|---|
| name | string | Optional |
| latitude | number | Optional |
| longitude | number | Optional |
| radius | integer | Optional |
| address | string | Optional |
๐ฅ Response (200)
{
"success": true,
"message": "Place updated successfully",
"data": { "id": 1, "name": "My Home", "radius": 150 }
}
DELETE
/circles/{circleId}/places/{placeId}
๐
Delete a place
โผ
๐ฅ Response (200)
{
"success": true,
"message": "Place deleted successfully"
}