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.
How routing + auth are wired
Section titled “How routing + auth are wired”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.
The exceptions that trip people up
Section titled “The exceptions that trip people up”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). - Leads —
leads,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-applicationdocument/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-country —
unitsbrowse/compare/export, destinations, saved-units, notifications, sales-offer gen. (logoutis 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 broadanalytics/*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 |
Endpoint counts
Section titled “Endpoint counts”| 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.)
