# LawNeu Booking — Complete API Reference

> **Version:** 2.0 · **Last Updated:** June 2026  
> **Base URL:** `https://page.law.indias.cloud/api/v1`  
> **Content-Type:** `application/json` (for all POST requests)

---

## Authentication

| Layer | Header | Value |
|-------|--------|-------|
| **User/Client** | None | Public access — no auth required |
| **Advocate/Admin** | `X-API-KEY` | `admin_secret_key` |
| **Master/Super Admin** | `Authorization` | `Bearer YOUR_MASTER_KEY` |

> [!IMPORTANT]
> All POST requests must send a JSON body with `Content-Type: application/json`.  
> All endpoints support CORS with `Access-Control-Allow-Origin: *`.
>
> Use `https://page.law.indias.cloud/api/v1` for all Lawneu Booking project API calls. Advocate-side tools stay under `/manage` and master admin stays under `/zlawpanel/`.

---

## HTTP Status Codes Used

| Code | Meaning |
|------|---------|
| `200` | Success |
| `400` | Bad Request — missing or invalid parameters |
| `401` | Unauthorized — invalid or missing API key |
| `405` | Method Not Allowed — wrong HTTP method |
| `500` | Internal Server Error |

---

# I. User (Client) Endpoints — No Auth Required

These public endpoints power the booking widget on advocate websites.

---

## 1. Check Subdomain Availability

Check if a subdomain prefix is available for a new advocate.

```
GET /check_subdomain.php?subdomain={subdomain}
```

**Query Parameters:**

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `subdomain` | string | ✅ | Lowercase alphanumeric subdomain to check |

**Case 1: Available**
```json
// GET /check_subdomain.php?subdomain=rajesh
{
  "success": true,
  "available": true,
  "subdomain": "rajesh"
}
```

**Case 2: Already Taken**
```json
// GET /check_subdomain.php?subdomain=test-advocate
{
  "success": true,
  "available": false,
  "subdomain": "test-advocate",
  "message": "Subdomain is already taken."
}
```

**Case 3: Reserved System Subdomain**
```json
// GET /check_subdomain.php?subdomain=admin
{
  "success": true,
  "available": false,
  "message": "This subdomain is reserved and cannot be used."
}
```

> [!NOTE]
> Reserved subdomains: `www`, `admin`, `api`, `page`, `test`, `app`, `mail`, `zlawpanel`, `coolify`, `panel`, `static`, `assets`, `dev`, `system`, `db`, `database`, `blog`, `webmail`, `support`, `status`, `help`, `billing`, `jobs`, `careers`, `account`, `profile`, `users`, `portal`, `dashboard`, `settings`, `config`, `auth`, `login`, `signup`, `register`

**cURL Example:**
```bash
curl "https://page.law.indias.cloud/api/v1/check_subdomain.php?subdomain=rajesh"
```

---

## 2. Fetch Available Slots

Get all open consultation time slots for a specific advocate on a specific date.

```
GET /slots.php?advocate_id={id}&date={YYYY-MM-DD}
```

**Query Parameters:**

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `advocate_id` | integer | ✅ | The advocate's database ID |
| `date` | string | ✅ | Date in `YYYY-MM-DD` format |

**Case 1: Slots Available**
```json
// GET /slots.php?advocate_id=1&date=2026-06-20
{
  "success": true,
  "is_accepting_bookings": true,
  "data": [
    { "id": "dyn_fca64f7b24e6fb29cf4d2165f9733054", "slot_time": "10:00 AM", "is_booked": 0 },
    { "id": "dyn_a2b3c4d5e6f7890123456789abcdef01", "slot_time": "11:00 AM", "is_booked": 0 },
    { "id": 42, "slot_time": "02:00 PM", "is_booked": 0 }
  ]
}
```

**Case 2: No Slots on This Date (Holiday/Weekend)**
```json
// GET /slots.php?advocate_id=1&date=2026-06-22 (Sunday)
{
  "success": true,
  "is_accepting_bookings": true,
  "data": []
}
```

**Case 3: Advocate Not Accepting Bookings**
```json
// GET /slots.php?advocate_id=1&date=2026-06-20
{
  "success": true,
  "is_accepting_bookings": false,
  "data": []
}
```

**Case 4: Missing advocate_id**
```json
{
  "error": "advocate_id is required"
}
```

> [!TIP]
> Slot `id` values starting with `dyn_` are dynamically generated from the advocate's weekly routine. Numeric IDs are manually created slots stored in the database. Both types can be booked the same way.

**cURL Example:**
```bash
curl "https://page.law.indias.cloud/api/v1/slots.php?advocate_id=1&date=2026-06-20"
```

---

## 3. Create Booking (Book Appointment)

Submit a consultation appointment request.

```
POST /book.php
```

**Headers:**

| Header | Value |
|--------|-------|
| `Content-Type` | `application/json` |
| `X-API-KEY` | `admin_secret_key` |

