Examples

List accessible sites

Returns a paginated, flat list of every site the token can read. Nested objects like zones and passages are intentionally omitted — fetch a single site if you need them.

The response's meta.pagination object contains limit, offset, total, hasPrevious, and hasNext to drive page navigation.

Example request:

curl "https://api.technis.com/v3/sites?limit=50&offset=0" \
  -H "x-api-key: $TECHNIS_API_KEY"

Archived and deleted sites are excluded from the list.

Get site details

Returns one site with its zones, passages, and the devices attached to each. Use this when you need the full topology of a location; you do not need to call separate zone, passage, or device endpoints.

curl https://api.technis.com/v3/sites/843 \
  -H "x-api-key: $TECHNIS_API_KEY"
{
  "data": {
    "id": "843",
    "name": "A | Balma-Gramont",
    "category": "mixed-use",
    "address": { "street": "Route de Lavaur", "postCode": "31500", "city": "Toulouse", "country": "France" },
    "timezone": "Europe/Paris",
    "organizationId": "316",
    "archived": false,
    "createdAt": "2026-06-02T14:04:55.780Z",
    "updatedAt": "2026-06-02T14:20:53.122Z",
    "constructionYear": null,
    "zones": [
      {
        "id": "2",
        "name": "Ground floor",
        "category": "sales",
        "capacity": 120,
        "area": 450.5,
        "devices": []
      }
    ],
    "passages": [
      {
        "id": "3",
        "name": "Main entrance",
        "fromZoneId": null,
        "toZoneId": "2",
        "devices": [
          { "id": "4", "name": "Entrance counter", "status": "Online" }
        ]
      }
    ]
  },
  "meta": {
    "requestId": "550e8400-e29b-41d4-a716-446655440000",
    "serverTag": "0.0.1",
    "warnings": [],
    "errors": []
  }
}

Notes:

  • passages[].fromZoneId: null (or toZoneId: null) means the passage opens to the outside.
  • zones[].devices lists atmosphere devices; passages[].devices lists pad devices.
  • category, timezone, updatedAt, and constructionYear are nullable.
  • A 404 with SITE_NOT_FOUND means the site does not exist in your scope; a 403 with FORBIDDEN_ACCESS means the key cannot read it.

Query historical metrics

A single endpoint that abstracts the historic Metrics API behind four required parameters and friendly names (for example, entrances instead of AFFLUENCE_IN).

Request body:

{
  "metrics": ["entrances"],
  "siteId": "46",
  "from": "3 months ago",
  "to": "now",
  "granularity": "day"
}

Required fields: metrics, siteId, from, to.

Optional fields:

FieldTypeDefaultNotes
granularity"minute" | "hour" | "day" | "month"server-inferredBucket size. "minute" is only allowed for ranges up to 1 day.
aggregation"average" | "sum" | "maximum" | "minimum"metric-specificHow values inside a bucket are reduced.
timezoneIANA name (e.g. Europe/Zurich)Etc/UTCAffects bucket boundaries.
filter.zoneIdsstring[]site's top zoneRestrict to specific zones.
filter.passageIdsstring[]Restrict to specific passages.
livebooleanfalseSwitches the endpoint into SSE mode (see below).

from and to accept a relative expression ("5 minutes ago", "3 months ago", "now") or an absolute datetime in YYYY-MM-DDTHH:MM:SS / YYYY-MM-DD HH:MM:SS format. Other formats return INVALID_TIME_FILTER.

Example:

curl -X POST https://api.technis.com/v3/metrics \
  -H "x-api-key: $TECHNIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "metrics": ["entrances"],
    "siteId": "843",
    "from": "2 months ago",
    "to": "1 day ago",
    "granularity": "day"
  }'

Response:

{
  "data": [
    { "timestamp": "2026-04-01T00:00:00+00:00", "metrics": { "entrances": 12840 } },
    { "timestamp": "2026-04-02T00:00:00+00:00", "metrics": { "entrances": 13975 } }
  ],
  "meta": {
    "requestId": "550e8400-e29b-41d4-a716-446655440000",
    "serverTag": "0.0.1",
    "warnings": [],
    "errors": [],
    "inferredParams": {
      "granularity": "day",
      "timezone": "Etc/UTC",
      "live": false,
      "filter": { "zoneIds": ["2122"] }
    }
  }
}

meta.inferredParams echoes back every optional field the server filled in on your behalf. Logging it is the fastest way to debug "why am I getting these numbers?" questions.

Stream real-time updates

Set "live": true in the request body to stream metrics as they update instead of receiving a single batch response.

curl -N -X POST https://api.technis.com/v3/metrics \
  -H "x-api-key: $TECHNIS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "metrics": ["entrances"],
    "siteId": "843",
    "from": "5 minutes ago",
    "to": "now",
    "granularity": "minute",
    "live": true
  }'

The server holds the connection open and emits one SSE event per update. Each event's data: payload is a JSON object with the same shape as a single entry in the non-live data array:

data: {"timestamp":"2026-05-29T08:42:00+00:00","metrics":{"entrances":3}}

data: {"timestamp":"2026-05-29T08:43:00+00:00","metrics":{"entrances":5}}

If you provide from, to and granularity together with live: true initial payload will contain the historical data as well. Omitting those fields means you'll get only live updates.

Latest know value for the metric is always pushed upon connection.

Treat the stream like any other SSE connection: read events until the server closes the connection or the client gives up, and reconnect with backoff if the network drops.

Get one-shot latest value

If you need to get the latest value of a metric in a single request for calculation in a server-side application, you can use from: now and to: now as the time range. The response will contain a single value per requested metric.

curl -N -X "POST" "https://api.technis.com/v3/metrics?limit=10&offset=0" \
     -H "X-API-KEY: $TECHNIS_API_KEY" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d $'{
  "siteId": "843",
  "to": "now",
  "from": "now",
  "metrics": ["entrances", "visitorsInside"]
}'

response:

{
  "data": [
    {
      "timestamp": "2026-06-11T08:24:20+00:00",
      "metrics": {
        "entrances": 12,
        "visitorsInside": 9
      },
      "matchingFilters": {
        "zoneIds": [
          "5797"
        ]
      }
    }
  ],
  "meta": {
    "requestId": "583e6212-31f6-4fd0-8136-b7710baefb9b",
    "serverTag": "v3.0.2",
    "warnings": [],
    "errors": [],
    "inferredParams": {
      "from": "2026-06-11T08:24:23",
      "to": "2026-06-11T08:24:23",
      "granularity": "minute",
      "timezone": "Etc/UTC",
      "live": false,
      "filter": {
        "zoneIds": [
          "5797"
        ]
      }
    }
  }
}


Did this page help you?