# Location Tracker API Documentation

**Base URL:** `http://your-domain.com/api/v1`

**Authentication:** Laravel Sanctum (Bearer Token)

**Headers (Protected Routes):**
```
Authorization: Bearer {token}
Content-Type: application/json
Accept: application/json
```

---

## Table of Contents

1. [Auth APIs](#1-auth-apis)
2. [Circle APIs](#2-circle-apis)
3. [Circle Action APIs](#3-circle-action-apis)
4. [Location APIs](#4-location-apis)
5. [Place / Geofence APIs](#5-place--geofence-apis)
6. [Error Responses](#6-common-error-responses)

---

## 1. Auth APIs

### 1.1 Register / Login

User register ya login karta hai phone number se. Agar phone already exist karta hai toh login ho jayega, nahi toh naya user ban jayega.

**Endpoint:** `POST /api/v1/auth/register`

**Auth Required:** No

**Request Body:**
```json
{
    "name": "Ali Khan",
    "phone": "+923001234567",
    "fcm_token": "firebase_token_here"   // optional
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | User ka naam (max 255 chars) |
| phone | string | Yes | Phone number (max 20 chars, unique) |
| fcm_token | string | No | Firebase Cloud Messaging token |

**Success Response (201):**
```json
{
    "success": true,
    "message": "User registered successfully",
    "data": {
        "user": {
            "id": 1,
            "name": "Ali Khan",
            "phone": "+923001234567",
            "avatar_url": null,
            "created_at": "2026-03-27T10:00:00.000000Z",
            "updated_at": "2026-03-27T10:00:00.000000Z"
        },
        "token": "1|abc123xyz456tokenvalue..."
    }
}
```

**Validation Error (422):**
```json
{
    "success": false,
    "message": "Validation error",
    "errors": {
        "name": ["The name field is required."],
        "phone": ["The phone field is required."]
    }
}
```

---

### 1.2 Get Current User Profile

Login user ki profile aur latest location return karta hai.

**Endpoint:** `GET /api/v1/auth/me`

**Auth Required:** Yes

**Request Body:** None

**Success Response (200):**
```json
{
    "success": true,
    "data": {
        "id": 1,
        "name": "Ali Khan",
        "phone": "+923001234567",
        "avatar_url": null,
        "created_at": "2026-03-27T10:00:00.000000Z",
        "updated_at": "2026-03-27T10:00:00.000000Z",
        "latest_location": {
            "user_id": 1,
            "latitude": "24.8607343",
            "longitude": "67.0011364",
            "battery_level": 85,
            "activity_type": "still",
            "is_moving": false,
            "updated_at": "2026-03-27T10:30:00.000000Z"
        }
    }
}
```

> **Note:** `latest_location` null ho sakta hai agar user ne abhi tak koi location send nahi ki.

---

### 1.3 Update Profile

User apna naam ya avatar update kar sakta hai.

**Endpoint:** `PUT /api/v1/auth/profile`

**Auth Required:** Yes

**Request Body:**
```json
{
    "name": "Ali Ahmed Khan",
    "avatar_url": "https://example.com/avatar.jpg"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| name | string | No | Naya naam (max 255 chars) |
| avatar_url | string (URL) | No | Avatar image ka URL |

**Success Response (200):**
```json
{
    "success": true,
    "message": "Profile updated successfully",
    "data": {
        "id": 1,
        "name": "Ali Ahmed Khan",
        "phone": "+923001234567",
        "avatar_url": "https://example.com/avatar.jpg",
        "created_at": "2026-03-27T10:00:00.000000Z",
        "updated_at": "2026-03-27T11:00:00.000000Z"
    }
}
```

---

### 1.4 Update FCM Token

Firebase push notification token update karna.

**Endpoint:** `PUT /api/v1/auth/fcm-token`

**Auth Required:** Yes

**Request Body:**
```json
{
    "fcm_token": "new_firebase_token_value_here"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| fcm_token | string | Yes | Naya FCM token |

**Success Response (200):**
```json
{
    "success": true,
    "message": "FCM token updated successfully"
}
```

---

### 1.5 Logout

Current token delete kar deta hai. User ko dobara login karna padega.

**Endpoint:** `POST /api/v1/auth/logout`

**Auth Required:** Yes

**Request Body:** None

**Success Response (200):**
```json
{
    "success": true,
    "message": "Logged out successfully"
}
```

---

## 2. Circle APIs

### 2.1 Get All Circles

User jin circles ka member hai wo sab return karta hai.

**Endpoint:** `GET /api/v1/circles`

**Auth Required:** Yes

**Request Body:** None

**Success Response (200):**
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "name": "Family",
            "user_id": 1,
            "invite_code": "ABC-XYZ",
            "invite_code_expires_at": "2026-03-28T10:00:00.000000Z",
            "created_at": "2026-03-27T10:00:00.000000Z",
            "updated_at": "2026-03-27T10:00:00.000000Z",
            "pivot": {
                "user_id": 1,
                "circle_id": 1,
                "role": "admin",
                "created_at": "2026-03-27T10:00:00.000000Z",
                "updated_at": "2026-03-27T10:00:00.000000Z"
            },
            "owner": {
                "id": 1,
                "name": "Ali Khan",
                "phone": "+923001234567",
                "avatar_url": null
            },
            "members": [
                {
                    "id": 1,
                    "name": "Ali Khan",
                    "phone": "+923001234567",
                    "avatar_url": null,
                    "pivot": {
                        "circle_id": 1,
                        "user_id": 1,
                        "role": "admin"
                    }
                },
                {
                    "id": 2,
                    "name": "Sara Khan",
                    "phone": "+923009876543",
                    "avatar_url": null,
                    "pivot": {
                        "circle_id": 1,
                        "user_id": 2,
                        "role": "member"
                    }
                }
            ]
        }
    ]
}
```

---

### 2.2 Create Circle

Naya circle banata hai. Creator automatically admin member ban jata hai. 24 ghante ka invite code generate hota hai.

**Endpoint:** `POST /api/v1/circles`

**Auth Required:** Yes

**Request Body:**
```json
{
    "name": "Family"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Circle ka naam (max 255 chars) |

**Success Response (201):**
```json
{
    "success": true,
    "message": "Circle created successfully",
    "data": {
        "circle": {
            "id": 1,
            "name": "Family",
            "user_id": 1,
            "invite_code": "ABC-XYZ",
            "invite_code_expires_at": "2026-03-28T10:00:00.000000Z",
            "created_at": "2026-03-27T10:00:00.000000Z",
            "updated_at": "2026-03-27T10:00:00.000000Z",
            "owner": {
                "id": 1,
                "name": "Ali Khan",
                "phone": "+923001234567",
                "avatar_url": null
            },
            "members": [
                {
                    "id": 1,
                    "name": "Ali Khan",
                    "phone": "+923001234567",
                    "avatar_url": null,
                    "pivot": {
                        "circle_id": 1,
                        "user_id": 1,
                        "role": "admin"
                    }
                }
            ]
        },
        "invite_link": "http://your-domain.com/join?code=ABC-XYZ"
    }
}
```

---

### 2.3 Get Circle Details

Ek circle ki poori details — owner, members, aur places sab.

**Endpoint:** `GET /api/v1/circles/{id}`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| id | integer | Circle ka ID |

**Success Response (200):**
```json
{
    "success": true,
    "data": {
        "id": 1,
        "name": "Family",
        "user_id": 1,
        "invite_code": "ABC-XYZ",
        "invite_code_expires_at": "2026-03-28T10:00:00.000000Z",
        "created_at": "2026-03-27T10:00:00.000000Z",
        "updated_at": "2026-03-27T10:00:00.000000Z",
        "owner": {
            "id": 1,
            "name": "Ali Khan",
            "phone": "+923001234567",
            "avatar_url": null
        },
        "members": [
            {
                "id": 1,
                "name": "Ali Khan",
                "phone": "+923001234567",
                "avatar_url": null,
                "pivot": { "circle_id": 1, "user_id": 1, "role": "admin" }
            }
        ],
        "places": [
            {
                "id": 1,
                "circle_id": 1,
                "created_by": 1,
                "name": "Home",
                "latitude": "24.8607343",
                "longitude": "67.0011364",
                "radius": 100,
                "address": "House #123, Block A, Karachi",
                "created_at": "2026-03-27T10:00:00.000000Z",
                "updated_at": "2026-03-27T10:00:00.000000Z"
            }
        ]
    }
}
```

**Not a Member (403):**
```json
{
    "success": false,
    "message": "You are not a member of this circle"
}
```

---

### 2.4 Update Circle Name

Sirf circle owner hi circle ka naam change kar sakta hai.

**Endpoint:** `PUT /api/v1/circles/{id}`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| id | integer | Circle ka ID |

**Request Body:**
```json
{
    "name": "Meri Family"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Naya circle naam (max 255 chars) |

**Success Response (200):**
```json
{
    "success": true,
    "message": "Circle updated successfully",
    "data": {
        "id": 1,
        "name": "Meri Family",
        "user_id": 1,
        "invite_code": "ABC-XYZ",
        "invite_code_expires_at": "2026-03-28T10:00:00.000000Z",
        "created_at": "2026-03-27T10:00:00.000000Z",
        "updated_at": "2026-03-27T11:00:00.000000Z"
    }
}
```

**Not Owner (403):**
```json
{
    "success": false,
    "message": "Only the circle owner can update it"
}
```

---

### 2.5 Delete Circle

Sirf owner hi circle delete kar sakta hai. Sab members aur places bhi delete ho jayenge (cascade).

**Endpoint:** `DELETE /api/v1/circles/{id}`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| id | integer | Circle ka ID |

**Success Response (200):**
```json
{
    "success": true,
    "message": "Circle deleted successfully"
}
```

**Not Owner (403):**
```json
{
    "success": false,
    "message": "Only the circle owner can delete it"
}
```

---

## 3. Circle Action APIs

### 3.1 Join Circle (Invite Code se)

Invite code daal ke circle mein join hona. Code 24 ghante ke baad expire ho jata hai.

**Endpoint:** `POST /api/v1/circles/join`

**Auth Required:** Yes

**Request Body:**
```json
{
    "invite_code": "ABC-XYZ"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| invite_code | string | Yes | Circle ka invite code (case-insensitive) |

**Success Response (200):**
```json
{
    "success": true,
    "message": "Successfully joined the circle",
    "data": {
        "id": 1,
        "name": "Family",
        "user_id": 1,
        "invite_code": "ABC-XYZ",
        "invite_code_expires_at": "2026-03-28T10:00:00.000000Z",
        "created_at": "2026-03-27T10:00:00.000000Z",
        "updated_at": "2026-03-27T10:00:00.000000Z",
        "owner": {
            "id": 1,
            "name": "Ali Khan",
            "phone": "+923001234567",
            "avatar_url": null
        },
        "members": [
            {
                "id": 1,
                "name": "Ali Khan",
                "phone": "+923001234567",
                "avatar_url": null,
                "pivot": { "circle_id": 1, "user_id": 1, "role": "admin" }
            },
            {
                "id": 2,
                "name": "Sara Khan",
                "phone": "+923009876543",
                "avatar_url": null,
                "pivot": { "circle_id": 1, "user_id": 2, "role": "member" }
            }
        ]
    }
}
```

**Invalid Code (404):**
```json
{
    "success": false,
    "message": "Invalid invite code"
}
```

**Code Expired (410):**
```json
{
    "success": false,
    "message": "Invite code has expired. Ask the circle owner for a new code."
}
```

**Already Member (409):**
```json
{
    "success": false,
    "message": "You are already a member of this circle"
}
```

---

### 3.2 Leave Circle

Circle chhod dena. Owner leave nahi kar sakta, usse circle delete karna padega.

**Endpoint:** `POST /api/v1/circles/{id}/leave`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| id | integer | Circle ka ID |

**Success Response (200):**
```json
{
    "success": true,
    "message": "You have left the circle"
}
```

**Owner Cannot Leave (403):**
```json
{
    "success": false,
    "message": "Circle owner cannot leave. Delete the circle instead."
}
```

---

### 3.3 Remove Member (Owner Only)

Owner kisi bhi member ko circle se nikal sakta hai, lekin khud ko nahi.

**Endpoint:** `POST /api/v1/circles/{id}/remove-member`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| id | integer | Circle ka ID |

**Request Body:**
```json
{
    "user_id": 2
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| user_id | integer | Yes | Jis member ko nikalna hai uska user ID |

**Success Response (200):**
```json
{
    "success": true,
    "message": "Member removed successfully"
}
```

**Not Owner (403):**
```json
{
    "success": false,
    "message": "Only the circle owner can remove members"
}
```

**Cannot Remove Owner (403):**
```json
{
    "success": false,
    "message": "Cannot remove the circle owner"
}
```

---

### 3.4 Regenerate Invite Code (Owner Only)

Purana code expire karke naya code generate karta hai (24 ghante ki expiry ke saath).

**Endpoint:** `POST /api/v1/circles/{id}/regenerate-code`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| id | integer | Circle ka ID |

**Request Body:** None

**Success Response (200):**
```json
{
    "success": true,
    "message": "Invite code regenerated successfully",
    "data": {
        "invite_code": "NEW-COD",
        "invite_code_expires_at": "2026-03-28T12:00:00.000000Z",
        "invite_link": "http://your-domain.com/join?code=NEW-COD"
    }
}
```

**Not Owner (403):**
```json
{
    "success": false,
    "message": "Only the circle owner can regenerate the invite code"
}
```

---

### 3.5 Get Members with Latest Locations

Circle ke sab members ki latest location return karta hai — map pe dikhane ke liye.

**Endpoint:** `GET /api/v1/circles/{id}/members-locations`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| id | integer | Circle ka ID |

**Success Response (200):**
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "name": "Ali Khan",
            "phone": "+923001234567",
            "avatar_url": null,
            "pivot": {
                "circle_id": 1,
                "user_id": 1,
                "role": "admin"
            },
            "latest_location": {
                "user_id": 1,
                "latitude": "24.8607343",
                "longitude": "67.0011364",
                "battery_level": 85,
                "activity_type": "still",
                "is_moving": false,
                "updated_at": "2026-03-27T10:30:00.000000Z"
            }
        },
        {
            "id": 2,
            "name": "Sara Khan",
            "phone": "+923009876543",
            "avatar_url": null,
            "pivot": {
                "circle_id": 1,
                "user_id": 2,
                "role": "member"
            },
            "latest_location": {
                "user_id": 2,
                "latitude": "24.8710000",
                "longitude": "67.0280000",
                "battery_level": 42,
                "activity_type": "driving",
                "is_moving": true,
                "updated_at": "2026-03-27T10:35:00.000000Z"
            }
        }
    ]
}
```

> **Note:** `latest_location` null ho sakta hai agar member ne abhi tak location share nahi ki.

**Not a Member (403):**
```json
{
    "success": false,
    "message": "You are not a member of this circle"
}
```

---

## 4. Location APIs

### 4.1 Save Single Location

Ek location save karta hai history mein aur latest location bhi update kar deta hai.

**Endpoint:** `POST /api/v1/locations`

**Auth Required:** Yes

**Request Body:**
```json
{
    "latitude": 24.8607343,
    "longitude": 67.0011364,
    "battery_level": 85,
    "activity_type": "still",
    "is_moving": false,
    "recorded_at": "2026-03-27T10:30:00Z"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| latitude | numeric | Yes | -90 se 90 ke beech |
| longitude | numeric | Yes | -180 se 180 ke beech |
| battery_level | integer | No | 0 se 100 (phone battery %) |
| activity_type | string | No | `still`, `walking`, `running`, `driving`, `cycling`, `unknown` |
| is_moving | boolean | No | User chal raha hai ya nahi (default: false) |
| recorded_at | date | No | Jab phone ne record kiya (default: current time) |

**Success Response (201):**
```json
{
    "success": true,
    "message": "Location saved successfully",
    "data": {
        "id": 1,
        "user_id": 1,
        "latitude": "24.8607343",
        "longitude": "67.0011364",
        "battery_level": 85,
        "activity_type": "still",
        "is_moving": false,
        "recorded_at": "2026-03-27T10:30:00.000000Z",
        "created_at": "2026-03-27T10:30:05.000000Z",
        "updated_at": "2026-03-27T10:30:05.000000Z"
    }
}
```

---

### 4.2 Batch Save Locations (Offline Sync)

Jab phone offline tha tab ki saari buffered locations ek saath bhejne ke liye. Maximum 500 locations ek batch mein.

**Endpoint:** `POST /api/v1/locations/batch`

**Auth Required:** Yes

**Request Body:**
```json
{
    "locations": [
        {
            "latitude": 24.8607343,
            "longitude": 67.0011364,
            "battery_level": 90,
            "activity_type": "still",
            "is_moving": false,
            "recorded_at": "2026-03-27T09:00:00Z"
        },
        {
            "latitude": 24.8710000,
            "longitude": 67.0280000,
            "battery_level": 85,
            "activity_type": "driving",
            "is_moving": true,
            "recorded_at": "2026-03-27T09:15:00Z"
        },
        {
            "latitude": 24.8800000,
            "longitude": 67.0350000,
            "battery_level": 80,
            "activity_type": "walking",
            "is_moving": true,
            "recorded_at": "2026-03-27T09:30:00Z"
        }
    ]
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| locations | array | Yes | Locations ki array (min: 1, max: 500) |
| locations.*.latitude | numeric | Yes | -90 se 90 |
| locations.*.longitude | numeric | Yes | -180 se 180 |
| locations.*.battery_level | integer | No | 0 se 100 |
| locations.*.activity_type | string | No | `still`, `walking`, `running`, `driving`, `cycling`, `unknown` |
| locations.*.is_moving | boolean | No | Default: false |
| locations.*.recorded_at | date | Yes | Jab record hua (zaroori hai batch mein) |

> **Note:** Batch mein `recorded_at` required hai, single location mein optional hai.

**Success Response (201):**
```json
{
    "success": true,
    "message": "3 locations saved successfully",
    "data": {
        "saved_count": 3
    }
}
```

---

### 4.3 Get Location History

User ki location history filter ke saath. Date range aur limit lagaya ja sakta hai.

**Endpoint:** `GET /api/v1/locations/history`

**Auth Required:** Yes

**Query Parameters:**

| Param | Type | Required | Description |
|---|---|---|---|
| from | date | No | Start date (e.g., `2026-03-27`) |
| to | date | No | End date (e.g., `2026-03-27`) |
| limit | integer | No | Kitni records chahiye (min: 1, max: 1000, default: 100) |

**Example:** `GET /api/v1/locations/history?from=2026-03-27&to=2026-03-27&limit=50`

**Success Response (200):**
```json
{
    "success": true,
    "data": [
        {
            "id": 3,
            "user_id": 1,
            "latitude": "24.8800000",
            "longitude": "67.0350000",
            "battery_level": 80,
            "activity_type": "walking",
            "is_moving": true,
            "recorded_at": "2026-03-27T09:30:00.000000Z",
            "created_at": "2026-03-27T09:30:05.000000Z",
            "updated_at": "2026-03-27T09:30:05.000000Z"
        },
        {
            "id": 2,
            "user_id": 1,
            "latitude": "24.8710000",
            "longitude": "67.0280000",
            "battery_level": 85,
            "activity_type": "driving",
            "is_moving": true,
            "recorded_at": "2026-03-27T09:15:00.000000Z",
            "created_at": "2026-03-27T09:15:05.000000Z",
            "updated_at": "2026-03-27T09:15:05.000000Z"
        }
    ]
}
```

> **Note:** Results `recorded_at` ke descending (newest first) order mein aate hain.

---

## 5. Place / Geofence APIs

Places = Saved locations with geofence radius (jaise Home, Office, School).

### 5.1 Get All Places in a Circle

Circle ke saare places/geofences return karta hai.

**Endpoint:** `GET /api/v1/circles/{circleId}/places`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| circleId | integer | Circle ka ID |

**Success Response (200):**
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "circle_id": 1,
            "created_by": 1,
            "name": "Home",
            "latitude": "24.8607343",
            "longitude": "67.0011364",
            "radius": 100,
            "address": "House #123, Block A, Gulshan, Karachi",
            "created_at": "2026-03-27T10:00:00.000000Z",
            "updated_at": "2026-03-27T10:00:00.000000Z",
            "creator": {
                "id": 1,
                "name": "Ali Khan"
            }
        },
        {
            "id": 2,
            "circle_id": 1,
            "created_by": 2,
            "name": "Office",
            "latitude": "24.8710000",
            "longitude": "67.0280000",
            "radius": 200,
            "address": "I.I. Chundrigar Road, Karachi",
            "created_at": "2026-03-27T11:00:00.000000Z",
            "updated_at": "2026-03-27T11:00:00.000000Z",
            "creator": {
                "id": 2,
                "name": "Sara Khan"
            }
        }
    ]
}
```

**Not a Member (403):**
```json
{
    "success": false,
    "message": "You are not a member of this circle"
}
```

---

### 5.2 Create Place / Geofence

Circle mein naya place add karna (jaise Home, Office, School).

**Endpoint:** `POST /api/v1/circles/{circleId}/places`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| circleId | integer | Circle ka ID |

**Request Body:**
```json
{
    "name": "Home",
    "latitude": 24.8607343,
    "longitude": 67.0011364,
    "radius": 150,
    "address": "House #123, Block A, Gulshan, Karachi"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Place ka naam (max 255 chars) |
| latitude | numeric | Yes | -90 se 90 |
| longitude | numeric | Yes | -180 se 180 |
| radius | integer | No | Geofence radius meters mein (min: 50, max: 5000, default: 100) |
| address | string | No | Address text (max 500 chars) |

**Success Response (201):**
```json
{
    "success": true,
    "message": "Place created successfully",
    "data": {
        "id": 1,
        "circle_id": 1,
        "created_by": 1,
        "name": "Home",
        "latitude": "24.8607343",
        "longitude": "67.0011364",
        "radius": 150,
        "address": "House #123, Block A, Gulshan, Karachi",
        "created_at": "2026-03-27T10:00:00.000000Z",
        "updated_at": "2026-03-27T10:00:00.000000Z",
        "creator": {
            "id": 1,
            "name": "Ali Khan"
        }
    }
}
```

---

### 5.3 Update Place / Geofence

Existing place ko update karna. Circle ka koi bhi member update kar sakta hai.

**Endpoint:** `PUT /api/v1/circles/{circleId}/places/{placeId}`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| circleId | integer | Circle ka ID |
| placeId | integer | Place ka ID |

**Request Body:**
```json
{
    "name": "Ghar",
    "radius": 200,
    "address": "Updated address here"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| name | string | No | Naya naam |
| latitude | numeric | No | Nayi latitude |
| longitude | numeric | No | Nayi longitude |
| radius | integer | No | Naya radius (50-5000 meters) |
| address | string | No | Naya address |

**Success Response (200):**
```json
{
    "success": true,
    "message": "Place updated successfully",
    "data": {
        "id": 1,
        "circle_id": 1,
        "created_by": 1,
        "name": "Ghar",
        "latitude": "24.8607343",
        "longitude": "67.0011364",
        "radius": 200,
        "address": "Updated address here",
        "created_at": "2026-03-27T10:00:00.000000Z",
        "updated_at": "2026-03-27T12:00:00.000000Z"
    }
}
```

---

### 5.4 Delete Place / Geofence

Place delete karna. Sirf circle owner ya place creator delete kar sakta hai.

**Endpoint:** `DELETE /api/v1/circles/{circleId}/places/{placeId}`

**Auth Required:** Yes

**URL Params:**

| Param | Type | Description |
|---|---|---|
| circleId | integer | Circle ka ID |
| placeId | integer | Place ka ID |

**Success Response (200):**
```json
{
    "success": true,
    "message": "Place deleted successfully"
}
```

**Not Authorized (403):**
```json
{
    "success": false,
    "message": "Only the circle owner or place creator can delete it"
}
```

---

## 6. Common Error Responses

### Unauthenticated (401)
Jab token missing ya invalid ho:
```json
{
    "message": "Unauthenticated."
}
```

### Validation Error (422)
Jab request data galat ho:
```json
{
    "success": false,
    "message": "Validation error",
    "errors": {
        "field_name": ["Error message here."]
    }
}
```

### Not Found (404)
Jab resource nahi mila:
```json
{
    "message": "No query results for model [App\\Models\\Circle] 999"
}
```

### Forbidden (403)
Jab permission nahi hai:
```json
{
    "success": false,
    "message": "Only the circle owner can ..."
}
```

---

## API Endpoints Summary

| # | Method | Endpoint | Auth | Description |
|---|---|---|---|---|
| 1 | POST | `/api/v1/auth/register` | No | Register / Login |
| 2 | GET | `/api/v1/auth/me` | Yes | Get profile + latest location |
| 3 | PUT | `/api/v1/auth/profile` | Yes | Update name / avatar |
| 4 | PUT | `/api/v1/auth/fcm-token` | Yes | Update FCM token |
| 5 | POST | `/api/v1/auth/logout` | Yes | Logout (delete token) |
| 6 | GET | `/api/v1/circles` | Yes | List user's circles |
| 7 | POST | `/api/v1/circles` | Yes | Create new circle |
| 8 | GET | `/api/v1/circles/{id}` | Yes | Circle details |
| 9 | PUT | `/api/v1/circles/{id}` | Yes | Update circle name |
| 10 | DELETE | `/api/v1/circles/{id}` | Yes | Delete circle |
| 11 | POST | `/api/v1/circles/join` | Yes | Join via invite code |
| 12 | POST | `/api/v1/circles/{id}/leave` | Yes | Leave circle |
| 13 | POST | `/api/v1/circles/{id}/remove-member` | Yes | Remove member |
| 14 | POST | `/api/v1/circles/{id}/regenerate-code` | Yes | New invite code |
| 15 | GET | `/api/v1/circles/{id}/members-locations` | Yes | Members + locations |
| 16 | POST | `/api/v1/locations` | Yes | Save single location |
| 17 | POST | `/api/v1/locations/batch` | Yes | Batch save (offline sync) |
| 18 | GET | `/api/v1/locations/history` | Yes | Location history |
| 19 | GET | `/api/v1/circles/{cId}/places` | Yes | List places |
| 20 | POST | `/api/v1/circles/{cId}/places` | Yes | Create place/geofence |
| 21 | PUT | `/api/v1/circles/{cId}/places/{pId}` | Yes | Update place |
| 22 | DELETE | `/api/v1/circles/{cId}/places/{pId}` | Yes | Delete place |

---

**Total APIs: 22** (1 public + 21 protected)
