-
Notifications
You must be signed in to change notification settings - Fork 0
/
apiary.apib
425 lines (236 loc) · 11.2 KB
/
apiary.apib
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
FORMAT: 1A
HOST: https://idm.c3-pro.org/
# C3-PRO IDM API
The C3-PRO Identidy & Demographics Manager (IDM) is an API for server systems that allow to store **subjects** (aka. _patients_, _participants_) in order to create a **link between** user-ids from different systems.
Participants are identified by a so-called _site-specific subject id_ (`SSSID`).
Most commonly such linking is established between subjects enrolled in a clinical trial who use a secondary system, such as a smartphone app, which has its own identifier.
This documentation lists the minimal API and data models that any IDM-compatible system must support.
# Data Structures
## Subject (object)
- sssid: 57592DDC (string, required) - Site Specific Subject ID
- name: John Doe (string, required)
- bday: `1954-12-10` (string, required)
- created: `2018-11-04T09:05:03Z` (string) - ISO-datetime the subject was created
- changed: `2018-11-04T09:05:03Z` (string) - ISO-datetime of last change
- date_invited: `2017-12-10T12:45:30Z` (string)
- date_consented: `2017-12-12T18:50:45Z` (string)
- date_enrolled: `2017-12-12T18:52:12Z` (string)
- date_withdrawn: `2018-11-04T09:05:03Z` (string)
## Subject Response (object)
- data (Subject, required)
## Subjects Response (object)
- data (array[Subject], required)
## Link (object)
- jti: 3524E85B (string, required) - The internal Link identifier
- iss: https://idm.srv.io/ (string) - The URL of the issuing IDM
- aud: https://idm.srv.io/ (string) - The URL where the link will be accepted
- exp: `2016-09-06T14:13:12Z` (string) - Expiration date & time; if this is present a JWT has been generated and can not be re-generated for this link
- sub: 57592DDC (string, required) - The SSSID this Link belongs to; will be replaced with the subject's name in the JWT!
- birthdate: `1954-12-10` (string) - The birthdate of the subject; will be pulled from `Subject` upon JWT generation
- linked_to: UUUID (string) - The external ID (usually the App's UUID) this link links to
- linked_on: `2016-09-28T14:22:23Z` (string) - When this link was established (if at all)
- linked_system: `https://c3-pro.io/fhir/` (string) - The system against which was linked and where `linked_to` is the identifier; should be a FHIR endpoint
- withdrawn_on: `2018-10-02T09:31:48Z` (string) - When this link was broken, i.e. the user has (been) withdrawn
## Link Response (object)
- data (Link, required)
## Audit (object)
- datetime: `2017-02-08T14:22:23Z` (string) - ISO datetime of the audit log
- actor: Bruce Willis (string) - A name or identifier for the person having caused the audit log
- action: consent (string) - Some description of the action (e.g. "update"; can be more verbose, your choice)
## Audit Response (object)
- data (Audit, required)
## Error Response (object)
- error (object, required)
- status (number, required) - The HTTP status represented by this error
- message (string, required) - A description of the error to help debug
# Group Subjects
A subject (aka. _participant_ or _patient_) is a person (to be) enrolled in a clinical trial.
A subject may have additional fields to the ones defined here.
TODO: determine fields
## Subjects [/subject]
+ Attributes (Subject)
### List Subjects [GET]
+ Parameters
- search: Searchstring to apply, if any
- offset: How many records to skip before returning data (paging)
- perpage: How many records to return (paging)
- ordercol: Which attribute should be used for ordering
- orderdir: Which direction to use while ordering: `ASC` or `DESC`
+ Request
+ Headers
Authorization: Bearer {...}
+ Attributes
- page
- perpage
- ordercol
- orderdir
+ Response 200 (application/json)
+ Attributes (Subjects Response)
### Add New Subject [POST]
+ Request (application/json)
+ Headers
Authorization: Bearer {...}
+ Attributes (Subject)
+ Response 201 (application/json)
Subject was successfully created.
+ Headers
Location: /subject/12345
+ Attributes (Subject Response)
+ Response 400 (appliaciton/json)
Invalid request, likely either `sssid` or `name` was missing or empty.
+ Attributes (Error Response)
+ Response 409 (application/json)
A subject with this `sssid` exists already.
+ Attributes (Error Response)
## Individual Subject [/subject/{sssid}]
Operations on an already registered subject, identified by `sssid`.
+ Parameters
- sssid (string) - The site-specific subject ID
### Retrieve Subject Details [GET]
+ Request
+ Headers
Authorization: Bearer {...}
+ Response 200 (application/json)
+ Attributes (Subject Response)
+ Response 403 (application/json)
The authorization token was invalid.
+ Attributes (Error Response)
+ Response 404 (application/json)
A subject with the given `sssid` does not exist.
+ Attributes (Error Response)
### Update Subject [PUT]
This call can be used to update subject details, most importantly to mark when a subject has been consented.
+ Request (application/json)
+ Headers
Authorization: Bearer {...}
+ Attributes (Subject)
+ Response 204
Subject data was successfully updated. Nothing will be returned.
+ Body
+ Response 400 (application/json)
Something was wrong with the request.
+ Attributes (Error Response)
+ Response 403 (application/json)
The authorization token was invalid.
+ Attributes (Error Response)
+ Response 409 (application/json)
There was a conflict updating the subject, most commonly the SSSID was attempted to be changed.
+ Attributes (Error Response)
# Group Subject Linking
Linking is achieved by creating a one-time-use “Link”, which is always represented as a [JWT](https://jwt.io) when used outside the system.
These JWT can be sent to external services and apps, who can establish links by using the JWT as an _Authorization_ header while sending a FHIR `Patient` resource, containing the identifier to be linked, in its body.
It is important to understand the distinction between the Link data, when working with the API internally, and the JWT representation of the Link:
data contained in the Link internally will end up in the _payload_ section of the JWT, with the following exceptions:
- `sub` will be replaced with the subject's name (it's the SSSID internally)
- `linked_on` and `linked_to` will not end up in the payload; usually they are not known when the JWT is needed anyway
A `Link`'s JWT is usually signed using **HMAC-SHA-256**.
## Links [/link/{jti}]
+ Parameters
- jti (String) - The linkable/JWT identifier; should not give hints about the sssid.
+ Attributes (Link)
### Information About a Link [GET]
+ Request (application/json)
A GET request to retrieve the JSON part of the JWT.
+ Headers
Authorization: Bearer {...}
+ Response 200 (application/json)
+ Attributes (Link Response)
### Update Link Content [PUT]
+ Request (application/json)
+ Headers
Authorization: Bearer {...}
+ Attributes (Link)
+ Response 204
Link was successfully updated. Nothing will be returned.
+ Body
+ Response 400 (application/json)
Something was wrong with the request.
+ Attributes (Error Response)
+ Response 409 (application/json)
There was a conflict updating the link.
+ Attributes (Error Response)
## Link as JSON Web Token [/link/{jti}/jwt]
+ Parameters
- jti (String) - The linkable/JWT identifier.
### Retrieve JWT [GET]
This is an open request that does not need to be protected.
+ Response 200 (application/jwt)
Returns the JWT in the response body.
+ Body
HEAD.BODY.SIGNATURE
+ Response 404 (application/json)
This link does not exist
+ Attributes (Error Response)
## Establish Link [/establish]
### Link Subject [POST]
+ Request (application/json)
The request body is a FHIR `Patient` resource that only needs to include the remote patient identifier as the first `Identifier` element.
Provide a `system` for the identifier, which is the URL of the system to which the subject sends research data to.
The `value` is the **in-app id** which is associated with research data.
+ Headers
Authorization: Bearer {JWT of this link, see `/link/{jti}/jwt`}
+ Body
{
"resourceType": "Patient",
"identifier": [{
"system": "{data-backend-url}",
"value": "{in-app-id}"
}]
}
+ Response 204
Link was successfully created. Nothing will be returned.
+ Body
+ Response 400 (application/json)
Something was wrong with the request.
+ Attributes (Error Response)
+ Response 401 (application/json)
No authorization was provided.
+ Attributes (Error Response)
+ Response 403 (application/json)
The JWT provided as authorization is not valid.
+ Attributes (Error Response)
+ Response 406 (application/json)
The Authorization header or the request body was not correctly formatted.
+ Attributes (Error Response)
+ Response 409 (application/json)
There was a conflict creating the link.
Most commonly this link (one time use!) or a link between SSSID and an identifier of the given **system** has already been established.
+ Attributes (Error Response)
## Subject Links [/subject/{sssid}/links]
+ Parameters
- sssid (string) - The site-specific subject ID
### Get All Links [GET]
+ Request
+ Headers
Authorization: Bearer {...}
+ Response 200 (application/json)
List all `Link` objects that are tied to the given subject.
+ Attributes (Subjects Response)
### Get New Link [POST]
A request to receive a new JWT that can be used by another application or system in order to establish a link between the subject's `sssid` and an external identifier.
+ Request (application/json)
+ Headers
Authorization: Bearer {...}
+ Response 200 (application/jwt)
+ Headers
Location: /link/{jti}
+ Attributes (Link)
+ Body
HEAD.BODY.SIGNATURE
+ Response 412 (application/json)
Failed to create the link.
Most commonly the subject has not yet been consented.
+ Attributes (Error Response)
# Group Audit Logs
These endpoints provide a means to retrieve audit logs for actions done on the data of a particular subject.
How auditing is done and what is logged is up to you, all that needs to be present is the following endpoint and the data coming back must contain at least the given properties fro `Audit`.
## Subject Audit Logs [/subject/{sssid}/audits]
+ Parameters
- sssid (string) - The site-specific subject ID
### Get All Logs [GET]
+ Request
+ Headers
Authorization: Bearer {...}
+ Response 200 (application/json)
List all `Audit` objects that are tied to the given subject.
+ Attributes (Audit Response)