Client Portal · API Referenceuser_type: client
Base URL/api/client/
AuthAuthorization: Bearer {token} · user_type must be client
Scope — all data filtered to projects where client_user_id = auth()->id(); only published documents and client-visibility gallery items are returned
📊

Dashboard

GET/api/client/dashboard

KPI dashboard for the client. Returns count of projects linked to this client.

Auth required
client user_type
Response
JSON
{
  "success": true,
  "msg": "Dashboard",
  "data": {
    "project_count": 2,
    "welcome_message": "Client portal dashboard"
  }
}
Errors
401 Unauthenticated403 Forbidden
🏗

Projects

GET/api/client/projects

All projects where this user is the client. Read-only; includes name, status, contract_value, current_phase_key.

Auth required
client user_type
Response
JSON
{
  "success": true,
  "msg": "Projects",
  "data": [
    {
      "id": 4,
      "business_id": 1,
      "location_id": 1,
      "client_user_id": 5,
      "name": "Residential Block A — Phase 2",
      "description": "Foundation and framing works",
      "status": "active",
      "contract_value": 2500000.0,
      "current_phase_key": "foundation",
      "address": "Plot 12, DHA Phase 8, Karachi"
    }
  ],
  "pagination": {"current_page": 1, "per_page": 20, "total": 2, "last_page": 1}
}
Errors
401 Unauthenticated403 Forbidden
📐

Project Progress

GET/api/client/progress

Phase progress across all client projects, ordered by sort_order. The client uses this to track build timeline visually.

Auth required
client user_type
Phases are from ALL client projects combined. The app should group by project_id for display.
Response
JSON
{
  "success": true,
  "msg": "Progress",
  "data": [
    {
      "id": 1,
      "project_id": 4,
      "phase_key": "foundation",
      "name": "Foundation Works",
      "status": "in_progress",
      "progress_percent": 65,
      "sort_order": 1
    },
    {
      "id": 2,
      "project_id": 4,
      "phase_key": "structural",
      "name": "Structural Framing",
      "status": "pending",
      "progress_percent": 0,
      "sort_order": 2
    }
  ],
  "pagination": {"current_page": 1, "per_page": 20, "total": 6, "last_page": 1}
}
Errors
401 Unauthenticated403 Forbidden
📄

Documents

GET/api/client/documents

Published project documents for client projects. Only documents with status=published are returned; drafts hidden.

Auth required
client user_type
document_type_id references the business document types table. Clients see the type category but not internal metadata.
Response
JSON
{
  "success": true,
  "msg": "Documents",
  "data": [
    {
      "id": 3,
      "business_id": 1,
      "project_id": 4,
      "document_type_id": 2,
      "title": "Structural Engineer Approval Letter",
      "file_path": "documents/proj4/struct-approval.pdf",
      "status": "published"
    }
  ],
  "pagination": {"current_page": 1, "per_page": 20, "total": 3, "last_page": 1}
}
Errors
401 Unauthenticated403 Forbidden
🖼

Gallery

🎫

Support Tickets

GET/api/client/support

List support tickets created by this client.

Auth required
client user_type
Response
JSON
{
  "success": true,
  "msg": "Support tickets",
  "data": [
    {
      "id": 2,
      "business_id": 1,
      "project_id": 4,
      "client_user_id": 5,
      "subject": "Request for updated timeline",
      "message": "Can we get an updated completion date after the foundation delay?",
      "status": "open"
    }
  ],
  "pagination": {"current_page": 1, "per_page": 20, "total": 2, "last_page": 1}
}
Errors
401 Unauthenticated403 Forbidden
POST/api/client/support

Open a new support ticket. Status is automatically set to open.

Auth required
client user_type
Request body
JSON
{
  "subject": "Request for updated foundation inspection report",
  "message": "Please share the structural engineer report from the 5 July inspection.",
  "project_id": 4
}
Response
JSON
{
  "success": true,
  "msg": "Ticket created",
  "data": {
    "id": 3,
    "business_id": 1,
    "project_id": 4,
    "client_user_id": 5,
    "subject": "Request for updated foundation inspection report",
    "message": "Please share the structural engineer report from the 5 July inspection.",
    "status": "open"
  }
}
Errors
401 Unauthenticated403 Forbidden422 Validation failed
📒

Financial Ledger

GET/api/client/ledger

Ledger entries where party_type=client and party_id=auth()->id(). Shows invoices issued and payments received.

Auth required
client user_type
Debit = money received from client (payment in); Credit = invoice amount owed. Net balance: SUM(debit) - SUM(credit).
Response
JSON
{
  "success": true,
  "msg": "Ledger",
  "data": [
    {
      "id": 10,
      "project_id": 4,
      "party_type": "client",
      "party_id": 5,
      "entry_type": "payment",
      "debit": 500000.0,
      "credit": 0.0,
      "reference": "INV-2026-0002",
      "description": "2nd milestone payment received",
      "entry_date": "2026-06-15"
    },
    {
      "id": 7,
      "project_id": 4,
      "party_type": "client",
      "party_id": 5,
      "entry_type": "invoice",
      "debit": 0.0,
      "credit": 750000.0,
      "reference": "INV-2026-0001",
      "description": "Initial mobilisation invoice",
      "entry_date": "2026-07-01"
    }
  ],
  "pagination": {"current_page": 1, "per_page": 20, "total": 4, "last_page": 1}
}
Errors
401 Unauthenticated403 Forbidden
🔔

Notifications

GET/api/client/notifications

In-app notifications for this client.

Auth required
client user_type
Response
JSON
{
  "success": true,
  "msg": "Notifications",
  "data": [
    {
      "id": 9,
      "title": "Phase update",
      "body": "Foundation Works is now 65% complete on Residential Block A",
      "is_read": false
    }
  ],
  "pagination": {"current_page": 1, "per_page": 20, "total": 1, "last_page": 1}
}
Errors
401 Unauthenticated403 Forbidden