Releasesv0.1.0
Api referenceEndpointsShares

Make a share link of the user's records

POST
/v1/users/{id}/shares

A SMART Health Link (HL7 FHIR IG "SMART Health Cards and Links", STU1) that the person gives to whoever they choose. The server reads the user's records of categories in [start, end) (the merged view, as the FHIR routes serve them), writes them as one FHIR R4 collection Bundle (a Patient with no identifier, the Observations, the Devices), compresses it (DEFLATE) and encrypts it as a compact JWE (alg dir, enc A256GCM) with a fresh random 256-bit key. It stores the ciphertext only. The answer holds the link (uri) and the built-in viewer's link (viewer_url), each carrying the key, this once: the server keeps neither and cannot show them again.

A category holds every metric the consent model files under it. Records of a source whose consent refuses the category, or whose purge is pending, are left out. The snapshot is fixed when it is made (no L flag): later records are not added. At most 50000 records; more is a 400. A sleep session's, a workout's or a daily summary's figures of another category (a resting heart rate is heart) are kept only on the terms of their own category. The records are read and the share stored in one transaction that holds the user and their consent: a consent change or an erasure that starts meanwhile waits, then revokes the share if it holds what they remove.

The route takes no Idempotency-Key: a stored response would keep the key. Sent with Cache-Control: no-store. See docs/share-links.md.

Authorization

tenantKey
headerAuthorizationBearer <token>

Tenant API key, ohs_sk_ + 43 base62 characters.

Path Parameters

id*string
Formatuuid

Header Parameters

Authorization*string

The tenant API key, as a bearer secret.

Request Body

application/json
  1. body
categories*array<>
Items1 <= items
start*|

Inclusive start of the window, RFC 3339 or YYYY-MM-DD.

end*|

Exclusive end of the window, after start.

expires_at*|

When the link stops working, in the future and at most 365 days ahead.

passcode?|

When set, the reader must give it. 6 to 64 characters, no control character. The server keeps a PBKDF2-SHA256 hash of it only.

Length6 <= length <= 64
label?string

Shown to the reader, for example who the link is for. One line.

Lengthlength <= 80

Response Body

The share and its link, shown only this once. Sent with Cache-Control: no-store.

application/json
  1. response

A share link as its owner reads it. Never the link, its key or the passcode.

id*string
Formatuuid
label*string

Shown to the reader; empty for none.

Lengthlength <= 80
categories*array<>
start*string

Inclusive start of the time window.

Formatdate-time
end*string

Exclusive end of the time window.

Formatdate-time
expires_at*string

When the link stops working.

Formatdate-time
passcode*boolean

Whether the link needs a passcode.

passcode_failures*integer

Wrong or missing passcodes so far; the 10th disables the link.

status*string

active: the link works. expired: past expires_at. revoked: stopped before its expiry (see revoked_reason). disabled: too many wrong passcodes.

Value in"active""expired""revoked""disabled"
revoked_at*|
Formatdate-time
revoked_reason*|
Value in"owner""consent""provider_erased""passcode_attempts"null
observations*integer

How many Observations the file holds.

file_bytes*integer

The size of the encrypted file when it was made.

accesses*integer

How many manifest requests were served the file.

last_accessed_at*|

The latest of them.

Formatdate-time
created_at*string
Formatdate-time
uri*string

The link, shlink:/ + the base64url payload (url, key, exp, flag P with a passcode, label). It carries the key: shown only this once.

viewer_url*string

The built-in viewer with the link in its fragment (.../shl/view#shlink:/...).

curl -X POST 'http://localhost:8080/v1/users/497f6eca-6276-4993-bfeb-53cbbbba6f08/shares' \  -H 'Authorization: Bearer ohs_sk_...' \  -H 'Content-Type: application/json' \  -d '{  "categories": [    "activity"  ],  "start": "2019-08-24T14:15:22Z",  "end": "2019-08-24T14:15:22Z",  "expires_at": "2019-08-24T14:15:22Z"}'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "label": "string",  "categories": [    "activity"  ],  "start": "2019-08-24T14:15:22Z",  "end": "2019-08-24T14:15:22Z",  "expires_at": "2019-08-24T14:15:22Z",  "passcode": true,  "passcode_failures": 0,  "status": "active",  "revoked_at": "2019-08-24T14:15:22Z",  "revoked_reason": "owner",  "observations": 0,  "file_bytes": 0,  "accesses": 0,  "last_accessed_at": "2019-08-24T14:15:22Z",  "created_at": "2019-08-24T14:15:22Z",  "uri": "string",  "viewer_url": "string"}
Edit on GitHub