How the API returns dates and times, which formats it accepts in requests, and how fields that only hold a date are represented.
The API returns every date and time in UTC.
In requests, it accepts UTC as well as local time in the Europe/Berlin time zone.
In shortRead every value as UTC.
Send UTC with a trailingZ, e.g.2025-03-10T15:09:36Z.
Responses
Every date and time in a response is an ISO 8601 timestamp in UTC, with whole seconds and a trailing Z:
{
"created": "2025-03-10T15:09:36Z",
"lastModified": null
}The format is always yyyy-MM-ddTHH:mm:ssZ.
A value that isn't set is null.
Webhooks
Dates and times in webhook messages are in UTC with a trailing Z as well, but they may contain fractional seconds, e.g. 2026-01-15T08:05:37.873Z.
Parse them as ISO 8601 instead of relying on a fixed number of digits.
Requests
Dates and times in request bodies, including the filters of search requests, are read as follows:
| Format | Example | Read as |
|---|---|---|
UTC with a trailing Z | 2025-03-10T15:09:36Z | UTC. Recommended. |
| Without a time zone | 2025-03-10T16:09:36 | Local time in Europe/Berlin (CET in winter, CEST in summer). |
| Date only | 2025-03-10 | Midnight of that day in Europe/Berlin. |
| With an offset | 2025-03-10T16:09:36+01:00 | Not supported. The offset isn't applied correctly, so the value may be off by hours. |
The first two examples describe the same point in time.
Fractional seconds, such as 2025-03-10T15:09:36.500Z, are accepted.
A value that can't be read is rejected with 400 Bad Request and the message Could not read datetime.
Always use ISO 8601, as other formats aren't guaranteed to be read correctly.
Fields that only hold a date
Some fields only hold a calendar date without a time, for example the move-in and move-out dates of a unit contract.
facilioo stores such a date as midnight in Europe/Berlin and returns that point in time in UTC, like any other value.
| Stored date | Returned value |
|---|---|
| 10 March 2025 (CET, UTC+1) | 2025-03-09T23:00:00Z |
| 1 May 2025 (CEST, UTC+2) | 2025-04-30T22:00:00Z |
The returned value therefore shows the previous day in UTC.
To get the date, convert the value to Europe/Berlin and use its date part.
When writing such a field, send the date only, e.g. 2025-05-01.
Filtering by date
Range filters such as createdFrom and createdUntil include their bounds: an entity created exactly at createdFrom is part of the result.
Send the bounds in UTC to avoid the shift between UTC and Europe/Berlin:
{
"createdFrom": "2025-01-01T00:00:00Z",
"createdUntil": "2025-12-31T23:59:59Z"
}Filtering fields that only hold a date
To filter a field that only holds a date, send the date only, e.g. 2025-03-10.
It is read as midnight in Europe/Berlin, which is exactly the point in time facilioo stores for that date, so you don't need to convert anything to UTC.
To find all consumption meters whose next reading is due on 10 March 2025, send the same date as both bounds:
{
"nextReadingDateAfter": "2025-03-10",
"nextReadingDateBefore": "2025-03-10"
}This matches the consumption meters that the API returns with "nextReadingDate": "2025-03-09T23:00:00Z".
Don't send the UTC midnight of the date, e.g. 2025-03-10T00:00:00Z, as that is 1 am in Europe/Berlin and misses the stored value.
