Source of truth: ServerMethodsHealthCheck.pas, CM_Health.pas, ServerMethodsBase.pas (WebAPI_Connect_Base, InternalConnect, CheckPervasive, ValidateDBConnectionInternal, DoValidateDBConnection), ServerMethodsWebAPI.pas (VerifyFundamentalConnections).
There are four different "is it working?" endpoints and they answer four different questions. Using the wrong one is the most common monitoring mistake with this service.
The four probes, and what each actually proves
| Endpoint | Credentials | Touches the database | Proves |
|---|---|---|---|
GET /HealthCheck/Health_Check | user HealthCheck, any password | No | The process is running and serving HTTP |
GET /{Class}/{X}_Handshake | real credentials | No | The process is running and your credentials are valid |
GET /TServerMethodsWebAPI/Connect | real credentials | Yes | A System Five session can be opened against the dataset |
POST /Vendors/ValidateDB | real credentials | Yes | The service is connected to the expected dataset |
Use them in that order when diagnosing a problem: each one that passes narrows the fault to the next layer.
GET /HealthCheck/Health_Check
GET /Windward/WebAPI/HealthCheck/Health_Check
Authorization: Basic base64("HealthCheck:anything")
{ "API Health Check": "I am here!", "Version": "1.2.3.4" }
The HealthCheck credential bypass
If the username is exactly HealthCheck (case-sensitive), the authentication handler grants the HealthCheck role and returns immediately — before the database check, the user lookup, the password test and the department check. The password is never examined.
That makes this the right probe for a load balancer or uptime monitor: it is cheap, it needs no real credential, and it never queues behind the service's global lock waiting on a database call.
It also makes it useless as an integration health check:
Important:
Health_Checkwill keep returning"I am here!"while the Pervasive/Zen engine is down, the dataset is unreachable, the licence has expired, or the service is pointed at the wrong data directory. It proves only that the process is alive.
The HealthCheck credential cannot be used for anything else — the HealthCheck role authorises only this one class.
Recommended monitor configuration
| Check | Endpoint | Alert on |
|---|---|---|
| Liveness | HealthCheck/Health_Check | non-200, or connection refused |
| Readiness | TServerMethodsWebAPI/Connect | Response != "Success" |
| Correctness | Vendors/ValidateDB | Success != "Y", run after any deployment or data-directory change |
Poll liveness frequently; poll readiness sparingly. Connect opens a System Five session and takes the global lock, so a tight polling interval will compete with real traffic.
GET /{Class}/{X}_Handshake
Every class except HealthCheck exposes a handshake:
| Class | Path | Response first key |
|---|---|---|
TServerMethodsWebAPI | /TServerMethodsWebAPI/Handshake | System Five Web API |
Invoice | /Invoice/Invoice_Handshake | System Five Invoice API |
Customer | /Customer/Customer_Handshake | System Five Customer API |
Inventory | /Inventory/Inventory_Handshake | System Five Inventory API |
VirtualInventory | /VirtualInventory/VirtualInventory_Handshake | System Five VirtualInventory API |
Vendors | /Vendors/Vendor_Handshake | System Five Vendor API |
APBill | /APBill/APBill_Handshake | System Five APBill API |
Category | /Category/Category_Handshake | System Five Category API |
Units | /Units/Unit_Handshake | System Five Unit API |
Keyword | /Keyword/Keyword_Handshake | System Five Keyword API |
{ "System Five Invoice API": "Handshake", "Version": "1.2.3.4" }
A handshake requires valid credentials, so a 200 with this body confirms that your username, password, user status and department access are all good. It does not open a dataset session.
Version is read from the S5WebAPISvc.exe file version resource. Record it when reporting a problem — behaviour differs across builds (the Update Inventory Supplier setting and the Invoices2 endpoint, for example, were added in specific builds).
GET /TServerMethodsWebAPI/Connect
The real readiness probe. It runs InternalConnect, which establishes a System Five session against the configured data directory.
Success returns the legacy envelope with Response: "Success". Failure returns Response: "Failed" with a reason.
VerifyFundamentalConnections — the gate that runs before every operation on the TServerMethodsWebAPI class — reports the same two failure modes, so these messages will also appear on ordinary calls:
| Reason | Meaning |
|---|---|
Unable to retrieve valid session | The engine answered but a System Five session could not be established. Usually a data-directory, licence-count or serial-number problem. |
| One of the Pervasive messages below | The database engine itself is unavailable or unlicensed. |
Pervasive / Zen check messages
Produced by TServerMethodsBase.CheckPervasive:
| Message | Meaning |
|---|---|
The Pervasive database check has not been done | The probe has not yet run |
The Pervasive database check has passed | Healthy |
The Pervasive database license check has failed; has your license expired or have you exceeded the maximum number of users? | Status 161 — licence or user-count limit |
The Pervasive database license check has failed; has your trial version expired? | Status 161 on a demo build |
The Pervasive database license check has failed with an unknown error. | Any other failure |
The user-count message is the one to watch in production: it appears when the site has exhausted its Zen user licences, and the API is competing for those licences with ordinary System Five workstations.
POST /Vendors/ValidateDB
Answers a question none of the others can: is this service connected to the dataset I think it is?
{ "Terminal": 1, "Desc": "prod-2026-09-01-a7f3" }
| Field | Notes |
|---|---|
Terminal | System Five terminal number; parsed with a default of 0 |
Desc | The marker string to compare |
The service reads the System Five setup value ('SQL', 'TEMP', Terminal) from its connected dataset and compares it, as a string, to Desc.
How to use it
- From inside System Five — or from any tool with a verified connection to the dataset you intend — write a unique marker into that setup slot for a chosen terminal number. Something dated and environment-specific works well:
prod-2026-09-01-a7f3. - Store the same marker in your integration's configuration.
- Call
ValidateDBat startup and after any deployment.
Responses
{ "Success": "Y", "Result": "Connection Successful" }
{ "Success": "N", "Result": "Failed; The Web API service is connected to a different database!" }
{ "Success": "N", "Result": "Required Validation Parameters missing" }
Success is the string "Y" or "N", not a boolean, and there is no APIResponse wrapper.
Required Validation Parameters missing means Terminal or Desc was absent; it is also returned when Desc is present but empty, because the comparison is skipped for an empty marker.
Important: This is the guard against the most damaging deployment mistake with this service: an API instance left pointing at a test or restored copy of the data directory, quietly accepting writes that never reach production. Run it after every deployment and every data-directory change.
The operation is declared on the Vendors class for historical reasons and has nothing to do with vendors.
Interpreting a failure
| Symptom | Most likely cause |
|---|---|
| Connection refused | Service stopped, or wrong port (default is 215, not 8080) |
403 with {"Error":"User not found ..."} | Username does not exist in System Five |
403 with {"Error":"Password check failed ..."} | Wrong password, or the KEK-encrypted form does not match |
403 with {"Error":"... does not have access to department"} | The user is valid but not permitted in the department this service instance is configured for |
403 with {"Error":"User has been locked out ..."} | The System Five user is locked; unlock it in System Five |
200 with Response: "Failed" and a Pervasive message | Engine or licence problem, not your payload |
200 with Response: "Failed" and Unable to retrieve valid session | Dataset/serial/licence problem, not your payload |
200 with IsSuccess: false and RecordCount: "0" | Query succeeded but matched nothing — see Response Envelopes and Error Semantics |
Health_Check works but everything else fails | The process is up but the database layer is not — exactly the case Health_Check cannot detect |
Every request is logged to the Windows event log (and to Log Analytics where configured), with verbosity controlled by the [System Five Web API Service] INI section. When a message in the body is not enough, the event log entry for the same call carries the parameters and the exception detail.


