openapi: 3.0.3
info:
title: 'Finweb API API Documentation'
description: ''
version: 1.0.0
servers:
-
url: 'https://dev.api.finweb.group'
tags:
-
name: 'Broker Sync'
description: ''
-
name: Endpoints
description: ''
-
name: 'Zoho CRM'
description: ''
paths:
/api/admin/brokers/sync:
post:
summary: 'Manually sync brokers from Zoho CRM.'
operationId: manuallySyncBrokersFromZohoCRM
description: ''
parameters: []
responses:
202:
description: ''
content:
application/json:
schema:
type: object
example:
data:
message: 'Zoho broker sync queued.'
properties:
data:
type: object
properties:
message:
type: string
example: 'Zoho broker sync queued.'
tags:
- 'Broker Sync'
/api/admin/brokers/sync-status:
get:
summary: 'Get latest broker sync status.'
operationId: getLatestBrokerSyncStatus
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
id: 1
broker_id: null
action: zoho.sync
status: success
source_system: zoho
message: 'Zoho broker sync completed.'
created_at: '2026-04-09T10:12:30Z'
properties:
data:
type: object
properties:
id:
type: integer
example: 1
broker_id:
type: string
example: null
nullable: true
action:
type: string
example: zoho.sync
status:
type: string
example: success
source_system:
type: string
example: zoho
message:
type: string
example: 'Zoho broker sync completed.'
created_at:
type: string
example: '2026-04-09T10:12:30Z'
tags:
- 'Broker Sync'
/api/admin/brokers/sync-logs:
get:
summary: 'Get Zoho sync logs.'
operationId: getZohoSyncLogs
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
-
id: 1
broker_id: null
action: zoho.sync
status: success
source_system: zoho
message: 'Zoho broker sync completed.'
created_at: '2026-04-09T10:12:30Z'
properties:
data:
type: array
example:
-
id: 1
broker_id: null
action: zoho.sync
status: success
source_system: zoho
message: 'Zoho broker sync completed.'
created_at: '2026-04-09T10:12:30Z'
items:
type: object
properties:
id:
type: integer
example: 1
broker_id:
type: string
example: null
nullable: true
action:
type: string
example: zoho.sync
status:
type: string
example: success
source_system:
type: string
example: zoho
message:
type: string
example: 'Zoho broker sync completed.'
created_at:
type: string
example: '2026-04-09T10:12:30Z'
tags:
- 'Broker Sync'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 1
nullable: true
'/api/admin/brokers/{broker_id}/logs':
get:
summary: 'Get broker logs.'
operationId: getBrokerLogs
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
-
id: 1
broker_id: 5
action: zoho.sync.record
status: success
source_system: zoho
message: 'Zoho broker record updated.'
created_at: '2026-04-09T10:12:30Z'
properties:
data:
type: array
example:
-
id: 1
broker_id: 5
action: zoho.sync.record
status: success
source_system: zoho
message: 'Zoho broker record updated.'
created_at: '2026-04-09T10:12:30Z'
items:
type: object
properties:
id:
type: integer
example: 1
broker_id:
type: integer
example: 5
action:
type: string
example: zoho.sync.record
status:
type: string
example: success
source_system:
type: string
example: zoho
message:
type: string
example: 'Zoho broker record updated.'
created_at:
type: string
example: '2026-04-09T10:12:30Z'
tags:
- 'Broker Sync'
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 1
nullable: true
parameters:
-
in: path
name: broker_id
description: 'The ID of the broker.'
example: 16
required: true
schema:
type: integer
/api/register:
post:
summary: ''
operationId: postApiRegister
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: zbailey@example.net
password:
type: string
description: 'Must be at least 8 characters.'
example: '-0pBNvYgxw'
required:
- name
- email
- password
security: []
/api/login:
post:
summary: 'Sign in with email and password.'
operationId: signInWithEmailAndPassword
description: "Returns a bearer token for direct sign-in, or a temporary two-step verification challenge when\nthe account has authenticator-based 2-step verification enabled."
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
oneOf:
-
description: 'Direct sign-in'
type: object
example:
token: 1|sanctum-token
two_factor_required: false
challenge_token: null
next_path: '/brokers?page=2'
user:
id: 1
name: 'Finweb Admin'
email: admin@finweb.com.au
role: admin
permissions:
- 'dashboard:view'
- 'brokers:view'
active: true
approved: true
must_change_password: false
properties:
token:
type: string
example: 1|sanctum-token
two_factor_required:
type: boolean
example: false
challenge_token:
type: string
example: null
nullable: true
next_path:
type: string
example: '/brokers?page=2'
user:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'Finweb Admin'
email:
type: string
example: admin@finweb.com.au
role:
type: string
example: admin
permissions:
type: array
example:
- 'dashboard:view'
- 'brokers:view'
items:
type: string
active:
type: boolean
example: true
approved:
type: boolean
example: true
must_change_password:
type: boolean
example: false
-
description: 'Two-step verification required'
type: object
example:
two_factor_required: true
challenge_token: login-2fa-challenge-token
next_path: '/brokers?page=2'
user:
id: 1
name: 'Finweb Admin'
email: admin@finweb.com.au
role: admin
permissions:
- 'dashboard:view'
- 'brokers:view'
active: true
approved: true
must_change_password: false
properties:
two_factor_required:
type: boolean
example: true
challenge_token:
type: string
example: login-2fa-challenge-token
next_path:
type: string
example: '/brokers?page=2'
user:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'Finweb Admin'
email:
type: string
example: admin@finweb.com.au
role:
type: string
example: admin
permissions:
type: array
example:
- 'dashboard:view'
- 'brokers:view'
items:
type: string
active:
type: boolean
example: true
approved:
type: boolean
example: true
must_change_password:
type: boolean
example: false
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: 'Portal account email.'
example: admin@finweb.com.au
password:
type: string
description: 'Portal account password.'
example: Finweb@2026
remember:
type: boolean
description: 'Optional Remember-me flag for future use.'
example: true
next:
type: string
description: 'Optional Intended portal path to continue to after sign-in.'
example: '/brokers?page=2'
nullable: true
required:
- email
- password
security: []
/api/auth/two-factor/verify-login:
post:
summary: 'Complete sign-in with a 2-step verification code.'
operationId: completeSignInWithA2StepVerificationCode
description: 'Exchanges a temporary login challenge plus a valid 6-digit authenticator code for the final portal token.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Two-step verification complete.'
data:
token: 1|sanctum-token
next_path: '/brokers?page=2'
user:
id: 1
name: 'Finweb Admin'
email: admin@finweb.com.au
role: admin
permissions:
- 'dashboard:view'
- 'brokers:view'
active: true
approved: true
must_change_password: false
properties:
message:
type: string
example: 'Two-step verification complete.'
data:
type: object
properties:
token:
type: string
example: 1|sanctum-token
next_path:
type: string
example: '/brokers?page=2'
user:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'Finweb Admin'
email:
type: string
example: admin@finweb.com.au
role:
type: string
example: admin
permissions:
type: array
example:
- 'dashboard:view'
- 'brokers:view'
items:
type: string
active:
type: boolean
example: true
approved:
type: boolean
example: true
must_change_password:
type: boolean
example: false
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
challenge_token:
type: string
description: 'Challenge token returned by /api/login or /api/google/auth/callback.'
example: login-2fa-challenge-token
code:
type: string
description: '6-digit authenticator code.'
example: '123456'
required:
- challenge_token
- code
security: []
/api/google/auth/url:
get:
summary: 'Get the Google OAuth authorization URL.'
operationId: getTheGoogleOAuthAuthorizationURL
description: ''
parameters:
-
in: query
name: context
description: 'Either `login` or `onboarding`.'
example: login
required: true
schema:
type: string
description: 'Either `login` or `onboarding`.'
example: login
-
in: query
name: token
description: 'Optional Broker invite token for onboarding mode.'
example: architecto
required: false
schema:
type: string
description: 'Optional Broker invite token for onboarding mode.'
example: architecto
-
in: query
name: next
description: 'Optional Intended portal path for login mode.'
example: '/brokers?page=2'
required: false
schema:
type: string
description: 'Optional Intended portal path for login mode.'
example: '/brokers?page=2'
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
url: 'https://accounts.google.com/o/oauth2/v2/auth?...'
properties:
data:
type: object
properties:
url:
type: string
example: 'https://accounts.google.com/o/oauth2/v2/auth?...'
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
context:
type: string
description: ''
example: login
enum:
- login
- onboarding
token:
type: string
description: ''
example: architecto
nullable: true
next:
type: string
description: ''
example: architecto
nullable: true
required:
- context
security: []
/api/google/auth/callback:
post:
summary: 'Complete the Google OAuth callback.'
operationId: completeTheGoogleOAuthCallback
description: 'The callback can return a direct bearer token, a two-step verification challenge, or an onboarding handoff.'
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
oneOf:
-
description: 'Direct login'
type: object
example:
message: 'Signed in with Google.'
data:
mode: login
next_path: /dashboard
token: 1|sanctum-token
user:
id: 1
name: 'Finweb Admin'
email: admin@finweb.com.au
role: admin
permissions:
- 'dashboard:view'
active: true
approved: true
must_change_password: false
properties:
message:
type: string
example: 'Signed in with Google.'
data:
type: object
properties:
mode:
type: string
example: login
next_path:
type: string
example: /dashboard
token:
type: string
example: 1|sanctum-token
user:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'Finweb Admin'
email:
type: string
example: admin@finweb.com.au
role:
type: string
example: admin
permissions:
type: array
example:
- 'dashboard:view'
items:
type: string
active:
type: boolean
example: true
approved:
type: boolean
example: true
must_change_password:
type: boolean
example: false
-
description: 'Two-step verification required'
type: object
example:
message: 'Google sign-in confirmed. Complete 2-step verification to continue.'
data:
mode: login
next_path: /dashboard
two_factor_required: true
challenge_token: login-2fa-challenge-token
user:
id: 1
name: 'Finweb Admin'
email: admin@finweb.com.au
role: admin
permissions:
- 'dashboard:view'
active: true
approved: true
must_change_password: false
properties:
message:
type: string
example: 'Google sign-in confirmed. Complete 2-step verification to continue.'
data:
type: object
properties:
mode:
type: string
example: login
next_path:
type: string
example: /dashboard
two_factor_required:
type: boolean
example: true
challenge_token:
type: string
example: login-2fa-challenge-token
user:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'Finweb Admin'
email:
type: string
example: admin@finweb.com.au
role:
type: string
example: admin
permissions:
type: array
example:
- 'dashboard:view'
items:
type: string
active:
type: boolean
example: true
approved:
type: boolean
example: true
must_change_password:
type: boolean
example: false
-
description: 'Onboarding handoff'
type: object
example:
message: 'Google account linked. Finish onboarding by setting a password.'
data:
mode: onboarding
next_path: '/onboarding?token=invite-token&google_linked=1'
properties:
message:
type: string
example: 'Google account linked. Finish onboarding by setting a password.'
data:
type: object
properties:
mode:
type: string
example: onboarding
next_path:
type: string
example: '/onboarding?token=invite-token&google_linked=1'
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
code:
type: string
description: 'Google authorization code.'
example: 4/0AdQt8q...
state:
type: string
description: 'Encrypted OAuth state returned by Google.'
example: eyJpdiI6Ii4uLiJ9
required:
- code
- state
security: []
/api/portal-onboarding/validate:
get:
summary: ''
operationId: getApiPortalOnboardingValidate
description: ''
parameters: []
responses:
422:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'This onboarding link is invalid.'
code: invalid_token
properties:
message:
type: string
example: 'This onboarding link is invalid.'
code:
type: string
example: invalid_token
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: 'Must be at least 32 characters.'
example: bngzmiyvdljnikhwaykcmyuwpwlvqwrsitcpscqldzsnrwtujwvlxjklqppwqbewtnn
required:
- token
security: []
/api/portal-onboarding/set-password:
post:
summary: ''
operationId: postApiPortalOnboardingSetPassword
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: 'Must be at least 32 characters.'
example: bngzmiyvdljnikhwaykcmyuwpwlvqwrsitcpscqldzsnrwtujwvlxjklqppwqbewtnn
password:
type: string
description: 'Must be at least 8 characters.'
example: 'Ou.*,JH'
required:
- token
- password
security: []
/api/auth/password-reset/request:
post:
summary: ''
operationId: postApiAuthPasswordResetRequest
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: 'Must be a valid email address.'
example: gbailey@example.net
required:
- email
security: []
/api/auth/account-recovery/request:
post:
summary: ''
operationId: postApiAuthAccountRecoveryRequest
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: 'Must be a valid email address.'
example: gbailey@example.net
required:
- email
security: []
/api/auth/password-reset/complete:
post:
summary: ''
operationId: postApiAuthPasswordResetComplete
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: 'Must be a valid email address.'
example: gbailey@example.net
token:
type: string
description: ''
example: architecto
password:
type: string
description: 'Must be at least 8 characters.'
example: ']|{+-0pBNvYg'
required:
- email
- token
- password
security: []
/api/auth/account-recovery/complete:
post:
summary: ''
operationId: postApiAuthAccountRecoveryComplete
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: ''
example: architecto
password:
type: string
description: 'Must be at least 8 characters.'
example: ']|{+-0pBNvYg'
required:
- token
- password
security: []
/api/auth/recovery-email/verify:
post:
summary: ''
operationId: postApiAuthRecoveryEmailVerify
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: ''
example: architecto
required:
- token
security: []
/api/join-us:
post:
summary: ''
operationId: postApiJoinUs
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
first_name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
last_name:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: ashly64@example.com
mobile:
type: string
description: 'Must not be greater than 50 characters.'
example: v
nullable: true
state:
type: string
description: 'Must not be greater than 50 characters.'
example: d
nullable: true
enquiry_type:
type: string
description: 'Must not be greater than 120 characters.'
example: l
message:
type: string
description: ''
example: architecto
nullable: true
source:
type: string
description: 'Must not be greater than 100 characters.'
example: 'n'
nullable: true
required:
- first_name
- last_name
- email
- enquiry_type
security: []
/api/get-in-touch:
post:
summary: ''
operationId: postApiGetInTouch
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
enquiry_type:
type: string
description: 'Must not be greater than 120 characters.'
example: b
nullable: true
name:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: ashly64@example.com
message:
type: string
description: ''
example: architecto
nullable: true
source:
type: string
description: 'Must not be greater than 100 characters.'
example: 'n'
nullable: true
required:
- name
- email
security: []
/api/auth/account-recovery/validate:
get:
summary: ''
operationId: getApiAuthAccountRecoveryValidate
description: ''
parameters: []
responses:
422:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'This account recovery link is invalid or expired.'
errors:
token:
- 'This account recovery link is invalid or expired.'
properties:
message:
type: string
example: 'This account recovery link is invalid or expired.'
errors:
type: object
properties:
token:
type: array
example:
- 'This account recovery link is invalid or expired.'
items:
type: string
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: ''
example: architecto
required:
- token
security: []
/api/auth/password-reset/validate:
get:
summary: ''
operationId: getApiAuthPasswordResetValidate
description: ''
parameters: []
responses:
422:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'This password reset link is invalid or expired.'
errors:
token:
- 'This password reset link is invalid or expired.'
properties:
message:
type: string
example: 'This password reset link is invalid or expired.'
errors:
type: object
properties:
token:
type: array
example:
- 'This password reset link is invalid or expired.'
items:
type: string
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
description: 'Must be a valid email address.'
example: gbailey@example.net
token:
type: string
description: ''
example: architecto
required:
- email
- token
security: []
/api/auth/recovery-email/validate:
get:
summary: ''
operationId: getApiAuthRecoveryEmailValidate
description: ''
parameters: []
responses:
422:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'This recovery email verification link is invalid or expired.'
errors:
token:
- 'This recovery email verification link is invalid or expired.'
properties:
message:
type: string
example: 'This recovery email verification link is invalid or expired.'
errors:
type: object
properties:
token:
type: array
example:
- 'This recovery email verification link is invalid or expired.'
items:
type: string
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: ''
example: architecto
required:
- token
security: []
'/api/cpd-records/{cpdRecord_id}/image':
get:
summary: ''
operationId: getApiCpdRecordsCpdRecord_idImage
description: ''
parameters: []
responses:
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'No query results for model [App\Models\CpdRecord] 16'
properties:
message:
type: string
example: 'No query results for model [App\Models\CpdRecord] 16'
tags:
- Endpoints
security: []
parameters:
-
in: path
name: cpdRecord_id
description: 'The ID of the cpdRecord.'
example: 16
required: true
schema:
type: integer
/api/awards:
get:
summary: ''
operationId: getApiAwards
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
-
id: 1
title: 'ABA 2024 - Boutique Aggregator of the Year'
logo_url: null
sort_order: 10
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 2
title: 'MFAA 2025 National Winner - Mentor Program Award'
logo_url: null
sort_order: 20
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 3
title: 'AMA 2024 - Excellence in Broker Support'
logo_url: null
sort_order: 30
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 4
title: 'Industry Excellence - Broker Network Growth'
logo_url: null
sort_order: 40
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
properties:
data:
type: array
example:
-
id: 1
title: 'ABA 2024 - Boutique Aggregator of the Year'
logo_url: null
sort_order: 10
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 2
title: 'MFAA 2025 National Winner - Mentor Program Award'
logo_url: null
sort_order: 20
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 3
title: 'AMA 2024 - Excellence in Broker Support'
logo_url: null
sort_order: 30
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 4
title: 'Industry Excellence - Broker Network Growth'
logo_url: null
sort_order: 40
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
items:
type: object
properties:
id:
type: integer
example: 1
title:
type: string
example: 'ABA 2024 - Boutique Aggregator of the Year'
logo_url:
type: string
example: null
nullable: true
sort_order:
type: integer
example: 10
is_active:
type: boolean
example: true
created_at:
type: string
example: '2026-07-31T01:51:48.000000Z'
updated_at:
type: string
example: '2026-07-31T01:51:48.000000Z'
tags:
- Endpoints
security: []
/api/brokers:
get:
summary: ''
operationId: getApiBrokers
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data: []
properties:
data:
type: array
example: []
tags:
- Endpoints
security: []
'/api/brokers/{slug}':
get:
summary: ''
operationId: getApiBrokersSlug
description: ''
parameters: []
responses:
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Broker not found.'
properties:
message:
type: string
example: 'Broker not found.'
tags:
- Endpoints
security: []
parameters:
-
in: path
name: slug
description: 'The slug of the broker.'
example: 16
required: true
schema:
type: integer
/api/broker-partners:
get:
summary: ''
operationId: getApiBrokerPartners
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data: []
properties:
data:
type: array
example: []
tags:
- Endpoints
security: []
/api/insights:
get:
summary: ''
operationId: getApiInsights
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
-
id: 1
title: 'A new face for finweb: sharper, quieter, more confident'
slug: new-finweb-website-face
published_at: '2026-04-17'
excerpt: 'Our new website direction is designed to feel more premium, more deliberate, and more aligned with the calibre of brokers we support.'
body: "finweb has introduced a more refined website direction built around clarity, confidence and a calmer premium feel.\n\nRather than chasing noise, the new experience focuses on stronger hierarchy, cleaner spacing and more intentional storytelling across broker profiles, services and editorial content.\n\nThis update is not just a visual refresh. It is a positioning move. Every section is being shaped to better reflect the quality of the network, the professionalism of our brokers and the kind of trust clients expect when they engage with a serious mortgage brand.\n\nKey changes in the new website direction include:\n- cleaner page structure with better pacing between sections\n- more premium visual language across cards, typography and motion\n- stronger broker profile presentation with clearer CRM-aligned visibility rules\n- more editorial insight layouts so updates feel like a publication, not a noticeboard\n- a better foundation for future services, broker onboarding and growth content\n\nThe result is a digital presence that feels more composed, more exclusive and more aligned with the next chapter of finweb."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 2
title: 'How to get your first 10 clients as a new mortgage broker.'
slug: how-to-get-your-first-10-clients-as-a-new-mortgage-broker
published_at: '2025-06-02'
excerpt: 'Most new brokers do not struggle because they are bad at loans. They struggle because not enough people know they exist. Here is what actually works in the first 90 days.'
body: "The most common mistake I see from new brokers is spending the first few months getting ready. Tweaking the logo. Perfecting the website. Waiting until the business cards arrive. I understand the impulse. It feels productive. But none of that creates clients.\n\nClients come from conversations. And the sooner you accept that, the sooner things start to move.\n\nIf I wanted to get my first 10 clients quickly, I would focus on five practical things.\n\nFirst, pick a clear target market. \"I help everyone with home loans\" is the fastest way to be forgettable. First home buyers, self-employed borrowers, investors, young families, business owners. The more specific your message, the easier it is for people to remember you and refer you.\n\nSecond, start with your warm network, but do not beg for business. Your job is to tell people clearly what you do, who you help and what situations you solve. Something simple works: \"I am helping people review their home loans and understand their options. If you hear someone mention buying, refinancing or feeling unsure about their lender, I would love an introduction.\"\n\nThird, create useful educational content. You do not need to go viral. You need to answer real questions. Borrowing capacity, deposits, refinancing, fixed-rate roll-offs, guarantor loans and common pre-approval mistakes are all strong early content topics because they build trust before a client speaks to you.\n\nFourth, build referral relationships early. Accountants, real estate agents, buyer's agents, conveyancers, financial planners and family lawyers all speak to people who need brokers. Focus on value, follow-up and trust rather than pushing for referrals too soon.\n\nFifth, run a daily prospecting rhythm. Conversations, follow-ups, content, referral outreach and CRM discipline matter more than aesthetics in the first 90 days. If you do enough of the right activity consistently, your first 10 clients become far more predictable.\n\nThe brokers who get moving fastest are not always the most experienced. They are the ones willing to be visible, useful and consistent long before things feel polished."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 3
title: 'If I was starting again as a broker, here is what I would do differently.'
slug: if-i-was-starting-again-as-a-broker-here-is-what-i-would-do-differently
published_at: '2025-06-01'
excerpt: 'Being new is not the problem. Being vague is. If I was starting again, this is the structure I would build from day one.'
body: "A lot of new brokers think they need experience before they can get clients. They do not. They need focus, volume and a simple reason to talk to people.\n\nIf I was starting again as a broker, I would not waste months trying to look established before I had any momentum. I would build activity before I built polish.\n\nThe first thing I would do is choose one niche and commit to it. First home buyers. Investors. Small business owners. Self-employed clients. One audience, one set of problems, one sharper message. The moment you narrow your focus, referrals make more sense and your marketing becomes easier to remember.\n\nThe second thing I would do is build a list before I built a brand. Past colleagues, business owners, property owners, family, friends, solicitors, accountants and local operators. Not because every one of them will become a client, but because every broker needs volume at the top of the funnel before they need a perfect website.\n\nThe third thing I would do is create a valuable reason to reach out. Market updates. Rate changes. New lender policy. A practical explanation of what is happening in the market. People respond to useful information more readily than to a cold sales pitch.\n\nThe fourth thing I would do is commit to daily outreach. Calls, emails, messages, follow-ups and relationship-building are not optional extras. They are the work. Momentum in broking comes from repeated, useful contact over time.\n\nAnd finally, I would document and share what I was learning. New brokers often feel like they need to wait until they are experts before they speak. They do not. Sharing useful observations, client questions and lessons from the field helps people understand your value before they ever enquire.\n\nIf I was starting again, I would focus less on looking ready and more on having enough conversations for the market to notice I was there."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 4
title: 'Why most new brokers struggle in year one, and what actually helps.'
slug: why-most-new-brokers-struggle-in-year-one-and-what-actually-helps
published_at: '2025-05-01'
excerpt: 'The things that hold new brokers back are rarely just about loans. They are about pipeline, confidence, support and the business itself.'
body: "When a new broker joins finweb, one of the first conversations we have is about where they are actually stuck. After doing that with enough brokers, the patterns become obvious.\n\nThe first reason most brokers struggle is simple: nobody really taught them how to get clients. Formal qualifications teach the mechanics of writing a loan. They do not teach you how to build a business, create demand or manage your own pipeline with confidence.\n\nThe second reason is that they underestimate how long the pipeline takes to mature. A broker can be doing the right things and still feel like nothing is happening, simply because the work from month one does not show up in settlements until much later.\n\nThe third reason is that they try to carry too much alone. Loan processing, compliance, client management, business development, follow-up and admin all land on one person. That creates fatigue quickly and usually slows the exact activities that bring in business.\n\nThe fourth reason is that they do not ask for help early enough. This is cultural as much as practical. Many new brokers assume they should already know the answer or that asking a question makes them look unready. In reality, the best-supported brokers ask earlier, learn faster and avoid more costly mistakes.\n\nWhat actually helps is a support structure that meets the real gaps. Mentoring that covers scenarios and business decisions. Processing support that protects time. Training that applies directly to current work. A community where asking questions is normal. And enough accountability that activity stays consistent while confidence catches up.\n\nYear one is rarely easy. But it becomes much more manageable when the support around the broker is built for the reality of the work, not the theory of it."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 5
title: 'What separates a good broker group from a great one.'
slug: what-separates-a-good-broker-group-from-a-great-one
published_at: '2025-04-01'
excerpt: 'The difference is rarely just lender access. Great broker groups combine support, standards, commercial usefulness and a community that actually feels real.'
body: "A lot of broker groups can offer the basics. A panel. A CRM. Compliance. A logo. That might be enough to make a group look competent from a distance. But it is not what makes the experience meaningfully different for the broker inside it.\n\nWhat separates a good broker group from a great one is the quality and consistency of support when the real work is happening.\n\nA great group makes mentoring accessible, not theoretical. It means a broker can ask a scenario question when they need it, pressure-test a deal structure before it becomes a problem and get practical answers from people who understand the commercial reality of broking.\n\nA great group also removes friction. Processing support, compliance guidance, usable systems and operational follow-through matter because they give brokers back time and decision-making capacity. Without that, even good brokers lose momentum under admin weight.\n\nThen there is the commercial layer. The right structure should help brokers grow, not make them feel boxed in. That includes transparent models, useful business coaching and an environment where the support feels aligned to the broker's stage rather than forced into one generic shape.\n\nAnd finally, a great group feels human. People know one another. Questions get answered. Wins get shared. The community is not a marketing line; it is part of why the group works.\n\nThe brokers who stay long term usually do not stay because of one headline feature. They stay because the whole environment makes the business easier to build well."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
properties:
data:
type: array
example:
-
id: 1
title: 'A new face for finweb: sharper, quieter, more confident'
slug: new-finweb-website-face
published_at: '2026-04-17'
excerpt: 'Our new website direction is designed to feel more premium, more deliberate, and more aligned with the calibre of brokers we support.'
body: "finweb has introduced a more refined website direction built around clarity, confidence and a calmer premium feel.\n\nRather than chasing noise, the new experience focuses on stronger hierarchy, cleaner spacing and more intentional storytelling across broker profiles, services and editorial content.\n\nThis update is not just a visual refresh. It is a positioning move. Every section is being shaped to better reflect the quality of the network, the professionalism of our brokers and the kind of trust clients expect when they engage with a serious mortgage brand.\n\nKey changes in the new website direction include:\n- cleaner page structure with better pacing between sections\n- more premium visual language across cards, typography and motion\n- stronger broker profile presentation with clearer CRM-aligned visibility rules\n- more editorial insight layouts so updates feel like a publication, not a noticeboard\n- a better foundation for future services, broker onboarding and growth content\n\nThe result is a digital presence that feels more composed, more exclusive and more aligned with the next chapter of finweb."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 2
title: 'How to get your first 10 clients as a new mortgage broker.'
slug: how-to-get-your-first-10-clients-as-a-new-mortgage-broker
published_at: '2025-06-02'
excerpt: 'Most new brokers do not struggle because they are bad at loans. They struggle because not enough people know they exist. Here is what actually works in the first 90 days.'
body: "The most common mistake I see from new brokers is spending the first few months getting ready. Tweaking the logo. Perfecting the website. Waiting until the business cards arrive. I understand the impulse. It feels productive. But none of that creates clients.\n\nClients come from conversations. And the sooner you accept that, the sooner things start to move.\n\nIf I wanted to get my first 10 clients quickly, I would focus on five practical things.\n\nFirst, pick a clear target market. \"I help everyone with home loans\" is the fastest way to be forgettable. First home buyers, self-employed borrowers, investors, young families, business owners. The more specific your message, the easier it is for people to remember you and refer you.\n\nSecond, start with your warm network, but do not beg for business. Your job is to tell people clearly what you do, who you help and what situations you solve. Something simple works: \"I am helping people review their home loans and understand their options. If you hear someone mention buying, refinancing or feeling unsure about their lender, I would love an introduction.\"\n\nThird, create useful educational content. You do not need to go viral. You need to answer real questions. Borrowing capacity, deposits, refinancing, fixed-rate roll-offs, guarantor loans and common pre-approval mistakes are all strong early content topics because they build trust before a client speaks to you.\n\nFourth, build referral relationships early. Accountants, real estate agents, buyer's agents, conveyancers, financial planners and family lawyers all speak to people who need brokers. Focus on value, follow-up and trust rather than pushing for referrals too soon.\n\nFifth, run a daily prospecting rhythm. Conversations, follow-ups, content, referral outreach and CRM discipline matter more than aesthetics in the first 90 days. If you do enough of the right activity consistently, your first 10 clients become far more predictable.\n\nThe brokers who get moving fastest are not always the most experienced. They are the ones willing to be visible, useful and consistent long before things feel polished."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 3
title: 'If I was starting again as a broker, here is what I would do differently.'
slug: if-i-was-starting-again-as-a-broker-here-is-what-i-would-do-differently
published_at: '2025-06-01'
excerpt: 'Being new is not the problem. Being vague is. If I was starting again, this is the structure I would build from day one.'
body: "A lot of new brokers think they need experience before they can get clients. They do not. They need focus, volume and a simple reason to talk to people.\n\nIf I was starting again as a broker, I would not waste months trying to look established before I had any momentum. I would build activity before I built polish.\n\nThe first thing I would do is choose one niche and commit to it. First home buyers. Investors. Small business owners. Self-employed clients. One audience, one set of problems, one sharper message. The moment you narrow your focus, referrals make more sense and your marketing becomes easier to remember.\n\nThe second thing I would do is build a list before I built a brand. Past colleagues, business owners, property owners, family, friends, solicitors, accountants and local operators. Not because every one of them will become a client, but because every broker needs volume at the top of the funnel before they need a perfect website.\n\nThe third thing I would do is create a valuable reason to reach out. Market updates. Rate changes. New lender policy. A practical explanation of what is happening in the market. People respond to useful information more readily than to a cold sales pitch.\n\nThe fourth thing I would do is commit to daily outreach. Calls, emails, messages, follow-ups and relationship-building are not optional extras. They are the work. Momentum in broking comes from repeated, useful contact over time.\n\nAnd finally, I would document and share what I was learning. New brokers often feel like they need to wait until they are experts before they speak. They do not. Sharing useful observations, client questions and lessons from the field helps people understand your value before they ever enquire.\n\nIf I was starting again, I would focus less on looking ready and more on having enough conversations for the market to notice I was there."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 4
title: 'Why most new brokers struggle in year one, and what actually helps.'
slug: why-most-new-brokers-struggle-in-year-one-and-what-actually-helps
published_at: '2025-05-01'
excerpt: 'The things that hold new brokers back are rarely just about loans. They are about pipeline, confidence, support and the business itself.'
body: "When a new broker joins finweb, one of the first conversations we have is about where they are actually stuck. After doing that with enough brokers, the patterns become obvious.\n\nThe first reason most brokers struggle is simple: nobody really taught them how to get clients. Formal qualifications teach the mechanics of writing a loan. They do not teach you how to build a business, create demand or manage your own pipeline with confidence.\n\nThe second reason is that they underestimate how long the pipeline takes to mature. A broker can be doing the right things and still feel like nothing is happening, simply because the work from month one does not show up in settlements until much later.\n\nThe third reason is that they try to carry too much alone. Loan processing, compliance, client management, business development, follow-up and admin all land on one person. That creates fatigue quickly and usually slows the exact activities that bring in business.\n\nThe fourth reason is that they do not ask for help early enough. This is cultural as much as practical. Many new brokers assume they should already know the answer or that asking a question makes them look unready. In reality, the best-supported brokers ask earlier, learn faster and avoid more costly mistakes.\n\nWhat actually helps is a support structure that meets the real gaps. Mentoring that covers scenarios and business decisions. Processing support that protects time. Training that applies directly to current work. A community where asking questions is normal. And enough accountability that activity stays consistent while confidence catches up.\n\nYear one is rarely easy. But it becomes much more manageable when the support around the broker is built for the reality of the work, not the theory of it."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 5
title: 'What separates a good broker group from a great one.'
slug: what-separates-a-good-broker-group-from-a-great-one
published_at: '2025-04-01'
excerpt: 'The difference is rarely just lender access. Great broker groups combine support, standards, commercial usefulness and a community that actually feels real.'
body: "A lot of broker groups can offer the basics. A panel. A CRM. Compliance. A logo. That might be enough to make a group look competent from a distance. But it is not what makes the experience meaningfully different for the broker inside it.\n\nWhat separates a good broker group from a great one is the quality and consistency of support when the real work is happening.\n\nA great group makes mentoring accessible, not theoretical. It means a broker can ask a scenario question when they need it, pressure-test a deal structure before it becomes a problem and get practical answers from people who understand the commercial reality of broking.\n\nA great group also removes friction. Processing support, compliance guidance, usable systems and operational follow-through matter because they give brokers back time and decision-making capacity. Without that, even good brokers lose momentum under admin weight.\n\nThen there is the commercial layer. The right structure should help brokers grow, not make them feel boxed in. That includes transparent models, useful business coaching and an environment where the support feels aligned to the broker's stage rather than forced into one generic shape.\n\nAnd finally, a great group feels human. People know one another. Questions get answered. Wins get shared. The community is not a marketing line; it is part of why the group works.\n\nThe brokers who stay long term usually do not stay because of one headline feature. They stay because the whole environment makes the business easier to build well."
image_url: null
button_text: 'Read more'
button_url: null
link_type: internal
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
items:
type: object
properties:
id:
type: integer
example: 1
title:
type: string
example: 'A new face for finweb: sharper, quieter, more confident'
slug:
type: string
example: new-finweb-website-face
published_at:
type: string
example: '2026-04-17'
excerpt:
type: string
example: 'Our new website direction is designed to feel more premium, more deliberate, and more aligned with the calibre of brokers we support.'
body:
type: string
example: "finweb has introduced a more refined website direction built around clarity, confidence and a calmer premium feel.\n\nRather than chasing noise, the new experience focuses on stronger hierarchy, cleaner spacing and more intentional storytelling across broker profiles, services and editorial content.\n\nThis update is not just a visual refresh. It is a positioning move. Every section is being shaped to better reflect the quality of the network, the professionalism of our brokers and the kind of trust clients expect when they engage with a serious mortgage brand.\n\nKey changes in the new website direction include:\n- cleaner page structure with better pacing between sections\n- more premium visual language across cards, typography and motion\n- stronger broker profile presentation with clearer CRM-aligned visibility rules\n- more editorial insight layouts so updates feel like a publication, not a noticeboard\n- a better foundation for future services, broker onboarding and growth content\n\nThe result is a digital presence that feels more composed, more exclusive and more aligned with the next chapter of finweb."
image_url:
type: string
example: null
nullable: true
button_text:
type: string
example: 'Read more'
button_url:
type: string
example: null
nullable: true
link_type:
type: string
example: internal
is_published:
type: boolean
example: true
created_at:
type: string
example: '2026-07-31T01:51:48.000000Z'
updated_at:
type: string
example: '2026-07-31T01:51:48.000000Z'
tags:
- Endpoints
security: []
'/api/insights/{slug}':
get:
summary: ''
operationId: getApiInsightsSlug
description: ''
parameters: []
responses:
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Insight not found.'
properties:
message:
type: string
example: 'Insight not found.'
tags:
- Endpoints
security: []
parameters:
-
in: path
name: slug
description: 'The slug of the insight.'
example: 1
required: true
schema:
type: integer
/api/stories:
get:
summary: ''
operationId: getApiStories
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
-
id: 1
title: 'Broker team moments'
slug: broker-team-moments
published_at: '2026-07-10'
excerpt: 'The everyday interactions, team wins and shared moments that make finweb feel like a real broker community rather than a distant network.'
body: "The strongest broker groups are not only judged by systems and service. They are judged by how it feels to work inside them.\n\nBroker team moments are the conversations between files, the practical support that happens in the middle of a hard scenario, the shared wins after settlement and the small interactions that make the business feel less isolated.\n\nAt finweb, those moments matter because they shape confidence. A newer broker sees how an experienced broker handles pressure. An established broker shares perspective that helps someone else avoid a mistake. Questions are asked earlier, answers come faster and the group becomes more than a logo or a lender panel.\n\nThat is part of what people mean when they say the group feels human. It is not just events or formal mentoring sessions. It is the consistency of people showing up for each other when the work is happening.\n\nWhen brokers talk about why they stay, those moments often sit underneath the bigger headlines. Processing matters. Compliance matters. Coaching matters. But so does the feeling that the people around you genuinely care whether you do well."
image_url: 'https://dev.api.finweb.group/storage/stories/broker-team-moments.jpg'
youtube_url: null
button_text: 'Read story'
button_url: null
link_type: internal
is_featured: false
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 2
title: 'Training and partner sessions'
slug: training-and-partner-sessions
published_at: '2026-07-03'
excerpt: 'A closer look at the sessions, partner-led programmes and practical learning environments that keep brokers building capability over time.'
body: "Training works best when it feels connected to the work brokers are actually doing.\n\nTraining and partner sessions inside finweb are designed around that idea. Some sessions focus on lender knowledge. Others focus on process quality, scenario handling, sales activity or the habits that make a business more repeatable. The common thread is that the learning is expected to be useful in practice, not just interesting in theory.\n\nPartner programmes add another layer. Sessions connected to Purple Thread and Mr Mentor help brokers work on different parts of the business, from prospecting and conversion through to the structure and rhythm required to write files confidently.\n\nThese sessions are also important culturally. They create places where brokers can ask better questions, share what is working and hear how others are thinking about the market. That keeps capability building over time rather than sitting in one burst of onboarding.\n\nThe goal is not simply to run more training. The goal is to keep brokers sharper, more commercial and better supported as the business evolves."
image_url: 'https://dev.api.finweb.group/storage/stories/training-and-partner-sessions.png'
youtube_url: null
button_text: 'Read story'
button_url: null
link_type: internal
is_featured: false
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
properties:
data:
type: array
example:
-
id: 1
title: 'Broker team moments'
slug: broker-team-moments
published_at: '2026-07-10'
excerpt: 'The everyday interactions, team wins and shared moments that make finweb feel like a real broker community rather than a distant network.'
body: "The strongest broker groups are not only judged by systems and service. They are judged by how it feels to work inside them.\n\nBroker team moments are the conversations between files, the practical support that happens in the middle of a hard scenario, the shared wins after settlement and the small interactions that make the business feel less isolated.\n\nAt finweb, those moments matter because they shape confidence. A newer broker sees how an experienced broker handles pressure. An established broker shares perspective that helps someone else avoid a mistake. Questions are asked earlier, answers come faster and the group becomes more than a logo or a lender panel.\n\nThat is part of what people mean when they say the group feels human. It is not just events or formal mentoring sessions. It is the consistency of people showing up for each other when the work is happening.\n\nWhen brokers talk about why they stay, those moments often sit underneath the bigger headlines. Processing matters. Compliance matters. Coaching matters. But so does the feeling that the people around you genuinely care whether you do well."
image_url: 'https://dev.api.finweb.group/storage/stories/broker-team-moments.jpg'
youtube_url: null
button_text: 'Read story'
button_url: null
link_type: internal
is_featured: false
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 2
title: 'Training and partner sessions'
slug: training-and-partner-sessions
published_at: '2026-07-03'
excerpt: 'A closer look at the sessions, partner-led programmes and practical learning environments that keep brokers building capability over time.'
body: "Training works best when it feels connected to the work brokers are actually doing.\n\nTraining and partner sessions inside finweb are designed around that idea. Some sessions focus on lender knowledge. Others focus on process quality, scenario handling, sales activity or the habits that make a business more repeatable. The common thread is that the learning is expected to be useful in practice, not just interesting in theory.\n\nPartner programmes add another layer. Sessions connected to Purple Thread and Mr Mentor help brokers work on different parts of the business, from prospecting and conversion through to the structure and rhythm required to write files confidently.\n\nThese sessions are also important culturally. They create places where brokers can ask better questions, share what is working and hear how others are thinking about the market. That keeps capability building over time rather than sitting in one burst of onboarding.\n\nThe goal is not simply to run more training. The goal is to keep brokers sharper, more commercial and better supported as the business evolves."
image_url: 'https://dev.api.finweb.group/storage/stories/training-and-partner-sessions.png'
youtube_url: null
button_text: 'Read story'
button_url: null
link_type: internal
is_featured: false
is_published: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
items:
type: object
properties:
id:
type: integer
example: 1
title:
type: string
example: 'Broker team moments'
slug:
type: string
example: broker-team-moments
published_at:
type: string
example: '2026-07-10'
excerpt:
type: string
example: 'The everyday interactions, team wins and shared moments that make finweb feel like a real broker community rather than a distant network.'
body:
type: string
example: "The strongest broker groups are not only judged by systems and service. They are judged by how it feels to work inside them.\n\nBroker team moments are the conversations between files, the practical support that happens in the middle of a hard scenario, the shared wins after settlement and the small interactions that make the business feel less isolated.\n\nAt finweb, those moments matter because they shape confidence. A newer broker sees how an experienced broker handles pressure. An established broker shares perspective that helps someone else avoid a mistake. Questions are asked earlier, answers come faster and the group becomes more than a logo or a lender panel.\n\nThat is part of what people mean when they say the group feels human. It is not just events or formal mentoring sessions. It is the consistency of people showing up for each other when the work is happening.\n\nWhen brokers talk about why they stay, those moments often sit underneath the bigger headlines. Processing matters. Compliance matters. Coaching matters. But so does the feeling that the people around you genuinely care whether you do well."
image_url:
type: string
example: 'https://dev.api.finweb.group/storage/stories/broker-team-moments.jpg'
youtube_url:
type: string
example: null
nullable: true
button_text:
type: string
example: 'Read story'
button_url:
type: string
example: null
nullable: true
link_type:
type: string
example: internal
is_featured:
type: boolean
example: false
is_published:
type: boolean
example: true
created_at:
type: string
example: '2026-07-31T01:51:48.000000Z'
updated_at:
type: string
example: '2026-07-31T01:51:48.000000Z'
tags:
- Endpoints
security: []
'/api/stories/{slug}':
get:
summary: ''
operationId: getApiStoriesSlug
description: ''
parameters: []
responses:
404:
description: ''
content:
application/json:
schema:
type: object
example:
message: 'Story not found.'
properties:
message:
type: string
example: 'Story not found.'
tags:
- Endpoints
security: []
parameters:
-
in: path
name: slug
description: 'The slug of the story.'
example: 1
required: true
schema:
type: integer
/api/testimonials:
get:
summary: ''
operationId: getApiTestimonials
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
-
id: 1
name: 'Nathan Bickford'
role: 'Mortgage Broker'
quote: 'From day one, I felt like part of the family. The support is real, the mentors check in, and the community wants you to win.'
image_url: 'https://finweb.group/wp-content/uploads/2025/06/HEADSHOT-WEBSITE-31.png'
rating: 5
sort_order: 10
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 2
name: 'Jesse Egan'
role: 'Finance Broker'
quote: 'Finweb was the perfect fit. The mentorship and guidance helped me grow fast and write loans across multiple markets.'
image_url: 'https://finweb.group/wp-content/uploads/2025/06/HTML-SIGNATURE-Photo-5.png'
rating: 5
sort_order: 20
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 3
name: 'Aluni Hermez'
role: 'Asset Finance Specialist'
quote: 'The collaboration and support are unmatched. Finweb gives me the confidence and structure to plan long-term.'
image_url: 'https://finweb.group/wp-content/uploads/2025/06/HEADSHOT-WEBSITE-24.png'
rating: 5
sort_order: 30
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 4
name: 'Chris Casha'
role: 'Finance Broker'
quote: 'Starting out was full-on, but Finweb made it feel manageable. There is always someone to lean on.'
image_url: 'https://finweb.group/wp-content/uploads/2025/06/HEADSHOT-WEBSITE-25.png'
rating: 5
sort_order: 40
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
properties:
data:
type: array
example:
-
id: 1
name: 'Nathan Bickford'
role: 'Mortgage Broker'
quote: 'From day one, I felt like part of the family. The support is real, the mentors check in, and the community wants you to win.'
image_url: 'https://finweb.group/wp-content/uploads/2025/06/HEADSHOT-WEBSITE-31.png'
rating: 5
sort_order: 10
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 2
name: 'Jesse Egan'
role: 'Finance Broker'
quote: 'Finweb was the perfect fit. The mentorship and guidance helped me grow fast and write loans across multiple markets.'
image_url: 'https://finweb.group/wp-content/uploads/2025/06/HTML-SIGNATURE-Photo-5.png'
rating: 5
sort_order: 20
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 3
name: 'Aluni Hermez'
role: 'Asset Finance Specialist'
quote: 'The collaboration and support are unmatched. Finweb gives me the confidence and structure to plan long-term.'
image_url: 'https://finweb.group/wp-content/uploads/2025/06/HEADSHOT-WEBSITE-24.png'
rating: 5
sort_order: 30
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
-
id: 4
name: 'Chris Casha'
role: 'Finance Broker'
quote: 'Starting out was full-on, but Finweb made it feel manageable. There is always someone to lean on.'
image_url: 'https://finweb.group/wp-content/uploads/2025/06/HEADSHOT-WEBSITE-25.png'
rating: 5
sort_order: 40
is_active: true
created_at: '2026-07-31T01:51:48.000000Z'
updated_at: '2026-07-31T01:51:48.000000Z'
items:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
example: 'Nathan Bickford'
role:
type: string
example: 'Mortgage Broker'
quote:
type: string
example: 'From day one, I felt like part of the family. The support is real, the mentors check in, and the community wants you to win.'
image_url:
type: string
example: 'https://finweb.group/wp-content/uploads/2025/06/HEADSHOT-WEBSITE-31.png'
rating:
type: integer
example: 5
sort_order:
type: integer
example: 10
is_active:
type: boolean
example: true
created_at:
type: string
example: '2026-07-31T01:51:48.000000Z'
updated_at:
type: string
example: '2026-07-31T01:51:48.000000Z'
tags:
- Endpoints
security: []
/api/google-reviews:
get:
summary: ''
operationId: getApiGoogleReviews
description: ''
parameters: []
responses:
403:
description: ''
content:
application/json:
schema:
type: object
example:
code: not_allowlisted
message: 'This Google place is not allowlisted.'
properties:
code:
type: string
example: not_allowlisted
message:
type: string
example: 'This Google place is not allowlisted.'
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
place_id:
type: string
description: 'Must not be greater than 255 characters.'
example: b
max_reviews:
type: integer
description: 'Must be at least 0. Must not be greater than 5.'
example: 2
security: []
/api/get-in-touch/content:
get:
summary: ''
operationId: getApiGetInTouchContent
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
badge_label: Contact
title: 'Get in touch'
phone_label: Phone
phone_value: '0421 639 947'
email_label: Email
email_value: contact@finweb.com.au
location_label: ''
location_value: ''
properties:
data:
type: object
properties:
badge_label:
type: string
example: Contact
title:
type: string
example: 'Get in touch'
phone_label:
type: string
example: Phone
phone_value:
type: string
example: '0421 639 947'
email_label:
type: string
example: Email
email_value:
type: string
example: contact@finweb.com.au
location_label:
type: string
example: ''
location_value:
type: string
example: ''
tags:
- Endpoints
security: []
/api/me:
get:
summary: ''
operationId: getApiMe
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiMe
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: zbailey@example.net
required:
- name
- email
security: []
/api/logout:
post:
summary: ''
operationId: postApiLogout
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
/api/auth/password:
put:
summary: ''
operationId: putApiAuthPassword
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
current_password:
type: string
description: ''
example: architecto
password:
type: string
description: ''
example: '|]|{+-'
required:
- current_password
- password
security: []
/api/me/avatar:
post:
summary: ''
operationId: postApiMeAvatar
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
avatar:
type: string
format: binary
description: 'This field is required when avatars is not present. Must be a file. Must be an image. Must not be greater than 4096 kilobytes.'
avatars:
type: array
description: 'Must be a file. Must be an image. Must not be greater than 4096 kilobytes.'
items:
type: string
format: binary
security: []
delete:
summary: ''
operationId: deleteApiMeAvatar
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
/api/me/recovery-email:
put:
summary: ''
operationId: putApiMeRecoveryEmail
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
recovery_email:
type: string
description: 'Must be a valid email address. Must not be one of .'
example: gbailey@example.net
required:
- recovery_email
security: []
delete:
summary: ''
operationId: deleteApiMeRecoveryEmail
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
/api/me/recovery-email/resend-verification:
post:
summary: ''
operationId: postApiMeRecoveryEmailResendVerification
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
/api/auth/two-factor:
get:
summary: ''
operationId: getApiAuthTwoFactor
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/auth/two-factor/setup:
post:
summary: ''
operationId: postApiAuthTwoFactorSetup
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
/api/auth/two-factor/confirm:
post:
summary: ''
operationId: postApiAuthTwoFactorConfirm
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
code:
type: string
description: 'Must match the regex /^\d{6}$/. Must be 6 characters.'
example: bngzmi
required:
- code
security: []
/api/auth/two-factor/disable:
post:
summary: ''
operationId: postApiAuthTwoFactorDisable
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
current_password:
type: string
description: ''
example: architecto
required:
- current_password
security: []
/api/dashboard/metrics:
get:
summary: ''
operationId: getApiDashboardMetrics
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/admin/awards:
get:
summary: ''
operationId: getApiAdminAwards
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
is_active:
type: boolean
description: ''
example: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 22
sort:
type: string
description: 'Must not be greater than 255 characters.'
example: g
security: []
post:
summary: ''
operationId: postApiAdminAwards
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
logo:
type: string
format: binary
description: 'Must be a file. Must not be greater than 5120 kilobytes.'
nullable: true
remove_logo:
type: boolean
description: ''
example: true
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 22
nullable: true
is_active:
type: boolean
description: ''
example: false
required:
- title
security: []
'/api/admin/awards/{award_id}':
get:
summary: ''
operationId: getApiAdminAwardsAward_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiAdminAwardsAward_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
logo:
type: string
format: binary
description: 'Must be a file. Must not be greater than 5120 kilobytes.'
nullable: true
remove_logo:
type: boolean
description: ''
example: true
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 22
nullable: true
is_active:
type: boolean
description: ''
example: false
security: []
patch:
summary: ''
operationId: patchApiAdminAwardsAward_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
logo:
type: string
format: binary
description: 'Must be a file. Must not be greater than 5120 kilobytes.'
nullable: true
remove_logo:
type: boolean
description: ''
example: true
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 22
nullable: true
is_active:
type: boolean
description: ''
example: false
security: []
delete:
summary: ''
operationId: deleteApiAdminAwardsAward_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: award_id
description: 'The ID of the award.'
example: 1
required: true
schema:
type: integer
/api/admin/brokers:
get:
summary: ''
operationId: getApiAdminBrokers
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
nullable: true
status:
type: string
description: 'Must not be greater than 100 characters.'
example: 'n'
nullable: true
active:
type: boolean
description: ''
example: true
nullable: true
approved:
type: boolean
description: ''
example: true
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 7
nullable: true
page:
type: integer
description: 'Must be at least 1.'
example: 66
nullable: true
sort:
type: string
description: 'Must match the regex /^-?(name|email|company_name|license_no|active|approved|created_at|updated_at|slug)$/. Must not be greater than 255 characters.'
example: m
nullable: true
security: []
post:
summary: ''
operationId: postApiAdminBrokers
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: zbailey@example.net
password:
type: string
description: 'Must be at least 8 characters.'
example: '-0pBNvYgxw'
slug:
type: string
description: 'Must not be greater than 255 characters.'
example: a
nullable: true
summary:
type: string
description: ''
example: architecto
nullable: true
profile_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
featured_image:
type: string
description: 'Must not be greater than 2048 characters.'
example: m
nullable: true
avatar:
type: string
description: 'Must not be greater than 2048 characters.'
example: i
nullable: true
company_name:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
phone:
type: string
description: 'Must not be greater than 50 characters.'
example: v
nullable: true
license_no:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
active:
type: boolean
description: ''
example: false
profile_content:
type: object
description: ''
example: null
properties:
intro:
type: object
description: ''
example: null
properties:
headline:
type: string
description: 'Must not be greater than 255 characters.'
example: l
nullable: true
paragraphs:
type: array
description: ''
example:
- architecto
items:
type: string
nullable: true
ctaLabel:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
nullable: true
sections:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: r
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.sections.*.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'no'
enum: ['yes', 'no', auto]
nullable: true
nullable: true
homeLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.homeLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'yes'
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
commercialLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.commercialLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
otherLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.otherLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
contact:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
formEmbedUrl:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'https://gaylord.com/modi-deserunt-aut-ab-provident-perspiciatis.html'
nullable: true
mapEmbedUrl:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://www.cruickshank.com/adipisci-quidem-nostrum-qui-commodi-incidunt-iure'
nullable: true
nullable: true
nullable: true
required:
- name
- email
- password
- company_name
security: []
/api/admin/broker-partners:
get:
summary: ''
operationId: getApiAdminBrokerPartners
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 22
page:
type: integer
description: 'Must be at least 1.'
example: 67
sort:
type: string
description: 'Must match the regex /^-?(title|status|created_at|updated_at)$/. Must not be greater than 255 characters.'
example: z
security: []
'/api/admin/brokers/{broker_id}':
get:
summary: ''
operationId: getApiAdminBrokersBroker_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiAdminBrokersBroker_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
summary:
type: string
description: ''
example: architecto
nullable: true
profile_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
featured_image:
type: string
description: 'Must not be greater than 2048 characters.'
example: m
nullable: true
avatar:
type: string
description: 'Must not be greater than 2048 characters.'
example: i
nullable: true
profile_content:
type: object
description: ''
example: null
properties:
intro:
type: object
description: ''
example: null
properties:
headline:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
paragraphs:
type: array
description: ''
example:
- architecto
items:
type: string
nullable: true
ctaLabel:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
nullable: true
sections:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: r
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.sections.*.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum: ['yes', 'no', auto]
nullable: true
nullable: true
homeLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.homeLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
commercialLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.commercialLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'no'
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
otherLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.otherLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'no'
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
contact:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
formEmbedUrl:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'https://gaylord.com/modi-deserunt-aut-ab-provident-perspiciatis.html'
nullable: true
mapEmbedUrl:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://www.cruickshank.com/adipisci-quidem-nostrum-qui-commodi-incidunt-iure'
nullable: true
nullable: true
nullable: true
security: []
patch:
summary: ''
operationId: patchApiAdminBrokersBroker_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
summary:
type: string
description: ''
example: architecto
nullable: true
profile_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
featured_image:
type: string
description: 'Must not be greater than 2048 characters.'
example: m
nullable: true
avatar:
type: string
description: 'Must not be greater than 2048 characters.'
example: i
nullable: true
profile_content:
type: object
description: ''
example: null
properties:
intro:
type: object
description: ''
example: null
properties:
headline:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
paragraphs:
type: array
description: ''
example:
- architecto
items:
type: string
nullable: true
ctaLabel:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
nullable: true
sections:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: r
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.sections.*.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'no'
enum: ['yes', 'no', auto]
nullable: true
nullable: true
homeLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.homeLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'no'
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
commercialLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.commercialLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'yes'
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
otherLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.otherLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
contact:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
formEmbedUrl:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'https://gaylord.com/modi-deserunt-aut-ab-provident-perspiciatis.html'
nullable: true
mapEmbedUrl:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://www.cruickshank.com/adipisci-quidem-nostrum-qui-commodi-incidunt-iure'
nullable: true
nullable: true
nullable: true
security: []
delete:
summary: ''
operationId: deleteApiAdminBrokersBroker_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: broker_id
description: 'The ID of the broker.'
example: 16
required: true
schema:
type: integer
'/api/admin/brokers/{broker_id}/send-portal-invite':
post:
summary: ''
operationId: postApiAdminBrokersBroker_idSendPortalInvite
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: broker_id
description: 'The ID of the broker.'
example: 16
required: true
schema:
type: integer
'/api/admin/brokers/{broker_id}/images':
post:
summary: ''
operationId: postApiAdminBrokersBroker_idImages
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
featured_image:
type: string
format: binary
description: 'Must be a file. Must be an image. Must not be greater than 2048 kilobytes.'
featured_images:
type: array
description: 'Must be a file. Must be an image. Must not be greater than 2048 kilobytes.'
items:
type: string
format: binary
avatar:
type: string
format: binary
description: 'Must be a file. Must be an image. Must not be greater than 4096 kilobytes.'
avatars:
type: array
description: 'Must be a file. Must be an image. Must not be greater than 4096 kilobytes.'
items:
type: string
format: binary
security: []
parameters:
-
in: path
name: broker_id
description: 'The ID of the broker.'
example: 16
required: true
schema:
type: integer
'/api/admin/brokers/{broker_id}/audits':
get:
summary: ''
operationId: getApiAdminBrokersBroker_idAudits
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 1
nullable: true
security: []
parameters:
-
in: path
name: broker_id
description: 'The ID of the broker.'
example: 16
required: true
schema:
type: integer
/api/admin/system-settings/broker-auto-sync:
get:
summary: ''
operationId: getApiAdminSystemSettingsBrokerAutoSync
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
patch:
summary: ''
operationId: patchApiAdminSystemSettingsBrokerAutoSync
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
enabled:
type: boolean
description: ''
example: false
interval_minutes:
type: integer
description: 'Must be at least 1. Must not be greater than 1440.'
example: 1
required:
- enabled
- interval_minutes
security: []
/api/admin/system-settings/cpd-sync:
get:
summary: ''
operationId: getApiAdminSystemSettingsCpdSync
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
patch:
summary: ''
operationId: patchApiAdminSystemSettingsCpdSync
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
enabled:
type: boolean
description: ''
example: false
interval_minutes:
type: integer
description: 'Must be at least 1. Must not be greater than 1440.'
example: 1
module_api_name:
type: string
description: 'Must match the regex /^[A-Za-z][A-Za-z0-9_]*$/. Must not be greater than 191 characters.'
example: 'n'
custom_view_id:
type: string
description: 'Must match the regex /^[0-9]+$/. Must not be greater than 191 characters.'
example: g
nullable: true
report_limit_message:
type: string
description: 'Must not be greater than 500 characters.'
example: z
required:
- enabled
- interval_minutes
- module_api_name
- report_limit_message
security: []
/api/admin/system-settings/cpd-sync/validate:
post:
summary: ''
operationId: postApiAdminSystemSettingsCpdSyncValidate
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
module_api_name:
type: string
description: 'Must match the regex /^[A-Za-z][A-Za-z0-9_]*$/. Must not be greater than 191 characters.'
example: b
custom_view_id:
type: string
description: 'Must match the regex /^[0-9]+$/. Must not be greater than 191 characters.'
example: 'n'
nullable: true
required:
- module_api_name
security: []
/api/admin/cpd-records/sync:
post:
summary: ''
operationId: postApiAdminCpdRecordsSync
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
/api/admin/cpd-records/sync-status:
get:
summary: ''
operationId: getApiAdminCpdRecordsSyncStatus
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
/api/admin/cpd-records/sync-logs:
get:
summary: ''
operationId: getApiAdminCpdRecordsSyncLogs
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 1
nullable: true
security: []
/api/admin/insights:
get:
summary: ''
operationId: getApiAdminInsights
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
is_published:
type: boolean
description: ''
example: true
sort:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 7
security: []
post:
summary: ''
operationId: postApiAdminInsights
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
slug:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
published_at:
type: string
description: 'Must be a valid date.'
example: '2026-07-31T02:03:50'
excerpt:
type: string
description: ''
example: architecto
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
image_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
button_text:
type: string
description: 'Must not be greater than 255 characters.'
example: m
nullable: true
button_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'https://www.gulgowski.com/nihil-accusantium-harum-mollitia-modi-deserunt'
nullable: true
link_type:
type: string
description: ''
example: internal
enum:
- internal
- external
is_published:
type: boolean
description: ''
example: false
required:
- title
- slug
- published_at
- link_type
security: []
'/api/admin/insights/{insight_id}':
get:
summary: ''
operationId: getApiAdminInsightsInsight_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiAdminInsightsInsight_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
slug:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
published_at:
type: string
description: 'Must be a valid date.'
example: '2026-07-31T02:03:50'
excerpt:
type: string
description: ''
example: architecto
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
image_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
button_text:
type: string
description: 'Must not be greater than 255 characters.'
example: m
nullable: true
button_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'https://www.gulgowski.com/nihil-accusantium-harum-mollitia-modi-deserunt'
nullable: true
link_type:
type: string
description: ''
example: external
enum:
- internal
- external
is_published:
type: boolean
description: ''
example: false
security: []
patch:
summary: ''
operationId: patchApiAdminInsightsInsight_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
slug:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
published_at:
type: string
description: 'Must be a valid date.'
example: '2026-07-31T02:03:50'
excerpt:
type: string
description: ''
example: architecto
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
image_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
button_text:
type: string
description: 'Must not be greater than 255 characters.'
example: m
nullable: true
button_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'https://www.gulgowski.com/nihil-accusantium-harum-mollitia-modi-deserunt'
nullable: true
link_type:
type: string
description: ''
example: internal
enum:
- internal
- external
is_published:
type: boolean
description: ''
example: true
security: []
delete:
summary: ''
operationId: deleteApiAdminInsightsInsight_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: insight_id
description: 'The ID of the insight.'
example: 1
required: true
schema:
type: integer
/api/admin/insights/upload:
post:
summary: ''
operationId: postApiAdminInsightsUpload
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
image:
type: string
format: binary
description: 'This field is required when images is not present. Must be a file. Must be an image. Must not be greater than 2048 kilobytes.'
images:
type: array
description: 'Must be a file. Must be an image. Must not be greater than 2048 kilobytes.'
items:
type: string
format: binary
security: []
/api/admin/stories:
get:
summary: ''
operationId: getApiAdminStories
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
is_published:
type: boolean
description: ''
example: false
sort:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 7
security: []
post:
summary: ''
operationId: postApiAdminStories
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
slug:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
published_at:
type: string
description: 'Must be a valid date.'
example: '2026-07-31T02:03:50'
excerpt:
type: string
description: ''
example: architecto
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
image_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
youtube_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://rempel.com/sunt-nihil-accusantium-harum-mollitia'
nullable: true
button_text:
type: string
description: 'Must not be greater than 255 characters.'
example: k
nullable: true
button_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://www.schuster.biz/perspiciatis-quo-omnis-nostrum-aut-adipisci-quidem-nostrum-qui'
nullable: true
link_type:
type: string
description: ''
example: external
enum:
- internal
- external
is_featured:
type: boolean
description: ''
example: false
is_published:
type: boolean
description: ''
example: false
required:
- title
- slug
- published_at
- link_type
security: []
'/api/admin/stories/{story_id}':
get:
summary: ''
operationId: getApiAdminStoriesStory_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiAdminStoriesStory_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
slug:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
published_at:
type: string
description: 'Must be a valid date.'
example: '2026-07-31T02:03:50'
excerpt:
type: string
description: ''
example: architecto
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
image_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
youtube_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://rempel.com/sunt-nihil-accusantium-harum-mollitia'
nullable: true
button_text:
type: string
description: 'Must not be greater than 255 characters.'
example: k
nullable: true
button_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://www.schuster.biz/perspiciatis-quo-omnis-nostrum-aut-adipisci-quidem-nostrum-qui'
nullable: true
link_type:
type: string
description: ''
example: internal
enum:
- internal
- external
is_featured:
type: boolean
description: ''
example: false
is_published:
type: boolean
description: ''
example: false
security: []
patch:
summary: ''
operationId: patchApiAdminStoriesStory_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
slug:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
published_at:
type: string
description: 'Must be a valid date.'
example: '2026-07-31T02:03:50'
excerpt:
type: string
description: ''
example: architecto
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
image_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
youtube_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://rempel.com/sunt-nihil-accusantium-harum-mollitia'
nullable: true
button_text:
type: string
description: 'Must not be greater than 255 characters.'
example: k
nullable: true
button_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://www.schuster.biz/perspiciatis-quo-omnis-nostrum-aut-adipisci-quidem-nostrum-qui'
nullable: true
link_type:
type: string
description: ''
example: external
enum:
- internal
- external
is_featured:
type: boolean
description: ''
example: true
is_published:
type: boolean
description: ''
example: false
security: []
delete:
summary: ''
operationId: deleteApiAdminStoriesStory_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: story_id
description: 'The ID of the story.'
example: 1
required: true
schema:
type: integer
/api/admin/stories/upload:
post:
summary: ''
operationId: postApiAdminStoriesUpload
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
image:
type: string
format: binary
description: 'Must be a file. Must be an image. Must not be greater than 5120 kilobytes.'
images:
type: array
description: 'Must be a file. Must be an image. Must not be greater than 5120 kilobytes.'
items:
type: string
format: binary
security: []
/api/admin/testimonials:
get:
summary: ''
operationId: getApiAdminTestimonials
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
is_active:
type: boolean
description: ''
example: false
sort:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 7
security: []
post:
summary: ''
operationId: postApiAdminTestimonials
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
role:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
quote:
type: string
description: ''
example: architecto
image:
type: string
format: binary
description: 'Must be a file. Must not be greater than 5120 kilobytes.'
nullable: true
remove_image:
type: boolean
description: ''
example: true
rating:
type: integer
description: 'Must be at least 1. Must not be greater than 5.'
example: 2
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 7
nullable: true
is_active:
type: boolean
description: ''
example: false
required:
- name
- role
- quote
- rating
security: []
'/api/admin/testimonials/{testimonial_id}':
get:
summary: ''
operationId: getApiAdminTestimonialsTestimonial_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiAdminTestimonialsTestimonial_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
role:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
quote:
type: string
description: ''
example: architecto
image:
type: string
format: binary
description: 'Must be a file. Must not be greater than 5120 kilobytes.'
nullable: true
remove_image:
type: boolean
description: ''
example: false
rating:
type: integer
description: 'Must be at least 1. Must not be greater than 5.'
example: 2
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 7
nullable: true
is_active:
type: boolean
description: ''
example: false
security: []
patch:
summary: ''
operationId: patchApiAdminTestimonialsTestimonial_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
role:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
quote:
type: string
description: ''
example: architecto
image:
type: string
format: binary
description: 'Must be a file. Must not be greater than 5120 kilobytes.'
nullable: true
remove_image:
type: boolean
description: ''
example: true
rating:
type: integer
description: 'Must be at least 1. Must not be greater than 5.'
example: 2
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 7
nullable: true
is_active:
type: boolean
description: ''
example: false
security: []
delete:
summary: ''
operationId: deleteApiAdminTestimonialsTestimonial_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: testimonial_id
description: 'The ID of the testimonial.'
example: 1
required: true
schema:
type: integer
/api/admin/join-us:
get:
summary: ''
operationId: getApiAdminJoinUs
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
nullable: true
enquiry_type:
type: string
description: 'Must not be greater than 120 characters.'
example: 'n'
nullable: true
source:
type: string
description: 'Must not be greater than 100 characters.'
example: g
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 16
nullable: true
sort:
type: string
description: 'Must not be greater than 50 characters.'
example: m
nullable: true
security: []
/api/admin/get-in-touch:
get:
summary: ''
operationId: getApiAdminGetInTouch
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
nullable: true
source:
type: string
description: 'Must not be greater than 100 characters.'
example: 'n'
nullable: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 7
nullable: true
sort:
type: string
description: 'Must not be greater than 50 characters.'
example: z
nullable: true
security: []
/api/admin/get-in-touch/content:
get:
summary: ''
operationId: getApiAdminGetInTouchContent
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiAdminGetInTouchContent
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
badge_label:
type: string
description: 'Must not be greater than 255 characters.'
example: b
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
phone_label:
type: string
description: 'Must not be greater than 255 characters.'
example: g
phone_value:
type: string
description: 'Must not be greater than 255 characters.'
example: z
email_label:
type: string
description: 'Must not be greater than 255 characters.'
example: m
email_value:
type: string
description: 'Must not be greater than 255 characters.'
example: i
location_label:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
location_value:
type: string
description: 'Must not be greater than 255 characters.'
example: v
required:
- badge_label
- title
- phone_label
- phone_value
- email_label
- email_value
- location_label
- location_value
security: []
patch:
summary: ''
operationId: patchApiAdminGetInTouchContent
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
badge_label:
type: string
description: 'Must not be greater than 255 characters.'
example: b
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
phone_label:
type: string
description: 'Must not be greater than 255 characters.'
example: g
phone_value:
type: string
description: 'Must not be greater than 255 characters.'
example: z
email_label:
type: string
description: 'Must not be greater than 255 characters.'
example: m
email_value:
type: string
description: 'Must not be greater than 255 characters.'
example: i
location_label:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
location_value:
type: string
description: 'Must not be greater than 255 characters.'
example: v
required:
- badge_label
- title
- phone_label
- phone_value
- email_label
- email_value
- location_label
- location_value
security: []
/api/admin/users:
get:
summary: ''
operationId: getApiAdminUsers
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
role:
type: string
description: ''
example: user
enum:
- admin
- broker
- user
active:
type: boolean
description: ''
example: false
approved:
type: boolean
description: ''
example: true
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 22
security: []
'/api/admin/users/{user_id}':
get:
summary: ''
operationId: getApiAdminUsersUser_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiAdminUsersUser_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: zbailey@example.net
password:
type: string
description: 'Must be at least 8 characters.'
example: '-0pBNvYgxw'
role:
type: string
description: ''
example: user
enum:
- admin
- broker
- user
permissions:
type: array
description: ''
example:
- 'insights:edit'
items:
type: string
enum:
- 'dashboard:view'
- 'dashboard:edit'
- 'brokers:view'
- 'brokers:edit'
- 'broker-partners:view'
- 'broker-partners:edit'
- 'awards:view'
- 'awards:edit'
- 'insights:view'
- 'insights:edit'
- 'stories:view'
- 'stories:edit'
- 'testimonials:view'
- 'testimonials:edit'
- 'services:view'
- 'services:edit'
- 'resources:view'
- 'resources:edit'
- 'lender-tools:view'
- 'lender-tools:edit'
- 'lender20-recordings:view'
- 'lender20-recordings:edit'
- 'cpd:view'
- 'cpd:edit'
- 'join-us:view'
- 'join-us:edit'
- 'get-in-touch:view'
- 'get-in-touch:edit'
- 'profile:view'
- 'profile:edit'
- 'users:view'
- 'users:edit'
- 'settings:view'
- 'settings:edit'
active:
type: boolean
description: ''
example: false
approved:
type: boolean
description: ''
example: true
security: []
patch:
summary: ''
operationId: patchApiAdminUsersUser_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: 'Must not be greater than 255 characters.'
example: b
email:
type: string
description: 'Must be a valid email address. Must not be greater than 255 characters.'
example: zbailey@example.net
password:
type: string
description: 'Must be at least 8 characters.'
example: '-0pBNvYgxw'
role:
type: string
description: ''
example: broker
enum:
- admin
- broker
- user
permissions:
type: array
description: ''
example:
- 'get-in-touch:edit'
items:
type: string
enum:
- 'dashboard:view'
- 'dashboard:edit'
- 'brokers:view'
- 'brokers:edit'
- 'broker-partners:view'
- 'broker-partners:edit'
- 'awards:view'
- 'awards:edit'
- 'insights:view'
- 'insights:edit'
- 'stories:view'
- 'stories:edit'
- 'testimonials:view'
- 'testimonials:edit'
- 'services:view'
- 'services:edit'
- 'resources:view'
- 'resources:edit'
- 'lender-tools:view'
- 'lender-tools:edit'
- 'lender20-recordings:view'
- 'lender20-recordings:edit'
- 'cpd:view'
- 'cpd:edit'
- 'join-us:view'
- 'join-us:edit'
- 'get-in-touch:view'
- 'get-in-touch:edit'
- 'profile:view'
- 'profile:edit'
- 'users:view'
- 'users:edit'
- 'settings:view'
- 'settings:edit'
active:
type: boolean
description: ''
example: true
approved:
type: boolean
description: ''
example: false
security: []
parameters:
-
in: path
name: user_id
description: 'The ID of the user.'
example: 1
required: true
schema:
type: integer
/api/profile:
get:
summary: ''
operationId: getApiProfile
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiProfile
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
summary:
type: string
description: ''
example: architecto
nullable: true
profile_content:
type: object
description: ''
example: null
properties:
intro:
type: object
description: ''
example: null
properties:
headline:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
paragraphs:
type: array
description: ''
example:
- architecto
items:
type: string
nullable: true
ctaLabel:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
nullable: true
sections:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: r
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.sections.*.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'yes'
enum: ['yes', 'no', auto]
nullable: true
nullable: true
homeLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.homeLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
commercialLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.commercialLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'yes'
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
otherLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.otherLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
contact:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
formEmbedUrl:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'https://gaylord.com/modi-deserunt-aut-ab-provident-perspiciatis.html'
nullable: true
mapEmbedUrl:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://www.cruickshank.com/adipisci-quidem-nostrum-qui-commodi-incidunt-iure'
nullable: true
nullable: true
nullable: true
security: []
patch:
summary: ''
operationId: patchApiProfile
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
summary:
type: string
description: ''
example: architecto
nullable: true
profile_content:
type: object
description: ''
example: null
properties:
intro:
type: object
description: ''
example: null
properties:
headline:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
paragraphs:
type: array
description: ''
example:
- architecto
items:
type: string
nullable: true
ctaLabel:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
nullable: true
nullable: true
sections:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: r
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.sections.*.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'yes'
enum: ['yes', 'no', auto]
nullable: true
nullable: true
homeLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: g
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.homeLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
commercialLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.commercialLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: 'no'
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
otherLoans:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
highlights:
type: array
description: 'Must not be greater than 255 characters.'
example:
- v
items:
type: string
nullable: true
accordion:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'y'
nullable: true
body:
type: string
description: ''
example: architecto
nullable: true
embed:
type: object
description: ''
example: null
properties:
iframeUrl:
type: string
description: 'This field is required when profile_content.otherLoans.accordion.*.embed is present. Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
height:
type: integer
description: 'Must be at least 100. Must not be greater than 2000.'
example: 17
nullable: true
allow:
type: string
description: 'Must not be greater than 255 characters.'
example: i
nullable: true
scrolling:
type: string
description: ''
example: auto
enum:
- 'yes'
- 'no'
- auto
nullable: true
nullable: true
nullable: true
contact:
type: object
description: ''
example: null
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: d
nullable: true
formEmbedUrl:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'https://gaylord.com/modi-deserunt-aut-ab-provident-perspiciatis.html'
nullable: true
mapEmbedUrl:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://www.cruickshank.com/adipisci-quidem-nostrum-qui-commodi-incidunt-iure'
nullable: true
nullable: true
nullable: true
security: []
/api/profile/images:
post:
summary: ''
operationId: postApiProfileImages
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
multipart/form-data:
schema:
type: object
properties:
featured_image:
type: string
format: binary
description: 'Must be a file. Must be an image. Must not be greater than 2048 kilobytes.'
featured_images:
type: array
description: 'Must be a file. Must be an image. Must not be greater than 2048 kilobytes.'
items:
type: string
format: binary
avatar:
type: string
format: binary
description: 'Must be a file. Must be an image. Must not be greater than 4096 kilobytes.'
avatars:
type: array
description: 'Must be a file. Must be an image. Must not be greater than 4096 kilobytes.'
items:
type: string
format: binary
security: []
/api/resources/content:
get:
summary: ''
operationId: getApiResourcesContent
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
patch:
summary: ''
operationId: patchApiResourcesContent
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
badge_label:
type: string
description: 'Must not be greater than 255 characters.'
example: b
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
intro:
type: string
description: ''
example: architecto
lender_tools_title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
lender_tools_description:
type: string
description: ''
example: architecto
lender_tools:
type: array
description: ''
example: null
items:
type: object
nullable: true
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: k
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://www.ernser.org/harum-mollitia-modi-deserunt-aut-ab-provident-perspiciatis-quo.html'
required:
- title
- url
drive_title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
drive_description:
type: string
description: ''
example: architecto
drive_embed_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
drive_open_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://rempel.com/sunt-nihil-accusantium-harum-mollitia'
nullable: true
youtube_title:
type: string
description: 'Must not be greater than 255 characters.'
example: k
youtube_description:
type: string
description: ''
example: architecto
youtube_embed_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://bailey.com/'
nullable: true
youtube_open_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://rempel.com/sunt-nihil-accusantium-harum-mollitia'
nullable: true
required:
- badge_label
- title
- intro
- lender_tools_title
- lender_tools_description
- drive_title
- drive_description
- youtube_title
- youtube_description
security: []
/api/lender-tools:
get:
summary: ''
operationId: getApiLenderTools
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
title:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
resource_url:
type: string
description: 'Must not be greater than 2048 characters.'
example: 'http://crooks.biz/et-fugiat-sunt-nihil-accusantium'
is_active:
type: boolean
description: ''
example: false
has_embed:
type: boolean
description: ''
example: true
page:
type: integer
description: 'Must be at least 1.'
example: 2
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 5
sort:
type: string
description: 'Must not be greater than 255 characters.'
example: k
security: []
post:
summary: ''
operationId: postApiLenderTools
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
resource_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://www.ernser.org/harum-mollitia-modi-deserunt-aut-ab-provident-perspiciatis-quo.html'
embed_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://swift.com/quidem-nostrum-qui-commodi-incidunt-iure-odit.html'
nullable: true
is_active:
type: boolean
description: ''
example: true
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 10
nullable: true
required:
- title
- resource_url
security: []
delete:
summary: ''
operationId: deleteApiLenderTools
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
ids:
type: array
description: 'The id of an existing record in the lender_tools table.'
example:
- 16
items:
type: integer
security: []
'/api/lender-tools/{lenderTool_id}':
get:
summary: ''
operationId: getApiLenderToolsLenderTool_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiLenderToolsLenderTool_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
resource_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://www.ernser.org/harum-mollitia-modi-deserunt-aut-ab-provident-perspiciatis-quo.html'
embed_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://swift.com/quidem-nostrum-qui-commodi-incidunt-iure-odit.html'
nullable: true
is_active:
type: boolean
description: ''
example: false
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 10
nullable: true
security: []
patch:
summary: ''
operationId: patchApiLenderToolsLenderTool_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
resource_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://www.ernser.org/harum-mollitia-modi-deserunt-aut-ab-provident-perspiciatis-quo.html'
embed_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://swift.com/quidem-nostrum-qui-commodi-incidunt-iure-odit.html'
nullable: true
is_active:
type: boolean
description: ''
example: true
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 10
nullable: true
security: []
delete:
summary: ''
operationId: deleteApiLenderToolsLenderTool_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: lenderTool_id
description: 'The ID of the lenderTool.'
example: 16
required: true
schema:
type: integer
/api/lender20-recordings:
get:
summary: ''
operationId: getApiLender20Recordings
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
is_active:
type: boolean
description: ''
example: false
page:
type: integer
description: 'Must be at least 1.'
example: 22
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 7
sort:
type: string
description: 'Must not be greater than 255 characters.'
example: z
security: []
post:
summary: ''
operationId: postApiLender20Recordings
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
youtube_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://www.ernser.org/harum-mollitia-modi-deserunt-aut-ab-provident-perspiciatis-quo.html'
is_active:
type: boolean
description: ''
example: true
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 24
nullable: true
required:
- title
- youtube_url
security: []
delete:
summary: ''
operationId: deleteApiLender20Recordings
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
ids:
type: array
description: 'The id of an existing record in the lender20_recordings table.'
example:
- 16
items:
type: integer
security: []
'/api/lender20-recordings/{lender20Recording_id}':
get:
summary: ''
operationId: getApiLender20RecordingsLender20Recording_id
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
security: []
put:
summary: ''
operationId: putApiLender20RecordingsLender20Recording_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
youtube_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://www.ernser.org/harum-mollitia-modi-deserunt-aut-ab-provident-perspiciatis-quo.html'
is_active:
type: boolean
description: ''
example: true
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 24
nullable: true
security: []
patch:
summary: ''
operationId: patchApiLender20RecordingsLender20Recording_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
title:
type: string
description: 'Must not be greater than 255 characters.'
example: b
description:
type: string
description: ''
example: 'Eius et animi quos velit et.'
nullable: true
youtube_url:
type: string
description: 'Must be a valid URL. Must not be greater than 2048 characters.'
example: 'http://www.ernser.org/harum-mollitia-modi-deserunt-aut-ab-provident-perspiciatis-quo.html'
is_active:
type: boolean
description: ''
example: false
sort_order:
type: integer
description: 'Must be at least 0. Must not be greater than 100000.'
example: 24
nullable: true
security: []
delete:
summary: ''
operationId: deleteApiLender20RecordingsLender20Recording_id
description: ''
parameters: []
responses: { }
tags:
- Endpoints
security: []
parameters:
-
in: path
name: lender20Recording_id
description: 'The ID of the lender20Recording.'
example: 16
required: true
schema:
type: integer
/api/cpd-records:
get:
summary: ''
operationId: getApiCpdRecords
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
type:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
date_from:
type: string
description: 'Must be a valid date. Must be a date before or equal to date_to.'
example: '2022-08-24'
date_to:
type: string
description: 'Must be a valid date. Must be a date after or equal to date_from.'
example: '2052-08-23'
page:
type: integer
description: 'Must be at least 1.'
example: 22
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 7
security: []
/api/cpd-records/export:
get:
summary: ''
operationId: getApiCpdRecordsExport
description: ''
parameters: []
responses:
401:
description: ''
content:
application/json:
schema:
type: object
example:
message: Unauthenticated.
properties:
message:
type: string
example: Unauthenticated.
tags:
- Endpoints
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
search:
type: string
description: 'Must not be greater than 255 characters.'
example: b
type:
type: string
description: 'Must not be greater than 255 characters.'
example: 'n'
date_from:
type: string
description: 'Must be a valid date. Must be a date before or equal to date_to.'
example: '2022-08-24'
date_to:
type: string
description: 'Must be a valid date. Must be a date after or equal to date_from.'
example: '2052-08-23'
page:
type: integer
description: 'Must be at least 1.'
example: 22
per_page:
type: integer
description: 'Must be at least 1. Must not be greater than 1000.'
example: 7
security: []
/api/admin/zoho/status:
get:
summary: 'Get Zoho connection status.'
operationId: getZohoConnectionStatus
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
connected: true
expires_at: '2026-04-09T10:12:30Z'
api_domain: 'https://www.zohoapis.com'
scope: ZohoCRM.modules.ALL
properties:
data:
type: object
properties:
connected:
type: boolean
example: true
expires_at:
type: string
example: '2026-04-09T10:12:30Z'
api_domain:
type: string
example: 'https://www.zohoapis.com'
scope:
type: string
example: ZohoCRM.modules.ALL
tags:
- 'Zoho CRM'
/api/admin/zoho/oauth/url:
get:
summary: 'Get Zoho OAuth authorization URL.'
operationId: getZohoOAuthAuthorizationURL
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
url: 'https://accounts.zoho.com/oauth/v2/auth?...'
properties:
data:
type: object
properties:
url:
type: string
example: 'https://accounts.zoho.com/oauth/v2/auth?...'
tags:
- 'Zoho CRM'
/api/admin/zoho/oauth/callback:
post:
summary: 'Exchange Zoho OAuth code for tokens.'
operationId: exchangeZohoOAuthCodeForTokens
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
connected: true
expires_at: '2026-04-09T10:12:30Z'
api_domain: 'https://www.zohoapis.com'
scope: ZohoCRM.modules.ALL
properties:
data:
type: object
properties:
connected:
type: boolean
example: true
expires_at:
type: string
example: '2026-04-09T10:12:30Z'
api_domain:
type: string
example: 'https://www.zohoapis.com'
scope:
type: string
example: ZohoCRM.modules.ALL
tags:
- 'Zoho CRM'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
code:
type: string
description: ''
example: architecto
state:
type: string
description: ''
example: architecto
required:
- code
- state
/api/admin/zoho/oauth/revoke:
post:
summary: 'Revoke Zoho OAuth tokens.'
operationId: revokeZohoOAuthTokens
description: ''
parameters: []
responses:
200:
description: ''
content:
application/json:
schema:
type: object
example:
data:
message: 'Zoho CRM connection revoked.'
properties:
data:
type: object
properties:
message:
type: string
example: 'Zoho CRM connection revoked.'
tags:
- 'Zoho CRM'