A person represents a natural person (applicant, guarantor, contact, etc.) inside an enterprise. The V2 endpoints are effectively read-only: store, update, and destroy routes exist but always return 403 Forbidden because their form requests use App\Http\Requests\Api\V2\Concerns\DeniesAccess.
Attributes
The shape returned by App\Http\Resources\V2\PersonResource::toArray():
| Attribute | Type | Description |
|---|---|---|
id |
string (UUID) | Stable public identifier. |
enterprise_id |
string (UUID) | null | UUID of the owning enterprise. |
title |
string | null | Title (e.g. Mr, Ms, Dr). |
first_name |
string | null | First name (PII, encrypted at rest). |
middle_name |
string | null | Middle name. |
last_name |
string | null | Last name. |
salutation |
string | null | Preferred salutation. |
maiden_name |
string | null | Maiden name. |
birthday |
string | null (date) | Date of birth. |
gender |
string | null | Gender label. |
licence |
string | null | Driver's licence number. |
licence_card |
string | null | Driver's licence card number. |
licence_state |
string | null | Licence-issuing state name (licenceState->name). |
licence_expiry |
string | null (date) | Licence expiry date. |
dependents |
integer | null | Number of dependents. |
dependents_ages |
string | null | Free-text ages of dependents. |
marital_status |
string | null | Marital-status label (maritalStatus->name). |
residency_status |
string | null | Residency-status label (residencyStatus->name). |
created_at |
string (ISO 8601) | Record creation timestamp. |
updated_at |
string (ISO 8601) | Record updated timestamp. |
phone_numbers |
object | NumbersResource collection — see Nested resources. |
emails |
object | EmailsResource collection. |
addresses |
object | AddressesResource collection. |
financials |
object | FinancialsResource collection. Only rows with amount > 0 are included. |
Nested resources
Each nested collection envelopes its rows under a data key.
phone_numbers[].* — NumberResource:
| Field | Type | Description |
|---|---|---|
id |
string (UUID) | Identifier of the phone-number row. |
type |
string | Type, capitalised via ucfirst() (e.g. Mobile). |
number |
string | Phone number as stored. |
is_primary |
boolean | True when primary == 1. |
created_at / updated_at |
string (ISO 8601) | Timestamps. |
emails[].* — EmailResource:
| Field | Type | Description |
|---|---|---|
id |
string (UUID) | Identifier of the email row. |
address |
string | Email address. |
is_primary |
boolean | True when primary == 1. |
created_at / updated_at |
string (ISO 8601) | Timestamps. |
addresses[].* — AddressResource:
| Field | Type | Description |
|---|---|---|
id |
string (UUID) | Identifier of the address row. |
type |
string | null | Address-type label (addressType->name). |
address |
string | null | Single-line composed address (line column). |
line1 / line2 / line3 |
string | null | Individual address lines. |
suburb |
string | null | Suburb. |
state |
string | null | State name (state->name). |
postcode |
string | null | Postcode. |
created_at / updated_at |
string (ISO 8601) | Timestamps. |
financials[].* — FinancialResource:
| Field | Type | Description |
|---|---|---|
id |
string (UUID) | Identifier of the financial row. |
type |
string | Type, capitalised via ucfirst() (e.g. Income, Expense). |
amount |
string (decimal) | Amount as stored. |
category |
string | null | Category label, title-cased via ucwords(). |
created_at / updated_at |
string (ISO 8601) | Timestamps. |
List people
GET /api/v2/people
Returns a paginated list of people belonging to the enterprise identified by X-Enterprise-Id. Page size is fixed at 100. Eager loads the team relation.
Responses
200— paginatedPeopleResourcecollection.403 Forbidden— caller is not a member of the enterprise.
Retrieve a person
GET /api/v2/people/{person:uuid}
Responses
200— singlePersonResourceenvelope.403 Forbidden— caller is not a member of the enterprise or the person'steam_iddoes not match.
Create a person
POST /api/v2/people
StorePersonRequest uses the DeniesAccess trait, so this endpoint always returns 403 Forbidden with body { "message": "Forbidden" }. The route is wired for parity with V1 but write access has not been enabled.
Update a person
PUT /api/v2/people/{person:uuid}
UpdatePersonRequest uses the DeniesAccess trait — always returns 403 Forbidden.
Delete a person
DELETE /api/v2/people/{person:uuid}
DestroyPersonRequest uses the DeniesAccess trait — always returns 403 Forbidden.
V2 differences — Although the write endpoints currently deny access, every V2 request body passes through
App\Http\Middleware\NormalizeApiInput, which snake-cases keys before validation. When write support is opened up, you can sendFirstName,firstName, orfirst_nameand they will all reach the validator asfirst_name. Submitting two casings of the same key in one payload causes the later one in the JSON to win.