Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save StephenBlackWasAlreadyTaken/adb0525344bedade1e25 to your computer and use it in GitHub Desktop.
Save StephenBlackWasAlreadyTaken/adb0525344bedade1e25 to your computer and use it in GitHub Desktop.
DexcomShare Endpoints for the Uploader App
  • these are the calls used by the dexcom uploader app
  • these are in no particular order!
  • User-Agent: Dexcom%20Share/3.0.2.11 CFNetwork/672.0.2 Darwin/14.0.0

General

Read Dexcoms System time clock

GET

/ShareWebServices/Services/General/SystemUtcTime

Body:

  none

Response:

  {
    "DateTime":"\/Date(1426767421178)\/",
    "OffsetMinutes":0
  }

Session Related

Login to a Publisher Account (Get a Session ID):

POST

/ShareWebServices/Services/General/LoginPublisherAccountByName

Body:

  {
    "accountName":"yourlogin",
    "applicationId":"d8665ade-9673-4e27-9ff6-92db4ce13d13",
    "password":"yourpassword"
  }

Response:

  "e3e3e6a5-coolsessionid-bro”

Authenticate Publisher Account (Get a Session ID):

POST

/ShareWebServices/Services/General/AuthenticatePublisherAccount

Body:

  {
    "accountName":"yourlogin",
    "applicationId":"d8665ade-9673-4e27-9ff6-92db4ce13d13",
    "password":"yourpassword"
  }

Response:

  "e3e3e6a5-coolsessionid-bro”

Check if the Reciever is assigned to your account

POST

/ShareWebServices/Services/Publisher/CheckMonitoredReceiverAssignmentStatus?sessionId={YourSessionId}&serialNumber={YourSerialNumber}/

Body:

  none

Response:

  `AssignedToYou` or `NotAssigned` (plaintext)

Assign the reciever to you (If you got NotAssigned or something else)

POST

/ShareWebServices/Services/Publisher/ReplacePublisherAccountMonitoredReceiver?sessionId={YourSessionId}&serialNumber={YourSerialNumber}

Body:

  none

Response:

  No Idea, Someone please tell me, if you assign one to yourself that was
  already yours you get a 500 error

Check remote monitoring session is valid

POST

/ShareWebServices/Services/Publisher/IsRemoteMonitoringSessionActive?sessionId={YourSessionId}

Body:

  none

Response:

  `true` or `false` (plaintext)

Start remote monitoring session

POST

/ShareWebServices/Services/Publisher/StartRemoteMonitoringSession?sessionId={yoursessionid}&serialNumber={YourdexcomSerialNumber}

Body:

  none

Response:

  just a status, `200`

Stop a remote monitoring session

POST

/ShareWebServices/Services/Publisher/StopRemoteMonitoringSession?sessionId={YourSessionId}

Body:

  none

Response:

  just a status, `200`

Update Publisher information (might be fun for sending them cute messages?)

POST

/ShareWebServices/Services/Publisher/UpdatePublisherAccountRuntimeInfo

Body:

  {
    "sessionId":"YourSessionId",
    "runtimeInfo":
      {
        "DeviceManufacturer":"Apple",
        "DeviceModel":"iPhone5,2",
        "DeviceOsVersion":"7.0.2",
        "AppVersion":"3.0.2.11",
        "AppName":"DexcomShare",
        "AppNumber":"SW10569",
        "DeviceOsName":"iPhone OS"
      }
  }

Response:

  just a status, `200`

Data!

Post BG Data

POST

/ShareWebServices/Services/Publisher/PostReceiverEgvRecords?sessionId={yourSessionId}

Body:

{
  "SN":"YourSerialNumber",
  "Egvs":[
      {
        "Trend":4,
        "ST":"\/Date(1426783106000)\/",
        "DT":"\/Date(1426754317000)\/",
        "Value":97
      }
    ],
  "TA":-14365
}

Response:

  just a status, `200`

ST system time, DT display time, TA is a time offset, multiply by 1000 and subtract it from the time (so subtracting a negative in this example, which is really adding)

Read BG Data

POST

/ShareWebServices/Services/Publisher/ReadPublisherLatestGlucoseValues?sessionId={YourSessionId}&minutes=1440&maxCount=1

Body:

  none

Response:

[
  {
    "DT":"\/Date(1426780716000-0700)\/",
    "ST":"\/Date(1426784306000)\/",
    "Trend":4,
    "Value":99,
    "WT":"\/Date(1426769941000)\/"
  }
]

Invite Follower Related

Check if someone is already a contact of yours

POST

/ShareWebServices/Services/Publisher/DoesContactExistByName?sessionId={YourSessionId}&contactName={NameOfNewFollower}

Body:

  none

Response:

  `true` or `false` (plaintext)

Create a contact if they dont already exist

POST

/ShareWebServices/Services/Publisher/CreateContact?sessionId={YourSessionId}&contactName={FollowerName}&emailAddress={FollowerEmail}

Body:

  none

Response:

  a contact id (needed for the invite!), `123312-af1341123-coolid`

Send the invite!!

POST

/ShareWebServices/Services/Publisher/CreateSubscriptionInvitation?sessionId={YourSessionId}&contactId={ContactId}

