Gluroo Global Connect (GGC) — Nightscout-compatible API

⚠️ EXPERIMENTAL — USE AT YOUR OWN RISK

Gluroo Global Connect (GGC) is an experimental, partial, Nightscout-compatible interface. It is provided “AS IS” and “AS AVAILABLE”, without warranties or guarantees of any kind.

  • Not for medical use. Do not use GGC or any data it returns to dose insulin, treat, diagnose, or make any medical decision. Data may be delayed, missing, duplicated, incomplete, altered, or wrong. Always use your CGM, pump, and meter directly, and consult your care team.
  • No warranty. We make no warranty of any kind, express or implied, including accuracy, availability, reliability, merchantability, fitness for a particular purpose, or non-infringement.
  • No stability guarantee. Endpoints, fields, behavior, and limits may change, break, or be removed at any time without notice. There is no SLA and no promise of uptime, data retention, or support.
  • Based on observed behavior, not Nightscout source code. This API was independently developed from studying the behavior of Nightscout sites. Due to licensing restrictions, Gluroo does not read or use the Nightscout source code. As a result, GGC may behave differently from Nightscout, including for endpoints, fields, validation, defaults, errors, and edge cases.
  • Compatibility is not guaranteed. Third-party apps (Loop, AndroidAPS, iAPS, xDrip+, Nightguard, etc.) are not tested or endorsed by us and may stop working at any time.
  • You are responsible for the apps and devices you connect, for keeping your credentials secret, and for any consequences of using this interface. To the fullest extent permitted by law, Gluroo is not liable for any loss or harm arising from its use.

Gluroo is not affiliated with, endorsed by, or sponsored by the Nightscout Project or any third-party app named in this document. “Nightscout” is used only to describe API compatibility.

Overview

Gluroo’s server can act as a (partial) Nightscout server so DIY tools can read from and write to your Gluroo account. It is not a full Nightscout: there is no Nightscout web UI, no database query language, and only the endpoints listed below exist. Use the Gluroo app itself for everything else. Its compatibility behavior was independently derived from observations of Nightscout sites, without reading or using Nightscout source code, so behavior may differ from Nightscout.

Gluroo appreciates the Nightscout project and community for pioneering broad access to CGM and diabetes data. Nightscout became the de facto API convention for many diabetes tools and integrations, which is why GGC follows a Nightscout-compatible approach instead of introducing an entirely separate, incompatible API.

What you upload through GGC (glucose readings, treatments, notes, device status, profiles) becomes part of your Gluroo group’s data and may be visible to the other members of that group.


1. Getting credentials (Gluroo mobile app)

In the Gluroo app go to Connections → DIY / Nightscout (Loop) and generate credentials. The screen shows:

ValueExampleUse
Nightscout URLhttps://<id>.ns.gluroo.comBase URL. Each account gets its own hostname.
API Secret Tokenxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxPlain secret. Goes in ?token=.
API Secret Header (SHA-1)40 hex characters, sha1(token)Goes in the api-secret HTTP header.