**Request Body:**

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `advocate_id` | integer | ✅ | Advocate's ID |
| `client_name` | string | ✅ | Client's full name |
| `client_phone` | string | ✅ | Client's phone number |
| `client_email` | string | ❌ | Client's email |
| `legal_issue` | string | ❌ | Brief description of the issue |
| `slot_id` | mixed | ❌* | Slot ID (numeric or `dyn_*` string) |
| `slot_date` / `preferred_date` / `date` | string | ❌* | Date in `YYYY-MM-DD` |
| `slot_time` / `preferred_time` / `time` | string | ❌* | Time like `10:00 AM` |

> *Either `slot_id` or both `date` + `time` must be provided.

**Case 1: Book by Slot ID (from calendar widget)**
```json
// POST /book.php
{
  "advocate_id": 1,
  "client_name": "Priya Singh",
  "client_phone": "9876543210",
  "client_email": "priya@example.com",
  "legal_issue": "Property dispute",
  "slot_id": "dyn_fca64f7b24e6fb29cf4d2165f9733054",
  "slot_date": "2026-06-20",
  "slot_time": "10:00 AM"
}
```
```json
// Response
{
  "success": true,
  "message": "Consultation booked successfully.",
  "booking_id": 15
}
```

**Case 2: Book by Date + Time (API client style)**
```json
// POST /book.php
{
  "advocate_id": 1,
  "client_name": "Vikram Patel",
  "client_phone": "8765432109",
  "date": "2026-06-21",
  "time": "02:00 PM"
}
```
```json
// Response
{
  "success": true,
  "message": "Consultation booked successfully.",
  "booking_id": 16
}
```

**Case 3: Slot Already Booked**
```json
{
  "success": false,
  "error": "Failed to book consultation: This slot is already booked."
}
```

**Case 4: Time Not in Routine**
```json
{
  "success": false,
  "error": "Failed to book consultation: The selected time slot is not within the advocate's scheduled routine or falls on a holiday."
}
```

**Case 5: Missing Required Fields**
```json
{
  "error": "Missing required fields (advocate_id, client_name, client_phone)"
}
```

**cURL Example:**
```bash
curl -X POST "https://page.law.indias.cloud/api/v1/book.php" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: admin_secret_key" \
  -d '{
    "advocate_id": 1,
    "client_name": "Priya Singh",
    "client_phone": "9876543210",
    "date": "2026-06-20",
    "time": "10:00 AM"
  }'
```

---

## 4. Fetch Client Booking History

Retrieve all past bookings for a client by phone or email.

```
GET /bookings.php?client_phone={phone}&client_email={email}
```

**Query Parameters:**

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `client_phone` | string | ❌ | Client phone number |
| `client_email` | string | ❌ | Client email address |

> At least one of `client_phone` or `client_email` is recommended.

**Response:**
```json
{
  "success": true,
  "bookings": [
    {
      "id": 15,
      "advocate_id": 1,
      "client_name": "Priya Singh",
      "client_email": "priya@example.com",
      "client_phone": "9876543210",
      "legal_issue": "Property dispute",
      "slot_id": 42,
      "status": "confirmed",
      "created_at": "2026-06-15 10:30:00",
      "slot_date": "2026-06-20",
      "slot_time": "10:00 AM",
      "advocate_name": "Adv. Anjali Sharma"
    }
  ]
}
```

---

# II. Advocate/Admin Endpoints — Auth Required

All endpoints below require: `X-API-KEY: admin_secret_key`

**Base:** `GET|POST /admin.php?action={action}&advocate_id={id}`

---

## 1. Get Dashboard Overview

```
GET /admin.php?action=get_dashboard&advocate_id=1
```

**Response:**
```json
{
  "success": true,
  "bookings": [
    {
      "id": 15,
      "advocate_id": 1,
      "client_name": "Priya Singh",
      "client_email": "priya@example.com",
      "client_phone": "9876543210",
      "legal_issue": "Property dispute",
      "slot_id": 42,
      "status": "pending",
      "created_at": "2026-06-15 10:30:00"
    }
  ],
  "services": [
    { "id": 1, "advocate_id": 1, "title": "Civil Law", "description": "Handling civil disputes..." }
  ]
}
```

---

## 2. Get Bookings (Paginated + Filterable)

```
GET /admin.php?action=get_bookings&advocate_id=1&page=1&limit=10
```

**Query Parameters:**

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `advocate_id` | integer | ❌ | Filter by advocate |
| `page` | integer | ❌ | Page number (default: 1) |
| `limit` | integer | ❌ | Results per page (default: 10) |
| `client_phone` / `phone` / `mobile` | string | ❌ | Filter by phone |
| `client_email` / `email` | string | ❌ | Filter by email |

**Response:**
```json
{
  "success": true,
  "bookings": [
    {
      "id": 15,
      "advocate_id": 1,
      "client_name": "Priya Singh",
      "client_phone": "9876543210",
      "client_email": "priya@example.com",
      "legal_issue": "Property dispute",
      "slot_id": 42,
      "status": "confirmed",
      "created_at": "2026-06-15 10:30:00",
      "slot_date": "2026-06-20",
      "slot_time": "10:00 AM"
    }
  ],
  "pagination": {
    "current_page": 1,
    "total_pages": 3,
    "total_records": 25,
    "limit": 10
  }
}
```

