# Fusion API (api.nexttheme.co.uk) — Full Compatibility Analysis

Generated: 2026-02-25 19:38 UTC

## 1. Routing model

- Uses a simple path router (`Fusion\Core\Router`) that matches **HTTP method + URL path** and calls controller methods.

- `.htaccess` rewrites all requests to `index.php`, so routes are accessed as normal paths (e.g. `/clients`).

- Request body is parsed as JSON (`Fusion\Core\Request` reads `php://input` and `json_decode`).


## 2. Authentication / access control

- `AuthController::login` sets `$_SESSION['user_id']` via `AuthService::login`.

- **Most controllers do not enforce session auth** (only `UserController::getUserDetails/updateUserDetails` checks `$_SESSION['user_id']`).

- No server-side API key / Bearer token checks were found in non-vendor code.

- CORS allowlist exists in `index.php`, but if a request has no `Origin` header it is not blocked.


## 3. Response model

- Standard JSON responses via `Fusion\Core\Response::json($data, $status)`.

- Many endpoints return `{success: true/false, ...}`; some echo raw JSON without the wrapper.


## 4. Route inventory (from routes.php)


### /addons

- `GET` `/addons` → `AddonsController.index`

### /analytics

- `GET` `/analytics` → `AnalyticsController.index`
- `GET` `/analytics/metrics` → `AnalyticsController.getAnalyticsMetrics`

### /approvals

- `PUT` `/approvals/{id}` → `ApprovalsController.update`

### /auth

- `POST` `/auth/login` → `AuthController.login`
- `POST` `/auth/logout` → `AuthController.logout`

### /campaigns

- `POST` `/campaigns` → `CampaignController.createCampaign`
- `GET` `/campaigns/metrics` → `CampaignController.getCampaignMetrics`
- `DELETE` `/campaigns/{id}` → `CampaignController.deleteCampaign`
- `GET` `/campaigns/{id}` → `CampaignController.getCampaign`
- `PUT` `/campaigns/{id}` → `CampaignController.updateCampaign`

### /client

- `GET` `/client/profile/{id}` → `ClientController.getClientProfile`

### /clients

- `GET` `/clients` → `ClientController.getClients`
- `POST` `/clients` → `ClientController.createClient`
- `PUT` `/clients/archive/{id}` → `ClientController.archiveClient`
- `GET` `/clients/projects/{id}` → `ClientController.getClientProjects`
- `DELETE` `/clients/{id}` → `ClientController.deleteClient`
- `GET` `/clients/{id}` → `ClientController.getClient`
- `PUT` `/clients/{id}` → `ClientController.updateClient`

### /cms

- `GET` `/cms/menus` → `CMSController.menus`
- `GET` `/cms/pages` → `CMSController.pages`
- `GET` `/cms/pages/{slug}` → `CMSController.page`

### /contracts

- `POST` `/contracts/sign` → `ContractsController.signContract`
- `GET` `/contracts/status/{id}` → `ContractsController.getStatus`
- `GET` `/contracts/{id}` → `ContractsController.getContract`

### /crm

- `GET` `/crm/dashboard` → `CRMController.dashboard`
- `GET` `/crm/leads` → `LeadController.getLeads`
- `POST` `/crm/leads` → `LeadController.createLead`
- `DELETE` `/crm/leads/{id}` → `LeadController.deleteLead`
- `GET` `/crm/leads/{id}` → `LeadController.getLead`
- `PUT` `/crm/leads/{id}` → `LeadController.updateLead`

### /dashboard

- `GET` `/dashboard` → `DashboardController.index`

### /domains

- `GET` `/domains` → `DomainsController.getAll`
- `POST` `/domains/check` → `DomainsController.check`
- `POST` `/domains/register` → `DomainsController.register`
- `POST` `/domains/renew` → `DomainsController.renew`
- `POST` `/domains/{id}/contacts` → `DomainsController.updateContacts`
- `POST` `/domains/{id}/dns` → `DomainsController.updateDNS`

### /duoservers

