Companies API
Manage companies in the system (create, list, update status/name, delete, and manage the Nomod payment token).
Base URL
/api/companies
Authentication & Authorization
- Auth is cookie-based JWT.
- All endpoints require a valid session.
- Role requirements per endpoint are listed below.
- For non–super-admin users, results are automatically scoped to the user's
allowedCompanieslist.
Content Types
- Requests:
application/jsonunless noted. - Responses:
application/json.
Data Model
Company (response shape)
{
"id": 1,
"name": "Acme Developments",
"isActive": true,
"createdAt": "2024-05-01T10:20:30.000Z",
"hasToken": true
}
hasTokenistruewhen a Nomod token is set (nomodTokenis stored server‑side and never returned).
Endpoints
List Companies
GET /api/companies
Auth: admin, sales, finance, or agent
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| query | string | No | Case-insensitive search by company name. |
Behavior
- If the caller is not
super-admin, the response is filtered to companies within the caller’sallowedCompanies. If the caller has no allowed companies, an empty array is returned.
Response – 200
[
{
"id": 3,
"name": "Blue Tower LLC",
"isActive": true,
"createdAt": "2024-02-18T12:44:00.000Z",
"hasToken": false
}
]
Errors
401 Unauthorized– No/invalid session.403 Forbidden– Role not permitted.500 Internal Server Error– Unexpected error.
cURL
curl -X GET \
-b "token=<jwt-cookie>" \
"https://your.api.host/api/companies?query=blue"
Create Company
POST /api/companies
Auth: admin
Request Body
{
"name": "Acme Developments",
"isActive": true
}
Response – 201
{
"message": "Companies created successfully",
"id": 42
}
Errors
401 Unauthorized– No/invalid session.403 Forbidden– Onlyadmin.500 Internal Server Error– Database/validation error.
cURL
curl -X POST https://your.api.host/api/companies \
-H "Content-Type: application/json" \
-b "token=<jwt-cookie>" \
-d '{"name":"Acme Developments","isActive":true}'
Update Company
PUT /api/companies/{id}
Auth: admin
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | number | Yes | Company identifier |
Request Body
Any combination of the following fields:
{
"name": "Acme Developments (UAE)",
"isActive": false
}
Response – 200
{ "message": "Companies updated successfully" }
Errors
401 Unauthorized403 Forbidden404 Not Found– Company does not exist.500 Internal Server Error
cURL
curl -X PUT https://your.api.host/api/companies/42 \
-H "Content-Type: application/json" \
-b "token=<jwt-cookie>" \
-d '{"name":"Acme Developments (UAE)","isActive":false}'
Delete Company
DELETE /api/companies/{id}
Auth: admin
Response – 200
{ "message": "Companies deleted successfully" }
Errors
401 Unauthorized403 Forbidden500 Internal Server Error
cURL
curl -X DELETE \
-b "token=<jwt-cookie>" \
https://your.api.host/api/companies/42
Set/Update Nomod Token
POST /api/companies/token
Auth: admin
Purpose: Set or replace the Nomod payment token for a company. The token is stored server-side and never returned by the API.
⚠️ Implementation note: The current handler uses
req.params.idbut the router path does not define:id. In production we recommend using either:
POST /api/companies/{id}/token(path parameter), orPOST /api/companies/tokenwith a request body includingcompanyId.The example below documents the request-body variant (works best without changing the route).
Request Body
{
"companyId": 42,
"token": "nomod_live_xxx"
}
Behavior
- Server persists the token against the specified company.
- No token value is ever returned in responses.
Response – 200
{ "message": "Company updated successfully" }
Errors
400 Bad Request– MissingcompanyIdortoken. (If you keep the path-parameter variant, validate and supply{id}in the path instead.)401 Unauthorized403 Forbidden404 Not Found– Company does not exist.500 Internal Server Error
cURL
curl -X POST https://your.api.host/api/companies/token \
-H "Content-Type: application/json" \
-b "token=<jwt-cookie>" \
-d '{"companyId":42,"token":"nomod_live_xxx"}'
Notes & Constraints
- Access scoping: Non–super-admin users will only see companies that belong to their
allowedCompaniesset. - Security: The Nomod token is write-only via the API; it is not included in any read responses. Externally, only a boolean
hasTokenis exposed. - Missing single-get route: There is an internal
getCompaniesByIdcontroller that is not currently mounted on the router. If needed, add:and document it accordingly.companiesRouter.get("/:id", authorize(["admin","sales","finance","agent"]), getCompaniesById)
Error Format
All non-2xx responses follow:
{ "message": "Human readable error message." }
Changelog
- v1.0 – Initial documentation for Companies API (list, create, update, delete, set Nomod token).