**cURL Example:**
```bash
curl "https://page.law.indias.cloud/api/v1/admin.php?action=get_bookings&advocate_id=1&page=1&limit=5" \
  -H "X-API-KEY: admin_secret_key"
```

---

## 3. Update Booking Status

```
POST /admin.php?action=update_booking&advocate_id=1
```

**Payload:**
```json
{ "booking_id": 15, "status": "confirmed" }
```

**Valid Statuses:** `pending`, `confirmed`, `cancelled`, `completed`

**Response:**
```json
{ "success": true, "message": "Booking updated" }
```

---

## 4. Cancel Booking

Cancels a booking and frees the associated slot.

```
POST /admin.php?action=cancel_booking&advocate_id=1
```

**Payload:**
```json
{ "booking_id": 15 }
```

**Response:**
```json
{ "success": true, "message": "Booking cancelled" }
```

---

## 5. Delete Booking

Permanently deletes a booking record and frees the slot.

```
POST /admin.php?action=delete_booking&advocate_id=1
```

**Payload:**
```json
{ "booking_id": 15 }
```

**Response:**
```json
{ "success": true, "message": "Booking deleted" }
```

---

## 6. Create Manual Booking

Create a booking directly (without going through the public widget).

```
POST /admin.php?action=create_manual_booking&advocate_id=1
```

**Payload:**
```json
{
  "client_name": "Walk-in Client",
  "client_email": "walkin@example.com",
  "client_phone": "9000000001",
  "legal_issue": "Contract review",
  "date": "2026-06-25",
  "time": "03:00 PM"
}
```

**Response:**
```json
{ "success": true, "message": "Manual booking created" }
```

---

## 7. Get Advocate Profile

```
GET /admin.php?action=get_advocate&advocate_id=1
```

**Response:**
```json
{
  "success": true,
  "advocate": {
    "id": 1,
    "subdomain": "test-advocate",
    "custom_domain": null,
    "name": "Adv. Anjali Sharma",
    "tagline": "Dedicated to Justice.",
    "bio": "I am Advocate Anjali Sharma...",
    "experience": "5+ Years",
    "court": "District & High Court",
    "education": "LL.B, LL.M",
    "approach": "Client-Centric Approach",
    "primary_color": "#6366f1",
    "disclaimer_text": "The content provided...",
    "contact_phone": "+91 98765 43210",
    "contact_email": "anjali@lawneu.com",
    "contact_address": "Legal Chambers, New Delhi",
    "bank_ac": "",
    "ifsc": "",
    "upi": "",
    "routine_json": "{\"mon\":{\"active\":true,\"slots\":[\"10:00 AM\"]}}",
    "is_accepting_bookings": 1,
    "custom_menu_links": "[{\"title\":\"Blog\",\"url\":\"https://blog.example.com\"}]",
    "gallery_urls": "[\"https://img1.jpg\"]",
    "is_active": 1,
    "created_at": "2026-06-15 10:00:00"
  }
}
```

---

## 8. Update Advocate Profile

```
POST /admin.php?action=update_advocate&advocate_id=1
```

**Payload (all fields optional — only include what you want to change):**
```json
{
  "name": "Adv. Anjali Sharma",
  "tagline": "Justice with Integrity",
  "bio": "Updated biography text...",
  "experience": "8+ Years",
  "court": "Supreme Court of India",
  "education": "LL.B, LL.M, Ph.D",
  "approach": "Compassionate & Strategic",
  "primary_color": "#2563eb",
  "disclaimer_text": "Custom disclaimer...",
  "contact_phone": "+91 99999 88888",
  "contact_email": "anjali@updated.com",
  "contact_address": "New Office, Mumbai",
  "bank_ac": "1234567890",
  "ifsc": "SBIN0001234",
  "upi": "anjali@upi",
  "is_accepting_bookings": 1,
  "custom_menu_links": [
    { "title": "Blog", "url": "https://blog.example.com" }
  ]
}
```

**Response:**
```json
{ "success": true, "message": "Advocate details updated" }
```

---

## 9. Create Advocate Profile (Public Onboarding)

> [!IMPORTANT]
> This is the ONLY admin action that does NOT require `X-API-KEY`. It is used during the public onboarding/signup flow.

```
POST /admin.php?action=create_advocate
```

**Payload:**
```json
{
  "subdomain": "rajesh-kumar",
  "name": "Adv. Rajesh Kumar",
  "tagline": "Fighting for Your Rights",
  "bio": "Experienced civil and criminal lawyer...",
  "experience": "12+ Years",
  "court": "High Court",
  "education": "LL.B",
  "approach": "Aggressive Litigation",
  "primary_color": "#dc2626",
  "disclaimer_text": "This is not legal advice...",
  "contact_phone": "+91 70000 12345",
  "contact_email": "rajesh@example.com",
  "contact_address": "Chamber No. 5, District Court",
  "services": [
    { "title": "Criminal Defense", "description": "Bail applications, trial defense..." },
    { "title": "Family Law", "description": "Divorce, custody, maintenance..." }
  ]
}
```

**Case 1: Success**
```json
{
  "success": true,
  "message": "Advocate created successfully",
  "advocate_id": 5,
  "url": "https://rajesh-kumar.lawneu.in"
}
```

