-
Notifications
You must be signed in to change notification settings - Fork 0
/
uclapi.openapi.json
6941 lines (6941 loc) · 240 KB
/
uclapi.openapi.json
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
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{
"openapi": "3.0.0",
"info": {
"title": "UCL API",
"description": "An API generated by a team of student developers to interact with student and university data at UCL.\n\nThe API is made up of several services, each of which will be separately explained. Every service will be documented here with important information, tips and examples.\n\n## Get Your API Key\n\nBefore you can use the API you should head to the API Dashboard and sign up using your UCL user account. Once logged into the dashboard simply name your app and you’ll be given a key that you can use to access all the services. Simple!\n\n## API Rate Limits\n\nRate limiting of the API is primarily on a per-user basis. The limit is calculated against the user, across all their access tokens.\n\nThe limit is 10,000 requests per day and resets every day at midnight, London time.\n\nWhen a request is throttled, the response returned by the server has HTTP Status Code “429 Too Many Requests”. It includes a Retry-After header with the number of seconds the client is throttled for.\n\nIf you would like your rate limit to be increased, contact us at isd.apiteam@ucl.ac.uk\n\n## API Data Freshness\n\nMuch of the data available from the API is served from cache. Bookings and Timetable data are updated every twenty minutes from UCL, and we update the [Library Study Spaces (Workspaces) API](https://uclapi.com/docs/#workspaces) every two minutes. The `Last-Modified` header will provide the time that the most recent caching operation completed in [RFC 2616](https://stackoverflow.com/a/21121453) format. Endpoints that do not rely on cached data will return the current timestamp in this field instead.\n\nThis allows your application to judge whether the data is stale, or might need refreshing. For example, if a booking is added to the database and the data you are using is more than twenty minutes old, it may be that the booking is not visible to you yet. Consider creating a fresh request in this case.\n\nIf you notice that the `Last-Modified` timestamp you see is unreasonably old, please [get in contact with us](mailto:isd.apiteam@ucl.ac.uk) ASAP to report this as it may indicate very stale data and an issue at our end.\n\n## OAuth\n\nOAuth is a protocol that lets external apps request secure access to private UCL account data without getting your password. This can be done with a \"Sign In With UCL\" button on your website or app which saves UCL users the trouble of registering a new account with you. It also allows your app or website to retrieve a user's personal timetable.\n\nCheck out a JS web app demo [here](https://uclapi-oauth-demo.glitch.me/). The source code for the demo is available [here](https://glitch.com/edit/#!/uclapi-oauth-demo).\n\nFor an example of a mobile app implementation, check out [UCL Assistant](https://github.com/uclapi/ucl-assistant-app) (written in React Native) and the accompanying [UCL Assistant API backend](https://github.com/uclapi/ucl-assistant-api/tree/master/src/oauth) (written in Node.JS).\n\n### Sign In With UCL Button\nIf you want to add a \"Sign In With UCL\" button to your site, which looks like this:\n\n<a href=\"https://uclapi.com/oauth/authorise?client_id=CLIENT_ID&state=STATE\">\n <img width=\"20%\" src=\"https://s3.eu-west-2.amazonaws.com/uclapi-static/SignInWithUCLSmall.png\">\n</a>\n\nyou can copy the following the code below and replace CLIENT_ID and STATE by the `client_id` of your app and a random `state`:\n\n```\n<a href=\"https://uclapi.com/oauth/authorise?client_id=CLIENT_ID&state=STATE\">\n <img src=\"https://s3.eu-west-2.amazonaws.com/uclapi-static/SignInWithUCLSmall.png\">\n</a>\n```\n\n### Scopes\n\nOAuth scopes specify what access your app needs to a UCL user’s account. As an app developer, you set the desired scopes in the API Dashboard. When a user is responding to your authorisation request, the requested scopes will be displayed to the user.\n\n### OAuth Workflow\n\nIf your application uses OAuth, you must set a callback URL in the dashboard. Then the app should follow this procedure:\n\n1. Redirect the user to `https://uclapi.com/oauth/authorise` with `state` and the application’s `client_id` as query parameters.\n\n2. The user logs in with their UCL credentials on the UCL Single Sign-on website (if not logged in already).\n\n3. The user reviews the OAuth scopes requested and either authorises or denies the application's request. If the application is authorised, the callback URL receives `client_id`, `state` (specified in 1.), `result`, and `code`.\n\nIf the application is denied, the callback URL receives `result` and `state`, and no private data will be provided to the application.\n\n4. To obtain a OAuth user token (necessary for retrieving personal data and certain API endpoints), we require `code` (from 3.), `client_id`, and `client_secret`. These should then be sent to `https://uclapi.com/oauth/token`, which will return a response containing `state`, `ok`, `client_id`, `token` (OAuth user token), and `scope` (OAuth scopes the app can access on the user’s behalf).\n\n**Note**: OAuth tokens and general API tokes are different. Whilst general API tokens can be used for all non-personal, generic data (such as room bookings), OAuth tokens must be used with an app's client_secret in order to retrieve personal data for a user. To make things easier, you can use personal OAuth tokens in place of general tokens once a user has logged into your app to retrieve generic data too.\n\n### Tokens\n\nTokens uniquely identify an app that is requesting data from the API.\n\nTokens are a long string variable of numbers and letters. e.g. `uclapi-5d58c3c4e6bf9c-c2910ad3b6e054-7ef60f44f1c14f-a05147bfd17fdb`.\n\nThere are two different kinds of tokens you can work with:\n\n1. Generic Tokens: These are tokens that are used to request non-personal data. These tokens are used between applications and the API to request any sort of data that the app may need that is not tied to a specific student. For example, UCL API’s Room booking service uses tokens to return information about rooms - when they are booked and which UCL rooms are free.\n\n2. OAuth Tokens: This type of token is used when an app requires personal data from users. One of the most common uses of this type of token is when you sign in via UCL on an app. The app will then use a token to request a user’s personal data such as:\n\n - Department\n - Email\n - Full name\n - Given name\n - UPI\n - If they are a student or not\n - Student number (*note:* to get this, you need to tick the relevant scope in the dashboard before a user logs in; more on scopes above).\n\nNote that you can also use OAuth Tokens to access all the same data that generic app tokens can access.\n\nEach token is uniquely generated for each user logging into each app.\n\nPlease note, access to any of this data needs to be approved by the user first.\n\nTo use this type of token for your app, you need to redirect the user to the \"Authorise\" endpoint at: `https://uclapi.com/oauth/authorise` which can be done directly or by including a “Sign in With UCL Button” in your app, such as the one provided below, which links users to the authorisation endpoint with your app’s Client ID (accessible via the dashboard) and a random state number included in the GET parameters.\n\nThe users then sign in with their UCL credentials and, if they authorise your app to use their personal data, a token will be generated which your app can use to get user’s personal data in JSON format from the oauth/user/data. Your application will receive the token at the callback URL you provided in the [Dashboard](https://uclapi.com/dashboard).\n\n## Code Samples\n\nAfter authorisation, calling most of the API endpoints will be fairly similar to each other. Authorisation code samples are provided in their respective descriptions.\n\nIn addition, please find short code examples of how you might call the `/roombookings/equipment` endpoint in your own code (you will find that only the request parameters will change between most different endpoints):\n\nPython:\n```python\nimport requests\n\nparams = {\n \"token\": \"uclapi-5d58c3c4e6bf9c-c2910ad3b6e054-7ef60f44f1c14f-a05147bfd17fdb\",\n \"roomid\": \"433\"\n \"siteid\": \"086\"\n}\n\nr = requests.get(\"https://uclapi.com/roombookings/equipment\", params=params)\nprint(r.json())\n```\n\nShell:\n```shell\ncurl -G https://uclapi.com/roombookings/equipment -d token=uclapi-5d58c3c4e6bf9c-c2910ad3b6e054-7ef60f44f1c14f-a05147bfd17fdb -d roomid=433 -d siteid=086\n```\n\nJavaScript:\n```js\nfetch(\"https://uclapi.com/roombookings/equipment?token=uclapi-5d58c3c4e6bf9c-c2910ad3b6e054-7ef60f44f1c14f-a05147bfd17fdb&roomid=433&siteid=086\")\n .then(response => response.json())\n .then(json => console.log(json));\n```",
"contact": {
"name": "API Support",
"email": "isd.apiteam@ucl.ac.uk",
"url": "https://uclapi.com"
},
"version": "1.4.11",
"termsOfService": "https://github.com/uclapi/uclapi/blob/master/backend/uclapi/uclapi/UCLAPIAcceptableUsePolicy.txt",
"license": {
"url": "https://github.com/uclapi/uclapi/blob/master/LICENSE",
"name": "MIT License"
}
},
"tags": [
{
"name": "Timetable",
"description": "Fetch timetables with various filters for various groups"
},
{
"name": "OAuth",
"description": "Authenticate and authorise applications for users"
},
{
"name": "Room Bookings",
"description": "Fetch details of room bookings within UCL"
},
{
"name": "Search",
"description": "Search for staff in UCL"
},
{
"name": "Resources",
"description": "Fetch desktop availability throughout UCL"
},
{
"name": "Workspaces",
"description": "Fetch workspace availablility and maps throughout UCL"
},
{
"name": "LibCal",
"description": "Manage and make seat reservations on the library booking system"
},
{
"name": "Analytics",
"description": "View analytics and stats about your app or API services"
}
],
"components": {
"parameters": {
"client_secret": {
"name": "client_secret",
"in": "query",
"description": "Client secret of the authenticating app.",
"required": true,
"schema": {
"type": "string"
}
},
"roomname": {
"name": "roomname",
"in": "query",
"description": "Every site (building) has a name. In some cases this is contained in the roomname as well.",
"required": false,
"schema": {
"type": "string"
}
},
"roomid": {
"name": "roomid",
"in": "query",
"description": "The room ID (not to be confused with the roomname).",
"required": false,
"schema": {
"type": "string"
}
},
"siteid": {
"name": "siteid",
"in": "query",
"description": "Every room is inside a site (building). All sites have IDs.",
"required": false,
"schema": {
"type": "string"
}
},
"sitename": {
"name": "sitename",
"in": "query",
"description": "Every site (building) has a name. In some cases this is contained in the roomname as well.",
"required": false,
"schema": {
"type": "string"
}
},
"classification": {
"name": "classification",
"in": "query",
"description": "The room type ID.",
"required": false,
"schema": {
"type": "string"
}
},
"capacity": {
"name": "capacity",
"in": "query",
"description": "Every room has a set capacity of how many people can fit inside it. When supplied, all rooms with the given capacity or greater will be returned.",
"required": false,
"schema": {
"type": "string"
}
},
"datetime__gte": {
"name": "datetime__gte",
"in": "query",
"description": "Filter result datetimes to be greater than or equal to this datetime.",
"required": false,
"example": "2020-01-16T14:00:00",
"schema": {
"type": "string"
}
},
"datetime__lte": {
"name": "datetime__lte",
"in": "query",
"description": "Filter result datetimes to be less than or equal to this datetime.",
"required": false,
"example": "2020-01-16T15:00:00",
"schema": {
"type": "string"
}
},
"datetime__exact": {
"name": "datetime__exact",
"in": "query",
"description": "Filter result datetimes to be equal to this datetime.",
"required": false,
"example": "2020-01-16T14:50:00",
"schema": {
"type": "string"
}
},
"datetime__gt": {
"name": "datetime__gt",
"in": "query",
"description": "Filter result datetimes to be greater than this datetime.",
"required": false,
"example": "2020-01-16T14:00:00",
"schema": {
"type": "string"
}
},
"datetime__lt": {
"name": "datetime__lt",
"in": "query",
"description": "Filter result datetimes to be less than this datetime.",
"required": false,
"example": "2020-01-16T15:00:00",
"schema": {
"type": "string"
}
},
"start_datetime": {
"name": "start_datetime",
"in": "query",
"description": "Start datetime of the booking. Returns bookings with a start_datetime after the one supplied. Follows the ISO 8601 formatting standard.",
"required": false,
"schema": {
"type": "string"
}
},
"end_datetime": {
"name": "end_datetime",
"in": "query",
"description": "End datetime of the booking. Returns bookings with an end_datetime before the one supplied. Follows the ISO 8601 formatting standard.",
"required": false,
"schema": {
"type": "string"
}
},
"date": {
"name": "date",
"in": "query",
"description": "Date of the bookings you need, in the format YYYYMMDD. Returns bookings occurring on this day. This query parameter is only considered when end_datetime and start_datetime are not supplied.",
"required": false,
"schema": {
"type": "string"
}
},
"description": {
"name": "description",
"in": "query",
"description": "Describes what the booking is. Could contain a module code (for example WIBRG005) or just the type of activity (for example Lecture).",
"required": false,
"schema": {
"type": "string"
}
},
"contact": {
"name": "contact",
"in": "query",
"description": "The name of the person who made the booking. Substrings of the contact name can be used, Queries for Mark will include Mark Herbster. Sometimes, a society or student group may be the contact for a booking.",
"required": false,
"schema": {
"type": "string"
}
},
"results_per_page": {
"name": "results_per_page",
"in": "query",
"description": "Number of bookings returned per page. Maximum allowed value is 1000. Defaults to 1000.",
"required": false,
"schema": {
"type": "number"
}
},
"survey_id": {
"name": "survey_id",
"in": "query",
"description": "Provides a list of every sensor within every map in a survey/library. It can optionally provide the current state of a sensor (e.g. Occupied / Absent), but by default it will only list the sensors without their states.",
"required": true,
"schema": {
"type": "number"
}
},
"survey_ids": {
"name": "survey_ids",
"in": "query",
"description": "A comma delimited list of Survey IDs. If this parameter is not supplied, historical data for every survey is returned.",
"required": false,
"schema": {
"type": "string"
}
},
"survey_filter": {
"name": "survey_filter",
"in": "query",
"description": "Filter the surveys based on who they are designed for. Valid values of this parameter are `all` (no filtering), `student` (return only student surveys; this is the default) and `staff` (return only surveys representing work areas for UCL staff only). It is recommended that the default (student) is used in apps aimed at students, unless a specific reason to include a staff workspace is required.",
"required": false,
"schema": {
"type": "string"
}
},
"sensor_id": {
"name": "sensor_id",
"in": "query",
"description": "The ID of a sensor.",
"required": true,
"example": "20520001",
"schema": {
"type": "number"
}
},
"cursor": {
"name": "cursor",
"in": "query",
"description": "Cursor from which to fetch the next or previous page of results.",
"required": false,
"example": "bz0xJnA9MjAyMC0wMS0xNysxMiUzQTQwJTNBMDA%3D",
"schema": {
"type": "string"
}
},
"page": {
"name": "page",
"in": "query",
"description": "Page of pagination results (see URL in `next` field).",
"required": false,
"example": "2",
"schema": {
"type": "integer"
}
},
"active": {
"name": "active",
"in": "query",
"description": "If a survey location is active (true) or not (false).",
"required": false,
"example": true,
"schema": {
"type": "boolean"
}
},
"libcal_details": {
"name": "details",
"in": "query",
"description": "Flag to indicate you want additional details such as terms and conditions.",
"required": false,
"example": 1,
"schema": {
"type": "integer"
}
},
"libcal_location_id": {
"name": "ids",
"in": "query",
"description": "A single LibCal location ID",
"required": true,
"example": "702",
"schema": {
"type": "string"
}
},
"libcal_location_ids": {
"name": "ids",
"in": "query",
"description": "Comma delimited list of LibCal location IDs",
"required": true,
"example": "702,703",
"schema": {
"type": "string"
}
},
"libcal_category_id": {
"name": "category_id",
"in": "query",
"description": "If specified, will only return data for that category",
"required": false,
"example": "3334",
"schema": {
"type": "string"
}
},
"libcal_category_ids": {
"name": "ids",
"in": "query",
"description": "Comma delimited list of LibCal category IDs",
"required": true,
"example": "3334,3335",
"schema": {
"type": "string"
}
},
"libcal_availability": {
"name": "availability",
"in": "query",
"description": "Either a single date or a comma delimited list of 2 dates (a start and end date). The keyword 'next' (alone) can also be used to return availability for the next date that this item is available. Setting this parameter also sets the details value to 1. Dates should be in YYYY-MM-DD format.",
"example": "2021-01-05",
"schema": {
"type": "string"
},
"required": false
},
"libcal_form_ids": {
"name": "ids",
"in": "query",
"description": "Comma delimited list of LibCal form IDs",
"required": true,
"example": "38,62",
"schema": {
"type": "string"
}
},
"libcal_field_ids": {
"name": "ids",
"in": "query",
"description": "Comma delimited list of LibCal field/question IDs",
"required": true,
"example": "43,8",
"schema": {
"type": "string"
}
},
"libcal_space_id": {
"name": "space_id",
"in": "query",
"description": "If specified, only return data for this space",
"required": false,
"example": "1791",
"schema": {
"type": "string"
}
},
"libcal_space_ids": {
"name": "ids",
"in": "query",
"description": "Comma delimited list of LibCal space IDs",
"required": true,
"example": "469,470",
"schema": {
"type": "string"
}
},
"libcal_zone_id": {
"name": "zone_id",
"in": "query",
"description": "If specified, will only return data for that zone",
"required": false,
"example": "87",
"schema": {
"type": "string"
}
},
"libcal_seat_id": {
"name": "ids",
"in": "query",
"description": "A single LibCal seat ID",
"required": true,
"example": "54435",
"schema": {
"type": "string"
}
},
"libcal_accessible_only": {
"name": "accessible_only",
"in": "query",
"description": "Return only acessible seats (i.e. seats with height-adjustable furniture).",
"required": false,
"example": false,
"schema": {
"type": "boolean"
}
},
"libcal_page_index": {
"name": "page_index",
"in": "query",
"description": "For pagination purposes, this specifies the page to be retrieved. Starts at 0 for the first page.",
"required": false,
"example": 0,
"schema": {
"type": "integer"
}
},
"libcal_page_size": {
"name": "page_size",
"in": "query",
"description": "For pagination purposes, this specifies the number of results per page. Must be >= 1 and <= 100. The default is 20.",
"required": false,
"example": 10,
"schema": {
"type": "integer"
}
},
"libcal_booking_ids": {
"name": "id",
"in": "query",
"description": "A comma delimited list of LibCal booking IDs to cancel",
"required": true,
"example": "cs_loYG4wTz,ab_P1bn30Mn",
"schema": {
"type": "string"
}
}
},
"schemas": {
"libcal_reserve_request_booking": {
"description": "Specify seat_id if booking a seat, otherwise omit it",
"properties": {
"id": {
"$ref": "#/components/schemas/libcal_space_id"
},
"to": {
"$ref": "#/components/schemas/libcal_booking_end"
},
"seat_id": {
"$ref": "#/components/schemas/libcal_seat_id"
}
},
"required": [
"id",
"to"
]
},
"libcal_reserve_request": {
"properties": {
"start": {
"$ref": "#/components/schemas/libcal_booking_start"
},
"test": {
"type": "integer",
"description": "Whether or not this is a test booking. If set, the system will process the booking but will not actually make it. This is useful during development.",
"example": 1
},
"nickname": {
"type": "string",
"description": "If the space to be booked has a nickname, then the nickname must be supplied here.",
"example": "Tutorial Group Y"
},
"bookings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/libcal_reserve_request_booking"
}
}
},
"required": [
"start",
"test"
]
},
"libcal_personal_seat_booking": {
"allOf": [
{
"$ref": "#/components/schemas/libcal_seat_booking"
}
],
"properties": {
"book_id": {
"$ref": "#/components/schemas/libcal_booking_id"
},
"first_name": {
"type": "string",
"description": "First name of the user who booked this",
"example": "Jeremy"
},
"last_name": {
"type": "string",
"description": "Last name of the user who booked this",
"example": "Bentham"
},
"email": {
"type": "string",
"description": "Email address of the user who booked this",
"example": "jeremy.bentham.00@ucl.ac.uk"
},
"check_in_code": {
"type": "string",
"description": "Email address of the user who booked this",
"example": "2A9"
}
}
},
"libcal_seat_booking": {
"properties": {
"eid": {
"$ref": "#/components/schemas/libcal_space_id"
},
"cid": {
"$ref": "#/components/schemas/libcal_category_id"
},
"lid": {
"$ref": "#/components/schemas/libcal_location_id"
},
"from_date": {
"$ref": "#/components/schemas/libcal_booking_start"
},
"to_date": {
"$ref": "#/components/schemas/libcal_booking_end"
},
"created": {
"$ref": "#/components/schemas/libcal_booking_created"
},
"status": {
"type": "string",
"description": "Status of this LibCal booking",
"example": "Confirmed"
},
"location_name": {
"$ref": "#/components/schemas/libcal_location_name"
},
"category_name": {
"$ref": "#/components/schemas/libcal_category_name"
},
"item_name": {
"$ref": "#/components/schemas/libcal_space_name"
},
"seat_id": {
"$ref": "#/components/schemas/libcal_seat_id"
},
"seat_name": {
"$ref": "#/components/schemas/libcal_seat_name"
},
"cancelled": {
"$ref": "#/components/schemas/libcal_cancelled"
}
}
},
"libcal_location_id": {
"type": "integer",
"description": "LibCal Location ID",
"example": 700
},
"libcal_seat_id": {
"type": "integer",
"description": "LibCal seat ID",
"example": 54435
},
"libcal_seat_name": {
"type": "string",
"description": "Name of the LibCal seat",
"example": "367 - Donaldson Reading Room (Law)"
},
"libcal_cancelled": {
"type": "string",
"description": "Timestamp (in ISO 8601 format) at which this LibCal booking was cancelled, if applicable",
"example": "2021-01-14T09:00:00+00:00"
},
"libcal_seat": {
"properties": {
"id": {
"$ref": "#/components/schemas/libcal_seat_id"
},
"name": {
"$ref": "#/components/schemas/libcal_seat_name"
},
"description": {
"type": "string",
"description": "Description provided for the LibCal seat. May contain HTML",
"example": "<p>Donaldson Reading Room (Law)</p>"
},
"is_accessible": {
"type": "boolean",
"description": "Whether the seat is height-adjustable and hence accessible by the differently-abled",
"example": true
},
"is_powered": {
"type": "boolean",
"description": "Whether a power socket is available at the seat",
"example": true
},
"image": {
"type": "string",
"description": "A URL pointing to an image of the seat. If none is available, an empty string will be returned",
"example": "https://example.org/seat.png"
},
"status": {
"type": "boolean",
"description": "The current status of the seat",
"example": true
}
}
},
"libcal_zone_id": {
"type": "integer",
"description": "LibCal Zone ID",
"example": 2263
},
"libcal_zone_name": {
"type": "string",
"description": "Name of the LibCal zone",
"example": "Fourth Floor North"
},
"libcal_zone": {
"properties": {
"id": {
"$ref": "#/components/schemas/libcal_zone_id"
},
"name": {
"$ref": "#/components/schemas/libcal_zone_name"
}
}
},
"libcal_utilisation_seat_summary": {
"properties": {
"active": {
"type": "integer",
"description": "Number of active LibCal bookings of seats",
"example": 2
},
"bookable_count": {
"type": "integer",
"description": "Number of LibCal seats available to be booked",
"example": 98
},
"total": {
"type": "integer",
"description": "Total number of LibCal seats in the location",
"example": 100
}
}
},
"libcal_utilisation_space_summary": {
"properties": {
"active": {
"type": "integer",
"description": "Number of active LibCal bookings of spaces",
"example": 2
},
"bookable_count": {
"type": "integer",
"description": "Number of LibCal spaces available to be booked",
"example": 28
},
"total": {
"type": "integer",
"description": "Total number of LibCal spaces in the location",
"example": 30
}
}
},
"libcal_booking_start": {
"type": "string",
"example": "2021-01-14T09:00:00+00:00",
"description": "Timestamp (in ISO 8601 format) at which this LibCal booking starts"
},
"libcal_booking_end": {
"type": "string",
"example": "2021-01-14T09:00:00+00:00",
"description": "Timestamp (in ISO 8601 format) at which this LibCal booking ends"
},
"libcal_booking_created": {
"type": "string",
"example": "2021-01-12T09:00:00+00:00",
"description": "Timestamp (in ISO 8601 format) denoting when this LibCal booking was created"
},
"libcal_booking_id": {
"type": "string",
"example": "_L4oMxm",
"description": "ID assigned to this LibCal booking"
},
"libcal_booking": {
"properties": {
"nickname": {
"type": "string",
"description": "Nickname assigned to this LibCal booking",
"example": "LAWS0339: Internet Law and Policy Seminar Group G"
},
"start": {
"$ref": "#/components/schemas/libcal_booking_start"
},
"end": {
"$ref": "#/components/schemas/libcal_booking_end"
},
"created": {
"$ref": "#/components/schemas/libcal_booking_created"
},
"booking_id": {
"$ref": "#/components/schemas/libcal_booking_id"
}
}
},
"libcal_space_id": {
"type": "integer",
"example": 469,
"description": "ID of this LibCal space"
},
"libcal_space_name": {
"type": "string",
"example": "Study Room 1",
"description": "Name of this LibCal space"
},
"libcal_space_base": {
"properties": {
"id": {
"$ref": "#/components/schemas/libcal_space_id"
},
"name": {
"$ref": "#/components/schemas/libcal_space_name"
},
"description": {
"type": "string",
"example": "A place for quiet study",
"description": "Description of this LibCal space"
},
"image": {
"type": "string",
"example": "https://example.org/image.jpg",
"description": "URL pointing to an image depicting this LibCal space"
},
"capacity": {
"type": "integer",
"example": 4,
"description": "Maximum number of persons this LibCal space can accommodate"
},
"formid": {
"type": "integer",
"example": 14,
"description": "ID of the form associated with this LibCal space"
}
}
},
"libcal_space_availability": {
"type": "array",
"items": {
"properties": {
"from": {
"type": "string",
"example": "2021-01-14T09:00:00+00:00",
"description": "Timestamp (in ISO 8601 format) from which this LibCal space is available to be booked"
},
"to": {
"type": "string",
"example": "2021-01-14T10:00:00+00:00",
"description": "Timestamp (in ISO 8601 format) to which this LibCal space is available to be booked"
}
}
}
},
"libcal_form_field": {
"properties": {
"label": {
"type": "string",
"example": "First Name",
"description": "Label for the field in the LibCal booking form"
},
"type": {
"type": "string",
"example": "string",
"description": "Field type for the field in the LibCal booking form. Examples of field types include 'string' and 'dropdown'."
},
"required": {
"type": "boolean",
"example": false,
"description": "Whether the field in the LibCal booking form is required (true) or optional (false)"
},
"options": {
"type": "array",
"items": {
"type": "string",
"example": "Medicine"
},
"description": "Array of options that will be provided if the field type is dropdown"
}
}
},
"libcal_form_id": {
"type": "integer",
"example": 0,
"description": "LibCal booking form ID"
},
"libcal_form": {
"properties": {
"id": {
"$ref": "#/components/schemas/libcal_form_id"
},
"name": {
"type": "string",
"example": "COVID Health Check",
"description": "Name of the LibCal booking form"
},
"fields": {
"type": "array",
"items": {
"$ref": "#/components/schemas/libcal_form_field"
}
}
}
},
"libcal_category_id": {
"type": "integer",
"example": 3334,
"description": "LibCal category ID denoting a category assigned to a particular space"
},
"libcal_category_public": {
"type": "integer",
"example": 0,
"description": "1 if the category of spaces is publicly-bookable, 0 if it is not"
},
"libcal_category_name": {
"type": "string",
"example": "Study Space",
"description": "Name of the category"
},
"libcal_category": {
"properties": {
"cid": {
"$ref": "#/components/schemas/libcal_category_id"
},
"formid": {
"$ref": "#/components/schemas/libcal_form_id"
},
"name": {
"$ref": "#/components/schemas/libcal_category_name"
},
"public": {
"$ref": "#/components/schemas/libcal_category_public"
}
}
},
"libcal_location_name": {
"type": "string",
"example": "Bartlett Library",
"description": "Name of the LibCal location in question"
},
"libcal_location_base": {
"properties": {
"lid": {
"type": "integer",
"example": 702,
"description": "ID for the LibCal location in question"
},
"name": {
"$ref": "#/components/schemas/libcal_location_name"
}
}
},
"libcal_location": {
"allOf": [
{
"$ref": "#/components/schemas/libcal_location_base"
}
],
"properties": {
"public": {
"type": "integer",
"example": 1,
"description": "1 if the location is publicly-bookable, 0 if it is not"
},
"terms": {
"type": "string",
"example": "<strong>You must bring your UCL ID and a copy of the confirmation email to gain access to the space.</strong>",
"description": "Additional details about the location, such as terms & conditions. May include HTML."
}
}
},
"user_data": {
"properties": {
"ok": {
"type": "boolean",
"example": "true",
"description": "Returns if the query was successful."
},
"email": {
"type": "string",
"example": "xxxxxxx@ucl.ac.uk",
"description": "Email address for the given user."
},
"full_name": {
"type": "string",
"example": "John Doe",
"description": "Full name of the user. Can be an empty string."
},
"department": {
"type": "string",
"example": "Dept of Computer Science",
"description": "Department the user belongs to. Can be an empty string."
},
"cn": {
"type": "string",
"example": "xxxxxxx",
"description": "UCL username of the given user."
},
"given_name": {
"type": "string",
"example": "John",
"description": "Given first name of the user. Can be an empty string."
},
"upi": {
"type": "string",
"example": "jdoe12",
"description": "Unique Person Identifier."
},
"scope_number": {
"type": "integer",
"format": "int64",
"example": 0,
"description": "Scopes the application has access to on behalf of the user."
},
"is_student": {
"type": "boolean",
"example": true,
"description": "Whether the user is a student in this academic year."
},
"ucl_groups": {
"type": "string",
"example": "ucl-all;ucl-ug",
"description": "A semi-colon delimited string of all UCL intranet groups that the user belongs to."
}
}
},
"event": {
"properties": {
"location": {
"$ref": "#/components/schemas/location"
},
"module": {
"$ref": "#/components/schemas/module"
},
"start_time": {
"type": "string",
"example": "2016-09-02T09:00:00+00:00",
"description": "Start time of the event."
},
"end_time": {
"type": "string",
"example": "2016-09-02T10:00:00+00:00",
"description": "End time of the event."
},
"duration": {
"type": "integer",
"format": "int64",
"example": 60,
"description": "Duration of the event in minutes."
},
"session_type": {
"type": "string",
"example": "L",
"description": "ID of the type of session, e.g. L = Lecture, PBL = Problem Based Learning. These come from UCL's internal database, and are provided in case a new session type that we are not aware of is in the timetable. See session_type_str below."
},
"session_type_str": {
"type": "string",
"example": "Lecture",
"description": "Type of event such as Lecture, Problem Based Learning, Practical, etc. If the session_type has not been recognised by us then this will have the value Unknown."
},
"session_group": {
"type": "string",
"example": "",
"description": "Used for lab groups, or other types of small group activity that does not involve the whole cohort. When the whole cohort is invited (e.g. lectures) this value is a blank string. In the personal timetable endpoint only the labs / group sessions assigned to the user with the OAuth token provided will be returned. For example, if the user is in LAB A then Labs B onwards will not be returned."
},
"session_title": {
"type": "string",
"example": "Computational Complexity A",
"description": "The title of the event."
},
"contact": {
"type": "string",