The screen also offers copy-ready formats for xDrip+ (https://<API_SECRET>@<host>/api/v1/), Nightguard (https://<host>?token=<API_SECRET>), and JSON.

To replace a lost or exposed secret, remove the connection in the app and create it again; you will get a new URL and secret, and the old ones stop working.

2. Authentication

Every endpoint below requires authentication (except where noted). Send either:

  1. api-secret header — the SHA-1 hex digest of your API secret. (xDrip+ does this for you when the URL is https://<API_SECRET>@<host>/.)
    curl -H "api-secret: $(printf %s "$SECRET" | shasum | cut -d' ' -f1)" \ "https://<id>.ns.gluroo.com/api/v1/entries.json?count=3"
  2. ?token= query parameter — the plain API secret, not its hash.
    curl "https://<id>.ns.gluroo.com/api/v1/entries.json?count=3&token=$SECRET"

If both are supplied, the header is used. Access is all-or-nothing: any valid credential can both read and write your account’s Nightscout data. There are no scoped or read-only tokens.

Treat both the API Secret Token and its SHA-1 value as passwords. Anyone who obtains either value can read from and write to your GGC API. The SHA-1 value does not need to be reversed to be used as a credential. Use HTTPS only. Prefer the header over ?token= where your app allows it because URLs are often logged by proxies, browsers, and apps. Never include either credential in screenshots, forums, logs, or bug reports.

Request requirements

  • Use the exact URL shown in the app. Requests sent through a different hostname or proxy may not authenticate even when the credential is otherwise valid.

Authentication errors

StatusMeaning
401Missing, unknown, or incorrect secret; or wrong hostname
429Daily request limit exceeded (see Rate limits)

Error bodies are plain text (Unauthorized, Too Many Requests), not JSON.

3. Rate limits and fair use

GGC is a shared service, so requests are limited.

LimitValue
Daily request budget5,000 authenticated requests per Gluroo account per UTC day
ScopeShared by all apps, devices, and endpoints using that account’s credentials
Reset00:00 UTC each day
When exceeded429 Too Many Requests. There is no Retry-After header; wait for the reset or reduce polling
Batch sizePOST /treatments: at most 40 treatments per request (larger batches are discarded)
Data windowRecent-readings requests are best served for about the last 24 hours (up to 730 readings)

Requests that fail authentication (401) are not counted against the budget. The limits above may be changed at any time, and Gluroo may throttle or block clients that place excessive load on the service. The limits describe the REST API.

Recommended practice

  • CGM values typically arrive every 2–5 minutes. Poll no more often than new data is expected, and never more than once every 2 minutes (up to 720 requests/day per client). Every client you run adds to the same shared budget, so several followers plus an uploader can add up quickly.
  • Ask only for what is new: pass a small count and use find[date][$gt]=<last reading time> (entries) or find[created_at][$gt]=<last time> (treatments) instead of re-downloading a large window.
  • On 429, stop retrying and back off until the next UTC day, or fix the client’s polling interval. Do not retry in a tight loop.
  • Upload in batches (≤ 40 treatments) and only new items. Do not re-upload history on every sync.
  • Use /api/v2/properties/bgnow,delta or count=1 when you only need the latest value.

4. Conventions

  • Glucose is always mg/dL integers.
  • Ordering: readings and treatments are returned newest first.
  • Content type: JSON, except the TSV variants under Entries.
  • .json suffixes are interchangeable with the bare path where both are listed.
  • Dates in find[...] queries accept ISO-8601 strings, or epoch milliseconds for entries.
  • Treatment _ids are opaque strings assigned by Gluroo. Return them unchanged for PUT/DELETE. Do not infer meaning or persistence from an ID’s format. IDs Gluroo did not assign get 404.
  • Write acknowledgments: a successful response means the request was processed, but some duplicate, unsupported, invalid, or out-of-window data may not be stored. Read the data back when confirmation is important.

5. Route table

MethodPath(s)Purpose
GET/api/v1/entries, /api/v1/entries.json, /api/v1/entries/sgv, /api/v1/entries/sgv.json, /api/v1/entries/current, /api/v2/entries, /api/v2/entries.json, /api/v2/entries/currentCGM readings
POST/api/v1/entries[.json], /api/v2/entries[.json], /api/v3/entries[.json]Upload CGM / fingerstick readings
GET/api/v1/treatments, /api/v1/treatments.jsonInsulin / carb / basal history
POST/api/v1/treatments[.json]Upload treatments
PUT/api/v1/treatments[.json]Edit a treatment
DELETE/api/v1/treatments/:idCancel a treatment
GET/api/v1/devicestatus.jsonLatest Loop/OpenAPS device status
POST/api/v1/devicestatus[.json]Upload device status
GET/api/v1/profile/current[.json]Last uploaded profile
POST/api/v1/profile[.json]Upload profile / profile switch
GET/api/v2/properties, /api/v2/properties.json, /api/v2/properties/:fieldsbgnow and delta
GET/api/v1/status.jsonServer status
GET/api/v1/verifyauthCredential check
GET/pebbleGlance / Pebble-format readings
GET/HTML landing page
GET/api/v1/experiments/testCredential probe (header only)
Socket.IOsame hostSee Socket.IO

The /api/v2/* and /api/v3/* entries routes are aliases of the v1 handlers; they do not implement v2/v3 behavior (no JWT/Bearer auth, no srvModified, no /api/v3 collections).

Any Nightscout endpoint not listed here (for example /api/v1/slice, /echo, /times, or DELETE /devicestatus) is not implemented.

6. Endpoints

6.1 GET /api/v1/entries[.json] (also /entries/sgv[.json], /entries/current, v2 aliases)

Returns CGM readings, newest first.

ParamMeaning
countMax readings. Default 10.
find[date][$gt], find[date][$gte], find[date][$lt], find[date][$lte]Bounds on reading time (epoch ms or ISO).
rr (query or header)xDrip+ “request time”: returns readings since rr minus 6 minutes.
  • Requests for recent data (roughly the last 24 hours, up to 730 readings) are the fastest; older ranges may be slower.
  • /entries/current returns one reading as TSV. /entries/sgv and Nightscout Menu Bar also get TSV. Nightguard requests for count=1440 are capped at 730.
  • Only sgv (CGM) entries are returned.

JSON response — array of:

[
  {
    "_id": "6f1c…",
    "sgv": 142, // mg/dL
    "date": 1664120907000, // epoch ms
    "dateString": "2022-09-25T15:48:27.000-07:00",
    "trend": 4, // see below
    "direction": "Flat", // omitted if unknown
    "device": "gluroo",
    "type": "sgv",
    "utcOffset": -420, // minutes
    "sysTime": "2022-09-25T15:48:27.000-07:00",
    "mills": 1664120907000
  }
]

trend is Gluroo’s numbering: 0 none, 1 DoubleUp, 2 SingleUp, 3 FortyFiveUp, 4 Flat, 5 FortyFiveDown, 6 SingleDown, 7 DoubleDown, 8 NotComputable, 9 OutOfRange, 99 fingerprick. This differs from Nightscout’s own numbering, so prefer direction, which uses Nightscout’s strings (DoubleUp, SingleUp, FortyFiveUp, Flat, FortyFiveDown, SingleDown, DoubleDown). Both are omitted when there is no trend.

TSV response (text/plain) — one tab-separated line per reading:

"2022-09-25T15:48:27.000-07:00"	1664120907000	142	"Flat"	"gluroo"

Columns: dateString, mills, sgv, direction, device. A missing direction appears as "undefined".

6.2 POST /api/v1/entries[.json] (also v2/v3 aliases)

Body: a JSON array of Nightscout entries; otherwise 400. Each entry needs dateString and either sgv or mbg, plus date (epoch ms, optional; falls back to dateString) and optionally direction.

[
  {
    "type": "sgv",
    "sgv": 118,
    "direction": "Flat",
    "date": 1664120907000,
    "dateString": "2022-09-25T15:48:27.000-07:00",
    "device": "loop://iPhone"
  }
]
  • type: "sgv" — stored as a CGM reading (unless CGM uploads are disabled for the account).
  • type: "mbg" — recorded as a fingerstick reading in the group log.
  • Duplicate, unsupported, invalid, or out-of-window entries may be acknowledged without being stored.
  • The response body is an empty object ({}) with status 200. Do not rely on the body.

6.3 GET /api/v1/treatments[.json]

Returns entries from the Gluroo log converted to Nightscout treatments.

ParamMeaning
countDefault 10.
find[created_at][$gte], find[created_at][$gt], find[created_at][$lte], find[created_at][$lt]ISO date bounds.
find[eventType]Filter by type (below).
find[carbs][$exists]=trueOnly carb entries (when eventType is not given).
find[eventType]Returns
Correction Bolus, Snack Bolus, Combo BolusInsulin doses
Dose BasalBasal insulin doses
Carb CorrectionCarb entries
Temp BasalBasal rate changes
Sensor Change, Site Change[] (not currently returned)
Temporary Target, Pump Battery Change[]
anything else, or omittedNo type filter

Only five eventTypes are ever returned: Correction Bolus, Carb Correction, Carb Intervention Snack, Temp Basal, Basal Insulin Dose. Other kinds of Gluroo log entries are omitted.

Common fields:

{
  "_id": "<opaque id>",
  "eventType": "Correction Bolus",
  "created_at": "2022-05-09T20:04:23.000Z",
  "utc_offset": 0,
  "mills": 1652126663000,
  "enteredBy": "Gluroo user name",
  "notes": "…",
  "duration": 30 // minutes; omitted if none
}
eventTypeExtra fields
Correction Bolusinsulin (U), carbs, protein, fat, absorptionTime (min)
Carb Correction, Carb Intervention Snackcarbs, protein, fat, absorptionTime, foodType
Temp Basalabsolute (U/h, or the raw rate if temp is percent), temp: "absolute" or "percent"
Basal Insulin Doseinsulin

6.4 POST /api/v1/treatments[.json]

Body: one treatment or an array (otherwise 400). Each accepted treatment is added to your Gluroo group’s log. At most 40 per request; larger requests are discarded whole.

Recognized eventTypes: Note/Notes, Question, Exercise, Profile Switch, BG Check, Correction Bolus, Combo Bolus, Bolus, SMB, Meal Bolus/Meal, Carb Correction, Sensor Start/Sensor Change, Suspend Pump, Basal Suspension/Basal Resume, Alarm, Temporary Override/Temporary Target, Temp Basal, Bolus Wizard, Insulin Change, Pump Battery Change, OpenAPS Offline, Announcement, Site Change, Settings Export. Unknown types are discarded. Other duplicate, invalid, or out-of-window treatments may be acknowledged without being stored.

The treatment time is taken from created_at, else timestamp, date, or eventTime.

Response — array, one element per input, in order:

[
  {
    "_id": "<opaque id>",
    "created_at": "2023-03-25T12:45:32Z",
    "eventType": "Carb Correction",
    "carbs": 15,
    "…": "rest of your treatment"
  },
  { "_id": "<opaque id>" }
]

The returned IDs are opaque. A successful response does not guarantee that every treatment was stored; read treatments back when confirmation is important.

6.5 PUT /api/v1/treatments[.json]

Body: one treatment whose _id was issued by Gluroo. The original entry is replaced by the edited one. Response { "_id": "<opaque id>" }. A successful response may acknowledge an edit that is not stored. 404 means the _id is not a Gluroo treatment id or cannot be found.

6.6 DELETE /api/v1/treatments/:id

Cancels the entry. Response {}. 404 if id is not a Gluroo treatment id.

6.7 GET /api/v1/devicestatus.json

count is ignored. Returns at most one compatible device-status object based on the latest status available for the account. Clients should ignore unknown fields.

[
  {
    "device": "loop://iPhone",
    "loop": { "…": "device status" }
  }
]

If no uploaded status is available, the response may contain only compatibility fields.

6.8 POST /api/v1/devicestatus[.json]

Body: one device status or an array. Documents must contain a loop block to be processed.

Response: array, one element per input. Each element is {} or contains an opaque _id.

6.9 GET /api/v1/profile/current[.json]

Returns the latest available Nightscout-format profile uploaded by your app, or {}. This is uploader data, not a conversion of Gluroo’s own settings.

6.10 POST /api/v1/profile[.json]

Body: a profile document or array. For Loop profiles, override and baseline changes are recorded in the group log. The response is the request body echoed back, even if parts were not stored.

6.11 GET /api/v2/properties[.json], /api/v2/properties/:fields

:fields is a comma-separated list. Only bgnow and delta are supported; other names are ignored. Without :fields, both are returned. Members are omitted when no data is available.

{
  "bgnow": {
    "mean": 142,
    "last": 142,
    "mills": 1664120907000,
    "sgvs": [
      {
        "mgdl": 142,
        "mills": 1664120907000,
        "device": "share2",
        "direction": "Flat",
        "type": "sgv",
        "scaled": 142
      }
    ]
  },
  "delta": {
    "absolute": -2,
    "elapsedMins": 5,
    "interpolated": false,
    "mean5MinsAgo": 144,
    "times": { "recent": 1664120907000, "previous": 1664120607000 },
    "mgdl": -2,
    "scaled": -2,
    "display": "-2",
    "previous": { "mean": 144, "last": 144, "mills": 1664120607000 }
  }
}

delta appears only if the previous reading is recent.

6.12 GET /api/v1/status.json

A Nightscout-shaped status document with mostly fixed values:

{
  "status": "ok",
  "name": "nightscoutApiByGluroo",
  "version": "0.0.1",
  "serverTime": "2024-01-01T00:00:00.000-08:00",
  "serverTimeEpoch": 1704096000000,
  "apiEnabled": true,
  "careportalEnabled": true,
  "boluscalcEnabled": false,
  "authorized": null,
  "runtimeState": "loaded",
  "settings": {
    "units": "mg/dl",
    "customTitle": "<account name>",
    "language": "<language>",
    "thresholds": {
      "bgHigh": 301,
      "bgTargetTop": 300,
      "bgTargetBottom": 70,
      "bgLow": 55
    },
    "…": "other display/alarm defaults"
  },
  "extendedSettings": { "devicestatus": { "advanced": true, "days": 1 } }
}

thresholds and alarm settings are fixed defaults, not your Gluroo targets or alerts.

6.13 GET /api/v1/verifyauth

Returns the following if the credential is valid (otherwise 401):

{
  "message": {
    "canRead": true,
    "canWrite": true,
    "isAdmin": true,
    "message": "AUTHORIZED",
    "permissions": "ROLE",
    "rolefound": "ADMIN"
  }
}

There is no outer "status": 200 as in stock Nightscout. The values are constants; GGC has no role model.

6.14 GET /pebble

For Glance and similar watch faces. count defaults to 10.

{
  "status": [{ "now": 1664120950000 }],
  "bgs": [
    {
      "sgv": 142,
      "trend": 4,
      "direction": "Flat",
      "datetime": 1664120907000,
      "bgdelta": -2,
      "cob": "22.0",
      "iob": "1.35"
    },
    { "sgv": 144, "trend": 4, "direction": "Flat", "datetime": 1664120607000 }
  ],
  "cals": []
}

bgdelta, cob, and iob (strings) appear only on the first element.

6.15 GET /

An HTML page (“Global Connect (GGC)”) confirming that your URL and credential work.

6.16 GET /api/v1/experiments/test

Credential probe. Send the SHA1 api-secret header. 400 if it is absent, 401 if it is not recognized, otherwise { "info": "ok" }.

7. Socket.IO API

A minimal, experimental emulation of Nightscout’s websocket protocol, intended for AndroidAPS uploads.

  • Authorize: emit authorize with { secret: "<SHA-1 of your API secret>" }. Plain secrets and ?token= are not accepted here. Bad credentials disconnect the socket.
  • After authorizing, the server emits connected and a placeholder dataUpdate (empty collections and a stub profile), and acknowledges with { read: true, write: true, write_treatment: true }. Live data is not pushed over the socket; use the REST endpoints to read data.
  • dbAdd{ collection, data } (acknowledged with [ { _id } ]):
    • devicestatus — same as the REST POST.
    • entries — same as the REST POST /entries.
    • treatments — one treatment, same as REST POST /treatments.
    • profile — acknowledged but not stored.
  • loadRetro replies retroUpdate with { deviceStatus: [] }.

8. Known limitations

  • POST /entries returns {} rather than per-entry ids.
  • GET /treatments does not return sensor changes, site changes, or several other event types.
  • status.json thresholds and alarm settings are stock defaults, not your settings.
  • Profiles are whatever your uploader last posted; Gluroo does not convert its own settings.
  • Nightscout find[...] queries work only for the fields listed above; sort, skip, $in, $regex, find[enteredBy], find[dateString] and similar are ignored.
  • There is no push notification, alarm, or live-stream support.

Last updated: 2026-09-24. This interface is experimental and may have changed since.