**Case 2: Subdomain Taken**
```json
{ "success": false, "error": "Subdomain is already taken" }
```

**Case 3: Reserved Subdomain**
```json
{ "success": false, "error": "This subdomain is reserved and cannot be used." }
```

**Case 4: Missing Required Fields**
```json
{ "success": false, "error": "Subdomain and name are required" }
```

---

## 10. Get / Update Weekly Routine

### GET Routine
```
GET /admin.php?action=get_routine&advocate_id=1
```

**Response:**
```json
{
  "success": true,
  "routine": {
    "mon": { "active": true, "slots": ["10:00 AM", "11:00 AM", "02:00 PM"] },
    "tue": { "active": true, "slots": ["10:00 AM", "11:00 AM"] },
    "wed": { "active": true, "slots": ["10:00 AM"] },
    "thu": { "active": true, "slots": [] },
    "fri": { "active": true, "slots": ["10:00 AM", "04:00 PM"] },
    "sat": { "active": true, "slots": ["10:00 AM"] },
    "sun": { "active": false, "slots": [] }
  }
}
```

### UPDATE Routine (Bulk)

Save the entire weekly routine at once.

```
POST /admin.php?action=update_routine&advocate_id=1
```

**Case 1: Set Full Working Week**
```json
{
  "routine": {
    "mon": { "active": true, "slots": ["10:00 AM", "11:00 AM", "02:00 PM", "04:00 PM"] },
    "tue": { "active": true, "slots": ["10:00 AM", "11:00 AM"] },
    "wed": { "active": true, "slots": ["10:00 AM", "02:00 PM"] },
    "thu": { "active": true, "slots": ["10:00 AM", "11:00 AM", "02:00 PM"] },
    "fri": { "active": true, "slots": ["10:00 AM", "02:00 PM", "05:00 PM"] },
    "sat": { "active": true, "slots": ["10:00 AM"] },
    "sun": { "active": false, "slots": [] }
  }
}
```

**Case 2: Mark Wednesday as Holiday**
```json
{
  "routine": {
    "wed": { "active": false, "slots": [] }
  }
}
```

**Case 3: Clear All Slots for a Day**
```json
{
  "routine": {
    "sat": { "active": true, "slots": [] }
  }
}
```

**Response:**
```json
{ "success": true, "message": "Routine updated" }
```

**Error — Invalid Data:**
```json
{ "success": false, "error": "routine data required" }
```

---

## 11. Toggle Day Routine (Single Day)

```
POST /admin.php?action=toggle_day_routine&advocate_id=1
```

**Payload:**
```json
{ "day": "wed", "active": false }
```

**Valid Days:** `mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun`

**Response:**
```json
{
  "success": true,
  "message": "Routine day updated",
  "day": "wed",
  "active": false
}
```

---

## 12. Add Routine Slot (Single Slot)

```
POST /admin.php?action=add_routine_slot&advocate_id=1
```

**Payload:**
```json
{ "day": "mon", "time": "03:00 PM" }
```

**Response:**
```json
{
  "success": true,
  "message": "Routine slot added",
  "day": "mon",
  "slots": ["10:00 AM", "11:00 AM", "02:00 PM", "03:00 PM"]
}
```

---

## 13. Delete Routine Slot (Single Slot)

```
POST /admin.php?action=delete_routine_slot&advocate_id=1
```

**Payload:**
```json
{ "day": "mon", "time": "03:00 PM" }
```

**Response:**
```json
{
  "success": true,
  "message": "Routine slot deleted",
  "day": "mon",
  "slots": ["10:00 AM", "11:00 AM", "02:00 PM"]
}
```

---

## 14. Create / Delete Manual Slot

### Create Slot
```
POST /admin.php?action=create_slot&advocate_id=1
```

**Payload:**
```json
{ "date": "2026-06-25", "time": "06:00 PM" }
```

**Response:**
```json
{ "success": true, "message": "Slot created", "slot_id": 55 }
```

### Delete Slot
```
POST /admin.php?action=delete_slot&advocate_id=1
```

**Payload:**
```json
{ "slot_id": 55 }
```

**Response:**
```json
{ "success": true, "message": "Slot deleted" }
```

---

## 15. Manage Services

### Create / Update Service
```
POST /admin.php?action=update_service&advocate_id=1
```

**Case 1: Create New Service** (omit `service_id`)
```json
{
  "title": "Intellectual Property",
  "description": "Trademark, copyright, and patent protection."
}
```

**Case 2: Update Existing Service**
```json
{
  "service_id": 3,
  "title": "Updated Title",
  "description": "Updated description."
}
```

**Response:**
```json
{ "success": true, "message": "Service updated" }
```

### Delete Service
```
POST /admin.php?action=delete_service&advocate_id=1
```

**Payload:**
```json
{ "service_id": 3 }
```

**Response:**
```json
{ "success": true, "message": "Service deleted" }
```

---

## 16. Update Booking Availability (Online/Offline Toggle)

```
POST /admin.php?action=update_booking_availability&advocate_id=1
```

**Payload:**
```json
{ "is_accepting_bookings": 0 }
```

| Value | Meaning |
|-------|---------|
| `1` | Accepting bookings (online) |
| `0` | Not accepting bookings (offline) |