Body:

  {
    "AlertSettings":{
      "HighAlert":{
        "MinValue":200,
        "AlarmDelay":"PT1H",
        "AlertType":1,
        "IsEnabled":false,
        "RealarmDelay":"PT2H",
        "Sound":"High.wav",
        "MaxValue":401
      },
      "LowAlert":{
        "MinValue":39,
        "AlarmDelay":"PT30M",
        "AlertType":2,
        "IsEnabled":false,
        "RealarmDelay":"PT2H",
        "Sound":"Low.wav",
        "MaxValue":70
      },
      "FixedLowAlert":{
        "MinValue":39,
        "AlarmDelay":"PT0M",
        "AlertType":3,
        "IsEnabled":true,
        "RealarmDelay":"PT30M",
        "Sound":"UrgentLow.wav",
        "MaxValue":55
      },
      "NoDataAlert":{
        "MinValue":39,
        "AlarmDelay":"PT1H",
        "AlertType":4,
        "IsEnabled":false,
        "RealarmDelay":"PT0M",
        "Sound":"NoData.wav",
        "MaxValue":401
      }
    },
    "Permissions":1,
    "DisplayName":"{YourAccountDisplayName}"
  }

Note that permissions 1 means they can view your graph data

Response:

  a subscriber id for the person you invited! (Usefull for updating their
  subscription permissions and such) `793312-af1341123-coolid`

List all Followers

POST

/ShareWebServices/Services/Publisher/ListPublisherAccountSubscriptions?sessionId={YourSessionId}

Body:

  none

Response:

  [
    {
      "ContactId":"FollowersContactId",
      "ContactName":"FollowersName",
      "DateTimeCreated":{
        "DateTime":"\/Date(1437101121008)\/",
        "OffsetMinutes":0
      },
      "DateTimeModified":{
        "DateTime":"\/Date(1437101121008)\/",
        "OffsetMinutes":0
      },
      "DisplayName":"YourDisplayName",
      "InviteExpires":{
        "DateTime":"\/Date(1437705921008)\/",
        "OffsetMinutes":0
      },
      "IsEnabled":false,
      "IsMonitoringSessionActive":true,
      "Permissions":1,
      "State":2,
      "SubscriberId":"00000000-0000-0000-0000-000000000000",
      "SubscriptionId":"theirSubscriptionIdIsuppose?"
    }
  ]

note: maybe we can use this subscription id to send our own custom invites to followers

Delete Follower

POST

/ShareWebServices/Services/Publisher/DeleteContact?sessionId={YourSessionId}&contactId={followersContactId}

Body:

  none

Response:

  just a status, `200`

Still undocumented but logged if you need info on it (Not adding it all here out of lazziness)

  • getting the image
  • getting the subscription display name
  • getting the subscription email address
  • reading the contact list
  • sending changes to the contacts Permissions
  • removing a contact
  • follower aknowledging alarms
  • follower reading invitation info
  • follower accepting invitation
  • follower updating runtimeInfo
  • folower listing all their subscriptions
  • read subscription alerts

CURL examples for getting values from Dexcom

curl -v \
  -H "Accept: application/json" -H "Content-Type: application/json" \
  -H "User-Agent: Dexcom Share/3.0.2.11 CFNetwork/711.2.23 Darwin/14.0.0" \
  -X POST https://share1.dexcom.com/ShareWebServices/Services/General/LoginPublisherAccountByName \
  -d '{"accountName":"YOURLOGIN","applicationId":"d8665ade-9673-4e27-9ff6-92db4ce13d13","password":"YOURPASSWORD"}' 

which should recieve a response like

"8c1234deb-323c-4e9d-8362-39cfa23499ed"

which you use to get values like

curl -v \
  -H "Content-Length: 0" -H "Accept: application/json" \
  -H "User-Agent: Dexcom Share/3.0.2.11 CFNetwork/672.0.2 Darwin/14.0.0" \
  -X POST "https://share1.dexcom.com/ShareWebServices/Services/Publisher/ReadPublisherLatestGlucoseValues?sessionId=8c1234deb-323c-4e9d-8362-39cfa23499ed&minutes=1440&maxCount=1" 
@jazeee
Copy link

jazeee commented Jan 6, 2024 via email

@KajBjurman
Copy link

KajBjurman commented Jan 6, 2024

It's kind of a JWT, but they either have a bug, or don't care about being fully compliant. The header doesn't static algorithm, so we don't know how the produce the signature, but the signature is also encoded incorrectly. The signature should be encoded in base 64, without padding, and with "url safe" mode, but we can see here, and I also saw in one of my captures, that the signature contained an underscore, which is invalid.

@fsallstrom
Copy link

Just a small update: it appears the Dexcom outage has been resolved and the old API is working again. I'll keep trying to reverse engineer the new API since I suspect they may push towards it, but is anyone still experiencing issues with the old one?

Nb: It's a bit ridiculous that a bioengineering/health company can have a two month outage, especially without any sort of timeline or communication... at my company I would be fired faster than I could explain why we only had 80% uptime on a relatively critical production component.

I don't get any more emails from users about the issue so it seems to be resolved across all/most markets.

@osa1
Copy link

osa1 commented Apr 25, 2024

Sorry for the noise -- it turns out Dexcom Android app logged me out from Dexcom services and stopped uploading data.

I also fixed my script in the meantime. Here's a working version: https://github.com/osa1/Dextrack/blob/main/tools/get_bg_levels.py

(Deleted my original comment to avoid adding noise to this useful page)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment