Scroll down to learn more

Documentation Center

Welcome to Verity Documentation Center. You find here all the content you need to enjoy your data.

Search Results for

    Show / Hide Table of Contents

    Getting started

    This page takes you from nothing to a data point you can read back, in six calls. It is deliberately literal: copy each command, replace the placeholders, and you have a working integration by the end.

    Everything here is done with curl, so it translates to any language.

    The six steps of a first integration

    Steps 2 to 4 build the structure and are done once. Steps 5 and 6 are what your integration repeats.

    Important

    If your sites and sources already exist — created in the interface, or by a master data synchronisation — skip to Step 5. You only need the variable id or the source identifier + mappingConfig pair.

    What you need

    • A client_id and client_secret, from support@opinum.com.
    • A Insights user with the Data Pusher right, created by a manager of your account.

    Details in Connect to the API.

    Step 1 — Get a token

    curl -s -X POST 'https://auth.opinum.com/realms/opinum/protocol/openid-connect/token' \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      --data-urlencode 'grant_type=password' \
      --data-urlencode 'client_id=YOUR_CLIENT_ID' \
      --data-urlencode 'client_secret=YOUR_CLIENT_SECRET' \
      --data-urlencode 'scope=datahub-api push-data' \
      --data-urlencode 'username=YOUR_USERNAME' \
      --data-urlencode 'password=YOUR_PASSWORD'
    

    The response contains access_token and expires_in. Keep it in a shell variable for the rest of this page:

    TOKEN="paste_the_access_token_here"
    AUTH=(-H "Authorization: Bearer $TOKEN" -H "Api-Version: 1.7")
    
    Tip

    Both scopes are requested here because this walkthrough uses the API and the push service. Asking for datahub-api alone would make step 5 fail with a 401.

    Confirm the token works before going further:

    curl -s "${AUTH[@]}" "https://api.opinum.com/sites?DisplayLevel=SiteLight"
    

    A JSON array — even an empty one — means you are connected.

    Step 2 — Create a site

    A site is the physical place the data comes from.

    curl -s -X POST "${AUTH[@]}" -H "Content-Type: application/json" \
      "https://api.opinum.com/sites" \
      -d '{
            "name": "Demo site",
            "typeId": 3,
            "timeZoneId": "Romance Standard Time"
          }'
    

    The response is the new site id, as a bare integer. typeId is a site type — 3 is Office; the 16 values are listed in Site types.

    Note

    timeZoneId is what every later date is interpreted against when you use UseReportingTimezone. Take a moment to set it correctly — see Reference data for the list.

    Step 3 — Create a source

    A source is what produces the data at that site: a meter, a gateway, a feed.

    curl -s -X POST "${AUTH[@]}" -H "Content-Type: application/json" \
      "https://api.opinum.com/sources" \
      -d '{
            "name": "Demo meter",
            "siteId": 12345,
            "serialNumber": "DEMO-0001",
            "sourceTypeId": 72,
            "energyTypeId": 1,
            "timeZoneId": "Romance Standard Time"
          }'
    

    The response is the full source object, not just an id — read id from it.

    Field Value used here Meaning
    sourceTypeId 72 Pushed Data — a source fed through the push API, which is what this walkthrough builds.
    energyTypeId 1 Electricity.
    serialNumber DEMO-0001 Your own identifier for this meter.
    Important

    sourceTypeId and energyTypeId are referential ids, not free values. GET /sourceTypes returns 114 entries and GET /energyTypes returns 27 — pick the one that describes your source rather than reusing the ids above blindly. See Reference data.

    Golden rule

    Set a business identifier on the source — a serial number, an EAN, a meter number.

    It is what lets your integration find this source again without storing our internal id. An integration keyed on serialNumber survives being pointed at another environment; one keyed on an internal id has to be remapped by hand.

    Step 4 — Create a variable

    A variable is one measured quantity of that source.

    curl -s -X POST "${AUTH[@]}" -H "Content-Type: application/json" \
      "https://api.opinum.com/variables" \
      -d '{
            "name": "General consumption",
            "sourceId": 67890,
            "variableTypeId": 0,
            "unitId": 8,
            "granularity": 1,
            "granularityTimeBase": 3,
            "quantityType": 2,
            "mappingConfig": "general-consumption"
          }'
    

    The response is the new variable id, as a bare integer.

    Field Value used here Why it matters
    mappingConfig general-consumption The key the push service uses to pick this variable inside the source. It becomes part of your integration's contract — choose it deliberately.
    variableTypeId 0 — General consumption What the variable measures.
    unitId 8 — Kilowatt-hour The unit the stored values are expressed in. Values are not converted on the way in.
    quantityType 2 — Integrated A consumption over an interval. An index would be 3, Cumulative.
    granularity + granularityTimeBase 1 + 3 — one hour The expected spacing between points: a count, and a time base.
    Important

    granularityTimeBase reads from GET /timePeriods (3 = Hour), not from GET /granularity, whose scale is different — there, 3 means Day. The two are easy to confuse; see Granularity and time base.

    Every id above comes from a referential you can list — see Reference data.

    Step 5 — Push a data point

    Data points go to push.opinum.com, not to the API.

    curl -s -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
      "https://push.opinum.com/api/data" \
      -d '[{
            "variableId": 111213,
            "data": [
              { "date": "2026-08-28T10:00:00Z", "value": 12.4 },
              { "date": "2026-08-28T11:00:00Z", "value": 11.8 }
            ]
          }]'
    

    You can also identify the variable without its id, by combining a source identifier with the mappingConfig — the full matrix is in Standard format:

    [{ "sourceSerialNumber": "DEMO-0001", "mappingConfig": "general-consumption",
       "data": [ { "date": "2026-08-28T10:00:00Z", "value": 12.4 } ] }]
    

    Golden rule

    A 200 from the push service means accepted, not stored.

    Parsing, validation, insertion and aggregation all happen after the response is returned. A payload naming a variable that does not exist is answered with a 200 and then discarded. The webhook is the only way to learn the real outcome — wire it before you trust the pipeline.

    Step 6 — Read it back

    Give the platform a few seconds, then:

    curl -s "${AUTH[@]}" \
      "https://api.opinum.com/data?VariableId=111213\
    &DisplayLevel=ValueVariableDateSource\
    &Granularity=Raw\
    &From=2026-08-28T00:00:00Z&To=2026-08-29T00:00:00Z&IncludeToBoundary=true"
    

    Your two points come back, each with its variableId, date and rawValue.

    If the array is empty, work through this list in order:

    Check How
    Did the push actually land? Look at the variable in the Insights interface.
    Is the variable id right? GET /variables?SourceId=<id>&DisplayLevel=Verbose
    Is the window right? Remember IncludeToBoundary, and that dates are read in the time zone you specify.
    Is aggregation interfering? Granularity=Raw returns the stored points untouched.
    Right account? A token issued for another account sees nothing.

    Where to go next

    • Querying the API — filtering conventions and the full GET /data reference.
    • Recipes — the same building blocks applied to real tasks.
    • Reference data — the referential ids used in steps 3 and 4.
    • Files and triggers — if your data arrives as files rather than as API calls.
    DOCS 2026.08 REVIEWED 2026-08-28 API 1.7 Documentation changelog →

    Developer Center

    User manual API Swagger Github
    © 2025  -   www.verity.global

    Follow us

    Linkedin