**Response:**
```json
{
  "success": true,
  "message": "Booking availability updated",
  "is_accepting_bookings": 0
}
```

---

## 17. Get Calendar (Monthly View)

```
GET /admin.php?action=get_calendar&advocate_id=1&month=2026-06
```

**Response:**
```json
{
  "success": true,
  "calendar": [
    {
      "id": 15,
      "advocate_id": 1,
      "client_name": "Priya Singh",
      "client_phone": "9876543210",
      "legal_issue": "Property dispute",
      "status": "confirmed",
      "slot_date": "2026-06-20",
      "slot_time": "10:00 AM"
    }
  ]
}
```

---

## 18. Custom Menu Links

### Add Link
```
POST /admin.php?action=add_custom_menu_link&advocate_id=1
```

**Payload:**
```json
{ "title": "My Blog", "url": "https://blog.example.com" }
```

**Response:**
```json
{
  "success": true,
  "message": "Custom menu link added",
  "custom_menu_links": [
    { "title": "My Blog", "url": "https://blog.example.com" }
  ]
}
```

### Delete Link
```
POST /admin.php?action=delete_custom_menu_link&advocate_id=1
```

**Payload:**
```json
{ "title": "My Blog", "url": "https://blog.example.com" }
```

### Bulk Update Links
```
POST /admin.php?action=update_custom_menu_links&advocate_id=1
```

**Payload:**
```json
{
  "custom_menu_links": [
    { "title": "Blog", "url": "https://blog.example.com" },
    { "title": "UPI Pay", "url": "upi://pay?pa=adv@upi" }
  ]
}
```

---

## 19. Gallery Images

### Update Gallery (Bulk Replace)
```
POST /admin.php?action=update_gallery_urls&advocate_id=1
```

**Payload:**
```json
{
  "gallery_urls": [
    "https://example.com/photo1.jpg",
    "https://example.com/photo2.jpg",
    "https://example.com/photo3.jpg"
  ]
}
```

**Response:**
```json
{
  "success": true,
  "message": "Gallery images updated",
  "gallery_urls": [
    "https://example.com/photo1.jpg",
    "https://example.com/photo2.jpg",
    "https://example.com/photo3.jpg"
  ]
}
```

> [!TIP]
> To add an image, fetch the current array, append the new URL, and send the full array back.  
> To remove an image, fetch the current array, filter it out, and send the updated array.

---

# III. Master/Super Admin Endpoints — Bearer Auth Required

These endpoints manage the entire platform. Access via `page.law.indias.cloud/zlawpanel`.

**Authentication:** `Authorization: Bearer YOUR_MASTER_KEY`

**Base:** `GET|POST /master.php?action={action}`

---

## 1. Dashboard Stats

```
GET /master.php?action=dashboard_stats
```

**Response:**
```json
{
  "status": "success",
  "stats": {
    "total_advocates": 12,
    "active_advocates": 10,
    "total_bookings": 156,
    "total_abuse_reports": 3
  }
}
```

**Error — Unauthorized:**
```json
// HTTP 401
{
  "status": "error",
  "message": "Unauthorized master access"
}
```

**cURL Example:**
```bash
curl "https://page.law.indias.cloud/api/v1/master.php?action=dashboard_stats" \
  -H "Authorization: Bearer YOUR_MASTER_KEY"
```

---

## 2. List All Advocates

```
GET /master.php?action=list_advocates
```

**Response:**
```json
{
  "status": "success",
  "data": [
    {
      "id": 1,
      "subdomain": "test-advocate",
      "custom_domain": null,
      "name": "Adv. Anjali Sharma",
      "contact_email": "anjali@lawneu.com",
      "is_active": 1,
      "created_at": "2026-06-15 10:00:00"
    },
    {
      "id": 2,
      "subdomain": "rajesh-kumar",
      "custom_domain": "rajeshlaw.com",
      "name": "Adv. Rajesh Kumar",
      "contact_email": "rajesh@example.com",
      "is_active": 1,
      "created_at": "2026-06-16 12:00:00"
    }
  ]
}
```

---

## 3. Toggle Advocate Status (Suspend/Activate)

```
POST /master.php?action=toggle_advocate_status
```

**Case 1: Suspend an Advocate**
```json
{ "id": 2, "is_active": false }
```

**Case 2: Re-activate a Suspended Advocate**
```json
{ "id": 2, "is_active": true }
```

**Response:**
```json
{
  "status": "success",
  "message": "Advocate status updated successfully"
}
```

**Error — Missing Fields:**
```json
// HTTP 400
{
  "status": "error",
  "message": "Missing required fields"
}
```

**Error — Wrong Method:**
```json
// HTTP 405
{
  "status": "error",
  "message": "Method not allowed"
}
```

---

## 4. Get Global Settings

```
GET /master.php?action=get_global_settings
```

**Response:**
```json
{
  "status": "success",
  "data": [
    { "id": 1, "setting_key": "platform_language", "setting_value": "en" },
    { "id": 2, "setting_key": "max_advocates", "setting_value": "100" }
  ]
}
```

---

## 5. Update Global Setting

```
POST /master.php?action=update_global_setting
```

**Payload:**
```json
{
  "setting_key": "platform_language",
  "setting_value": "hi"
}
```

**Response:**
```json
{
  "status": "success",
  "message": "Setting updated successfully"
}
```

> [!NOTE]
> Uses `INSERT ... ON CONFLICT UPDATE` — creates the setting if it doesn't exist, updates it if it does.

---

# Database Schema Reference

## `advocates` Table

| Column | Type | Default | Description |
|--------|------|---------|-------------|
| `id` | INTEGER | AUTO | Primary key |
| `subdomain` | TEXT | — | Unique subdomain prefix |
| `custom_domain` | TEXT | NULL | Optional custom domain |
| `name` | TEXT | — | Advocate display name |
| `tagline` | TEXT | — | Hero section tagline |
| `bio` | TEXT | — | About section content |
| `experience` | TEXT | — | Years of experience |
| `court` | TEXT | — | Court of practice |
| `education` | TEXT | — | Educational background |
| `approach` | TEXT | — | Practice approach |
| `primary_color` | TEXT | `#6366f1` | Brand color |
| `bg_image_url` | TEXT | NULL | Background image URL |
| `profile_image_url` | TEXT | NULL | Profile photo URL |
| `disclaimer_text` | TEXT | — | Legal disclaimer |
| `contact_email` | TEXT | — | Contact email |
| `contact_phone` | TEXT | — | Contact phone |
| `contact_address` | TEXT | — | Office address |
| `bank_ac` | TEXT | — | Bank account number |
| `ifsc` | TEXT | — | IFSC code |
| `upi` | TEXT | — | UPI ID |
| `routine_json` | TEXT | NULL | Weekly routine JSON |
| `is_accepting_bookings` | INTEGER | 1 | Online/offline toggle |
| `custom_menu_links` | TEXT | NULL | JSON array of nav links |
| `gallery_urls` | TEXT | NULL | JSON array of image URLs |
| `is_active` | INTEGER | 1 | Master admin control |
| `created_at` | DATETIME | NOW | Registration timestamp |

## `bookings` Table

| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER | Primary key |
| `advocate_id` | INTEGER | FK → advocates |
| `client_name` | TEXT | Client full name |
| `client_email` | TEXT | Client email |
| `client_phone` | TEXT | Client phone |
| `legal_issue` | TEXT | Issue description |
| `slot_id` | INTEGER | FK → slots |
| `status` | TEXT | `pending` / `confirmed` / `cancelled` / `completed` |
| `created_at` | DATETIME | Booking timestamp |

## `slots` Table

| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER | Primary key |
| `advocate_id` | INTEGER | FK → advocates |
| `slot_date` | TEXT | Date `YYYY-MM-DD` |
| `slot_time` | TEXT | Time `HH:MM AM/PM` |
| `is_booked` | INTEGER | 0 = free, 1 = booked |

## `services` Table

| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER | Primary key |
| `advocate_id` | INTEGER | FK → advocates |
| `title` | TEXT | Service name |
| `description` | TEXT | Service description |

## `global_settings` Table

| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER | Primary key |
| `setting_key` | TEXT | Unique setting name |
| `setting_value` | TEXT | Setting value |

## `abuse_reports` Table

| Column | Type | Description |
|--------|------|-------------|
| `id` | INTEGER | Primary key |
| `advocate_id` | INTEGER | FK → advocates |
| `report_text` | TEXT | Report content |
| `reporter_ip` | TEXT | Reporter's IP |
| `created_at` | DATETIME | Report timestamp |


---

# Booking Messages Read/Reply API

These endpoints save every booking message in the database, allow admin/master read access, and allow replies from `/manage` or `/master`.

## Database

New tables:

- `booking_messages`: stores the initial client message and all admin replies.
- `email_logs`: stores email send attempts and failures.

## Public Booking Response

`POST /api/v1/book.php` now returns a thank-you popup message:

```json
{
  "success": true,
  "message": "Thank you. Your booking request has been received. We will reply soon.",
  "popup": "Thank you. Your booking request has been received. We will reply soon.",
  "booking_id": 15
}
```

The front-end booking form shows `popup` with an alert and still displays `message` on the page.

## Admin/Master Messages Endpoint

Base endpoint:

```text
/api/v1/messages.php
```

Admin auth:

```text
X-API-KEY: admin_secret_key
```

Master auth:

```text
Authorization: Bearer YOUR_MASTER_KEY
```

or:

```text
X-Master-Key: YOUR_MASTER_KEY
```

### List Threads

```bash
curl "https://page.law.indias.cloud/api/v1/messages.php?action=list&advocate_id=1" \
  -H "X-API-KEY: admin_secret_key"
```

Master can list all advocates without `advocate_id`:

```bash
curl "https://page.law.indias.cloud/api/v1/messages.php?action=list" \
  -H "Authorization: Bearer YOUR_MASTER_KEY"
```

### Read Thread

```bash
curl "https://page.law.indias.cloud/api/v1/messages.php?action=read&booking_id=15&advocate_id=1" \
  -H "X-API-KEY: admin_secret_key"
```

### Reply To Client

