/api/admin/ for all endpointsScope — all queries filtered by authenticated user's
business_idAuth —
Authorization: Bearer {sanctum_token} · user_type must be admin or staffEnvelope —
{ "success": true, "msg": "...", "data": [...], "pagination": {...} }Dashboard
Business-scoped KPI summary. Returns live counts of projects, proposals, open vouchers, and upcoming calendar events.
{
"success": true,
"msg": "Dashboard",
"data": {
"project_count": 12,
"active_project_count": 7,
"proposal_count": 18,
"open_voucher_count": 4,
"upcoming_event_count": 3,
"welcome_message": "Business admin dashboard"
}
}Projects
Paginated list of project. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"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"
}
}Create a new project record. If template_id is provided, the API auto-creates phases using the template's phase_keys and Phase Library default_duration_days values.
{
"name": "Residential Block A β Phase 2",
"description": "Foundation and framing works",
"location_id": 1,
"client_user_id": 5,
"status": "active",
"contract_value": 2500000,
"start_date": "2026-07-01",
"expected_end_date": "2026-12-31",
"current_phase_key": "foundation",
"address": "Plot 12, DHA Phase 8, Karachi",
"template_id": 2
}{
"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"
}
}Retrieve one project by ID.
{
"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"
}
}Update any fields on an existing project. All fields optional.
{
"name": "Residential Block A β Phase 2",
"description": "Foundation and framing works",
"location_id": 1,
"client_user_id": 5,
"status": "active",
"contract_value": 2500000,
"start_date": "2026-07-01",
"expected_end_date": "2026-12-31",
"current_phase_key": "foundation",
"address": "Plot 12, DHA Phase 8, Karachi"
}{
"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"
}
}Permanently delete this project.
{
"success": true,
"msg": "Deleted",
"data": null
}Project Detail Sub-routes
All sub-routes require projects.view. Project must belong to admin's business.
All phases for a project ordered by sort_order.
{
"success": true,
"msg": "Phases",
"data": [
{
"id": 1,
"project_id": 4,
"phase_key": "foundation",
"name": "Foundation Works",
"status": "in_progress",
"progress_percent": 65,
"sort_order": 1
}
],
"pagination": {"current_page":1,"per_page":20,"total":3,"last_page":1}
}All proposals linked to a project.
{
"success": true,
"msg": "Proposals",
"data": [
{
"id": 2,
"business_id": 1,
"project_id": 4,
"title": "Revised foundation proposal",
"status": "accepted",
"quoted_amount": 2500000.0,
"current_round": 2
}
],
"pagination": {"current_page":1,"per_page":20,"total":2,"last_page":1}
}All vouchers for a project.
{
"success": true,
"msg": "Vouchers",
"data": [
{
"id": 7,
"business_id": 1,
"project_id": 4,
"subcontractor_id": 2,
"voucher_no": "VCH-2026-0007",
"voucher_type": "subcontractor",
"status": "submitted",
"amount": 185000.0,
"week_ending": "2026-06-21"
}
],
"pagination": {"current_page":1,"per_page":20,"total":4,"last_page":1}
}Ledger entries for a project, ordered by entry_date desc.
{
"success": true,
"msg": "Ledgers",
"data": [
{
"id": 3,
"business_id": 1,
"project_id": 4,
"party_type": "subcontractor",
"party_id": 2,
"entry_type": "payment",
"debit": 0.0,
"credit": 185000.0,
"reference": "VCH-2026-0007",
"description": "Payment for week ending 21 Jun 2026",
"entry_date": "2026-06-22"
}
],
"pagination": {"current_page":1,"per_page":20,"total":3,"last_page":1}
}Contract and drawing revisions for a project (not paginated, returns object with two arrays).
{
"success": true,
"msg": "Revisions",
"data": {
"contracts": [
{
"id": 1,
"type": "contract",
"revision_number": 2,
"status": "signed",
"contract_value": 2500000.0,
"file_path": "contracts/proj4-rev2.pdf"
}
],
"drawings": [
{
"id": 1,
"type": "drawing",
"drawing_code": "DWG-A-001",
"revision_number": 3,
"status": "approved",
"file_path": "drawings/DWG-A-001-rev3.pdf"
}
]
}
}Material stock entries for a project.
{
"success": true,
"msg": "Materials",
"data": [
{
"id": 1,
"project_id": 4,
"material_name": "OPC Cement 50kg",
"unit": "bags",
"quantity_on_hand": 240.0,
"quantity_reserved": 60.0
}
],
"pagination": {"current_page":1,"per_page":20,"total":5,"last_page":1}
}Daily progress logs for a project, newest first.
{
"success": true,
"msg": "Daily logs",
"data": [
{
"id": 1,
"business_id": 1,
"project_id": 4,
"subcontractor_id": 2,
"user_id": 3,
"log_date": "2026-06-22",
"work_summary": "Completed 3 column foundations; 8 workers on site",
"workers_count": 8,
"status": "submitted"
}
],
"pagination": {"current_page":1,"per_page":20,"total":18,"last_page":1}
}Proposals
Paginated list of proposals. Scoped to authenticated business. project_name is resolved via the project relation β never just project_id.
| Param | Description |
|---|---|
| search | Optional. Matches against title OR the linked project's name (case-insensitive substring). |
| status | Optional. Exact match on one of: draft, scheduled, in_review, revision_requested, accepted, deposit_paid, converted (see GET /api/common/proposal-stages). Unknown value β empty data: [], not an error. |
| project_id | Optional. Restrict to proposals on one project. Must belong to the authenticated business β invalid id β empty data: []. |
| page | Optional. Default 1. |
| per_page | Optional. Default 20. Pass -1 for unpaginated. |
{
"success": true,
"msg": "Proposals",
"data": [
{
"id": 3,
"business_id": 1,
"project_id": 4,
"project_name": "Block A",
"title": "Revised foundation proposal round 2",
"status": "draft",
"quoted_amount": 2500000.0,
"current_round": 2
}
],
"pagination": {"current_page": 1, "per_page": 20, "total": 1, "last_page": 1}
}Create a new proposal record.
| Field | Description |
|---|---|
| project_id | Required. Integer. Must belong to the authenticated business. |
| title | Required. String, max 255. |
| status | Optional. String, max 32. One of the 7 canonical proposal_stages values; defaults to draft at the DB level if omitted. |
| quoted_amount | Optional. Numeric, β₯0. |
| current_round | Optional. Integer, β₯0. Bump manually on each new negotiation round. |
{
"project_id": 4,
"title": "Revised foundation proposal round 2",
"status": "draft",
"quoted_amount": 2500000,
"current_round": 2
}{
"success": true,
"msg": "Created",
"data": {
"id": 3,
"business_id": 1,
"project_id": 4,
"project_name": "Block A",
"title": "Revised foundation proposal round 2",
"status": "draft",
"quoted_amount": 2500000.0,
"current_round": 2
}
}Retrieve one proposal by ID.
| Param | Description |
|---|---|
| id | Required. Proposal ID. Must belong to the authenticated business β otherwise 404. |
{
"success": true,
"msg": "Proposals",
"data": {
"id": 3,
"business_id": 1,
"project_id": 4,
"project_name": "Block A",
"title": "Revised foundation proposal round 2",
"status": "draft",
"quoted_amount": 2500000.0,
"current_round": 2
}
}Update any fields on an existing proposal. All fields optional.
| Field | Description |
|---|---|
| project_id | Optional. Integer. Must belong to the authenticated business. |
| title | Optional. String, max 255. |
| status | Optional. String, max 32. One of the 7 canonical proposal_stages values. |
| quoted_amount | Optional. Numeric, β₯0. |
| current_round | Optional. Integer, β₯0. |
{
"project_id": 4,
"title": "Revised foundation proposal round 2",
"status": "draft",
"quoted_amount": 2500000,
"current_round": 2
}{
"success": true,
"msg": "Updated",
"data": {
"id": 3,
"business_id": 1,
"project_id": 4,
"project_name": "Block A",
"title": "Revised foundation proposal round 2",
"status": "draft",
"quoted_amount": 2500000.0,
"current_round": 2
}
}Permanently delete this proposal. Does not cascade-delete ProposalRound history β clean those up separately if needed.
| Param | Description |
|---|---|
| id | Required. Proposal ID. Must belong to the authenticated business β otherwise 404. |
{
"success": true,
"msg": "Deleted",
"data": { "id": 3 }
}Proposal Rounds
Paginated list of proposal round history. Scoped to authenticated business. proposal_title is resolved via the proposal relation β never just proposal_id.
| Param | Description |
|---|---|
| proposal_id | Optional. Restrict to rounds on one proposal β this is how the Admin Portal builds the round-history table on the Proposal Detail screen. No cross-business existence check is performed; a non-matching id simply yields zero rows. |
| status | Optional. Exact match on one of: pending, accepted, superseded. |
| search | Optional. Matches against notes OR the parent proposal's title (case-insensitive substring). |
| page | Optional. Default 1. |
| per_page | Optional. Default 20. Pass -1 for unpaginated. |
{
"success": true,
"msg": "Proposal rounds",
"data": [
{
"id": 3,
"business_id": 1,
"proposal_id": 1,
"proposal_title": "Initial BOQ Proposal",
"round_number": 3,
"amount": 11800000.0,
"status": "accepted",
"notes": "Negotiation round 3",
"submitted_at": "2026-05-29T18:20:54+00:00"
},
{
"id": 2,
"business_id": 1,
"proposal_id": 1,
"proposal_title": "Initial BOQ Proposal",
"round_number": 2,
"amount": 11500000.0,
"status": "superseded",
"notes": "Negotiation round 2",
"submitted_at": "2026-04-29T18:20:54+00:00"
}
],
"pagination": {"current_page":1,"per_page":20,"total":3,"last_page":1}
}Create a new proposal round record.
| Field | Description |
|---|---|
| proposal_id | Required. Integer β no existence check performed (matches the light-validation convention used by sibling FK fields such as Voucher's subcontractor_id). |
| round_number | Required. Integer, β₯1. Should match the parent proposal's current_round once this round becomes the live one. |
| amount | Optional. Numeric, β₯0. |
| status | Optional. String, max 32. One of pending (default), accepted, superseded. |
| notes | Optional. Free text. |
| submitted_at | Optional. Date. When this round's figure was shared with the client. |
{
"proposal_id": 1,
"round_number": 4,
"amount": 11750000,
"status": "pending",
"notes": "Final negotiated figure"
}{
"success": true,
"msg": "Created",
"data": {
"id": 4,
"business_id": 1,
"proposal_id": 1,
"proposal_title": "Initial BOQ Proposal",
"round_number": 4,
"amount": 11750000.0,
"status": "pending",
"notes": "Final negotiated figure",
"submitted_at": ""
}
}Retrieve one proposal round by ID.
| Param | Description |
|---|---|
| id | Required. Proposal round ID. Must belong to the authenticated business β otherwise 404. |
{
"success": true,
"msg": "Proposal rounds",
"data": {
"id": 4,
"business_id": 1,
"proposal_id": 1,
"proposal_title": "Initial BOQ Proposal",
"round_number": 4,
"amount": 11750000.0,
"status": "accepted",
"notes": "Final negotiated figure",
"submitted_at": ""
}
}Update any fields on an existing proposal round. All fields optional. Typical use: flip status to accepted or superseded.
| Field | Description |
|---|---|
| proposal_id | Optional. Integer. |
| round_number | Optional. Integer, β₯1. |
| amount | Optional. Numeric, β₯0. |
| status | Optional. String, max 32. One of pending, accepted, superseded. |
| notes | Optional. Free text. |
| submitted_at | Optional. Date. |
{
"status": "accepted"
}{
"success": true,
"msg": "Updated",
"data": {
"id": 4,
"business_id": 1,
"proposal_id": 1,
"proposal_title": "Initial BOQ Proposal",
"round_number": 4,
"amount": 11750000.0,
"status": "accepted",
"notes": "Final negotiated figure",
"submitted_at": ""
}
}Permanently delete this proposal round record.
| Param | Description |
|---|---|
| id | Required. Proposal round ID. Must belong to the authenticated business β otherwise 404. |
{
"success": true,
"msg": "Deleted",
"data": {
"id": 4
}
}Proposal Members
List staff members assigned to a proposal. Scoped to authenticated business.
| Param | Description |
|---|---|
| proposal_id | Required. Filter by proposal. |
{
"success": true,
"msg": "Proposal members",
"data": [
{
"id": 1,
"proposal_id": 1,
"user_id": 7,
"user_name": "Zainul Abideen",
"role_label": "Lead Estimator",
"assigned_at": "2026-03-15T10:00:00.000000Z"
}
]
}Assign a staff member to a proposal.
{
"proposal_id": 1,
"user_id": 7,
"role_label": "Lead Estimator"
}{
"success": true,
"msg": "Member assigned",
"data": {
"id": 1,
"proposal_id": 1,
"user_id": 7,
"user_name": "Zainul Abideen",
"role_label": "Lead Estimator",
"assigned_at": "2026-08-11T09:00:00.000000Z"
}
}Remove a staff member from a proposal.
{
"success": true,
"msg": "Deleted",
"data": { "id": 1 }
}Proposal Notes
List internal notes for a proposal. Not visible to the client. Scoped to authenticated business.
| Param | Description |
|---|---|
| proposal_id | Required. Filter by proposal. |
{
"success": true,
"msg": "Proposal notes",
"data": [
{
"id": 1,
"proposal_id": 1,
"author_id": 7,
"author_name": "Zainul Abideen",
"body": "Client pushed back on tile & marble budget β will itemise for round 2.",
"created_at": "2026-03-28T10:15:00.000000Z",
"updated_at": "2026-03-28T10:15:00.000000Z"
}
]
}Add an internal note to a proposal.
{
"proposal_id": 1,
"body": "Client approved round 3 verbally β formal acceptance email expected EOD."
}{
"success": true,
"msg": "Note saved",
"data": {
"id": 3,
"proposal_id": 1,
"author_id": 7,
"author_name": "Zainul Abideen",
"body": "Client approved round 3 verbally β formal acceptance email expected EOD.",
"created_at": "2026-08-11T09:00:00.000000Z",
"updated_at": "2026-08-11T09:00:00.000000Z"
}
}Update an existing proposal note. Only the note author or an admin may edit.
{
"body": "Updated note text."
}Delete an internal note.
{
"success": true,
"msg": "Deleted",
"data": { "id": 3 }
}Proposal Messages
List the client communication log for a proposal. Ordered oldest-first. Scoped to authenticated business.
| Param | Description |
|---|---|
| proposal_id | Required. Filter by proposal. |
{
"success": true,
"msg": "Proposal messages",
"data": [
{
"id": 1,
"proposal_id": 1,
"direction": "outbound",
"sender_name": "Zainul Abideen",
"body": "Please find attached our initial BOQ proposalβ¦",
"sent_at": "2026-03-29T11:00:00.000000Z"
},
{
"id": 2,
"proposal_id": 1,
"direction": "inbound",
"sender_name": "Mr. Bilal Chaudhry",
"body": "Thank you for the proposal. We'd like to defer the external claddingβ¦",
"sent_at": "2026-04-10T15:15:00.000000Z"
}
]
}Log an inbound or outbound client message against a proposal.
{
"proposal_id": 1,
"direction": "outbound",
"sender_name": "Zainul Abideen",
"body": "Please find the revised proposal (Round 2)β¦",
"sent_at": "2026-04-29T10:30:00"
}| Field | Notes |
|---|---|
| direction | outbound (team sent to client) or inbound (client sent to team) |
| sender_name | Free text β the name displayed in the message log |
| sent_at | Nullable. Defaults to now() if omitted. |
{
"success": true,
"msg": "Message logged",
"data": {
"id": 5,
"proposal_id": 1,
"direction": "outbound",
"sender_name": "Zainul Abideen",
"body": "Please find the revised proposal (Round 2)β¦",
"sent_at": "2026-04-29T10:30:00.000000Z"
}
}Phases
Paginated list of phase. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Phases",
"data": {
"id": 5,
"project_id": 4,
"phase_key": "structural",
"name": "Structural Framing",
"status": "pending",
"progress_percent": 0,
"sort_order": 2
}
}Create a new phase record.
{
"project_id": 4,
"phase_key": "structural",
"name": "Structural Framing",
"status": "pending",
"progress_percent": 0,
"planned_start": "2026-08-01",
"planned_end": "2026-10-15",
"sort_order": 2
}{
"success": true,
"msg": "Phases",
"data": {
"id": 5,
"project_id": 4,
"phase_key": "structural",
"name": "Structural Framing",
"status": "pending",
"progress_percent": 0,
"sort_order": 2
}
}Retrieve one phase by ID.
{
"success": true,
"msg": "Phases",
"data": {
"id": 5,
"project_id": 4,
"phase_key": "structural",
"name": "Structural Framing",
"status": "pending",
"progress_percent": 0,
"sort_order": 2
}
}Update any fields on an existing phase. All fields optional.
{
"project_id": 4,
"phase_key": "structural",
"name": "Structural Framing",
"status": "pending",
"progress_percent": 0,
"planned_start": "2026-08-01",
"planned_end": "2026-10-15",
"sort_order": 2
}{
"success": true,
"msg": "Phases",
"data": {
"id": 5,
"project_id": 4,
"phase_key": "structural",
"name": "Structural Framing",
"status": "pending",
"progress_percent": 0,
"sort_order": 2
}
}Permanently delete this phase.
{
"success": true,
"msg": "Deleted",
"data": null
}People — Staff
Paginated list of staff profile. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Staff",
"data": {
"id": 3,
"business_id": 1,
"user_id": 7,
"location_id": 1,
"job_title": "Site Engineer",
"department": "Engineering",
"status": "active"
}
}Create a new staff profile record.
{
"user_id": 7,
"location_id": 1,
"job_title": "Site Engineer",
"department": "Engineering",
"status": "active"
}{
"success": true,
"msg": "Staff",
"data": {
"id": 3,
"business_id": 1,
"user_id": 7,
"location_id": 1,
"job_title": "Site Engineer",
"department": "Engineering",
"status": "active"
}
}Retrieve one staff profile by ID.
{
"success": true,
"msg": "Staff",
"data": {
"id": 3,
"business_id": 1,
"user_id": 7,
"location_id": 1,
"job_title": "Site Engineer",
"department": "Engineering",
"status": "active"
}
}Update any fields on an existing staff profile. All fields optional.
{
"user_id": 7,
"location_id": 1,
"job_title": "Site Engineer",
"department": "Engineering",
"status": "active"
}{
"success": true,
"msg": "Staff",
"data": {
"id": 3,
"business_id": 1,
"user_id": 7,
"location_id": 1,
"job_title": "Site Engineer",
"department": "Engineering",
"status": "active"
}
}Permanently delete this staff profile.
{
"success": true,
"msg": "Deleted",
"data": null
}People — Subcontractors
Paginated list of subcontractor. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Subcontractors",
"data": {
"id": 3,
"business_id": 1,
"user_id": null,
"company_name": "RapidSteel Contractors",
"trade_type": "steel_works",
"contact_email": "rapidsteel@contractors.test",
"contact_phone": "+92-321-0011223",
"status": "active"
}
}Create a new subcontractor record.
{
"user_id": null,
"company_name": "RapidSteel Contractors",
"trade_type": "steel_works",
"contact_email": "rapidsteel@contractors.test",
"contact_phone": "+92-321-0011223",
"status": "active"
}{
"success": true,
"msg": "Subcontractors",
"data": {
"id": 3,
"business_id": 1,
"user_id": null,
"company_name": "RapidSteel Contractors",
"trade_type": "steel_works",
"contact_email": "rapidsteel@contractors.test",
"contact_phone": "+92-321-0011223",
"status": "active"
}
}Retrieve one subcontractor by ID.
{
"success": true,
"msg": "Subcontractors",
"data": {
"id": 3,
"business_id": 1,
"user_id": null,
"company_name": "RapidSteel Contractors",
"trade_type": "steel_works",
"contact_email": "rapidsteel@contractors.test",
"contact_phone": "+92-321-0011223",
"status": "active"
}
}Update any fields on an existing subcontractor. All fields optional.
{
"user_id": null,
"company_name": "RapidSteel Contractors",
"trade_type": "steel_works",
"contact_email": "rapidsteel@contractors.test",
"contact_phone": "+92-321-0011223",
"status": "active"
}{
"success": true,
"msg": "Subcontractors",
"data": {
"id": 3,
"business_id": 1,
"user_id": null,
"company_name": "RapidSteel Contractors",
"trade_type": "steel_works",
"contact_email": "rapidsteel@contractors.test",
"contact_phone": "+92-321-0011223",
"status": "active"
}
}Permanently delete this subcontractor.
{
"success": true,
"msg": "Deleted",
"data": null
}Financial — Vouchers
Paginated list of voucher. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Vouchers",
"data": {
"id": 8,
"business_id": 1,
"project_id": 4,
"subcontractor_id": 3,
"voucher_no": "VCH-2026-0008",
"voucher_type": "subcontractor",
"status": "draft",
"amount": 220000.0,
"week_ending": "2026-06-28"
}
}Create a new voucher record.
{
"project_id": 4,
"subcontractor_id": 3,
"voucher_no": "VCH-2026-0008",
"voucher_type": "subcontractor",
"status": "draft",
"amount": 220000,
"week_ending": "2026-06-28"
}{
"success": true,
"msg": "Vouchers",
"data": {
"id": 8,
"business_id": 1,
"project_id": 4,
"subcontractor_id": 3,
"voucher_no": "VCH-2026-0008",
"voucher_type": "subcontractor",
"status": "draft",
"amount": 220000.0,
"week_ending": "2026-06-28"
}
}Retrieve one voucher by ID.
{
"success": true,
"msg": "Vouchers",
"data": {
"id": 8,
"business_id": 1,
"project_id": 4,
"subcontractor_id": 3,
"voucher_no": "VCH-2026-0008",
"voucher_type": "subcontractor",
"status": "draft",
"amount": 220000.0,
"week_ending": "2026-06-28"
}
}Update any fields on an existing voucher. All fields optional.
{
"project_id": 4,
"subcontractor_id": 3,
"voucher_no": "VCH-2026-0008",
"voucher_type": "subcontractor",
"status": "draft",
"amount": 220000,
"week_ending": "2026-06-28"
}{
"success": true,
"msg": "Vouchers",
"data": {
"id": 8,
"business_id": 1,
"project_id": 4,
"subcontractor_id": 3,
"voucher_no": "VCH-2026-0008",
"voucher_type": "subcontractor",
"status": "draft",
"amount": 220000.0,
"week_ending": "2026-06-28"
}
}Permanently delete this voucher.
{
"success": true,
"msg": "Deleted",
"data": null
}Financial — Ledger Entries
Paginated list of ledger entry. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Ledgers",
"data": {
"id": 4,
"business_id": 1,
"project_id": 4,
"party_type": "subcontractor",
"party_id": 3,
"entry_type": "payment",
"debit": 0.0,
"credit": 220000.0,
"reference": "VCH-2026-0008",
"description": "Payment against voucher",
"entry_date": "2026-06-28"
}
}Create a new ledger entry record.
{
"project_id": 4,
"party_type": "subcontractor",
"party_id": 3,
"entry_type": "payment",
"debit": 0,
"credit": 220000,
"reference": "VCH-2026-0008",
"description": "Payment against voucher",
"entry_date": "2026-06-28"
}{
"success": true,
"msg": "Ledgers",
"data": {
"id": 4,
"business_id": 1,
"project_id": 4,
"party_type": "subcontractor",
"party_id": 3,
"entry_type": "payment",
"debit": 0.0,
"credit": 220000.0,
"reference": "VCH-2026-0008",
"description": "Payment against voucher",
"entry_date": "2026-06-28"
}
}Retrieve one ledger entry by ID.
{
"success": true,
"msg": "Ledgers",
"data": {
"id": 4,
"business_id": 1,
"project_id": 4,
"party_type": "subcontractor",
"party_id": 3,
"entry_type": "payment",
"debit": 0.0,
"credit": 220000.0,
"reference": "VCH-2026-0008",
"description": "Payment against voucher",
"entry_date": "2026-06-28"
}
}Update any fields on an existing ledger entry. All fields optional.
{
"project_id": 4,
"party_type": "subcontractor",
"party_id": 3,
"entry_type": "payment",
"debit": 0,
"credit": 220000,
"reference": "VCH-2026-0008",
"description": "Payment against voucher",
"entry_date": "2026-06-28"
}{
"success": true,
"msg": "Ledgers",
"data": {
"id": 4,
"business_id": 1,
"project_id": 4,
"party_type": "subcontractor",
"party_id": 3,
"entry_type": "payment",
"debit": 0.0,
"credit": 220000.0,
"reference": "VCH-2026-0008",
"description": "Payment against voucher",
"entry_date": "2026-06-28"
}
}Permanently delete this ledger entry.
{
"success": true,
"msg": "Deleted",
"data": null
}Financial — Variation Orders
Paginated list of variation order. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Variation orders",
"data": {
"id": 1,
"business_id": 1,
"project_id": 4,
"vo_number": "VO-2026-0001",
"title": "Additional reinforcement for column footings",
"description": "Structural engineer requirement after soil report",
"amount": 75000.0,
"status": "pending"
}
}Create a new variation order record.
{
"project_id": 4,
"vo_number": "VO-2026-0001",
"title": "Additional reinforcement for column footings",
"description": "Structural engineer requirement after soil report",
"amount": 75000,
"status": "pending"
}{
"success": true,
"msg": "Variation orders",
"data": {
"id": 1,
"business_id": 1,
"project_id": 4,
"vo_number": "VO-2026-0001",
"title": "Additional reinforcement for column footings",
"description": "Structural engineer requirement after soil report",
"amount": 75000.0,
"status": "pending"
}
}Retrieve one variation order by ID.
{
"success": true,
"msg": "Variation orders",
"data": {
"id": 1,
"business_id": 1,
"project_id": 4,
"vo_number": "VO-2026-0001",
"title": "Additional reinforcement for column footings",
"description": "Structural engineer requirement after soil report",
"amount": 75000.0,
"status": "pending"
}
}Update any fields on an existing variation order. All fields optional.
{
"project_id": 4,
"vo_number": "VO-2026-0001",
"title": "Additional reinforcement for column footings",
"description": "Structural engineer requirement after soil report",
"amount": 75000,
"status": "pending"
}{
"success": true,
"msg": "Variation orders",
"data": {
"id": 1,
"business_id": 1,
"project_id": 4,
"vo_number": "VO-2026-0001",
"title": "Additional reinforcement for column footings",
"description": "Structural engineer requirement after soil report",
"amount": 75000.0,
"status": "pending"
}
}Permanently delete this variation order.
{
"success": true,
"msg": "Deleted",
"data": null
}Financial — Daywork Orders
Paginated list of daywork order. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Daywork orders",
"data": {
"id": 1,
"business_id": 1,
"project_id": 4,
"dwo_number": "DWO-2026-0001",
"title": "Emergency waterproofing works",
"description": "Urgent waterproofing after rain damage",
"amount": 32000.0,
"status": "draft",
"work_date": "2026-06-22"
}
}Create a new daywork order record.
{
"project_id": 4,
"dwo_number": "DWO-2026-0001",
"title": "Emergency waterproofing works",
"description": "Urgent waterproofing after rain damage",
"amount": 32000,
"status": "draft",
"work_date": "2026-06-22"
}{
"success": true,
"msg": "Daywork orders",
"data": {
"id": 1,
"business_id": 1,
"project_id": 4,
"dwo_number": "DWO-2026-0001",
"title": "Emergency waterproofing works",
"description": "Urgent waterproofing after rain damage",
"amount": 32000.0,
"status": "draft",
"work_date": "2026-06-22"
}
}Retrieve one daywork order by ID.
{
"success": true,
"msg": "Daywork orders",
"data": {
"id": 1,
"business_id": 1,
"project_id": 4,
"dwo_number": "DWO-2026-0001",
"title": "Emergency waterproofing works",
"description": "Urgent waterproofing after rain damage",
"amount": 32000.0,
"status": "draft",
"work_date": "2026-06-22"
}
}Update any fields on an existing daywork order. All fields optional.
{
"project_id": 4,
"dwo_number": "DWO-2026-0001",
"title": "Emergency waterproofing works",
"description": "Urgent waterproofing after rain damage",
"amount": 32000,
"status": "draft",
"work_date": "2026-06-22"
}{
"success": true,
"msg": "Daywork orders",
"data": {
"id": 1,
"business_id": 1,
"project_id": 4,
"dwo_number": "DWO-2026-0001",
"title": "Emergency waterproofing works",
"description": "Urgent waterproofing after rain damage",
"amount": 32000.0,
"status": "draft",
"work_date": "2026-06-22"
}
}Permanently delete this daywork order.
{
"success": true,
"msg": "Deleted",
"data": null
}Calendar Events
Paginated list of calendar event. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Calendar",
"data": {
"id": 5,
"business_id": 1,
"project_id": 4,
"assigned_user_id": 7,
"title": "Foundation inspection",
"description": "Structural engineer site visit for foundation sign-off",
"starts_at": "2026-07-05T09:00:00+05:00",
"ends_at": "2026-07-05T12:00:00+05:00",
"event_type": "inspection"
}
}Create a new calendar event record.
{
"project_id": 4,
"assigned_user_id": 7,
"title": "Foundation inspection",
"description": "Structural engineer site visit for foundation sign-off",
"starts_at": "2026-07-05T09:00:00+05:00",
"ends_at": "2026-07-05T12:00:00+05:00",
"event_type": "inspection"
}{
"success": true,
"msg": "Calendar",
"data": {
"id": 5,
"business_id": 1,
"project_id": 4,
"assigned_user_id": 7,
"title": "Foundation inspection",
"description": "Structural engineer site visit for foundation sign-off",
"starts_at": "2026-07-05T09:00:00+05:00",
"ends_at": "2026-07-05T12:00:00+05:00",
"event_type": "inspection"
}
}Retrieve one calendar event by ID.
{
"success": true,
"msg": "Calendar",
"data": {
"id": 5,
"business_id": 1,
"project_id": 4,
"assigned_user_id": 7,
"title": "Foundation inspection",
"description": "Structural engineer site visit for foundation sign-off",
"starts_at": "2026-07-05T09:00:00+05:00",
"ends_at": "2026-07-05T12:00:00+05:00",
"event_type": "inspection"
}
}Update any fields on an existing calendar event. All fields optional.
{
"project_id": 4,
"assigned_user_id": 7,
"title": "Foundation inspection",
"description": "Structural engineer site visit for foundation sign-off",
"starts_at": "2026-07-05T09:00:00+05:00",
"ends_at": "2026-07-05T12:00:00+05:00",
"event_type": "inspection"
}{
"success": true,
"msg": "Calendar",
"data": {
"id": 5,
"business_id": 1,
"project_id": 4,
"assigned_user_id": 7,
"title": "Foundation inspection",
"description": "Structural engineer site visit for foundation sign-off",
"starts_at": "2026-07-05T09:00:00+05:00",
"ends_at": "2026-07-05T12:00:00+05:00",
"event_type": "inspection"
}
}Permanently delete this calendar event.
{
"success": true,
"msg": "Deleted",
"data": null
}Setup & Reference Data
Configure these during business onboarding before creating projects. Each follows the standard 5-endpoint CRUD pattern scoped to the business.
Paginated list of location. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Locations",
"data": {
"id": 2,
"business_id": 1,
"name": "Karachi Office",
"address": "Plot 14, SITE Area, Karachi",
"contact_person": "Usman Ali",
"contact_phone": "+92-300-4455667",
"is_active": true
}
}Create a new location record.
{
"name": "Karachi Office",
"address": "Plot 14, SITE Area, Karachi",
"contact_person": "Usman Ali",
"contact_phone": "+92-300-4455667",
"is_active": true
}{
"success": true,
"msg": "Locations",
"data": {
"id": 2,
"business_id": 1,
"name": "Karachi Office",
"address": "Plot 14, SITE Area, Karachi",
"contact_person": "Usman Ali",
"contact_phone": "+92-300-4455667",
"is_active": true
}
}Retrieve one location by ID.
{
"success": true,
"msg": "Locations",
"data": {
"id": 2,
"business_id": 1,
"name": "Karachi Office",
"address": "Plot 14, SITE Area, Karachi",
"contact_person": "Usman Ali",
"contact_phone": "+92-300-4455667",
"is_active": true
}
}Update any fields on an existing location. All fields optional.
{
"name": "Karachi Office",
"address": "Plot 14, SITE Area, Karachi",
"contact_person": "Usman Ali",
"contact_phone": "+92-300-4455667",
"is_active": true
}{
"success": true,
"msg": "Locations",
"data": {
"id": 2,
"business_id": 1,
"name": "Karachi Office",
"address": "Plot 14, SITE Area, Karachi",
"contact_person": "Usman Ali",
"contact_phone": "+92-300-4455667",
"is_active": true
}
}Permanently delete this location.
{
"success": true,
"msg": "Deleted",
"data": null
}Paginated list of phase library item. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| category | Filter by category slug (e.g. civil_structural, mep_rough_in) |
| per_page | Default 20 |
{
"success": true,
"msg": "Phase library",
"data": {
"id": 5,
"business_id": 1,
"phase_key": "electrical",
"category": "civil_structural",
"name": "Electrical Works",
"description": "Full electrical wiring, panel installation, fixtures",
"default_duration_days": 45,
"sort_order": 5,
"is_active": true
}
}Create a new phase library item record.
{
"phase_key": "electrical",
"category": "civil_structural",
"name": "Electrical Works",
"description": "Full electrical wiring, panel installation, fixtures",
"default_duration_days": 45,
"sort_order": 5,
"is_active": true
}{
"success": true,
"msg": "Phase library",
"data": {
"id": 5,
"business_id": 1,
"phase_key": "electrical",
"category": "civil_structural",
"name": "Electrical Works",
"description": "Full electrical wiring, panel installation, fixtures",
"default_duration_days": 45,
"sort_order": 5,
"is_active": true
}
}Retrieve one phase library item by ID.
{
"success": true,
"msg": "Phase library",
"data": {
"id": 5,
"business_id": 1,
"phase_key": "electrical",
"category": "civil_structural",
"name": "Electrical Works",
"description": "Full electrical wiring, panel installation, fixtures",
"default_duration_days": 45,
"sort_order": 5,
"is_active": true
}
}Update any fields on an existing phase library item. All fields optional.
{
"phase_key": "electrical",
"category": "civil_structural",
"name": "Electrical Works",
"description": "Full electrical wiring, panel installation, fixtures",
"default_duration_days": 45,
"sort_order": 5,
"is_active": true
}{
"success": true,
"msg": "Phase library",
"data": {
"id": 5,
"business_id": 1,
"phase_key": "electrical",
"category": "civil_structural",
"name": "Electrical Works",
"description": "Full electrical wiring, panel installation, fixtures",
"default_duration_days": 45,
"sort_order": 5,
"is_active": true
}
}Permanently delete this phase library item.
{
"success": true,
"msg": "Deleted",
"data": null
}Paginated list of document type. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Document types",
"data": {
"id": 3,
"business_id": 1,
"name": "Completion Certificate",
"category": "certification",
"requires_approval": true,
"is_active": true
}
}Create a new document type record.
{
"name": "Completion Certificate",
"category": "certification",
"requires_approval": true,
"is_active": true
}{
"success": true,
"msg": "Document types",
"data": {
"id": 3,
"business_id": 1,
"name": "Completion Certificate",
"category": "certification",
"requires_approval": true,
"is_active": true
}
}Retrieve one document type by ID.
{
"success": true,
"msg": "Document types",
"data": {
"id": 3,
"business_id": 1,
"name": "Completion Certificate",
"category": "certification",
"requires_approval": true,
"is_active": true
}
}Update any fields on an existing document type. All fields optional.
{
"name": "Completion Certificate",
"category": "certification",
"requires_approval": true,
"is_active": true
}{
"success": true,
"msg": "Document types",
"data": {
"id": 3,
"business_id": 1,
"name": "Completion Certificate",
"category": "certification",
"requires_approval": true,
"is_active": true
}
}Permanently delete this document type.
{
"success": true,
"msg": "Deleted",
"data": null
}Paginated list of trade type. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Trade types",
"data": {
"id": 4,
"business_id": 1,
"name": "Structural Steel Works",
"code": "SSW",
"is_active": true
}
}Create a new trade type record.
{
"name": "Structural Steel Works",
"code": "SSW",
"is_active": true
}{
"success": true,
"msg": "Trade types",
"data": {
"id": 4,
"business_id": 1,
"name": "Structural Steel Works",
"code": "SSW",
"is_active": true
}
}Retrieve one trade type by ID.
{
"success": true,
"msg": "Trade types",
"data": {
"id": 4,
"business_id": 1,
"name": "Structural Steel Works",
"code": "SSW",
"is_active": true
}
}Update any fields on an existing trade type. All fields optional.
{
"name": "Structural Steel Works",
"code": "SSW",
"is_active": true
}{
"success": true,
"msg": "Trade types",
"data": {
"id": 4,
"business_id": 1,
"name": "Structural Steel Works",
"code": "SSW",
"is_active": true
}
}Permanently delete this trade type.
{
"success": true,
"msg": "Deleted",
"data": null
}Paginated list of subcontractor category. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Subcontractor categories",
"data": {
"id": 2,
"business_id": 1,
"name": "Civil Works",
"code": "CIV",
"is_active": true
}
}Create a new subcontractor category record.
{
"name": "Civil Works",
"code": "CIV",
"is_active": true
}{
"success": true,
"msg": "Subcontractor categories",
"data": {
"id": 2,
"business_id": 1,
"name": "Civil Works",
"code": "CIV",
"is_active": true
}
}Retrieve one subcontractor category by ID.
{
"success": true,
"msg": "Subcontractor categories",
"data": {
"id": 2,
"business_id": 1,
"name": "Civil Works",
"code": "CIV",
"is_active": true
}
}Update any fields on an existing subcontractor category. All fields optional.
{
"name": "Civil Works",
"code": "CIV",
"is_active": true
}{
"success": true,
"msg": "Subcontractor categories",
"data": {
"id": 2,
"business_id": 1,
"name": "Civil Works",
"code": "CIV",
"is_active": true
}
}Permanently delete this subcontractor category.
{
"success": true,
"msg": "Deleted",
"data": null
}Paginated list of project template. Scoped to authenticated business.
| Param | Description |
|---|---|
| search | Text search |
| per_page | Default 20 |
{
"success": true,
"msg": "Project templates",
"data": {
"id": 2,
"business_id": 1,
"name": "Residential Construction Standard",
"description": "Standard phases for a residential build",
"phase_keys": ["foundation","structural","roofing","plumbing","electrical","finishing"],
"is_active": true
}
}Create a new project template record.
{
"name": "Residential Construction Standard",
"description": "Standard phases for a residential build",
"phase_keys": ["foundation","structural","roofing","plumbing","electrical","finishing"],
"is_active": true
}{
"success": true,
"msg": "Project templates",
"data": {
"id": 2,
"business_id": 1,
"name": "Residential Construction Standard",
"description": "Standard phases for a residential build",
"phase_keys": ["foundation","structural","roofing","plumbing","electrical","finishing"],
"is_active": true
}
}Retrieve one project template by ID.
{
"success": true,
"msg": "Project templates",
"data": {
"id": 2,
"business_id": 1,
"name": "Residential Construction Standard",
"description": "Standard phases for a residential build",
"phase_keys": ["foundation","structural","roofing","plumbing","electrical","finishing"],
"is_active": true
}
}Update any fields on an existing project template. All fields optional.
{
"name": "Residential Construction Standard",
"description": "Standard phases for a residential build",
"phase_keys": ["foundation","structural","roofing","plumbing","electrical","finishing"],
"is_active": true
}{
"success": true,
"msg": "Project templates",
"data": {
"id": 2,
"business_id": 1,
"name": "Residential Construction Standard",
"description": "Standard phases for a residential build",
"phase_keys": ["foundation","structural","roofing","plumbing","electrical","finishing"],
"is_active": true
}
}Permanently delete this project template.
{
"success": true,
"msg": "Deleted",
"data": null
}Settings — Signature
Get the business-level signature settings used on vouchers, certificates, and documents.
{
"success": true,
"msg": "Signature settings",
"data": {
"id": 1,
"business_id": 1,
"user_id": 0,
"signature_image_path": "signatures/business-1-default.png",
"signer_name": "Eng. Arif Khan",
"signer_title": "Director - Pak Engineering Service"
}
}Update/upsert the business signature. Creates the record if it does not yet exist.
{
"signature_image_path": "signatures/business-1-default.png",
"signer_name": "Eng. Arif Khan",
"signer_title": "Director - Pak Engineering Service"
}{
"success": true,
"msg": "Signature settings",
"data": {
"id": 1,
"business_id": 1,
"user_id": 0,
"signature_image_path": "signatures/business-1-default.png",
"signer_name": "Eng. Arif Khan",
"signer_title": "Director - Pak Engineering Service"
}
}Notifications (Bell Dropdown)
Bell-dropdown endpoint. Returns up to 20 most recent unread notifications for the authenticated user. Available to both admin and staff. No pagination key β designed for lightweight bell polling.
{
"success": true,
"msg": "Notifications",
"data": [
{
"id": 12,
"type": "project_created",
"title": "New Project Created",
"body": "Residential Block A has been created and assigned to you.",
"is_read": false,
"data": { "project_id": 5 },
"created_at": "2026-07-01T09:14:00+05:00"
},
{
"id": 11,
"type": "phase_updated",
"title": "Phase Status Changed",
"body": "Foundation Work phase marked as complete.",
"is_read": false,
"data": { "phase_id": 18 },
"created_at": "2026-07-01T08:30:00+05:00"
}
]
}Marks all unread notifications as read for the authenticated user. Used when the user opens the bell dropdown and dismisses it.
{ "success": true, "msg": "All marked read", "data": null }Audit Logs (Admin Only)
Paginated full history of all notifications/audit events for the authenticated admin user. Admin only β staff get 403. Supports filter by type, is_read, and text search across title, body, type.
| Param | Type | Description |
|---|---|---|
| type | string | Filter by notification type (e.g. project_created, phase_updated) |
| is_read | 0/1/true/false | Filter unread or read entries |
| search | string | Full-text search on title, body, type, and numeric id |
| per_page | int | Default 15 |
{
"success": true,
"msg": "Audit logs",
"data": [
{
"id": 12,
"type": "project_created",
"title": "New Project Created",
"body": "Residential Block A has been created and assigned to you.",
"is_read": true,
"data": { "project_id": 5 },
"created_at": "2026-07-01T09:14:00+05:00"
}
],
"pagination": { "total": 48, "per_page": 15, "current_page": 1, "last_page": 4 }
}Returns a single audit log entry scoped to the authenticated admin's own records.
{
"success": true,
"msg": "Audit log",
"data": {
"id": 12, "type": "project_created", "title": "New Project Created",
"body": "Residential Block A has been created and assigned to you.",
"is_read": true, "data": { "project_id": 5 },
"created_at": "2026-07-01T09:14:00+05:00"
}
}Marks all unread audit log entries as read for the authenticated admin.
{ "success": true, "msg": "All marked read", "data": null }Marks a single audit log entry as read by id. Scoped to the authenticated admin's records.
{ "success": true, "msg": "Marked read", "data": { "id": 12, "is_read": true } }Hard-deletes a single audit log entry. Admin only. Record must belong to the authenticated user.
{ "success": true, "msg": "Deleted", "data": null }Roles & Permissions
List all roles with their assigned permissions.
{
"success": true,
"msg": "Roles",
"data": [
{
"id": 1,
"slug": "admin",
"name": "Business Admin",
"is_system": true,
"permissions": [
{"id": 1, "slug": "projects.view", "name": "View Projects"},
{"id": 2, "slug": "projects.manage", "name": "Manage Projects"},
{"id": 3, "slug": "dashboard.view", "name": "View Dashboard"}
]
},
{
"id": 3,
"slug": "site-supervisor",
"name": "Site Supervisor",
"is_system": false,
"permissions": [
{"id": 1, "slug": "projects.view", "name": "View Projects"},
{"id": 5, "slug": "phases.view", "name": "View Phases"}
]
}
]
}Create a custom role with specified permission IDs.
{
"name": "Site Supervisor",
"permission_ids": [1, 5, 9, 13]
}{
"success": true,
"msg": "Roles",
"data": [
{
"id": 1,
"slug": "admin",
"name": "Business Admin",
"is_system": true,
"permissions": [
{"id": 1, "slug": "projects.view", "name": "View Projects"},
{"id": 2, "slug": "projects.manage", "name": "Manage Projects"},
{"id": 3, "slug": "dashboard.view", "name": "View Dashboard"}
]
},
{
"id": 3,
"slug": "site-supervisor",
"name": "Site Supervisor",
"is_system": false,
"permissions": [
{"id": 1, "slug": "projects.view", "name": "View Projects"},
{"id": 5, "slug": "phases.view", "name": "View Phases"}
]
}
]
}