Web Service Data Sources
Reading any REST or HTTP API — endpoints, JSON paths, headers, timestamp units, and response caching.
The Web Service connector reads any REST or HTTP API. It is the general-purpose connector — the answer for ERP endpoints, cloud platforms, laboratory systems, grid and weather services, and anything else with no dedicated Infohub connector.
It also has the largest property set of any data source, because APIs vary so much. This article covers the request and response side; authentication is large enough to have its own article.
Connection properties#
| Property | Notes |
|---|---|
| Host | Base address of the API |
| Authentication | None, Basic, or OAuth 2.0 |
| Validate Server Certificate | Whether the TLS certificate is verified |
| Username / Password | For Basic authentication |
| Endpoint Key | A key value, referenced from headers as [Key] |
| Headers | Header templates sent with every request |
| Cache | Enable response caching |
| Cache Duration | How long a cached response stays valid |
| Maximum Concurrent | Parallel request limit |
The OAuth 2.0 properties — token URL, grant type, client authentication, keys, claims, scope — are covered separately.
Validate Server Certificate defaults to False. The default is permissive so that development against self-signed endpoints works out of the box. Turn it on for anything reaching a real service. Leaving it off means Infohub will accept any certificate, including one presented by something that is not the service you intended to call.
Headers#
The Headers property carries header templates sent with every request. Each line is one header, in the form Name:Value:
Authorization:Bearer [Key]
Accept:application/json
X-Client-Id:flow-production
[Key] substitutes the Endpoint Key, which keeps the credential in its own property rather than embedded in the header text.
Two rules about the format matter.
A header needs a name and a value, separated by a colon. A line containing only Bearer is not a header — it has no name. The connector validates header templates when the connection is tested, so a malformed line is reported then rather than producing an unexplained authorisation failure later.
Only the first colon separates. Everything after it is the value, so values containing colons — URLs, timestamps — are preserved intact.
The most common header mistake. Writing Bearer alone, or Bearer [Key], instead of Authorization:Bearer [Key]. The header name is Authorization; Bearer is part of the value. A connection with this mistake fails with an unauthorised response from the service, which sends people to check credentials that were never the problem.
Per-measure properties#
Each measure describes one endpoint and how to find its values in the response.
| Property | Notes |
|---|---|
| Endpoint | Path appended to the host |
| Data path | Path to the collection of readings within the response |
| Value path | Path to the value within each reading |
| Quality path | Path to a quality indicator, if present |
| Timestamp path | Path to the timestamp within each reading |
| Timestamp unit | Auto, Seconds, or Milliseconds |
Plus the usual retrieval processing: Aggregation, Rollover, Deadband, State Comparator / State, Scaling.
Mapping a JSON response#
Start by capturing an actual response. Call the endpoint with a generic HTTP client, look at the JSON, and only then configure the measure. Guessing the shape is the main reason a Web Service measure returns nothing while the connection tests perfectly.
Array of objects#
The most common shape — a list of readings, each with its own timestamp and value:
{
"data": [
{ "from": "2026-08-13T10:00Z", "intensity": { "actual": 214 } },
{ "from": "2026-08-13T10:30Z", "intensity": { "actual": 221 } }
]
}
| Property | Value |
|---|---|
| Data path | data |
| Timestamp path | from |
| Value path | intensity.actual |
The data path locates the array; the timestamp and value paths are evaluated relative to each element.
Parallel arrays#
Some APIs return separate lists — one of timestamps, one of values — that correspond by position:
{
"hourly": {
"time": ["2026-08-13T10:00", "2026-08-13T11:00"],
"temperature": [18.4, 19.1]
}
}
The connector handles this shape too, pairing the lists by index. Point the timestamp path at the time list and the value path at the value list.
This is worth knowing because parallel arrays are common in weather and forecasting APIs, and it is not obvious that a connector designed around arrays of objects would cope with them.
Timestamp units and time zones#
Two things go wrong with timestamps often enough to call out.
Epoch seconds versus milliseconds. Numeric timestamps are frequently Unix epoch values, and nothing in the number tells you which unit it is. Auto infers it from magnitude, which is reliable for present-day timestamps. Set it explicitly to Seconds or Milliseconds when you know, particularly for historical data far from the present where the inference has less to work with.
Getting this wrong is unmistakable once you look: values land decades away from where they belong.
Missing offsets. A timestamp such as 2026-08-13T10:00 carries no zone. Where an API returns times without an offset, confirm what it means by them before trusting the alignment. A response read as server-local when it was meant as UTC shifts every value by the offset — enough to put readings in the wrong hour, and in the wrong day near midnight.
Verify with a known value. Retrieve one measure, then compare a single value and its timestamp against what the API returns in a browser. Timestamp errors are obvious when checked and invisible when assumed.
Response caching#
Cache and Cache Duration let one response serve several measures.
This is genuinely valuable, because many APIs return a document containing dozens of values. Without caching, twenty measures reading the same document make twenty identical calls per interval. With caching, the first call is made and the rest are served from it.
The cache is bounded by both the duration you set and an internal entry cap, so it cannot grow without limit.
Set Cache Duration to a little less than the interval at which the source actually updates. A service publishing half-hourly gains nothing from a five-second cache and nothing is lost by a twenty-minute one.
Rate limits are a real constraint. Public and commercial APIs meter calls, and some cost money per call. Before deploying, multiply: measures × calls per interval × intervals per day. Enable caching, keep Maximum Concurrent modest, and retrieve at the interval the data actually changes rather than more often. An enthusiastic Infohub model can exhaust a daily quota before lunch.
Reliability#
APIs fail differently from historians — they time out, rate-limit, return partial data, and change shape without warning.
Practical defences:
- Set a realistic concurrency limit. Parallelism that a historian shrugs off will trip an API's rate limiter.
- Expect gaps and guard calculations that depend on the data, so a failed call produces no value rather than a wrong one.
- Watch for shape changes. A provider adding a nesting level breaks the value path. If a long-working measure stops returning values, re-capture the response before investigating Infohub.
- Retrieve at the source's real resolution. Asking a half-hourly service for minutely data produces repeated values and wasted calls.
Diagnosing#
| Symptom | Check |
|---|---|
| Unauthorised response | Header format — Authorization:Bearer [Key], not Bearer alone |
| TLS error | Validate Server Certificate, and whether the Platform host trusts the chain |
| Connection tests, measure returns nothing | Data, value, and timestamp paths against a real captured response |
| Values at absurd dates | Timestamp unit — seconds versus milliseconds |
| Values shifted by whole hours | Time zone; the response has no offset |
| Worked for months, now empty | The API's response shape changed |
| Rate limited or throttled | Enable caching, lower concurrency, retrieve less often |
| Duplicate values across intervals | Retrieving more often than the source updates |