```bash
curl -X POST "https://page.law.indias.cloud/api/v1/messages.php?action=reply&advocate_id=1" \
  -H "X-API-KEY: admin_secret_key" \
  -H "Content-Type: application/json" \
  -d '{"booking_id":15,"message":"Thank you. We can schedule your consultation tomorrow."}'
```

Reply response:

```json
{
  "success": true,
  "message": "Reply saved and emailed.",
  "email_sent": true,
  "email_error": ""
}
```

If email fails, the reply remains saved and the error is logged in `email_logs`.

## Browser Access

```text
/manage/messages.php?advocate_id=1
/zlawpanel/
```

The existing `/manage` scheduler now includes a `Read / Reply` button on booking cards.

## Additional Markdown Docs

```text
/api_doc.md
/LAWNEU_BOOKING_API.md
/LAWNEU_MASTER_ADMIN_API.md
/LAWNEU_ADVOCATE_APP_API.md
/LAWNEU_LEGAL_REQUESTS_API.md
/LAWNEU_CALL_AI_API.md
/LAWNEU_APP_POSTMAN_COLLECTION.json
```

- `/api_doc.md` is the main combined API reference.
- `/LAWNEU_BOOKING_API.md` covers booking submit, inbox messages, and email logging samples.
- `/LAWNEU_MASTER_ADMIN_API.md` covers `/zlawpanel/` usage and master admin API samples.
- `/LAWNEU_ADVOCATE_APP_API.md` covers the Android advocate app REST endpoints.
- `/LAWNEU_LEGAL_REQUESTS_API.md` covers public legal requests, advocate-scoped list/read, and accept flow.
- `/LAWNEU_CALL_AI_API.md` covers AI draft generation through Lawneu/Open WebUI settings and notes that P2P calls are internal app-wrapped.
- `/LAWNEU_APP_POSTMAN_COLLECTION.json` is the downloadable Postman collection with placeholder variables. Set `masterKey` inside Postman before use.

## Portal Doc Menu Order

The master portal keeps docs serially by feature:

```text
API Documentation        -> combined reference
Advanced Docs            -> booking, master, advocate app map
Legal Request Docs       -> legal request create/list/read/accept
AI / Internal Call Docs  -> AI draft and internal app-wrapped call notes
Postman JSON             -> downloadable app API collection
```

---

# V. Advocate App REST Endpoints

These endpoint paths match `lawneu-advocate-app/app/src/main/java/com/example/data/ApiService.kt`.

**Base URL:** `https://page.law.indias.cloud/api/v1`

## Auth

Production mobile login can remain Firebase-based. API requests should use the existing project master key:

```text
X-Master-Key: YOUR_MASTER_KEY
```

or:

```text
Authorization: Bearer YOUR_MASTER_KEY
```

The PHP auth endpoints below are optional development helpers only and are not required for production login.

```bash
curl -X POST "https://page.law.indias.cloud/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"mobileNumber":"919876543210","countryCode":"IN","dialCode":"+91"}'
```

```bash
curl -X POST "https://page.law.indias.cloud/api/v1/auth/verify" \
  -H "Content-Type: application/json" \
  -d '{"mobileNumber":"919876543210","otpCode":"123456","deviceToken":"android-device-token"}'
```

## Advocate Registry

```bash
curl "https://page.law.indias.cloud/api/v1/subdomains/check?subdomain=adv-sharma"
curl -X POST "https://page.law.indias.cloud/api/v1/advocates/create" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"subdomain":"adv-sharma","advocateName":"Adv. Sharma","contactPhone":"+91 98765 43210","createMailAccount":true}'
curl "https://page.law.indias.cloud/api/v1/advocates?countryCode=IN&currencyCode=INR&specialty=civil"
curl "https://page.law.indias.cloud/api/v1/advocates/1"
curl "https://page.law.indias.cloud/api/v1/advocates/profile?advocate_id=3" -H "X-Master-Key: YOUR_MASTER_KEY"
curl -X POST "https://page.law.indias.cloud/api/v1/advocates/update" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"advocate_id":3,"name":"Advocate Arjun Mehta","countryCode":"IN","countryName":"India","state":"Delhi","city":"New Delhi","county":"Central Delhi","defaultCurrency":"INR","isAcceptingBookings":true}'
curl -X POST "https://page.law.indias.cloud/api/v1/advocates/services" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"advocate_id":3,"title":"Civil Law","description":"Civil disputes"}'
curl -X POST "https://page.law.indias.cloud/api/v1/advocates/gallery" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"advocate_id":3,"gallery_urls":["https://example.com/photo.jpg"]}'
```

## Case Management

```bash
curl -X POST "https://page.law.indias.cloud/api/v1/cases/initiate" \
  -H "X-Master-Key: YOUR_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"clientName":"Ravi Kumar","advocateId":"1","title":"Property consultation","category":"Civil","initialDescription":"Need advice","countryCode":"IN","countryName":"India","state":"Delhi","city":"New Delhi","county":"Central Delhi","currencyCode":"INR","agreedRetainerAmount":2500}'
```

```bash
curl "https://page.law.indias.cloud/api/v1/cases/my-cases?advocate_id=3" -H "X-Master-Key: YOUR_MASTER_KEY"
```