- `GET` `/duoservers/domain/check` → `$duoController.checkDomain`
- `POST` `/duoservers/domain/check` → `$duoController.checkDomain`
- `PUT` `/duoservers/domain/details` → `$duoController.getDomainDetails`
- `GET` `/duoservers/domain/list` → `$duoController.listDomains`
- `POST` `/duoservers/domain/register` → `$duoController.registerDomain`

### /hosting

- `GET` `/hosting/accounts` → `HostingController.getAccounts`
- `POST` `/hosting/create` → `HostingController.create`
- `GET` `/hosting/{id}` → `HostingController.getAccount`
- `POST` `/hosting/{id}/mailbox` → `HostingController.addMailbox`
- `DELETE` `/hosting/{id}/mailbox/{mail_id}` → `HostingController.deleteMailbox`

### /invoices

- `GET` `/invoices` → `InvoiceController.getInvoices`
- `POST` `/invoices` → `InvoiceController.createInvoice`
- `DELETE` `/invoices/{id}` → `InvoiceController.deleteInvoice`
- `GET` `/invoices/{id}` → `InvoiceController.getInvoice`
- `PUT` `/invoices/{id}` → `InvoiceController.updateInvoice`

### /leads

- `POST` `/leads/convert/{id}` → `LeadController.convertLead`

### /orders

- `GET` `/orders` → `OrdersController.index`
- `POST` `/orders` → `OrdersController.create`
- `POST` `/orders` → `OrdersController.create`
- `DELETE` `/orders/{id}` → `OrdersController.delete`
- `GET` `/orders/{id}` → `OrdersController.get`
- `PUT` `/orders/{id}` → `OrdersController.update`

### /payments

- `GET` `/payments` → `PaymentController.getPayments`
- `POST` `/payments` → `PaymentController.createPayment`
- `POST` `/payments/initiate` → `PaymentController.initiate`
- `GET` `/payments/provider/{quote_id:[A-Za-z0-9_-]+}` → `PaymentController.suggestProvider`
- `GET` `/payments/quote/{quote_id:[A-Za-z0-9_-]+}` → `PaymentController.getQuote`
- `GET` `/payments/status` → `PaymentController.statusQuery`
- `GET` `/payments/status/{quote_id:[A-Za-z0-9_-]+}` → `PaymentController.status`
- `POST` `/payments/webhook` → `PaymentController.webhook`
- `DELETE` `/payments/{id:[A-Za-z0-9_-]+}` → `PaymentController.deletePayment`
- `GET` `/payments/{id:[A-Za-z0-9_-]+}` → `PaymentController.getPayment`
- `PUT` `/payments/{id:[A-Za-z0-9_-]+}` → `PaymentController.updatePayment`

### /portal-users

- `GET` `/portal-users` → `PortalUsersController.index`
- `POST` `/portal-users` → `PortalUsersController.create`
- `DELETE` `/portal-users/{id}` → `PortalUsersController.delete`

### /products

- `GET` `/products` → `ProductsController.index`
- `POST` `/products` → `ProductsController.create`
- `DELETE` `/products/{id}` → `ProductsController.delete`
- `GET` `/products/{id}` → `ProductsController.get`
- `PUT` `/products/{id}` → `ProductsController.update`

### /projects

- `GET` `/projects` → `ProjectController.getProjects`
- `POST` `/projects` → `ProjectController.createProject`
- `GET` `/projects/tasks/{projectid}` → `ProjectController.getTasksByProject`
- `DELETE` `/projects/{id}` → `ProjectController.deleteProject`
- `GET` `/projects/{id}` → `ProjectController.getProject`
- `PUT` `/projects/{id}` → `ProjectController.updateProject`
- `GET` `/projects/{id}/approvals` → `ApprovalsController.index`
- `POST` `/projects/{id}/approvals` → `ApprovalsController.create`
- `GET` `/projects/{id}/messages` → `MessagesController.index`
- `POST` `/projects/{id}/messages` → `MessagesController.create`
- `GET` `/projects/{id}/requirements` → `RequirementsController.getByProject`
- `POST` `/projects/{id}/requirements` → `RequirementsController.submit`
- `GET` `/projects/{id}/timeline` → `TimelineController.get`

