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'