```bash
curl -X POST "https://page.law.indias.cloud/api/v1/cases/CASE-1234/link-statute" \
  -H "X-Master-Key: YOUR_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"actCode":"BNS","sectionNumber":"420","titleText":"Cheating"}'
```

```bash
curl -X POST "https://page.law.indias.cloud/api/v1/cases/pairing" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"action":"create","caseId":"CASE-1234","clientName":"Ravi Kumar","clientMobile":"919876543210"}'
curl "https://page.law.indias.cloud/api/v1/cases/pairing?pairingCode=CASE-1-RAVI" -H "X-Master-Key: YOUR_MASTER_KEY"
curl -X POST "https://page.law.indias.cloud/api/v1/cases/pairing" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"action":"unlink","pairingCode":"CASE-1-RAVI"}'
curl -X POST "https://page.law.indias.cloud/api/v1/cases/files" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"caseId":"CASE-1234","fileName":"petition.pdf","storagePath":"https://example.com/petition.pdf","uploadedBy":"ADVOCATE"}'
curl "https://page.law.indias.cloud/api/v1/cases/files?caseId=CASE-1234" -H "X-Master-Key: YOUR_MASTER_KEY"
```

## Sync, Payments, AI

```bash
curl "https://page.law.indias.cloud/api/v1/bare-acts/sync?last_updated=0"
```

```bash
curl -X POST "https://page.law.indias.cloud/api/v1/payments/initiate" \
  -H "X-Master-Key: YOUR_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"advocate_id":3,"caseId":"CASE-1234","amount":500,"currencyCode":"INR","countryCode":"IN","countryName":"India","transactionPurpose":"Consultation","paymentGatewayMode":"UPI"}'
curl "https://page.law.indias.cloud/api/v1/payments/status?txnReferenceId=TXN-123" -H "X-Master-Key: YOUR_MASTER_KEY"
curl "https://page.law.indias.cloud/api/v1/payments/detail?txnReferenceId=TXN-123" -H "X-Master-Key: YOUR_MASTER_KEY"
curl -X POST "https://page.law.indias.cloud/api/v1/payments/update-status" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"txnReferenceId":"TXN-123","status":"SUCCESS"}'
curl "https://page.law.indias.cloud/api/v1/cases/payment?caseId=CASE-1234" -H "X-Master-Key: YOUR_MASTER_KEY"
curl -X POST "https://page.law.indias.cloud/api/v1/cases/payment" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"caseId":"CASE-1234","paymentTotal":50000,"paymentPaid":20000,"state":"Delhi","city":"New Delhi","county":"Central Delhi","currencyCode":"INR","countryCode":"IN","countryName":"India"}'
curl "https://page.law.indias.cloud/api/v1/cases/receipts?caseId=CASE-1234" -H "X-Master-Key: YOUR_MASTER_KEY"
curl -X POST "https://page.law.indias.cloud/api/v1/cases/receipts" -H "X-Master-Key: YOUR_MASTER_KEY" -H "Content-Type: application/json" -d '{"caseId":"CASE-1234","label":"Retainer Deposit Received","amount":20000,"currencyCode":"INR","countryCode":"IN","countryName":"India","date":"2026-06-19","method":"UPI"}'
```

## Internal P2P Calls

P2P call/session handling is wrapped by the Lawneu app/backend flow and is not published as a direct Postman or public API-doc surface.

```bash
curl -X POST "https://page.law.indias.cloud/api/v1/ai/generate-draft" \
  -H "X-Master-Key: YOUR_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"draftType":"LEGAL_NOTICE","statePartiesDetail":"Facts","specificClausesOverride":"Payment demand","countryCode":"IN","countryName":"India"}'
```

## Country And Currency Support

Country/currency fields are supported wherever money, jurisdiction, or filtering is needed: advocates, cases, case payment ledger, receipts, payments, payouts, internal calls, financial entries, and AI drafts.

Common request fields:

```json
{
  "countryCode": "IN",
  "countryName": "India",
  "state": "Delhi",
  "city": "New Delhi",
  "county": "Central Delhi",
  "currencyCode": "INR"
}
```

Aliases accepted: `country`, `country_code`, `currency`, `currency_code`, `stateName`, `cityName`, and `countyName`.

## Email Configuration

## Advocate-Scoped Linked Mail

When a new advocate website is created, Lawneu can create a linked mail-account record such as `adv-sharma@zeetx.com`.

This is intentionally not a public mail-management API:

- No direct mail endpoint is published in Postman or portal docs.
- No domain-level mailbox browsing is allowed.
- Any future Lawneu-wrapped mail read/reply flow must check `advocate_mail_accounts` and allow access only when the requested mailbox is linked to that `advocate_id`.
- The internal mail access key is stored only in zlawpanel settings.

Recommended environment variables:

```text
SMTP_HOST
SMTP_PORT
SMTP_USER
SMTP_PASSWORD
SMTP_FROM
SMTP_SECURE
```

Equivalent `global_settings` keys:

```text
smtp_host
smtp_port
smtp_user
smtp_password
mail_from
smtp_secure
admin_email
```

If SMTP is not configured, the system falls back to PHP `mail()` and logs the result.
