/api/Auth —
Authorization: Bearer {sanctum_token} on every protected routeEnvelope —
{ "success": true|false, "msg": "...", "data": {}, "pagination": {} }Seed super admin —
superadmin@engineering.test / Test@1234
Authentication
Authenticate with email/password and receive a Sanctum bearer token. Use this token in all subsequent requests. Super admin accounts also have user_type: super_admin in the response.
{
"email": "superadmin@engineering.test",
"password": "Test@1234"
}
{
"success": true,
"msg": "Logged in",
"data": {
"token": "1|abcxyz...",
"user": {
"id": 1,
"username": "superadmin",
"email": "superadmin@engineering.test",
"display_name": "Super Admin",
"user_type": "super_admin",
"business_id": null,
"is_active": true
}
}
}
Revokes the current Sanctum token. The token becomes invalid immediately.
None required — token is read from Authorization header.
{
"success": true,
"msg": "Logged out",
"data": null
}
Dashboard
Platform KPI summary. Returns tenant counts, plan breakdown (how many tenants on each plan), and the 5 most recently onboarded tenants. No permission slug required beyond super_admin role.
{
"success": true,
"msg": "Dashboard",
"data": {
"tenant_count": 3,
"active_tenant_count": 2,
"suspended_tenant_count": 1,
"subscription_plan_count": 2,
"plan_breakdown": [
{
"plan_id": 1,
"plan_name": "Starter Tier",
"tenant_count": 1,
"is_active": true
},
{
"plan_id": 2,
"plan_name": "Pro",
"tenant_count": 2,
"is_active": true
}
],
"recent_tenants": [
{
"id": 3,
"business_name": "BuildCorp Pakistan",
"owner_name": "Jahanzaib Khan",
"contact_email": "jk@buildcorp.test",
"contact_phone": "+92-300-1234567",
"subscription_plan_id": 2,
"plan_name": "Pro",
"subscription_status": "active",
"subdomain_slug": "buildcorp-pakistan",
"is_active": true,
"created_at": "2026-06-20T10:15:00+00:00"
}
],
"welcome_message": "Platform dashboard"
}
}
Tenants (Business Workspaces)
Paginated list of all tenant businesses. Supports search and filters.
| Param | Type | Required | Description |
|---|---|---|---|
| search | string | optional | Searches business_name, owner_name, contact_email |
| subscription_plan_id | integer | optional | Filter by plan ID (returns empty if plan doesn't exist) |
| is_active | boolean | optional | true or false — filter active/inactive |
| subscription_status | string | optional | active | suspended | past_due | cancelled |
| per_page | integer | optional | Records per page (default 20) |
{
"success": true,
"msg": "Tenants",
"data": [
{
"id": 1,
"business_name": "Pak Engineering Service",
"owner_name": "Seed Owner",
"contact_email": "admin@engineering.test",
"contact_phone": "+92-300-0000000",
"subscription_plan_id": 2,
"plan_name": "Pro",
"subscription_status": "active",
"subdomain_slug": "pak-engineering-service",
"is_active": true
}
],
"pagination": {
"current_page": 1,
"per_page": 20,
"total": 1,
"last_page": 1
}
}
Invite a new tenant (business). Creates the Business record, auto-generates a unique subdomain_slug, and optionally creates an admin user with a one-time temporary password. Writes a tenant_created audit event.
| Field | Type | Required | Validation |
|---|---|---|---|
| business_name | string | required | max:255 |
| owner_name | string | required | max:255 |
| contact_email | string | required | valid email, max:255 |
| contact_phone | string | optional | max:64 |
| subscription_plan_id | integer | required | must exist in t_subscription_plans and be active |
| create_admin_user | boolean | optional | default: true — creates admin user account |
{
"business_name": "BuildCorp Pakistan",
"owner_name": "Jahanzaib Khan",
"contact_email": "jk@buildcorp.test",
"contact_phone": "+92-300-1234567",
"subscription_plan_id": 2,
"create_admin_user": true
}
{
"success": true,
"msg": "Tenant invited",
"data": {
"id": 3,
"business_name": "BuildCorp Pakistan",
"owner_name": "Jahanzaib Khan",
"contact_email": "jk@buildcorp.test",
"contact_phone": "+92-300-1234567",
"subscription_plan_id": 2,
"plan_name": "Pro",
"subscription_status": "active",
"subdomain_slug": "buildcorp-pakistan",
"is_active": true,
"admin_invite": {
"user_id": 8,
"username": "buildcorppakistan_admin",
"email": "jk@buildcorp.test",
"temporary_password": "xK9#mP2vQwLn"
}
}
}
Retrieve a single tenant by ID. Includes subscription plan details.
{
"success": true,
"msg": "Tenants",
"data": {
"id": 3,
"business_name": "BuildCorp Pakistan",
"owner_name": "Jahanzaib Khan",
"contact_email": "jk@buildcorp.test",
"contact_phone": "+92-300-1234567",
"subscription_plan_id": 2,
"plan_name": "Pro",
"subscription_status": "active",
"subdomain_slug": "buildcorp-pakistan",
"is_active": true
}
}
Update any combination of tenant fields. All fields are optional (partial update). Setting is_active: false while tenant was previously active also logs a tenant_suspended audit event in addition to tenant_updated.
| Field | Type | Validation |
|---|---|---|
| business_name | string | max:255 |
| owner_name | string | max:255 |
| contact_email | string | valid email, max:255 |
| contact_phone | string|null | max:64 |
| subscription_plan_id | integer | must exist + be active |
| subscription_status | string | active | suspended | past_due | cancelled |
| is_active | boolean | true | false |
{
"is_active": false,
"subscription_status": "suspended"
}
{
"success": true,
"msg": "Updated",
"data": {
"id": 3,
"business_name": "BuildCorp Pakistan",
"owner_name": "Jahanzaib Khan",
"contact_email": "jk@buildcorp.test",
"contact_phone": "+92-300-1234567",
"subscription_plan_id": 2,
"plan_name": "Pro",
"subscription_status": "suspended",
"subdomain_slug": "buildcorp-pakistan",
"is_active": false
}
}
Soft suspend only — does not hard-delete the business. Sets is_active=false and subscription_status=suspended. Business data is preserved. Logs tenant_suspended audit event.
{
"success": true,
"msg": "Tenant suspended",
"data": {
"id": 3,
"is_active": false
}
}
Subscription Plans
List all subscription plans ordered by monthly_price ascending. Limits appear as -1 in API for unlimited (stored as 0 in DB).
{
"success": true,
"msg": "Subscription plans",
"data": [
{
"id": 1,
"name": "Starter Tier",
"slug": "starter-tier",
"monthly_price": 49,
"max_projects": 5,
"max_locations": 1,
"max_employees": 10,
"has_client_portal": false,
"has_offline_sync": false,
"is_active": true
},
{
"id": 2,
"name": "Pro",
"slug": "pro",
"monthly_price": 299,
"max_projects": -1,
"max_locations": -1,
"max_employees": -1,
"has_client_portal": true,
"has_offline_sync": true,
"is_active": true
}
],
"pagination": {
"current_page": 1,
"per_page": 20,
"total": 2,
"last_page": 1
}
}
Create a new subscription plan. slug is auto-generated from name if omitted. Pass -1 for any limit field to mean "unlimited".
| Field | Type | Required | Validation |
|---|---|---|---|
| name | string | required | max:128 |
| slug | string | optional | max:64, must be unique; auto-generated from name if omitted |
| monthly_price | decimal | required | min:0 |
| max_projects | integer | required | -1 = unlimited, or positive integer |
| max_locations | integer | required | -1 = unlimited, or positive integer |
| max_employees | integer | required | -1 = unlimited, or positive integer |
| has_client_portal | boolean | optional | default false |
| has_offline_sync | boolean | optional | default false |
| is_active | boolean | optional | default true |
{
"name": "Enterprise",
"monthly_price": 799,
"max_projects": -1,
"max_locations": -1,
"max_employees": -1,
"has_client_portal": true,
"has_offline_sync": true,
"is_active": true
}
{
"success": true,
"msg": "Created",
"data": {
"id": 3,
"name": "Enterprise",
"slug": "enterprise",
"monthly_price": 799,
"max_projects": -1,
"max_locations": -1,
"max_employees": -1,
"has_client_portal": true,
"has_offline_sync": true,
"is_active": true
}
}
Retrieve a single plan by ID.
{
"success": true,
"msg": "Subscription plans",
"data": {
"id": 2,
"name": "Pro",
"slug": "pro",
"monthly_price": 299,
"max_projects": -1,
"max_locations": -1,
"max_employees": -1,
"has_client_portal": true,
"has_offline_sync": true,
"is_active": true
}
}
Partial update on any plan field. Logs a plan_updated audit event on success.
{
"max_projects": -1,
"max_locations": -1,
"has_client_portal": true
}
{
"success": true,
"msg": "Updated",
"data": {
"id": 1,
"name": "Starter Tier",
"slug": "starter-tier",
"monthly_price": 49,
"max_projects": -1,
"max_locations": -1,
"max_employees": 10,
"has_client_portal": true,
"has_offline_sync": false,
"is_active": true
}
}
Hard-delete the plan if no tenants are assigned. If tenants exist, deactivates the plan instead and returns 422 with error: "tenants_assigned" — this is a safe degradation, not a failure.
{
"success": true,
"msg": "Deleted",
"data": {
"id": 3
}
}
{
"success": false,
"msg": "Plan has assigned tenants; deactivated instead of deleted",
"error": "tenants_assigned",
"data": {
"id": 2,
"name": "Pro",
"slug": "pro",
"monthly_price": 299,
"max_projects": -1,
"max_locations": -1,
"max_employees": -1,
"has_client_portal": true,
"has_offline_sync": true,
"is_active": false
}
}
Audit Events (Platform Notifications)
Paginated audit event log. Events are ordered newest-first. Filter by read status or category. Supports text search across title, body, and event code.
| Param | Type | Description |
|---|---|---|
| is_read | boolean | 0/false = unread only, 1/true = read only |
| category | string | tenant_created | tenant_updated | tenant_suspended | plan_created | plan_updated |
| search | string | Searches title, body, event_code (EVT-xxxxx) |
| per_page | integer | Default 20 |
{
"success": true,
"msg": "Platform notifications",
"data": [
{
"id": 1,
"event_code": "EVT-00001",
"category": "tenant_created",
"severity": "info",
"title": "New Tenant Registration",
"body": "BuildCorp Pakistan signed up for the Pro tier.",
"entity_type": "business",
"entity_id": 3,
"actor_user_id": 1,
"actor_name": "superadmin",
"metadata": {
"business_name": "BuildCorp Pakistan",
"plan_name": "Pro"
},
"is_read": false,
"created_at": "2026-06-20T10:15:01+00:00"
}
],
"pagination": {
"current_page": 1,
"per_page": 20,
"total": 1,
"last_page": 1
}
}
Retrieve a single audit event.
{
"success": true,
"msg": "Platform notifications",
"data": {
"id": 1,
"event_code": "EVT-00001",
"category": "tenant_created",
"severity": "info",
"title": "New Tenant Registration",
"body": "BuildCorp Pakistan signed up for the Pro tier.",
"entity_type": "business",
"entity_id": 3,
"actor_user_id": 1,
"actor_name": "superadmin",
"metadata": {
"business_name": "BuildCorp Pakistan",
"plan_name": "Pro"
},
"is_read": false,
"created_at": "2026-06-20T10:15:01+00:00"
}
}
Mark a single audit event as read. No request body required.
{
"success": true,
"msg": "Marked read",
"data": {
"id": 1,
"is_read": true
}
}
Mark all unread audit events as read in a single operation.
{
"success": true,
"msg": "All marked read",
"data": {
"success": true
}
}
Permanently delete a single audit event.
{
"success": true,
"msg": "Deleted",
"data": null
}