### /quotes

- `GET` `/quotes/status/{quote_id:[A-Za-z0-9_-]+}` → `PaymentController.status`

### /search

- `GET` `/search` → `SearchController.search`

### /social_media

- `POST` `/social_media/add_page` → `SocialMediaController.addPage`
- `GET` `/social_media/analytics` → `SocialMediaController.analytics`
- `GET` `/social_media/best_posts` → `SocialMediaController.getBestPosts`
- `GET` `/social_media/calendar` → `SocialMediaController.calendar`
- `POST` `/social_media/campaigns` → `SocialMediaController.createCampaign`
- `GET` `/social_media/comments` → `SocialMediaController.getComments`
- `GET` `/social_media/dashboard` → `SocialMediaController.dashboard`
- `PUT` `/social_media/edit_page/{id}` → `SocialMediaController.editPage`
- `GET` `/social_media/library` → `SocialMediaController.library`
- `POST` `/social_media/posts` → `SocialMediaController.schedulePost`

### /status

- `GET` `/status/quote/{quote_id:[A-Za-z0-9_-]+}` → `PaymentController.status`

### /subscriptions

- `GET` `/subscriptions` → `SubscriptionsController.index`
- `POST` `/subscriptions` → `SubscriptionsController.create`
- `DELETE` `/subscriptions/{id}` → `SubscriptionsController.delete`
- `PUT` `/subscriptions/{id}` → `SubscriptionsController.update`

### /suppliers

- `GET` `/suppliers` → `SupplierController.getSuppliers`
- `POST` `/suppliers` → `SupplierController.createSupplier`
- `DELETE` `/suppliers/{id}` → `SupplierController.deleteSupplier`
- `GET` `/suppliers/{id}` → `SupplierController.getSupplier`
- `PUT` `/suppliers/{id}` → `SupplierController.updateSupplier`

### /support

- `GET` `/support/tickets` → `SupportController.index`
- `POST` `/support/tickets` → `SupportController.create`
- `POST` `/support/tickets/{id}/reply` → `SupportController.reply`

### /tasks

- `GET` `/tasks` → `TaskController.getTasks`
- `POST` `/tasks` → `TaskController.createTask`
- `PUT` `/tasks/assign/{id}` → `TaskController.assignTask`
- `DELETE` `/tasks/{id}` → `TaskController.deleteTask`
- `GET` `/tasks/{id}` → `TaskController.getTask`
- `PUT` `/tasks/{id}` → `TaskController.updateTask`

### /users

- `GET` `/users` → `UserController.getUsers`

### /v1

- `GET` `/v1/catalog/bundles` → `PackageController.getPackages`
- `GET` `/v1/catalog/bundles/{id}` → `PackageController.getPackage`
- `GET` `/v1/catalog/products` → `ProductsController.getProducts`
- `GET` `/v1/catalog/products` → `ProductsController.getProducts`
- `GET` `/v1/catalog/products/{id}` → `ProductsController.getProduct`
- `GET` `/v1/catalog/products/{id}` → `ProductsController.getProduct`
- `POST` `/v1/checkout/start` → `CheckoutController.start`
- `GET` `/v1/cms/portfolio` → `CMSController.portfolio`
- `GET` `/v1/cms/posts` → `CMSController.posts`

### /voip

- `POST` `/voip/buy` → `VoipController.buy`
- `GET` `/voip/numbers` → `VoipController.getNumbers`
- `GET` `/voip/{id}/logs` → `VoipController.getCallLogs`
- `POST` `/voip/{id}/routing` → `VoipController.updateRouting`
- `POST` `/voip/{id}/voicemail` → `VoipController.setVoicemail`

### /website

- `POST` `/website/checkout/pay` → `WebsiteController.createPayment`
- `POST` `/website/checkout/start` → `WebsiteController.startCheckout`

### /{any:.+}

- `OPTIONS` `/{any:.+}` → `None.None`