Skip to content

API reference, by persona

The backend exposes ~372 persona endpoints across six route files. Rather than reprint every route (the routes/api/*.php files are the exhaustive, always-current source), this page gives you the map: how routing + auth are wired, what each persona exposes by resource, and the handful of exceptions that cause most “why is this 401/404/raw-XML” confusion. Verified against current code.

Each persona file is mounted under an api/<persona> prefix with a matching controller namespace (RouteServiceProvider.php:143-186), and auth is two layers: a file-level user-provider:<persona> (selects the model/guard) wrapping an inner auth:sanctum + ability:access-<persona>-api group.

Persona Prefix Provider Ability (Sanctum)
Shopper api/shopper shoppers access-shopper-api
Broker api/broker brokers access-broker-api (+ access-pre-registration-broker-api for Oman pre-reg)
Sales-Man api/sales-man sales_man access-sales-man-api
Sales-Manager api/sales-manager sales_managers access-sales-manager-api
Shopper-Admin api/shopper-admin shopper_admins access-shopper-analytics-api
CRM-middleware api/crms-middleware Passport client (client_credentials)

Ability strings live in AuthTokenAbilities.php:7-12. The auth model explains the token mechanics; this page is about which endpoints exist.

Shopper — api/shopper access-shopper-api

Section titled “Shopper — api/shopper ”

The public customer app. Split: public/token-gated (shopper.php:10-91) and authenticated (:97-143). Resource groups:

  • Auth / registration — login + registration OTP, user-data-availability (public); logout, me, details (auth).
  • Catalog browse (public) — countries, destinations/{slug} (+ unit-types/projects/locations/ testimonials/facilities/faqs/construction-updates/educational-hubs), units, units/compare, units/{unit}, filters, promotions, news, pages/{pageName}.
  • CRM sale-form lookups (public) — sales-nationalities|-countries|-cities|-occupations|-connections.
  • Sales offer…/sales-offer/{plan}/generate (public, throttled) → …/status…/download (signed). See Generating a sales-offer PDF.
  • The purchase flow (auth) — units/{unit}/sale{sale}/reserve{salePayment}/payment{sale}/update-info{sale}/reservation-form{sale}/finish-sale. See Shopper buys a unit.
  • Add-ons (auth) — list/show/submit/purchase.
  • EOI payment (public, link-gated) — launches/{launch}/eois/{eoi}/payment, …/validate-token.
  • Owner dashboards (auth) — user/cards|offers|news|referrals|units|saved-units|customer-requests.

Broker — api/broker access-broker-api+ pre-reg ability

Section titled “Broker — api/broker ”

External sales agents. Three tiers: public (auth/OTP, whitelist, signed download), the Oman pre-registration sub-tree under access-pre-registration-broker-api (:50-68), and the main access-broker-api API (:79-283). Main resource groups:

  • Account — register/OTP/password-reset (public); logout, whitelabel logo, notifications, documents.
  • Catalog — destinations/units/filters/news/launches (many resource-visibility-gated per assignment).
  • Sales offer…/generate/status/download (signed).
  • Leadsleads, leads/count, leads/{id}, leads-duplicate, meetings, sales_invoices. See Broker submits a lead.
  • EOI — full CRUD: eois (list/search/export), launches/{launch}/eois (create), update/cancel/ require-action/attachments, and the products → unit-types → preferences nested tree. See Submitting an EOI.
  • Analytics — revenue-insights, commissions, rankings, lifecycle-counts (180/min).
  • Oman — the pre-registration workflow (own ability) + the post-registration oman-application document/contract resubmission. See Oman broker pre-registration.

Sales-Man — api/sales-man access-sales-man-apicountry-gated

Section titled “Sales-Man — api/sales-man ”

Internal ODH agents (Microsoft SSO). Three tiers: public lookups + signed download; authenticated without country gate; authenticated behind salesman-country-validation (the bulk). Groups:

  • No-countryunits browse/compare/export, destinations, saved-units, notifications, sales-offer gen. (logout is a GET.)
  • Country-gated — the whole CRM pipeline: leads (lifecycle: search/check-eligible/disqualify/ feedback), sales, customers, pipelines (+ meetings/unit-types/feedback), meetings, the same EOI tree as broker, taskeen (handover), and a broad analytics/* surface (sales/leads/meetings overviews, rankings). Plus CRM conditional-field lookups (ambassadors, events, offices, system-users, exhibitions, crm-units, brokers, sales-agents, competitions, corporates, lead-sources/subsources, lead-countries). See Sales-Man closes a sale.

Sales-Manager — api/sales-manager access-sales-manager-api

Section titled “Sales-Manager — api/sales-manager ”

A role inside the broker app, analytics-only — no public routes. logout + analytics/*: filters, leads/lifecycle-counts, commissions (+ brokers-commissions/export), and rankings (brokerages/sales-managers/brokers) + revenue-insights + sales/count-per-destination/international.

Shopper-Admin — api/shopper-admin access-shopper-analytics-api

Section titled “Shopper-Admin — api/shopper-admin ”

The shopper-behaviour analytics persona. Public login/reset; authenticated analytics/*: overview summaries, destinations/unit-types performance, user-requests, logins, sales & leads analytics, customer behaviour (searches-with-no-results), demographics (per-country), and funnel analysis.

CRM-middleware webhook — api/crms-middleware Passport client_credentials

Section titled “CRM-middleware webhook — api/crms-middleware ”

The inbound surface crms-middleware calls to push CRM changes into the local mirror. POST login is public; the rest are under the bare client guard (crms-middleware.php:7).

METHOD · path Controller Purpose
POST login AuthController@login (public) Obtain a client token
POST units/{sourceId} UnitController@insert Upsert a unit into the local mirror
POST brokers/register · PATCH brokers/update BrokerController@register/update Broker sync (mints the real Broker)
POST brokers/user/notifications NotificationController@generalNotification Broker notification
POST leads/{id}/notifications · meetings/{id}/notifications · eois/{id}/notifications NotificationController@* Status notifications
PATCH sales/{saleSourceId} UnitSaleController@updateSale CRM sale-status → local unit_sale
POST eoi EOIController@store Persist an EOI from the CRM
Persona Public / token-gated Authenticated Total
Shopper 49 28 77
Broker 15 99 (12 Oman-pre-reg + 87 main) 114
Sales-Man 6 114 (29 no-country + 85 country-gated) 120
Sales-Manager 0 16 16
Shopper-Admin 3 32 35
CRM-middleware 1 9 10
Total (persona files) ≈ 372

(Counts are literal Route:: declarations; the routes/api/*.php files are the exhaustive, current source — this page maps the structure, not every line.)